diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..f4d39b2 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,361 @@ +name: CI - Multi-Platform Native + +on: + pull_request: + push: + branches: [ master, develop ] + workflow_dispatch: + inputs: + configuration: + description: 'Build configuration' + required: false + default: 'Debug' + type: choice + options: + - Debug + - Release + platforms: + description: 'Comma-separated platforms to build (ios, android, linux)' + required: false + default: 'ios' + type: string + run_tests: + description: 'Run unit tests' + required: false + default: true + type: boolean + +defaults: + run: + shell: bash + +jobs: + # iOS Build Job + build-ios: + name: Build iOS (RSSuper) + runs-on: macos + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Show available Xcode versions + run: | + echo "=== Available Xcode installations ===" + ls -la /Applications/ | grep -i xcode || echo "No Xcode found in /Applications" + echo "" + echo "=== Current xcode-select path ===" + xcode-select -p || echo "xcode-select failed" + echo "" + echo "=== xcodebuild version ===" + xcodebuild -version || echo "xcodebuild failed" + + - name: Select Xcode version + run: | + echo "=== Current xcode-select path ===" + xcode-select -p || echo "xcode-select failed" + echo "=== Current Xcode version ===" + xcodebuild -version || echo "xcodebuild failed" + + # Try common Xcode paths in order of preference (newest first) + for path in \ + "/Applications/Xcode_16.3.app/Contents/Developer" \ + "/Applications/Xcode_16.2.app/Contents/Developer" \ + "/Applications/Xcode_16.1.app/Contents/Developer" \ + "/Applications/Xcode_16.0.app/Contents/Developer" \ + "/Applications/Xcode_15.4.app/Contents/Developer" \ + "/Applications/Xcode_15.3.app/Contents/Developer" \ + "/Applications/Xcode_15.2.app/Contents/Developer" \ + "/Applications/Xcode_15.1.app/Contents/Developer" \ + "/Applications/Xcode_15.0.app/Contents/Developer" \ + "/Applications/Xcode.app/Contents/Developer" + do + if [ -d "$path" ]; then + CURRENT_PATH=$(xcode-select -p 2>/dev/null || echo "") + if [ "$CURRENT_PATH" != "$path" ]; then + echo "Switching Xcode to: $path" + xcode-select -s "$path" || true + else + echo "Xcode already selected at: $path" + fi + break + fi + done + + echo "=== Selected Xcode path ===" + xcode-select -p + echo "=== Xcode version ===" + xcodebuild -version + + - name: Build iOS Debug + id: build_ios_debug + run: | + cd native-route/ios/RSSuper + + TIMESTAMP=$(date -u "+%Y-%m-%d %H:%M:%S UTC") + COMMIT="${{ github.sha }}" + SHORT_COMMIT="${COMMIT:0:7}" + REF="${{ github.ref_name }}" + + BUILD_LOG=$(mktemp) + echo "Capturing build output to: $BUILD_LOG" + + set +e + xcodebuild -project RSSuper.xcodeproj \ + -scheme RSSuper \ + -configuration Debug \ + -destination "generic/platform=iOS" \ + build > "$BUILD_LOG" 2>&1 + BUILD_EXIT=$? + set -e + + cat "$BUILD_LOG" + echo "Build completed with exit code: $BUILD_EXIT" + + if [ "$BUILD_EXIT" = "0" ]; then + STATUS="PASSED" + else + STATUS="FAILED" + fi + + # Extract errors + ERRORS="" + WARNINGS="" + FALLBACK="" + + if [ -f "$BUILD_LOG" ] && [ -s "$BUILD_LOG" ]; then + ERRORS=$(grep -E "\.swift:[0-9]+:[0-9]+: error:" "$BUILD_LOG" \ + | sed 's|.*/\([^/]*\.swift\)|\1|' \ + | sort -u || true) + + GENERAL_ERRORS=$(grep -E "error:|Error:" "$BUILD_LOG" \ + | grep -v "\.swift:[0-9]+:[0-9]+:" \ + | head -10 || true) + + WARNINGS=$(grep -E "\.swift:[0-9]+:[0-9]+: warning:" "$BUILD_LOG" \ + | sed 's|.*/\([^/]*\.swift\)|\1|' \ + | sort -u || true) + + if [ -z "$ERRORS" ] && [ -z "$GENERAL_ERRORS" ]; then + FALLBACK=$(grep -E "error:|failed|FAILED|BUILD FAILED|note:" "$BUILD_LOG" \ + | grep -v "^export " \ + | grep -v "^ " \ + | tail -30 || true) + fi + fi + + # Generate iOS build report + { + echo "# iOS Build Report" + echo "" + echo "| | |" + echo "|---|---|" + echo "| **Status** | $STATUS |" + echo "| **Commit** | \`$SHORT_COMMIT\` |" + echo "| **Branch** | \`$REF\` |" + echo "| **Time** | $TIMESTAMP |" + echo "" + + if [ "$STATUS" = "FAILED" ]; then + echo "## Errors" + echo "" + if [ -n "$ERRORS" ]; then + echo '```' + echo "$ERRORS" + echo '```' + echo "" + fi + else + echo "## Result" + echo "" + echo "iOS build completed successfully." + echo "" + fi + + if [ -n "$WARNINGS" ]; then + echo "## Warnings" + echo "" + echo '```' + echo "$WARNINGS" + echo '```' + echo "" + fi + } > ios-build-report.md + + echo "=== Generated ios-build-report.md ===" + cat ios-build-report.md + + rm -f "$BUILD_LOG" + exit $BUILD_EXIT + + - name: Upload iOS Debug artifact + if: steps.build_ios_debug.outcome == 'success' + uses: actions/upload-artifact@v4 + with: + name: RSSuper-iOS-Debug + path: | + ~/Library/Developer/Xcode/DerivedData/RSSuper-*/Build/Products/Debug-iphoneos/RSSuper.app + if-no-files-found: warn + retention-days: 7 + + - name: Run iOS Unit Tests + if: ${{ github.event_name != 'workflow_dispatch' || inputs.run_tests == true }} + run: | + cd native-route/ios/RSSuper + xcodebuild test -project RSSuper.xcodeproj \ + -scheme RSSuper \ + -configuration Debug \ + -destination "generic/platform=iOS" \ + ONLY_ACTIVE_ARCH=NO + + - name: Build iOS Release + run: | + cd native-route/ios/RSSuper + xcodebuild -project RSSuper.xcodeproj \ + -scheme RSSuper \ + -configuration Release \ + -destination "generic/platform=iOS" \ + build + + - name: Upload iOS Release artifact + uses: actions/upload-artifact@v4 + with: + name: RSSuper-iOS-Release + path: | + ~/Library/Developer/Xcode/DerivedData/RSSuper-*/Build/Products/Release-iphoneos/RSSuper.app + if-no-files-found: warn + retention-days: 30 + + # macOS Build Job (using same iOS project) + build-macos: + name: Build macOS + runs-on: macos-15 + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Select Xcode + run: | + xcode-select -s /Applications/Xcode.app/Contents/Developer + xcodebuild -version + + - name: Build macOS + run: | + cd native-route/ios/RSSuper + + # Note: This requires the Xcode project to have a macOS target + # For now, we'll build for iOS simulator which can run on macOS + xcodebuild -project RSSuper.xcodeproj \ + -scheme RSSuper \ + -configuration Debug \ + -destination "platform=macOS" \ + build || echo "macOS target not configured yet" + + # Android Build Job + build-android: + name: Build Android + runs-on: ubuntu-24.04 + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + + - name: Setup Android SDK + uses: android-actions/setup-android@v3 + + - name: Build Android Debug + run: | + cd native-route/android + + # Create basic Android project structure if it doesn't exist + if [ ! -f "build.gradle.kts" ]; then + echo "Android project not yet initialized" + echo "Placeholder for Android build" + else + ./gradlew assembleDebug + fi + + - name: Upload Android artifact + if: always() + uses: actions/upload-artifact@v4 + with: + name: RSSuper-Android-Debug + path: native-route/android/app/build/outputs/apk/debug/*.apk + if-no-files-found: ignore + retention-days: 7 + + # Linux Build Job + build-linux: + name: Build Linux + runs-on: ubuntu-24.04 + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y \ + build-essential \ + cmake \ + ninja-build \ + pkg-config \ + libgtk-3-dev \ + libsqlite3-dev + + - name: Build Linux + run: | + cd native-route/linux + + # Placeholder for Linux build + # This will be set up with proper build system later + echo "Linux build placeholder" + echo "Project structure will be created with:" + echo "- CMake or Meson build system" + echo "- GTK4 or GTK+3 for UI" + echo "- Swift Linux runtime or alternative" + + # Summary Job + build-summary: + name: Build Summary + runs-on: ubuntu-24.04 + needs: [build-ios, build-macos, build-android, build-linux] + if: always() + + steps: + - name: Generate Summary + run: | + echo "# RSSuper Multi-Platform Build Summary" > summary.md + echo "" >> summary.md + echo "## Build Results" >> summary.md + echo "" >> summary.md + echo "| Platform | Status |" >> summary.md + echo "|----------|--------|" >> summary.md + echo "| iOS | ${{ needs.build-ios.result }} |" >> summary.md + echo "| macOS | ${{ needs.build-macos.result }} |" >> summary.md + echo "| Android | ${{ needs.build-android.result }} |" >> summary.md + echo "| Linux | ${{ needs.build-linux.result }} |" >> summary.md + echo "" >> summary.md + echo "## Details" >> summary.md + echo "" >> summary.md + echo "- **Commit:** ${{ github.sha }}" >> summary.md + echo "- **Branch:** ${{ github.ref_name }}" >> summary.md + echo "- **Date:** $(date -u "+%Y-%m-%d %H:%M:%S UTC")" >> summary.md + echo "" >> summary.md + + cat summary.md + + - name: Upload Summary + uses: actions/upload-artifact@v4 + with: + name: build-summary + path: summary.md + retention-days: 1 diff --git a/README.md b/README.md index 4d67aec..939001f 100644 --- a/README.md +++ b/README.md @@ -1,56 +1,136 @@ -# Welcome to your Expo app 👋 +# RSSuper - Native Multi-Platform RSS Reader -This is an [Expo](https://expo.dev) project created with [`create-expo-app`](https://www.npmjs.com/package/create-expo-app). +A native RSS reader built for iOS, macOS, Android, Linux, and Windows. -## Get started +## Architecture -1. Install dependencies +RSSuper uses a native-first approach, building truly native applications for each platform: - ```bash - npm install - ``` +| Platform | Language | UI Framework | Status | +|----------|----------|--------------|--------| +| iOS | Swift | SwiftUI | ✅ Active | +| macOS | Swift | SwiftUI | ✅ Active | +| Android | Kotlin | Jetpack Compose | 🚧 Setup | +| Linux | C/Vala | GTK4 + Libadwaita | 🚧 Setup | +| Windows | C# | WinUI 3 | 🔜 Planned | -2. Start the app +## Quick Start - ```bash - npx expo start - ``` - -In the output, you'll find options to open the app in a - -- [development build](https://docs.expo.dev/develop/development-builds/introduction/) -- [Android emulator](https://docs.expo.dev/workflow/android-studio-emulator/) -- [iOS simulator](https://docs.expo.dev/workflow/ios-simulator/) -- [Expo Go](https://expo.dev/go), a limited sandbox for trying out app development with Expo - -You can start developing by editing the files inside the **app** directory. This project uses [file-based routing](https://docs.expo.dev/router/introduction). - -## Get a fresh project - -When you're ready, run: +### Build All Platforms ```bash -npm run reset-project +./scripts/build.sh ``` -This command will move the starter code to the **app-example** directory and create a blank **app** directory where you can start developing. +### Build Specific Platform -### Other setup steps +```bash +# iOS/macOS +./scripts/build.sh -p ios -- To set up ESLint for linting, run `npx expo lint`, or follow our guide on ["Using ESLint and Prettier"](https://docs.expo.dev/guides/using-eslint/) -- If you'd like to set up unit testing, follow our guide on ["Unit Testing with Jest"](https://docs.expo.dev/develop/unit-testing/) -- Learn more about the TypeScript setup in this template in our guide on ["Using TypeScript"](https://docs.expo.dev/guides/typescript/) +# Android +./scripts/build.sh -p android -## Learn more +# Linux +./scripts/build.sh -p linux +``` -To learn more about developing your project with Expo, look at the following resources: +## Project Structure -- [Expo documentation](https://docs.expo.dev/): Learn fundamentals, or go into advanced topics with our [guides](https://docs.expo.dev/guides). -- [Learn Expo tutorial](https://docs.expo.dev/tutorial/introduction/): Follow a step-by-step tutorial where you'll create a project that runs on Android, iOS, and the web. +``` +RSSuper/ +├── native-route/ # Native platform projects +│ ├── ios/ # iOS/macOS Xcode project +│ ├── android/ # Android Gradle project +│ ├── linux/ # Linux Meson project +│ └── windows/ # Windows project (planned) +├── scripts/ # Build scripts +│ ├── build.sh # Main build orchestrator +│ ├── build-ios.sh # iOS/macOS builder +│ ├── build-android.sh # Android builder +│ ├── build-linux.sh # Linux builder +│ └── common.sh # Shared utilities +├── src/ # Expo/web project (legacy) +└── .github/workflows/ # CI configuration +``` -## Join the community +## Build System -Join our community of developers creating universal apps. +The build system is adapted from the Nessa project, providing: -- [Expo on GitHub](https://github.com/expo/expo): View our open source platform and contribute. -- [Discord community](https://chat.expo.dev): Chat with Expo users and ask questions. +- **Cross-platform build orchestration** +- **Automatic Xcode version selection** +- **Build reports with error extraction** +- **GitHub Actions CI/CD** +- **Consistent build experience across platforms** + +### Build Commands + +```bash +# Build all platforms (debug) +./scripts/build.sh + +# Build release +./scripts/build.sh -t release + +# Build specific platforms +./scripts/build.sh -p ios,android + +# Run tests +./scripts/build.sh --test + +# Clean builds +./scripts/build.sh -a clean +``` + +### Individual Platform Scripts + +```bash +# iOS/macOS +./scripts/build-ios.sh [Debug|Release] [iOS|macOS] [destination] [action] + +# Android +./scripts/build-android.sh [debug|release] [assemble|build|test|clean] + +# Linux +./scripts/build-linux.sh [debug|release] [build|install|test|clean|setup] +``` + +## CI/CD + +GitHub Actions automatically builds all platforms on: +- Pull requests +- Pushes to main/develop branches +- Manual workflow dispatch + +See `.github/workflows/ci.yml` for configuration. + +## Platform Details + +### iOS/macOS +- Swift + SwiftUI +- Xcode build system +- Minimum: iOS 16.0+ + +### Android +- Kotlin + Jetpack Compose +- Gradle build system +- Minimum: Android 7.0 (API 24) + +### Linux +- C/Vala + GTK4 + Libadwaita +- Meson build system +- Requires: GTK4, Libadwaita, SQLite3 + +### Windows (Planned) +- C# + WinUI 3 +- MSBuild/Cake build system + +## Learn More + +- [Native Route README](native-route/README.md) - Detailed platform documentation +- [Build Scripts](scripts/) - Build system source + +## License + +MIT diff --git a/bun.lock b/bun.lock index 2e767bb..9ca0187 100644 --- a/bun.lock +++ b/bun.lock @@ -5,11 +5,14 @@ "": { "name": "rssuper", "dependencies": { + "@react-native-async-storage/async-storage": "^3.0.2", "@react-navigation/bottom-tabs": "^7.15.5", "@react-navigation/elements": "^2.9.10", "@react-navigation/native": "^7.1.33", "@tanstack/react-query": "^5.95.2", "axios": "^1.14.0", + "buffer": "^6.0.3", + "events": "^3.3.0", "expo": "55.0.10-canary-20260328-2049187", "expo-constants": "55.0.10-canary-20260328-2049187", "expo-device": "55.0.11-canary-20260328-2049187", @@ -27,21 +30,25 @@ "expo-system-ui": "55.0.12-canary-20260328-2049187", "expo-task-manager": "55.0.11-canary-20260328-2049187", "expo-web-browser": "55.0.11-canary-20260328-2049187", + "fast-xml-parser": "^5.5.9", "react": "19.2.0", "react-dom": "19.2.0", "react-native": "0.83.4", "react-native-gesture-handler": "~2.30.0", "react-native-reanimated": "4.2.1", + "react-native-render-html": "^6.3.4", "react-native-safe-area-context": "~5.6.2", "react-native-screens": "~4.23.0", "react-native-web": "~0.21.0", "react-native-worklets": "0.7.2", - "xml2js": "^0.6.2", + "stream-browserify": "^3.0.0", "zustand": "^5.0.12", }, "devDependencies": { "@types/react": "~19.2.2", "@types/xml2js": "^0.4.14", + "eslint": "^9.0.0", + "eslint-config-expo": "55.0.1-canary-20260328-2049187", "typescript": "~5.9.2", }, }, @@ -235,6 +242,30 @@ "@egjs/hammerjs": ["@egjs/hammerjs@2.0.17", "", { "dependencies": { "@types/hammerjs": "^2.0.36" } }, "sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A=="], + "@emnapi/core": ["@emnapi/core@1.9.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.0", "tslib": "^2.4.0" } }, "sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA=="], + + "@emnapi/runtime": ["@emnapi/runtime@1.9.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA=="], + + "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg=="], + + "@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.9.1", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ=="], + + "@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.2", "", {}, "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew=="], + + "@eslint/config-array": ["@eslint/config-array@0.21.2", "", { "dependencies": { "@eslint/object-schema": "^2.1.7", "debug": "^4.3.1", "minimatch": "^3.1.5" } }, "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw=="], + + "@eslint/config-helpers": ["@eslint/config-helpers@0.4.2", "", { "dependencies": { "@eslint/core": "^0.17.0" } }, "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw=="], + + "@eslint/core": ["@eslint/core@0.17.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ=="], + + "@eslint/eslintrc": ["@eslint/eslintrc@3.3.5", "", { "dependencies": { "ajv": "^6.14.0", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.1", "minimatch": "^3.1.5", "strip-json-comments": "^3.1.1" } }, "sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg=="], + + "@eslint/js": ["@eslint/js@9.39.4", "", {}, "sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw=="], + + "@eslint/object-schema": ["@eslint/object-schema@2.1.7", "", {}, "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA=="], + + "@eslint/plugin-kit": ["@eslint/plugin-kit@0.4.1", "", { "dependencies": { "@eslint/core": "^0.17.0", "levn": "^0.4.1" } }, "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA=="], + "@expo-google-fonts/material-symbols": ["@expo-google-fonts/material-symbols@0.4.27", "", {}, "sha512-cnb3DZnWUWpezGFkJ8y4MT5f/lw6FcgDzeJzic+T+vpQHLHG1cg3SC3i1w1i8Bk4xKR4HPY3t9iIRNvtr5ml8A=="], "@expo/cli": ["@expo/cli@55.0.20-canary-20260328-2049187", "", { "dependencies": { "@expo/code-signing-certificates": "^0.0.6", "@expo/config": "55.0.12-canary-20260328-2049187", "@expo/config-plugins": "55.0.8-canary-20260328-2049187", "@expo/devcert": "^1.2.1", "@expo/env": "2.1.2-canary-20260328-2049187", "@expo/image-utils": "0.8.13-canary-20260328-2049187", "@expo/json-file": "10.0.13-canary-20260328-2049187", "@expo/log-box": "55.0.9-canary-20260328-2049187", "@expo/metro": "~54.2.0", "@expo/metro-config": "55.0.12-canary-20260328-2049187", "@expo/osascript": "2.4.3-canary-20260328-2049187", "@expo/package-manager": "1.10.4-canary-20260328-2049187", "@expo/plist": "0.5.3-canary-20260328-2049187", "@expo/prebuild-config": "55.0.12-canary-20260328-2049187", "@expo/require-utils": "55.0.4-canary-20260328-2049187", "@expo/router-server": "55.0.12-canary-20260328-2049187", "@expo/schema-utils": "55.0.3-canary-20260328-2049187", "@expo/spawn-async": "^1.7.2", "@expo/ws-tunnel": "^1.0.1", "@expo/xcpretty": "^4.4.0", "@react-native/dev-middleware": "0.83.4", "accepts": "^1.3.8", "arg": "^5.0.2", "better-opn": "~3.0.2", "bplist-creator": "0.1.0", "bplist-parser": "^0.3.1", "chalk": "^4.0.0", "ci-info": "^3.3.0", "compression": "^1.7.4", "connect": "^3.7.0", "debug": "^4.3.4", "dnssd-advertise": "^1.1.3", "expo-server": "55.0.7-canary-20260328-2049187", "fetch-nodeshim": "^0.4.6", "getenv": "^2.0.0", "glob": "^13.0.0", "lan-network": "^0.2.0", "multitars": "^0.2.3", "node-forge": "^1.3.3", "npm-package-arg": "^11.0.0", "ora": "^3.4.0", "picomatch": "^4.0.3", "pretty-format": "^29.7.0", "progress": "^2.0.3", "prompts": "^2.3.2", "resolve-from": "^5.0.0", "semver": "^7.6.0", "send": "^0.19.0", "slugify": "^1.3.4", "source-map-support": "~0.5.21", "stacktrace-parser": "^0.1.10", "structured-headers": "^0.4.1", "terminal-link": "^2.1.1", "toqr": "^0.1.1", "wrap-ansi": "^7.0.0", "ws": "^8.12.1", "zod": "^3.25.76" }, "peerDependencies": { "expo": "55.0.10-canary-20260328-2049187", "expo-router": "55.0.9-canary-20260328-2049187", "react-native": "*" }, "optionalPeers": ["expo-router", "react-native"], "bin": { "expo-internal": "build/bin/cli" } }, "sha512-drj/Gg7BpGeqCNBTxPeQR7kfiW4EFTOHRmrtcnXtT1qC96LVlpzOrkwcCLRdumvmeARGA055HFqKdHNxvwsCmg=="], @@ -297,6 +328,14 @@ "@expo/xcpretty": ["@expo/xcpretty@4.4.1", "", { "dependencies": { "@babel/code-frame": "^7.20.0", "chalk": "^4.1.0", "js-yaml": "^4.1.0" }, "bin": { "excpretty": "build/cli.js" } }, "sha512-KZNxZvnGCtiM2aYYZ6Wz0Ix5r47dAvpNLApFtZWnSoERzAdOMzVBOPysBoM0JlF6FKWZ8GPqgn6qt3dV/8Zlpg=="], + "@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="], + + "@humanfs/node": ["@humanfs/node@0.16.7", "", { "dependencies": { "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.4.0" } }, "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ=="], + + "@humanwhocodes/module-importer": ["@humanwhocodes/module-importer@1.0.1", "", {}, "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA=="], + + "@humanwhocodes/retry": ["@humanwhocodes/retry@0.4.3", "", {}, "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ=="], + "@isaacs/ttlcache": ["@isaacs/ttlcache@1.4.1", "", {}, "sha512-RQgQ4uQ+pLbqXfOmieB91ejmLwvSgv9nLx6sT6sD83s7umBypgg+OIBOBbEUiJXrfpnp9j0mRhYYdzp9uqq3lA=="], "@istanbuljs/load-nyc-config": ["@istanbuljs/load-nyc-config@1.1.0", "", { "dependencies": { "camelcase": "^5.3.1", "find-up": "^4.1.0", "get-package-type": "^0.1.0", "js-yaml": "^3.13.1", "resolve-from": "^5.0.0" } }, "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ=="], @@ -327,6 +366,18 @@ "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="], + "@jsamr/counter-style": ["@jsamr/counter-style@2.0.2", "", {}, "sha512-2mXudGVtSzVxWEA7B9jZLKjoXUeUFYDDtFrQoC0IFX9/Dszz4t1vZOmafi3JSw/FxD+udMQ+4TAFR8Qs0J3URQ=="], + + "@jsamr/react-native-li": ["@jsamr/react-native-li@2.3.1", "", { "peerDependencies": { "@jsamr/counter-style": "^1.0.0 || ^2.0.0", "react": "*", "react-native": "*" } }, "sha512-Qbo4NEj48SQ4k8FZJHFE2fgZDKTWaUGmVxcIQh3msg5JezLdTMMHuRRDYctfdHI6L0FZGObmEv3haWbIvmol8w=="], + + "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@0.2.12", "", { "dependencies": { "@emnapi/core": "^1.4.3", "@emnapi/runtime": "^1.4.3", "@tybys/wasm-util": "^0.10.0" } }, "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ=="], + + "@native-html/css-processor": ["@native-html/css-processor@1.11.0", "", { "dependencies": { "css-to-react-native": "^3.0.0", "csstype": "^3.0.8" }, "peerDependencies": { "@types/react": "*", "@types/react-native": "*" } }, "sha512-NnhBEbJX5M2gBGltPKOetiLlKhNf3OHdRafc8//e2ZQxXN8JaSW/Hy8cm94pnIckQxwaMKxrtaNT3x4ZcffoNQ=="], + + "@native-html/transient-render-engine": ["@native-html/transient-render-engine@11.2.3", "", { "dependencies": { "@native-html/css-processor": "1.11.0", "@types/ramda": "^0.27.44", "csstype": "^3.0.9", "domelementtype": "^2.2.0", "domhandler": "^4.2.2", "domutils": "^2.8.0", "htmlparser2": "^7.1.2", "ramda": "^0.27.2" }, "peerDependencies": { "@types/react-native": "*", "react-native": "^*" } }, "sha512-zXwgA3gPUEmFs3I3syfnvDvS6WiUHXEE6jY09OBzK+trq7wkweOSFWIoyXiGkbXrozGYG0KY90YgPyr8Tg8Uyg=="], + + "@nolyfill/is-core-module": ["@nolyfill/is-core-module@1.0.39", "", {}, "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA=="], + "@radix-ui/primitive": ["@radix-ui/primitive@1.1.3", "", {}, "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg=="], "@radix-ui/react-collection": ["@radix-ui/react-collection@1.1.7", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw=="], @@ -369,6 +420,8 @@ "@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ=="], + "@react-native-async-storage/async-storage": ["@react-native-async-storage/async-storage@3.0.2", "", { "dependencies": { "idb": "8.0.3" }, "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-XP0zDIl+1XoeuQ7f878qXKdl77zLwzLALPpxvNRc7ZtDh9ew36WSvOdQOhFkexMySapFAWxEbZxS8K8J2DU4eg=="], + "@react-native/assets-registry": ["@react-native/assets-registry@0.83.4", "", {}, "sha512-aqKtpbJDSQeSX/Dwv0yMe1/Rd2QfXi12lnyZDXNn/OEKz59u6+LuPBVgO/9CRyclHmdlvwg8c7PJ9eX2ZMnjWg=="], "@react-native/babel-plugin-codegen": ["@react-native/babel-plugin-codegen@0.83.4", "", { "dependencies": { "@babel/traverse": "^7.25.3", "@react-native/codegen": "0.83.4" } }, "sha512-UFsK+c1rvT84XZfzpmwKePsc5nTr5LK7hh18TI0DooNlVcztDbMDsQZpDnhO/gmk7aTbWEqO5AB3HJ7tvGp+Jg=="], @@ -405,6 +458,8 @@ "@react-navigation/routers": ["@react-navigation/routers@7.5.3", "", { "dependencies": { "nanoid": "^3.3.11" } }, "sha512-1tJHg4KKRJuQ1/EvJxatrMef3NZXEPzwUIUZ3n1yJ2t7Q97siwRtbynRpQG9/69ebbtiZ8W3ScOZF/OmhvM4Rg=="], + "@rtsao/scc": ["@rtsao/scc@1.1.0", "", {}, "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g=="], + "@sinclair/typebox": ["@sinclair/typebox@0.27.10", "", {}, "sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA=="], "@sinonjs/commons": ["@sinonjs/commons@3.0.1", "", { "dependencies": { "type-detect": "4.0.8" } }, "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ=="], @@ -415,6 +470,8 @@ "@tanstack/react-query": ["@tanstack/react-query@5.95.2", "", { "dependencies": { "@tanstack/query-core": "5.95.2" }, "peerDependencies": { "react": "^18 || ^19" } }, "sha512-/wGkvLj/st5Ud1Q76KF1uFxScV7WeqN1slQx5280ycwAyYkIPGaRZAEgHxe3bjirSd5Zpwkj6zNcR4cqYni/ZA=="], + "@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="], + "@types/babel__core": ["@types/babel__core@7.20.5", "", { "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA=="], "@types/babel__generator": ["@types/babel__generator@7.27.0", "", { "dependencies": { "@babel/types": "^7.0.0" } }, "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg=="], @@ -423,6 +480,8 @@ "@types/babel__traverse": ["@types/babel__traverse@7.28.0", "", { "dependencies": { "@babel/types": "^7.28.2" } }, "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q=="], + "@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="], + "@types/graceful-fs": ["@types/graceful-fs@4.1.9", "", { "dependencies": { "@types/node": "*" } }, "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ=="], "@types/hammerjs": ["@types/hammerjs@2.0.46", "", {}, "sha512-ynRvcq6wvqexJ9brDMS4BnBLzmr0e14d6ZJTEShTBWKymQiHwlAyGu0ZPEFI2Fh1U53F7tN9ufClWM5KvqkKOw=="], @@ -433,20 +492,88 @@ "@types/istanbul-reports": ["@types/istanbul-reports@3.0.4", "", { "dependencies": { "@types/istanbul-lib-report": "*" } }, "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ=="], + "@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="], + + "@types/json5": ["@types/json5@0.0.29", "", {}, "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ=="], + "@types/node": ["@types/node@25.5.0", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw=="], + "@types/ramda": ["@types/ramda@0.27.66", "", { "dependencies": { "ts-toolbelt": "^6.15.1" } }, "sha512-i2YW+E2U6NfMt3dp0RxNcejox+bxJUNDjB7BpYuRuoHIzv5juPHkJkNgcUOu+YSQEmaWu8cnAo/8r63C0NnuVA=="], + "@types/react": ["@types/react@19.2.14", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w=="], + "@types/react-native": ["@types/react-native@0.73.0", "", { "dependencies": { "react-native": "*" } }, "sha512-6ZRPQrYM72qYKGWidEttRe6M5DZBEV5F+MHMHqd4TTYx0tfkcdrUFGdef6CCxY0jXU7wldvd/zA/b0A/kTeJmA=="], + "@types/stack-utils": ["@types/stack-utils@2.0.3", "", {}, "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw=="], + "@types/urijs": ["@types/urijs@1.19.26", "", {}, "sha512-wkXrVzX5yoqLnndOwFsieJA7oKM8cNkOKJtf/3vVGSUFkWDKZvFHpIl9Pvqb/T9UsawBBFMTTD8xu7sK5MWuvg=="], + "@types/xml2js": ["@types/xml2js@0.4.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-4YnrRemBShWRO2QjvUin8ESA41rH+9nQGLUGZV/1IDhi3SL9OhdpNC/MrulTWuptXKwhx/aDxE7toV0f/ypIXQ=="], "@types/yargs": ["@types/yargs@17.0.35", "", { "dependencies": { "@types/yargs-parser": "*" } }, "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg=="], "@types/yargs-parser": ["@types/yargs-parser@21.0.3", "", {}, "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ=="], + "@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.57.2", "", { "dependencies": { "@eslint-community/regexpp": "^4.12.2", "@typescript-eslint/scope-manager": "8.57.2", "@typescript-eslint/type-utils": "8.57.2", "@typescript-eslint/utils": "8.57.2", "@typescript-eslint/visitor-keys": "8.57.2", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.4.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.57.2", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-NZZgp0Fm2IkD+La5PR81sd+g+8oS6JwJje+aRWsDocxHkjyRw0J5L5ZTlN3LI1LlOcGL7ph3eaIUmTXMIjLk0w=="], + + "@typescript-eslint/parser": ["@typescript-eslint/parser@8.57.2", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.57.2", "@typescript-eslint/types": "8.57.2", "@typescript-eslint/typescript-estree": "8.57.2", "@typescript-eslint/visitor-keys": "8.57.2", "debug": "^4.4.3" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-30ScMRHIAD33JJQkgfGW1t8CURZtjc2JpTrq5n2HFhOefbAhb7ucc7xJwdWcrEtqUIYJ73Nybpsggii6GtAHjA=="], + + "@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.57.2", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.57.2", "@typescript-eslint/types": "^8.57.2", "debug": "^4.4.3" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-FuH0wipFywXRTHf+bTTjNyuNQQsQC3qh/dYzaM4I4W0jrCqjCVuUh99+xd9KamUfmCGPvbO8NDngo/vsnNVqgw=="], + + "@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.57.2", "", { "dependencies": { "@typescript-eslint/types": "8.57.2", "@typescript-eslint/visitor-keys": "8.57.2" } }, "sha512-snZKH+W4WbWkrBqj4gUNRIGb/jipDW3qMqVJ4C9rzdFc+wLwruxk+2a5D+uoFcKPAqyqEnSb4l2ULuZf95eSkw=="], + + "@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.57.2", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-3Lm5DSM+DCowsUOJC+YqHHnKEfFh5CoGkj5Z31NQSNF4l5wdOwqGn99wmwN/LImhfY3KJnmordBq/4+VDe2eKw=="], + + "@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.57.2", "", { "dependencies": { "@typescript-eslint/types": "8.57.2", "@typescript-eslint/typescript-estree": "8.57.2", "@typescript-eslint/utils": "8.57.2", "debug": "^4.4.3", "ts-api-utils": "^2.4.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-Co6ZCShm6kIbAM/s+oYVpKFfW7LBc6FXoPXjTRQ449PPNBY8U0KZXuevz5IFuuUj2H9ss40atTaf9dlGLzbWZg=="], + + "@typescript-eslint/types": ["@typescript-eslint/types@8.57.2", "", {}, "sha512-/iZM6FnM4tnx9csuTxspMW4BOSegshwX5oBDznJ7S4WggL7Vczz5d2W11ecc4vRrQMQHXRSxzrCsyG5EsPPTbA=="], + + "@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.57.2", "", { "dependencies": { "@typescript-eslint/project-service": "8.57.2", "@typescript-eslint/tsconfig-utils": "8.57.2", "@typescript-eslint/types": "8.57.2", "@typescript-eslint/visitor-keys": "8.57.2", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.4.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-2MKM+I6g8tJxfSmFKOnHv2t8Sk3T6rF20A1Puk0svLK+uVapDZB/4pfAeB7nE83uAZrU6OxW+HmOd5wHVdXwXA=="], + + "@typescript-eslint/utils": ["@typescript-eslint/utils@8.57.2", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", "@typescript-eslint/scope-manager": "8.57.2", "@typescript-eslint/types": "8.57.2", "@typescript-eslint/typescript-estree": "8.57.2" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-krRIbvPK1ju1WBKIefiX+bngPs+odIQUtR7kymzPfo1POVw3jlF+nLkmexdSSd4UCbDcQn+wMBATOOmpBbqgKg=="], + + "@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.57.2", "", { "dependencies": { "@typescript-eslint/types": "8.57.2", "eslint-visitor-keys": "^5.0.0" } }, "sha512-zhahknjobV2FiD6Ee9iLbS7OV9zi10rG26odsQdfBO/hjSzUQbkIYgda+iNKK1zNiW2ey+Lf8MU5btN17V3dUw=="], + "@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="], + "@unrs/resolver-binding-android-arm-eabi": ["@unrs/resolver-binding-android-arm-eabi@1.11.1", "", { "os": "android", "cpu": "arm" }, "sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw=="], + + "@unrs/resolver-binding-android-arm64": ["@unrs/resolver-binding-android-arm64@1.11.1", "", { "os": "android", "cpu": "arm64" }, "sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g=="], + + "@unrs/resolver-binding-darwin-arm64": ["@unrs/resolver-binding-darwin-arm64@1.11.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g=="], + + "@unrs/resolver-binding-darwin-x64": ["@unrs/resolver-binding-darwin-x64@1.11.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ=="], + + "@unrs/resolver-binding-freebsd-x64": ["@unrs/resolver-binding-freebsd-x64@1.11.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw=="], + + "@unrs/resolver-binding-linux-arm-gnueabihf": ["@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1", "", { "os": "linux", "cpu": "arm" }, "sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw=="], + + "@unrs/resolver-binding-linux-arm-musleabihf": ["@unrs/resolver-binding-linux-arm-musleabihf@1.11.1", "", { "os": "linux", "cpu": "arm" }, "sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw=="], + + "@unrs/resolver-binding-linux-arm64-gnu": ["@unrs/resolver-binding-linux-arm64-gnu@1.11.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ=="], + + "@unrs/resolver-binding-linux-arm64-musl": ["@unrs/resolver-binding-linux-arm64-musl@1.11.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w=="], + + "@unrs/resolver-binding-linux-ppc64-gnu": ["@unrs/resolver-binding-linux-ppc64-gnu@1.11.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA=="], + + "@unrs/resolver-binding-linux-riscv64-gnu": ["@unrs/resolver-binding-linux-riscv64-gnu@1.11.1", "", { "os": "linux", "cpu": "none" }, "sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ=="], + + "@unrs/resolver-binding-linux-riscv64-musl": ["@unrs/resolver-binding-linux-riscv64-musl@1.11.1", "", { "os": "linux", "cpu": "none" }, "sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew=="], + + "@unrs/resolver-binding-linux-s390x-gnu": ["@unrs/resolver-binding-linux-s390x-gnu@1.11.1", "", { "os": "linux", "cpu": "s390x" }, "sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg=="], + + "@unrs/resolver-binding-linux-x64-gnu": ["@unrs/resolver-binding-linux-x64-gnu@1.11.1", "", { "os": "linux", "cpu": "x64" }, "sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w=="], + + "@unrs/resolver-binding-linux-x64-musl": ["@unrs/resolver-binding-linux-x64-musl@1.11.1", "", { "os": "linux", "cpu": "x64" }, "sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA=="], + + "@unrs/resolver-binding-wasm32-wasi": ["@unrs/resolver-binding-wasm32-wasi@1.11.1", "", { "dependencies": { "@napi-rs/wasm-runtime": "^0.2.11" }, "cpu": "none" }, "sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ=="], + + "@unrs/resolver-binding-win32-arm64-msvc": ["@unrs/resolver-binding-win32-arm64-msvc@1.11.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw=="], + + "@unrs/resolver-binding-win32-ia32-msvc": ["@unrs/resolver-binding-win32-ia32-msvc@1.11.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ=="], + + "@unrs/resolver-binding-win32-x64-msvc": ["@unrs/resolver-binding-win32-x64-msvc@1.11.1", "", { "os": "win32", "cpu": "x64" }, "sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g=="], + "@xmldom/xmldom": ["@xmldom/xmldom@0.8.11", "", {}, "sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw=="], "abort-controller": ["abort-controller@3.0.0", "", { "dependencies": { "event-target-shim": "^5.0.0" } }, "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg=="], @@ -455,15 +582,19 @@ "acorn": ["acorn@8.16.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw=="], + "acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="], + "agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="], + "ajv": ["ajv@6.14.0", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw=="], + "anser": ["anser@1.4.10", "", {}, "sha512-hCv9AqTQ8ycjpSd3upOJd7vFwW1JaoYQ7tpham03GJ1ca8/65rqn0RpaWpItOAd6ylW9wAw6luXYPJIyPFVOww=="], "ansi-escapes": ["ansi-escapes@4.3.2", "", { "dependencies": { "type-fest": "^0.21.3" } }, "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ=="], "ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], - "ansi-styles": ["ansi-styles@5.2.0", "", {}, "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA=="], + "ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], "anymatch": ["anymatch@3.1.3", "", { "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw=="], @@ -473,10 +604,30 @@ "aria-hidden": ["aria-hidden@1.2.6", "", { "dependencies": { "tslib": "^2.0.0" } }, "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA=="], + "array-buffer-byte-length": ["array-buffer-byte-length@1.0.2", "", { "dependencies": { "call-bound": "^1.0.3", "is-array-buffer": "^3.0.5" } }, "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw=="], + + "array-includes": ["array-includes@3.1.9", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.4", "define-properties": "^1.2.1", "es-abstract": "^1.24.0", "es-object-atoms": "^1.1.1", "get-intrinsic": "^1.3.0", "is-string": "^1.1.1", "math-intrinsics": "^1.1.0" } }, "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ=="], + + "array.prototype.findlast": ["array.prototype.findlast@1.2.5", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-abstract": "^1.23.2", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", "es-shim-unscopables": "^1.0.2" } }, "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ=="], + + "array.prototype.findlastindex": ["array.prototype.findlastindex@1.2.6", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.4", "define-properties": "^1.2.1", "es-abstract": "^1.23.9", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "es-shim-unscopables": "^1.1.0" } }, "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ=="], + + "array.prototype.flat": ["array.prototype.flat@1.3.3", "", { "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-abstract": "^1.23.5", "es-shim-unscopables": "^1.0.2" } }, "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg=="], + + "array.prototype.flatmap": ["array.prototype.flatmap@1.3.3", "", { "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-abstract": "^1.23.5", "es-shim-unscopables": "^1.0.2" } }, "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg=="], + + "array.prototype.tosorted": ["array.prototype.tosorted@1.1.4", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-abstract": "^1.23.3", "es-errors": "^1.3.0", "es-shim-unscopables": "^1.0.2" } }, "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA=="], + + "arraybuffer.prototype.slice": ["arraybuffer.prototype.slice@1.0.4", "", { "dependencies": { "array-buffer-byte-length": "^1.0.1", "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-abstract": "^1.23.5", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "is-array-buffer": "^3.0.4" } }, "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ=="], + "asap": ["asap@2.0.6", "", {}, "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA=="], + "async-function": ["async-function@1.0.0", "", {}, "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA=="], + "asynckit": ["asynckit@0.4.0", "", {}, "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="], + "available-typed-arrays": ["available-typed-arrays@1.0.7", "", { "dependencies": { "possible-typed-array-names": "^1.0.0" } }, "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ=="], + "await-lock": ["await-lock@2.2.2", "", {}, "sha512-aDczADvlvTGajTDjcjpJMqRkOF6Qdz3YbPZm/PyW6tKPkx2hlYBzxMhEywM/tU72HrVZjgl5VCdRuMlA7pZ8Gw=="], "axios": ["axios@1.14.0", "", { "dependencies": { "follow-redirects": "^1.15.11", "form-data": "^4.0.5", "proxy-from-env": "^2.1.0" } }, "sha512-3Y8yrqLSwjuzpXuZ0oIYZ/XGgLwUIBU3uLvbcpb0pidD9ctpShJd43KSlEEkVQg6DS0G9NKyzOvBfUtDKEyHvQ=="], @@ -509,7 +660,7 @@ "badgin": ["badgin@1.2.3", "", {}, "sha512-NQGA7LcfCpSzIbGRbkgjgdWkjy7HI+Th5VLxTJfW5EeaAf3fnS+xWQaQOCYiny+q6QSvxqoSO04vCx+4u++EJw=="], - "balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], + "balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], "base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="], @@ -523,7 +674,7 @@ "bplist-parser": ["bplist-parser@0.3.1", "", { "dependencies": { "big-integer": "1.6.x" } }, "sha512-PyJxiNtA5T2PlLIeBot4lbp7rj4OadzjnMZD/G5zuBNt8ei/yCU7+wW0h2bag9vr8c+/WuRWmSxbqAl9hL1rBA=="], - "brace-expansion": ["brace-expansion@5.0.5", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ=="], + "brace-expansion": ["brace-expansion@1.1.13", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w=="], "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="], @@ -531,18 +682,32 @@ "bser": ["bser@2.1.1", "", { "dependencies": { "node-int64": "^0.4.0" } }, "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ=="], + "buffer": ["buffer@6.0.3", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" } }, "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA=="], + "buffer-from": ["buffer-from@1.1.2", "", {}, "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="], "bytes": ["bytes@3.1.2", "", {}, "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="], + "call-bind": ["call-bind@1.0.8", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", "get-intrinsic": "^1.2.4", "set-function-length": "^1.2.2" } }, "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww=="], + "call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="], + "call-bound": ["call-bound@1.0.4", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" } }, "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg=="], + + "callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="], + "camelcase": ["camelcase@6.3.0", "", {}, "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA=="], + "camelize": ["camelize@1.0.1", "", {}, "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ=="], + "caniuse-lite": ["caniuse-lite@1.0.30001781", "", {}, "sha512-RdwNCyMsNBftLjW6w01z8bKEvT6e/5tpPVEgtn22TiLGlstHOVecsX2KHFkD5e/vRnIE4EGzpuIODb3mtswtkw=="], "chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], + "character-entities-html4": ["character-entities-html4@1.1.4", "", {}, "sha512-HRcDxZuZqMx3/a+qrzxdBKBPUpxWEq9xw2OPZ3a/174ihfrQKVsFhqtthBInFy1zZ9GgZyFXOatNujm8M+El3g=="], + + "character-entities-legacy": ["character-entities-legacy@1.1.4", "", {}, "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA=="], + "chrome-launcher": ["chrome-launcher@0.15.2", "", { "dependencies": { "@types/node": "*", "escape-string-regexp": "^4.0.0", "is-wsl": "^2.2.0", "lighthouse-logger": "^1.0.0" }, "bin": { "print-chrome-path": "bin/print-chrome-path.js" } }, "sha512-zdLEwNo3aUVzIhKhTtXfxhdvZhUghrnmkvcAq2NoDd+LeOHKf03H5jwZ8T/STsAlzyALkBVK552iaG1fGf1xVQ=="], "chromium-edge-launcher": ["chromium-edge-launcher@0.2.0", "", { "dependencies": { "@types/node": "*", "escape-string-regexp": "^4.0.0", "is-wsl": "^2.2.0", "lighthouse-logger": "^1.0.0", "mkdirp": "^1.0.4", "rimraf": "^3.0.2" } }, "sha512-JfJjUnq25y9yg4FABRRVPmBGWPZZi+AQXT4mxupb67766/0UlhG8PAZCz6xzEMXTbW3CsSoE8PcCWA49n35mKg=="], @@ -587,20 +752,36 @@ "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], + "css-color-keywords": ["css-color-keywords@1.0.0", "", {}, "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg=="], + "css-in-js-utils": ["css-in-js-utils@3.1.0", "", { "dependencies": { "hyphenate-style-name": "^1.0.3" } }, "sha512-fJAcud6B3rRu+KHYk+Bwf+WFL2MDCJJ1XG9x137tJQ0xYxor7XziQtuGFbWNdqrvF4Tk26O3H73nfVqXt/fW1A=="], + "css-to-react-native": ["css-to-react-native@3.2.0", "", { "dependencies": { "camelize": "^1.0.0", "css-color-keywords": "^1.0.0", "postcss-value-parser": "^4.0.2" } }, "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ=="], + "csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="], + "data-view-buffer": ["data-view-buffer@1.0.2", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "is-data-view": "^1.0.2" } }, "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ=="], + + "data-view-byte-length": ["data-view-byte-length@1.0.2", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "is-data-view": "^1.0.2" } }, "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ=="], + + "data-view-byte-offset": ["data-view-byte-offset@1.0.1", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "is-data-view": "^1.0.1" } }, "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ=="], + "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], "decode-uri-component": ["decode-uri-component@0.2.2", "", {}, "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ=="], + "deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="], + "deepmerge": ["deepmerge@4.3.1", "", {}, "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="], "defaults": ["defaults@1.0.4", "", { "dependencies": { "clone": "^1.0.2" } }, "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A=="], + "define-data-property": ["define-data-property@1.1.4", "", { "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", "gopd": "^1.0.1" } }, "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A=="], + "define-lazy-prop": ["define-lazy-prop@2.0.0", "", {}, "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og=="], + "define-properties": ["define-properties@1.2.1", "", { "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" } }, "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg=="], + "delayed-stream": ["delayed-stream@1.0.0", "", {}, "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="], "depd": ["depd@2.0.0", "", {}, "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="], @@ -613,6 +794,16 @@ "dnssd-advertise": ["dnssd-advertise@1.1.4", "", {}, "sha512-AmGyK9WpNf06WeP5TjHZq/wNzP76OuEeaiTlKr9E/EEelYLczywUKoqRz+DPRq/ErssjT4lU+/W7wzJW+7K/ZA=="], + "doctrine": ["doctrine@2.1.0", "", { "dependencies": { "esutils": "^2.0.2" } }, "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw=="], + + "dom-serializer": ["dom-serializer@1.4.1", "", { "dependencies": { "domelementtype": "^2.0.1", "domhandler": "^4.2.0", "entities": "^2.0.0" } }, "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag=="], + + "domelementtype": ["domelementtype@2.3.0", "", {}, "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="], + + "domhandler": ["domhandler@4.3.1", "", { "dependencies": { "domelementtype": "^2.2.0" } }, "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ=="], + + "domutils": ["domutils@2.8.0", "", { "dependencies": { "dom-serializer": "^1.0.1", "domelementtype": "^2.2.0", "domhandler": "^4.2.0" } }, "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A=="], + "dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="], "ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="], @@ -623,28 +814,72 @@ "encodeurl": ["encodeurl@2.0.0", "", {}, "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg=="], + "entities": ["entities@3.0.1", "", {}, "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q=="], + "error-stack-parser": ["error-stack-parser@2.1.4", "", { "dependencies": { "stackframe": "^1.3.4" } }, "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ=="], + "es-abstract": ["es-abstract@1.24.1", "", { "dependencies": { "array-buffer-byte-length": "^1.0.2", "arraybuffer.prototype.slice": "^1.0.4", "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", "call-bound": "^1.0.4", "data-view-buffer": "^1.0.2", "data-view-byte-length": "^1.0.2", "data-view-byte-offset": "^1.0.1", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "es-set-tostringtag": "^2.1.0", "es-to-primitive": "^1.3.0", "function.prototype.name": "^1.1.8", "get-intrinsic": "^1.3.0", "get-proto": "^1.0.1", "get-symbol-description": "^1.1.0", "globalthis": "^1.0.4", "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", "has-proto": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "internal-slot": "^1.1.0", "is-array-buffer": "^3.0.5", "is-callable": "^1.2.7", "is-data-view": "^1.0.2", "is-negative-zero": "^2.0.3", "is-regex": "^1.2.1", "is-set": "^2.0.3", "is-shared-array-buffer": "^1.0.4", "is-string": "^1.1.1", "is-typed-array": "^1.1.15", "is-weakref": "^1.1.1", "math-intrinsics": "^1.1.0", "object-inspect": "^1.13.4", "object-keys": "^1.1.1", "object.assign": "^4.1.7", "own-keys": "^1.0.1", "regexp.prototype.flags": "^1.5.4", "safe-array-concat": "^1.1.3", "safe-push-apply": "^1.0.0", "safe-regex-test": "^1.1.0", "set-proto": "^1.0.0", "stop-iteration-iterator": "^1.1.0", "string.prototype.trim": "^1.2.10", "string.prototype.trimend": "^1.0.9", "string.prototype.trimstart": "^1.0.8", "typed-array-buffer": "^1.0.3", "typed-array-byte-length": "^1.0.3", "typed-array-byte-offset": "^1.0.4", "typed-array-length": "^1.0.7", "unbox-primitive": "^1.1.0", "which-typed-array": "^1.1.19" } }, "sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw=="], + "es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="], "es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="], + "es-iterator-helpers": ["es-iterator-helpers@1.3.1", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.4", "define-properties": "^1.2.1", "es-abstract": "^1.24.1", "es-errors": "^1.3.0", "es-set-tostringtag": "^2.1.0", "function-bind": "^1.1.2", "get-intrinsic": "^1.3.0", "globalthis": "^1.0.4", "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", "has-proto": "^1.2.0", "has-symbols": "^1.1.0", "internal-slot": "^1.1.0", "iterator.prototype": "^1.1.5", "math-intrinsics": "^1.1.0", "safe-array-concat": "^1.1.3" } }, "sha512-zWwRvqWiuBPr0muUG/78cW3aHROFCNIQ3zpmYDpwdbnt2m+xlNyRWpHBpa2lJjSBit7BQ+RXA1iwbSmu5yJ/EQ=="], + "es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="], "es-set-tostringtag": ["es-set-tostringtag@2.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA=="], + "es-shim-unscopables": ["es-shim-unscopables@1.1.0", "", { "dependencies": { "hasown": "^2.0.2" } }, "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw=="], + + "es-to-primitive": ["es-to-primitive@1.3.0", "", { "dependencies": { "is-callable": "^1.2.7", "is-date-object": "^1.0.5", "is-symbol": "^1.0.4" } }, "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g=="], + "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="], "escape-html": ["escape-html@1.0.3", "", {}, "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="], "escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="], + "eslint": ["eslint@9.39.4", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.21.2", "@eslint/config-helpers": "^0.4.2", "@eslint/core": "^0.17.0", "@eslint/eslintrc": "^3.3.5", "@eslint/js": "9.39.4", "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "ajv": "^6.14.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.4.0", "eslint-visitor-keys": "^4.2.1", "espree": "^10.4.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.5", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ=="], + + "eslint-config-expo": ["eslint-config-expo@55.0.1-canary-20260328-2049187", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "^8.18.2", "@typescript-eslint/parser": "^8.18.2", "eslint-import-resolver-typescript": "^3.6.3", "eslint-plugin-expo": "1.0.1-canary-20260328-2049187", "eslint-plugin-import": "^2.30.0", "eslint-plugin-react": "^7.37.3", "eslint-plugin-react-hooks": "^5.1.0", "globals": "^16.0.0" }, "peerDependencies": { "eslint": ">=8.10" } }, "sha512-JlC49CdX65Zbs3gKX/4y6fOXSfr98eZEK0hnRUVv5MwqyZRTFcK/73AE0U9M5ILSfIh5Pxel0N5MH+oxZXhJEw=="], + + "eslint-import-resolver-node": ["eslint-import-resolver-node@0.3.9", "", { "dependencies": { "debug": "^3.2.7", "is-core-module": "^2.13.0", "resolve": "^1.22.4" } }, "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g=="], + + "eslint-import-resolver-typescript": ["eslint-import-resolver-typescript@3.10.1", "", { "dependencies": { "@nolyfill/is-core-module": "1.0.39", "debug": "^4.4.0", "get-tsconfig": "^4.10.0", "is-bun-module": "^2.0.0", "stable-hash": "^0.0.5", "tinyglobby": "^0.2.13", "unrs-resolver": "^1.6.2" }, "peerDependencies": { "eslint": "*", "eslint-plugin-import": "*", "eslint-plugin-import-x": "*" }, "optionalPeers": ["eslint-plugin-import", "eslint-plugin-import-x"] }, "sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ=="], + + "eslint-module-utils": ["eslint-module-utils@2.12.1", "", { "dependencies": { "debug": "^3.2.7" } }, "sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw=="], + + "eslint-plugin-expo": ["eslint-plugin-expo@1.0.1-canary-20260328-2049187", "", { "dependencies": { "@typescript-eslint/types": "^8.29.1", "@typescript-eslint/utils": "^8.29.1", "eslint": "^9.24.0" } }, "sha512-jCZIQZ3B6C5G4V4sujKaHc9rQTZ1mEy5N6iVVz3BV2s2ApY35ww/w+4BroAU8TT2kZisBDLJeUV5jO7O6nKx4g=="], + + "eslint-plugin-import": ["eslint-plugin-import@2.32.0", "", { "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", "array.prototype.findlastindex": "^1.2.6", "array.prototype.flat": "^1.3.3", "array.prototype.flatmap": "^1.3.3", "debug": "^3.2.7", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.9", "eslint-module-utils": "^2.12.1", "hasown": "^2.0.2", "is-core-module": "^2.16.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", "object.fromentries": "^2.0.8", "object.groupby": "^1.0.3", "object.values": "^1.2.1", "semver": "^6.3.1", "string.prototype.trimend": "^1.0.9", "tsconfig-paths": "^3.15.0" }, "peerDependencies": { "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" } }, "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA=="], + + "eslint-plugin-react": ["eslint-plugin-react@7.37.5", "", { "dependencies": { "array-includes": "^3.1.8", "array.prototype.findlast": "^1.2.5", "array.prototype.flatmap": "^1.3.3", "array.prototype.tosorted": "^1.1.4", "doctrine": "^2.1.0", "es-iterator-helpers": "^1.2.1", "estraverse": "^5.3.0", "hasown": "^2.0.2", "jsx-ast-utils": "^2.4.1 || ^3.0.0", "minimatch": "^3.1.2", "object.entries": "^1.1.9", "object.fromentries": "^2.0.8", "object.values": "^1.2.1", "prop-types": "^15.8.1", "resolve": "^2.0.0-next.5", "semver": "^6.3.1", "string.prototype.matchall": "^4.0.12", "string.prototype.repeat": "^1.0.0" }, "peerDependencies": { "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" } }, "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA=="], + + "eslint-plugin-react-hooks": ["eslint-plugin-react-hooks@5.2.0", "", { "peerDependencies": { "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" } }, "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg=="], + + "eslint-scope": ["eslint-scope@8.4.0", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg=="], + + "eslint-visitor-keys": ["eslint-visitor-keys@4.2.1", "", {}, "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ=="], + + "espree": ["espree@10.4.0", "", { "dependencies": { "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.2.1" } }, "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ=="], + "esprima": ["esprima@4.0.1", "", { "bin": { "esparse": "./bin/esparse.js", "esvalidate": "./bin/esvalidate.js" } }, "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="], + "esquery": ["esquery@1.7.0", "", { "dependencies": { "estraverse": "^5.1.0" } }, "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g=="], + + "esrecurse": ["esrecurse@4.3.0", "", { "dependencies": { "estraverse": "^5.2.0" } }, "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag=="], + + "estraverse": ["estraverse@5.3.0", "", {}, "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="], + + "esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="], + "etag": ["etag@1.8.1", "", {}, "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="], "event-target-shim": ["event-target-shim@5.0.1", "", {}, "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="], + "events": ["events@3.3.0", "", {}, "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q=="], + "expo": ["expo@55.0.10-canary-20260328-2049187", "", { "dependencies": { "@babel/runtime": "^7.20.0", "@expo/cli": "55.0.20-canary-20260328-2049187", "@expo/config": "55.0.12-canary-20260328-2049187", "@expo/config-plugins": "55.0.8-canary-20260328-2049187", "@expo/devtools": "55.0.3-canary-20260328-2049187", "@expo/fingerprint": "0.16.7-canary-20260328-2049187", "@expo/local-build-cache-provider": "55.0.8-canary-20260328-2049187", "@expo/log-box": "55.0.9-canary-20260328-2049187", "@expo/metro": "~54.2.0", "@expo/metro-config": "55.0.12-canary-20260328-2049187", "@expo/vector-icons": "^15.0.2", "@ungap/structured-clone": "^1.3.0", "babel-preset-expo": "55.0.14-canary-20260328-2049187", "expo-asset": "55.0.11-canary-20260328-2049187", "expo-constants": "55.0.10-canary-20260328-2049187", "expo-file-system": "55.0.13-canary-20260328-2049187", "expo-font": "55.0.5-canary-20260328-2049187", "expo-keep-awake": "55.0.5-canary-20260328-2049187", "expo-modules-autolinking": "55.0.13-canary-20260328-2049187", "expo-modules-core": "55.0.19-canary-20260328-2049187", "pretty-format": "^29.7.0", "react-refresh": "^0.14.2", "whatwg-url-minimum": "^0.1.1" }, "peerDependencies": { "@expo/dom-webview": "55.0.4-canary-20260328-2049187", "@expo/metro-runtime": "55.0.8-canary-20260328-2049187", "react": "*", "react-native": "*", "react-native-webview": "*" }, "optionalPeers": ["@expo/dom-webview", "@expo/metro-runtime", "react-native-webview"], "bin": { "expo": "bin/cli", "expo-modules-autolinking": "bin/autolinking", "fingerprint": "bin/fingerprint" } }, "sha512-98gWHe8BWedTDs3f4pK7qjEz58rrJhyByOVPWhdKbmEKmU5xNCS/XUxXV5t2QiLDybR7EWesrOspWiHFSV5eLw=="], "expo-application": ["expo-application@55.0.11-canary-20260328-2049187", "", { "peerDependencies": { "expo": "55.0.10-canary-20260328-2049187" } }, "sha512-XrWghJefOb3fTdxK0B3RKuz9l31nZn2SIPqn2qhYx4kOPXa/CytaUvH5wG5gHJ2ZGtonk4JPmw+a69OiDj7MfQ=="], @@ -699,6 +934,12 @@ "fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="], + "fast-levenshtein": ["fast-levenshtein@2.0.6", "", {}, "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="], + + "fast-xml-builder": ["fast-xml-builder@1.1.4", "", { "dependencies": { "path-expression-matcher": "^1.1.3" } }, "sha512-f2jhpN4Eccy0/Uz9csxh3Nu6q4ErKxf0XIsasomfOihuSUa3/xw6w8dnOtCDgEItQFJG8KyXPzQXzcODDrrbOg=="], + + "fast-xml-parser": ["fast-xml-parser@5.5.9", "", { "dependencies": { "fast-xml-builder": "^1.1.4", "path-expression-matcher": "^1.2.0", "strnum": "^2.2.2" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-jldvxr1MC6rtiZKgrFnDSvT8xuH+eJqxqOBThUVjYrxssYTo1avZLGql5l0a0BAERR01CadYzZ83kVEkbyDg+g=="], + "fb-dotslash": ["fb-dotslash@0.5.8", "", { "bin": { "dotslash": "bin/dotslash" } }, "sha512-XHYLKk9J4BupDxi9bSEhkfss0m+Vr9ChTrjhf9l2iw3jB5C7BnY4GVPoMcqbrTutsKJso6yj2nAB6BI/F2oZaA=="], "fb-watchman": ["fb-watchman@2.0.2", "", { "dependencies": { "bser": "2.1.1" } }, "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA=="], @@ -707,15 +948,23 @@ "fbjs-css-vars": ["fbjs-css-vars@1.0.2", "", {}, "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ=="], + "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], + "fetch-nodeshim": ["fetch-nodeshim@0.4.10", "", {}, "sha512-m6I8ALe4L4XpdETy7MJZWs6L1IVMbjs99bwbpIKphxX+0CTns4IKDWJY0LWfr4YsFjfg+z1TjzTMU8lKl8rG0w=="], + "file-entry-cache": ["file-entry-cache@8.0.0", "", { "dependencies": { "flat-cache": "^4.0.0" } }, "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ=="], + "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="], "filter-obj": ["filter-obj@1.1.0", "", {}, "sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ=="], "finalhandler": ["finalhandler@1.1.2", "", { "dependencies": { "debug": "2.6.9", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "on-finished": "~2.3.0", "parseurl": "~1.3.3", "statuses": "~1.5.0", "unpipe": "~1.0.0" } }, "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA=="], - "find-up": ["find-up@4.1.0", "", { "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" } }, "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw=="], + "find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="], + + "flat-cache": ["flat-cache@4.0.1", "", { "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" } }, "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw=="], + + "flatted": ["flatted@3.4.2", "", {}, "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA=="], "flow-enums-runtime": ["flow-enums-runtime@0.0.6", "", {}, "sha512-3PYnM29RFXwvAN6Pc/scUfkI7RwhQ/xqyLUyPNlXUp9S40zI8nup9tUSrTLSVnWGBN38FNiGWbwZOB6uR4OGdw=="], @@ -723,6 +972,8 @@ "fontfaceobserver": ["fontfaceobserver@2.3.0", "", {}, "sha512-6FPvD/IVyT4ZlNe7Wcn5Fb/4ChigpucKYSvD6a+0iMoLn2inpo711eyIcKjmDtE5XNcgAkSH9uN/nfAeZzHEfg=="], + "for-each": ["for-each@0.3.5", "", { "dependencies": { "is-callable": "^1.2.7" } }, "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg=="], + "form-data": ["form-data@4.0.5", "", { "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" } }, "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w=="], "fresh": ["fresh@0.5.2", "", {}, "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q=="], @@ -733,6 +984,12 @@ "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="], + "function.prototype.name": ["function.prototype.name@1.1.8", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "functions-have-names": "^1.2.3", "hasown": "^2.0.2", "is-callable": "^1.2.7" } }, "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q=="], + + "functions-have-names": ["functions-have-names@1.2.3", "", {}, "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ=="], + + "generator-function": ["generator-function@2.0.1", "", {}, "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g=="], + "gensync": ["gensync@1.0.0-beta.2", "", {}, "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="], "get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="], @@ -745,16 +1002,32 @@ "get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="], + "get-symbol-description": ["get-symbol-description@1.1.0", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6" } }, "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg=="], + + "get-tsconfig": ["get-tsconfig@4.13.7", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-7tN6rFgBlMgpBML5j8typ92BKFi2sFQvIdpAqLA2beia5avZDrMs0FLZiM5etShWq5irVyGcGMEA1jcDaK7A/Q=="], + "getenv": ["getenv@2.0.0", "", {}, "sha512-VilgtJj/ALgGY77fiLam5iD336eSWi96Q15JSAG1zi8NRBysm3LXKdGnHb4m5cuyxvOLQQKWpBZAT6ni4FI2iQ=="], "glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="], + "glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="], + + "globals": ["globals@16.5.0", "", {}, "sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ=="], + + "globalthis": ["globalthis@1.0.4", "", { "dependencies": { "define-properties": "^1.2.1", "gopd": "^1.0.1" } }, "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ=="], + "gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="], "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="], + "has-bigints": ["has-bigints@1.1.0", "", {}, "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg=="], + "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="], + "has-property-descriptors": ["has-property-descriptors@1.0.2", "", { "dependencies": { "es-define-property": "^1.0.0" } }, "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg=="], + + "has-proto": ["has-proto@1.2.0", "", { "dependencies": { "dunder-proto": "^1.0.0" } }, "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ=="], + "has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="], "has-tostringtag": ["has-tostringtag@1.0.2", "", { "dependencies": { "has-symbols": "^1.0.3" } }, "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw=="], @@ -771,16 +1044,24 @@ "hosted-git-info": ["hosted-git-info@7.0.2", "", { "dependencies": { "lru-cache": "^10.0.1" } }, "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w=="], + "htmlparser2": ["htmlparser2@7.2.0", "", { "dependencies": { "domelementtype": "^2.0.1", "domhandler": "^4.2.2", "domutils": "^2.8.0", "entities": "^3.0.1" } }, "sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog=="], + "http-errors": ["http-errors@2.0.1", "", { "dependencies": { "depd": "~2.0.0", "inherits": "~2.0.4", "setprototypeof": "~1.2.0", "statuses": "~2.0.2", "toidentifier": "~1.0.1" } }, "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ=="], "https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="], "hyphenate-style-name": ["hyphenate-style-name@1.1.0", "", {}, "sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw=="], + "idb": ["idb@8.0.3", "", {}, "sha512-LtwtVyVYO5BqRvcsKuB2iUMnHwPVByPCXFXOpuU96IZPPoPN6xjOGxZQ74pgSVVLQWtUOYgyeL4GE98BY5D3wg=="], + + "ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="], + "ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="], "image-size": ["image-size@1.2.1", "", { "dependencies": { "queue": "6.0.2" }, "bin": { "image-size": "bin/image-size.js" } }, "sha512-rH+46sQJ2dlwfjfhCyNx5thzrv+dtmBIhPHk0zgRUukHzZ/kRueTJXoYYsclBaKcSMBWuGbOFXtioLpzTb5euw=="], + "import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="], + "imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="], "inflight": ["inflight@1.0.6", "", { "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA=="], @@ -789,26 +1070,80 @@ "inline-style-prefixer": ["inline-style-prefixer@7.0.1", "", { "dependencies": { "css-in-js-utils": "^3.1.0" } }, "sha512-lhYo5qNTQp3EvSSp3sRvXMbVQTLrvGV6DycRMJ5dm2BLMiJ30wpXKdDdgX+GmJZ5uQMucwRKHamXSst3Sj/Giw=="], + "internal-slot": ["internal-slot@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "hasown": "^2.0.2", "side-channel": "^1.1.0" } }, "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw=="], + "invariant": ["invariant@2.2.4", "", { "dependencies": { "loose-envify": "^1.0.0" } }, "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA=="], + "is-array-buffer": ["is-array-buffer@3.0.5", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "get-intrinsic": "^1.2.6" } }, "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A=="], + "is-arrayish": ["is-arrayish@0.3.4", "", {}, "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA=="], + "is-async-function": ["is-async-function@2.1.1", "", { "dependencies": { "async-function": "^1.0.0", "call-bound": "^1.0.3", "get-proto": "^1.0.1", "has-tostringtag": "^1.0.2", "safe-regex-test": "^1.1.0" } }, "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ=="], + + "is-bigint": ["is-bigint@1.1.0", "", { "dependencies": { "has-bigints": "^1.0.2" } }, "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ=="], + + "is-boolean-object": ["is-boolean-object@1.2.2", "", { "dependencies": { "call-bound": "^1.0.3", "has-tostringtag": "^1.0.2" } }, "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A=="], + + "is-bun-module": ["is-bun-module@2.0.0", "", { "dependencies": { "semver": "^7.7.1" } }, "sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ=="], + + "is-callable": ["is-callable@1.2.7", "", {}, "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA=="], + "is-core-module": ["is-core-module@2.16.1", "", { "dependencies": { "hasown": "^2.0.2" } }, "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w=="], + "is-data-view": ["is-data-view@1.0.2", "", { "dependencies": { "call-bound": "^1.0.2", "get-intrinsic": "^1.2.6", "is-typed-array": "^1.1.13" } }, "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw=="], + + "is-date-object": ["is-date-object@1.1.0", "", { "dependencies": { "call-bound": "^1.0.2", "has-tostringtag": "^1.0.2" } }, "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg=="], + "is-docker": ["is-docker@2.2.1", "", { "bin": { "is-docker": "cli.js" } }, "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ=="], + "is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="], + + "is-finalizationregistry": ["is-finalizationregistry@1.1.1", "", { "dependencies": { "call-bound": "^1.0.3" } }, "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg=="], + "is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="], + "is-generator-function": ["is-generator-function@1.1.2", "", { "dependencies": { "call-bound": "^1.0.4", "generator-function": "^2.0.0", "get-proto": "^1.0.1", "has-tostringtag": "^1.0.2", "safe-regex-test": "^1.1.0" } }, "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA=="], + + "is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="], + + "is-map": ["is-map@2.0.3", "", {}, "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw=="], + + "is-negative-zero": ["is-negative-zero@2.0.3", "", {}, "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw=="], + "is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="], + "is-number-object": ["is-number-object@1.1.1", "", { "dependencies": { "call-bound": "^1.0.3", "has-tostringtag": "^1.0.2" } }, "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw=="], + + "is-regex": ["is-regex@1.2.1", "", { "dependencies": { "call-bound": "^1.0.2", "gopd": "^1.2.0", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g=="], + + "is-set": ["is-set@2.0.3", "", {}, "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg=="], + + "is-shared-array-buffer": ["is-shared-array-buffer@1.0.4", "", { "dependencies": { "call-bound": "^1.0.3" } }, "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A=="], + + "is-string": ["is-string@1.1.1", "", { "dependencies": { "call-bound": "^1.0.3", "has-tostringtag": "^1.0.2" } }, "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA=="], + + "is-symbol": ["is-symbol@1.1.1", "", { "dependencies": { "call-bound": "^1.0.2", "has-symbols": "^1.1.0", "safe-regex-test": "^1.1.0" } }, "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w=="], + + "is-typed-array": ["is-typed-array@1.1.15", "", { "dependencies": { "which-typed-array": "^1.1.16" } }, "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ=="], + + "is-weakmap": ["is-weakmap@2.0.2", "", {}, "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w=="], + + "is-weakref": ["is-weakref@1.1.1", "", { "dependencies": { "call-bound": "^1.0.3" } }, "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew=="], + + "is-weakset": ["is-weakset@2.0.4", "", { "dependencies": { "call-bound": "^1.0.3", "get-intrinsic": "^1.2.6" } }, "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ=="], + "is-wsl": ["is-wsl@2.2.0", "", { "dependencies": { "is-docker": "^2.0.0" } }, "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww=="], + "isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="], + "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], "istanbul-lib-coverage": ["istanbul-lib-coverage@3.2.2", "", {}, "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg=="], "istanbul-lib-instrument": ["istanbul-lib-instrument@5.2.1", "", { "dependencies": { "@babel/core": "^7.12.3", "@babel/parser": "^7.14.7", "@istanbuljs/schema": "^0.1.2", "istanbul-lib-coverage": "^3.2.0", "semver": "^6.3.0" } }, "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg=="], + "iterator.prototype": ["iterator.prototype@1.1.5", "", { "dependencies": { "define-data-property": "^1.1.4", "es-object-atoms": "^1.0.0", "get-intrinsic": "^1.2.6", "get-proto": "^1.0.0", "has-symbols": "^1.1.0", "set-function-name": "^2.0.2" } }, "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g=="], + "jest-environment-node": ["jest-environment-node@29.7.0", "", { "dependencies": { "@jest/environment": "^29.7.0", "@jest/fake-timers": "^29.7.0", "@jest/types": "^29.6.3", "@types/node": "*", "jest-mock": "^29.7.0", "jest-util": "^29.7.0" } }, "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw=="], "jest-get-type": ["jest-get-type@29.6.3", "", {}, "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw=="], @@ -837,14 +1172,26 @@ "jsesc": ["jsesc@3.1.0", "", { "bin": { "jsesc": "bin/jsesc" } }, "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA=="], + "json-buffer": ["json-buffer@3.0.1", "", {}, "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="], + + "json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="], + + "json-stable-stringify-without-jsonify": ["json-stable-stringify-without-jsonify@1.0.1", "", {}, "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="], + "json5": ["json5@2.2.3", "", { "bin": { "json5": "lib/cli.js" } }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="], + "jsx-ast-utils": ["jsx-ast-utils@3.3.5", "", { "dependencies": { "array-includes": "^3.1.6", "array.prototype.flat": "^1.3.1", "object.assign": "^4.1.4", "object.values": "^1.1.6" } }, "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ=="], + + "keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="], + "kleur": ["kleur@3.0.3", "", {}, "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w=="], "lan-network": ["lan-network@0.2.0", "", { "bin": { "lan-network": "dist/lan-network-cli.js" } }, "sha512-EZgbsXMrGS+oK+Ta12mCjzBFse+SIewGdwrSTr5g+MSymnjpox2x05ceI20PQejJOFvOgzcXrfDk/SdY7dSCtw=="], "leven": ["leven@3.1.0", "", {}, "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A=="], + "levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="], + "lighthouse-logger": ["lighthouse-logger@1.4.2", "", { "dependencies": { "debug": "^2.6.9", "marky": "^1.2.2" } }, "sha512-gPWxznF6TKmUHrOQjlVo2UbaL2EJ71mb2CCeRs/2qBpi4L/g4LUVc9+3lKQ6DTUZwJswfM7ainGrLO1+fOqa2g=="], "lightningcss": ["lightningcss@1.32.0", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.32.0", "lightningcss-darwin-arm64": "1.32.0", "lightningcss-darwin-x64": "1.32.0", "lightningcss-freebsd-x64": "1.32.0", "lightningcss-linux-arm-gnueabihf": "1.32.0", "lightningcss-linux-arm64-gnu": "1.32.0", "lightningcss-linux-arm64-musl": "1.32.0", "lightningcss-linux-x64-gnu": "1.32.0", "lightningcss-linux-x64-musl": "1.32.0", "lightningcss-win32-arm64-msvc": "1.32.0", "lightningcss-win32-x64-msvc": "1.32.0" } }, "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ=="], @@ -871,10 +1218,12 @@ "lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.32.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q=="], - "locate-path": ["locate-path@5.0.0", "", { "dependencies": { "p-locate": "^4.1.0" } }, "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g=="], + "locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="], "lodash.debounce": ["lodash.debounce@4.0.8", "", {}, "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="], + "lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="], + "lodash.throttle": ["lodash.throttle@4.1.1", "", {}, "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ=="], "log-symbols": ["log-symbols@2.2.0", "", { "dependencies": { "chalk": "^2.0.1" } }, "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg=="], @@ -931,7 +1280,9 @@ "mimic-fn": ["mimic-fn@1.2.0", "", {}, "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ=="], - "minimatch": ["minimatch@10.2.4", "", { "dependencies": { "brace-expansion": "^5.0.2" } }, "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg=="], + "minimatch": ["minimatch@3.1.5", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w=="], + + "minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="], "minipass": ["minipass@7.1.3", "", {}, "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A=="], @@ -943,8 +1294,14 @@ "nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], + "napi-postinstall": ["napi-postinstall@0.3.4", "", { "bin": { "napi-postinstall": "lib/cli.js" } }, "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ=="], + + "natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="], + "negotiator": ["negotiator@0.6.3", "", {}, "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg=="], + "node-exports-info": ["node-exports-info@1.6.0", "", { "dependencies": { "array.prototype.flatmap": "^1.3.3", "es-errors": "^1.3.0", "object.entries": "^1.1.9", "semver": "^6.3.1" } }, "sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw=="], + "node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="], "node-forge": ["node-forge@1.4.0", "", {}, "sha512-LarFH0+6VfriEhqMMcLX2F7SwSXeWwnEAJEsYm5QKWchiVYVvJyV9v7UDvUv+w5HO23ZpQTXDv/GxdDdMyOuoQ=="], @@ -963,6 +1320,20 @@ "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="], + "object-inspect": ["object-inspect@1.13.4", "", {}, "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="], + + "object-keys": ["object-keys@1.1.1", "", {}, "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="], + + "object.assign": ["object.assign@4.1.7", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0", "has-symbols": "^1.1.0", "object-keys": "^1.1.1" } }, "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw=="], + + "object.entries": ["object.entries@1.1.9", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.4", "define-properties": "^1.2.1", "es-object-atoms": "^1.1.1" } }, "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw=="], + + "object.fromentries": ["object.fromentries@2.0.8", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-abstract": "^1.23.2", "es-object-atoms": "^1.0.0" } }, "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ=="], + + "object.groupby": ["object.groupby@1.0.3", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-abstract": "^1.23.2" } }, "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ=="], + + "object.values": ["object.values@1.2.1", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" } }, "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA=="], + "on-finished": ["on-finished@2.4.1", "", { "dependencies": { "ee-first": "1.1.1" } }, "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg=="], "on-headers": ["on-headers@1.1.0", "", {}, "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A=="], @@ -973,20 +1344,28 @@ "open": ["open@7.4.2", "", { "dependencies": { "is-docker": "^2.0.0", "is-wsl": "^2.1.1" } }, "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q=="], + "optionator": ["optionator@0.9.4", "", { "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" } }, "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g=="], + "ora": ["ora@3.4.0", "", { "dependencies": { "chalk": "^2.4.2", "cli-cursor": "^2.1.0", "cli-spinners": "^2.0.0", "log-symbols": "^2.2.0", "strip-ansi": "^5.2.0", "wcwidth": "^1.0.1" } }, "sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg=="], - "p-limit": ["p-limit@2.3.0", "", { "dependencies": { "p-try": "^2.0.0" } }, "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w=="], + "own-keys": ["own-keys@1.0.1", "", { "dependencies": { "get-intrinsic": "^1.2.6", "object-keys": "^1.1.1", "safe-push-apply": "^1.0.0" } }, "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg=="], - "p-locate": ["p-locate@4.1.0", "", { "dependencies": { "p-limit": "^2.2.0" } }, "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A=="], + "p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="], + + "p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="], "p-try": ["p-try@2.2.0", "", {}, "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="], + "parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="], + "parse-png": ["parse-png@2.1.0", "", { "dependencies": { "pngjs": "^3.3.0" } }, "sha512-Nt/a5SfCLiTnQAjx3fHlqp8hRgTL3z7kTQZzvIMS9uCAepnCyjpdEc6M/sz69WqMBdaDBw9sF1F1UaHROYzGkQ=="], "parseurl": ["parseurl@1.3.3", "", {}, "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="], "path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="], + "path-expression-matcher": ["path-expression-matcher@1.2.0", "", {}, "sha512-DwmPWeFn+tq7TiyJ2CxezCAirXjFxvaiD03npak3cRjlP9+OjTmSy1EpIrEbh+l6JgUundniloMLDQ/6VTdhLQ=="], + "path-is-absolute": ["path-is-absolute@1.0.1", "", {}, "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="], "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="], @@ -1005,10 +1384,14 @@ "pngjs": ["pngjs@3.4.0", "", {}, "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w=="], + "possible-typed-array-names": ["possible-typed-array-names@1.1.0", "", {}, "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg=="], + "postcss": ["postcss@8.4.49", "", { "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA=="], "postcss-value-parser": ["postcss-value-parser@4.2.0", "", {}, "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="], + "prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="], + "pretty-format": ["pretty-format@29.7.0", "", { "dependencies": { "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" } }, "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ=="], "proc-log": ["proc-log@4.2.0", "", {}, "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA=="], @@ -1019,12 +1402,18 @@ "prompts": ["prompts@2.4.2", "", { "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" } }, "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q=="], + "prop-types": ["prop-types@15.8.1", "", { "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", "react-is": "^16.13.1" } }, "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg=="], + "proxy-from-env": ["proxy-from-env@2.1.0", "", {}, "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA=="], + "punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="], + "query-string": ["query-string@7.1.3", "", { "dependencies": { "decode-uri-component": "^0.2.2", "filter-obj": "^1.1.0", "split-on-first": "^1.0.0", "strict-uri-encode": "^2.0.0" } }, "sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg=="], "queue": ["queue@6.0.2", "", { "dependencies": { "inherits": "~2.0.3" } }, "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA=="], + "ramda": ["ramda@0.27.2", "", {}, "sha512-SbiLPU40JuJniHexQSAgad32hfwd+DRUdwF2PlVuI5RZD0/vahUco7R8vD86J/tcEKKF9vZrUVwgtmGCqlCKyA=="], + "range-parser": ["range-parser@1.2.1", "", {}, "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="], "react": ["react@19.2.0", "", {}, "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ=="], @@ -1047,6 +1436,8 @@ "react-native-reanimated": ["react-native-reanimated@4.2.1", "", { "dependencies": { "react-native-is-edge-to-edge": "1.2.1", "semver": "7.7.3" }, "peerDependencies": { "react": "*", "react-native": "*", "react-native-worklets": ">=0.7.0" } }, "sha512-/NcHnZMyOvsD/wYXug/YqSKw90P9edN0kEPL5lP4PFf1aQ4F1V7MKe/E0tvfkXKIajy3Qocp5EiEnlcrK/+BZg=="], + "react-native-render-html": ["react-native-render-html@6.3.4", "", { "dependencies": { "@jsamr/counter-style": "^2.0.1", "@jsamr/react-native-li": "^2.3.0", "@native-html/transient-render-engine": "11.2.3", "@types/ramda": "^0.27.40", "@types/urijs": "^1.19.15", "prop-types": "^15.5.7", "ramda": "^0.27.2", "stringify-entities": "^3.1.0", "urijs": "^1.19.6" }, "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-H2jSMzZjidE+Wo3qCWPUMU1nm98Vs2SGCvQCz/i6xf0P3Y9uVtG/b0sDbG/cYFir2mSYBYCIlS1Dv0WC1LjYig=="], + "react-native-safe-area-context": ["react-native-safe-area-context@5.6.2", "", { "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-4XGqMNj5qjUTYywJqpdWZ9IG8jgkS3h06sfVjfw5yZQZfWnRFXczi0GnYyFyCc2EBps/qFmoCH8fez//WumdVg=="], "react-native-screens": ["react-native-screens@4.23.0", "", { "dependencies": { "react-freeze": "^1.0.0", "warn-once": "^0.1.0" }, "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-XhO3aK0UeLpBn4kLecd+J+EDeRRJlI/Ro9Fze06vo1q163VeYtzfU9QS09/VyDFMWR1qxDC1iazCArTPSFFiPw=="], @@ -1063,12 +1454,18 @@ "react-style-singleton": ["react-style-singleton@2.2.3", "", { "dependencies": { "get-nonce": "^1.0.0", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ=="], + "readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], + + "reflect.getprototypeof": ["reflect.getprototypeof@1.0.10", "", { "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-abstract": "^1.23.9", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", "get-intrinsic": "^1.2.7", "get-proto": "^1.0.1", "which-builtin-type": "^1.2.1" } }, "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw=="], + "regenerate": ["regenerate@1.4.2", "", {}, "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A=="], "regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="], "regenerator-runtime": ["regenerator-runtime@0.13.11", "", {}, "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="], + "regexp.prototype.flags": ["regexp.prototype.flags@1.5.4", "", { "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-errors": "^1.3.0", "get-proto": "^1.0.1", "gopd": "^1.2.0", "set-function-name": "^2.0.2" } }, "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA=="], + "regexpu-core": ["regexpu-core@6.4.0", "", { "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.2.2", "regjsgen": "^0.8.0", "regjsparser": "^0.13.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.2.1" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="], "regjsgen": ["regjsgen@0.8.0", "", {}, "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q=="], @@ -1077,10 +1474,12 @@ "require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="], - "resolve": ["resolve@1.22.11", "", { "dependencies": { "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ=="], + "resolve": ["resolve@2.0.0-next.6", "", { "dependencies": { "es-errors": "^1.3.0", "is-core-module": "^2.16.1", "node-exports-info": "^1.6.0", "object-keys": "^1.1.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-3JmVl5hMGtJ3kMmB3zi3DL25KfkCEyy3Tw7Gmw7z5w8M9WlwoPFnIvwChzu1+cF3iaK3sp18hhPz8ANeimdJfA=="], "resolve-from": ["resolve-from@5.0.0", "", {}, "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw=="], + "resolve-pkg-maps": ["resolve-pkg-maps@1.0.0", "", {}, "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw=="], + "resolve-workspace-root": ["resolve-workspace-root@2.0.1", "", {}, "sha512-nR23LHAvaI6aHtMg6RWoaHpdR4D881Nydkzi2CixINyg9T00KgaJdJI6Vwty+Ps8WLxZHuxsS0BseWjxSA4C+w=="], "restore-cursor": ["restore-cursor@2.0.0", "", { "dependencies": { "onetime": "^2.0.0", "signal-exit": "^3.0.2" } }, "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q=="], @@ -1089,8 +1488,14 @@ "rtl-detect": ["rtl-detect@1.1.2", "", {}, "sha512-PGMBq03+TTG/p/cRB7HCLKJ1MgDIi07+QU1faSjiYRfmY5UsAttV9Hs08jDAHVwcOwmVLcSJkpwyfXszVjWfIQ=="], + "safe-array-concat": ["safe-array-concat@1.1.3", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.2", "get-intrinsic": "^1.2.6", "has-symbols": "^1.1.0", "isarray": "^2.0.5" } }, "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q=="], + "safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="], + "safe-push-apply": ["safe-push-apply@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0", "isarray": "^2.0.5" } }, "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA=="], + + "safe-regex-test": ["safe-regex-test@1.1.0", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "is-regex": "^1.2.1" } }, "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw=="], + "sax": ["sax@1.6.0", "", {}, "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA=="], "scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="], @@ -1105,6 +1510,12 @@ "server-only": ["server-only@0.0.1", "", {}, "sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA=="], + "set-function-length": ["set-function-length@1.2.2", "", { "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", "has-property-descriptors": "^1.0.2" } }, "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg=="], + + "set-function-name": ["set-function-name@2.0.2", "", { "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", "functions-have-names": "^1.2.3", "has-property-descriptors": "^1.0.2" } }, "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ=="], + + "set-proto": ["set-proto@1.0.0", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0" } }, "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw=="], + "setimmediate": ["setimmediate@1.0.5", "", {}, "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA=="], "setprototypeof": ["setprototypeof@1.2.0", "", {}, "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="], @@ -1119,6 +1530,14 @@ "shell-quote": ["shell-quote@1.8.3", "", {}, "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw=="], + "side-channel": ["side-channel@1.1.0", "", { "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" } }, "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw=="], + + "side-channel-list": ["side-channel-list@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3" } }, "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA=="], + + "side-channel-map": ["side-channel-map@1.0.1", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3" } }, "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA=="], + + "side-channel-weakmap": ["side-channel-weakmap@1.0.2", "", { "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" } }, "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A=="], + "signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="], "simple-plist": ["simple-plist@1.3.1", "", { "dependencies": { "bplist-creator": "0.1.0", "bplist-parser": "0.3.1", "plist": "^3.0.5" } }, "sha512-iMSw5i0XseMnrhtIzRb7XpQEXepa9xhWxGUojHBL43SIpQuDQkh3Wpy67ZbDzZVr6EKxvwVChnVpdl8hEVLDiw=="], @@ -1141,6 +1560,8 @@ "sprintf-js": ["sprintf-js@1.0.3", "", {}, "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g=="], + "stable-hash": ["stable-hash@0.0.5", "", {}, "sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA=="], + "stack-utils": ["stack-utils@2.0.6", "", { "dependencies": { "escape-string-regexp": "^2.0.0" } }, "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ=="], "stackframe": ["stackframe@1.3.4", "", {}, "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw=="], @@ -1149,14 +1570,38 @@ "statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="], + "stop-iteration-iterator": ["stop-iteration-iterator@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "internal-slot": "^1.1.0" } }, "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ=="], + + "stream-browserify": ["stream-browserify@3.0.0", "", { "dependencies": { "inherits": "~2.0.4", "readable-stream": "^3.5.0" } }, "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA=="], + "stream-buffers": ["stream-buffers@2.2.0", "", {}, "sha512-uyQK/mx5QjHun80FLJTfaWE7JtwfRMKBLkMne6udYOmvH0CawotVa7TfgYHzAnpphn4+TweIx1QKMnRIbipmUg=="], "strict-uri-encode": ["strict-uri-encode@2.0.0", "", {}, "sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ=="], "string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], + "string.prototype.matchall": ["string.prototype.matchall@4.0.12", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-abstract": "^1.23.6", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", "get-intrinsic": "^1.2.6", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "internal-slot": "^1.1.0", "regexp.prototype.flags": "^1.5.3", "set-function-name": "^2.0.2", "side-channel": "^1.1.0" } }, "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA=="], + + "string.prototype.repeat": ["string.prototype.repeat@1.0.0", "", { "dependencies": { "define-properties": "^1.1.3", "es-abstract": "^1.17.5" } }, "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w=="], + + "string.prototype.trim": ["string.prototype.trim@1.2.10", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.2", "define-data-property": "^1.1.4", "define-properties": "^1.2.1", "es-abstract": "^1.23.5", "es-object-atoms": "^1.0.0", "has-property-descriptors": "^1.0.2" } }, "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA=="], + + "string.prototype.trimend": ["string.prototype.trimend@1.0.9", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.2", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" } }, "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ=="], + + "string.prototype.trimstart": ["string.prototype.trimstart@1.0.8", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" } }, "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg=="], + + "string_decoder": ["string_decoder@1.3.0", "", { "dependencies": { "safe-buffer": "~5.2.0" } }, "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA=="], + + "stringify-entities": ["stringify-entities@3.1.0", "", { "dependencies": { "character-entities-html4": "^1.0.0", "character-entities-legacy": "^1.0.0", "xtend": "^4.0.0" } }, "sha512-3FP+jGMmMV/ffZs86MoghGqAoqXAdxLrJP4GUdrDN1aIScYih5tuIO3eF4To5AJZ79KDZ8Fpdy7QJnK8SsL1Vg=="], + "strip-ansi": ["strip-ansi@5.2.0", "", { "dependencies": { "ansi-regex": "^4.1.0" } }, "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA=="], + "strip-bom": ["strip-bom@3.0.0", "", {}, "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA=="], + + "strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="], + + "strnum": ["strnum@2.2.2", "", {}, "sha512-DnR90I+jtXNSTXWdwrEy9FakW7UX+qUZg28gj5fk2vxxl7uS/3bpI4fjFYVmdK9etptYBPNkpahuQnEwhwECqA=="], + "structured-headers": ["structured-headers@0.4.1", "", {}, "sha512-0MP/Cxx5SzeeZ10p/bZI0S6MpgD+yxAhi1BOQ34jgnMXsCq3j1t6tQnZu+KdlL7dvJTLT3g9xN8tl10TqgFMcg=="], "styleq": ["styleq@0.1.3", "", {}, "sha512-3ZUifmCDCQanjeej1f6kyl/BeP/Vae5EYkQ9iJfUm/QwZvlgnZzyflqAsAWYURdtea8Vkvswu2GrC57h3qffcA=="], @@ -1175,6 +1620,8 @@ "throat": ["throat@5.0.0", "", {}, "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA=="], + "tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="], + "tmpl": ["tmpl@1.0.5", "", {}, "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw=="], "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], @@ -1185,16 +1632,34 @@ "tr46": ["tr46@0.0.3", "", {}, "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="], + "ts-api-utils": ["ts-api-utils@2.5.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA=="], + + "ts-toolbelt": ["ts-toolbelt@6.15.5", "", {}, "sha512-FZIXf1ksVyLcfr7M317jbB67XFJhOO1YqdTcuGaq9q5jLUoTikukZ+98TPjKiP2jC5CgmYdWWYs0s2nLSU0/1A=="], + + "tsconfig-paths": ["tsconfig-paths@3.15.0", "", { "dependencies": { "@types/json5": "^0.0.29", "json5": "^1.0.2", "minimist": "^1.2.6", "strip-bom": "^3.0.0" } }, "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg=="], + "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], + "type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="], + "type-detect": ["type-detect@4.0.8", "", {}, "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g=="], "type-fest": ["type-fest@0.7.1", "", {}, "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg=="], + "typed-array-buffer": ["typed-array-buffer@1.0.3", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "is-typed-array": "^1.1.14" } }, "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw=="], + + "typed-array-byte-length": ["typed-array-byte-length@1.0.3", "", { "dependencies": { "call-bind": "^1.0.8", "for-each": "^0.3.3", "gopd": "^1.2.0", "has-proto": "^1.2.0", "is-typed-array": "^1.1.14" } }, "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg=="], + + "typed-array-byte-offset": ["typed-array-byte-offset@1.0.4", "", { "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", "for-each": "^0.3.3", "gopd": "^1.2.0", "has-proto": "^1.2.0", "is-typed-array": "^1.1.15", "reflect.getprototypeof": "^1.0.9" } }, "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ=="], + + "typed-array-length": ["typed-array-length@1.0.7", "", { "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", "is-typed-array": "^1.1.13", "possible-typed-array-names": "^1.0.0", "reflect.getprototypeof": "^1.0.6" } }, "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg=="], + "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], "ua-parser-js": ["ua-parser-js@0.7.41", "", { "bin": { "ua-parser-js": "script/cli.js" } }, "sha512-O3oYyCMPYgNNHuO7Jjk3uacJWZF8loBgwrfd/5LE/HyZ3lUIOdniQ7DNXJcIgZbwioZxk0fLfI4EVnetdiX5jg=="], + "unbox-primitive": ["unbox-primitive@1.1.0", "", { "dependencies": { "call-bound": "^1.0.3", "has-bigints": "^1.0.2", "has-symbols": "^1.1.0", "which-boxed-primitive": "^1.1.1" } }, "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw=="], + "undici-types": ["undici-types@7.18.2", "", {}, "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w=="], "unicode-canonical-property-names-ecmascript": ["unicode-canonical-property-names-ecmascript@2.0.1", "", {}, "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg=="], @@ -1209,8 +1674,14 @@ "unpipe": ["unpipe@1.0.0", "", {}, "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="], + "unrs-resolver": ["unrs-resolver@1.11.1", "", { "dependencies": { "napi-postinstall": "^0.3.0" }, "optionalDependencies": { "@unrs/resolver-binding-android-arm-eabi": "1.11.1", "@unrs/resolver-binding-android-arm64": "1.11.1", "@unrs/resolver-binding-darwin-arm64": "1.11.1", "@unrs/resolver-binding-darwin-x64": "1.11.1", "@unrs/resolver-binding-freebsd-x64": "1.11.1", "@unrs/resolver-binding-linux-arm-gnueabihf": "1.11.1", "@unrs/resolver-binding-linux-arm-musleabihf": "1.11.1", "@unrs/resolver-binding-linux-arm64-gnu": "1.11.1", "@unrs/resolver-binding-linux-arm64-musl": "1.11.1", "@unrs/resolver-binding-linux-ppc64-gnu": "1.11.1", "@unrs/resolver-binding-linux-riscv64-gnu": "1.11.1", "@unrs/resolver-binding-linux-riscv64-musl": "1.11.1", "@unrs/resolver-binding-linux-s390x-gnu": "1.11.1", "@unrs/resolver-binding-linux-x64-gnu": "1.11.1", "@unrs/resolver-binding-linux-x64-musl": "1.11.1", "@unrs/resolver-binding-wasm32-wasi": "1.11.1", "@unrs/resolver-binding-win32-arm64-msvc": "1.11.1", "@unrs/resolver-binding-win32-ia32-msvc": "1.11.1", "@unrs/resolver-binding-win32-x64-msvc": "1.11.1" } }, "sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg=="], + "update-browserslist-db": ["update-browserslist-db@1.2.3", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w=="], + "uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="], + + "urijs": ["urijs@1.19.11", "", {}, "sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ=="], + "use-callback-ref": ["use-callback-ref@1.3.3", "", { "dependencies": { "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg=="], "use-latest-callback": ["use-latest-callback@0.2.6", "", { "peerDependencies": { "react": ">=16.8" } }, "sha512-FvRG9i1HSo0wagmX63Vrm8SnlUU3LMM3WyZkQ76RnslpBrX694AdG4A0zQBx2B3ZifFA0yv/BaEHGBnEax5rZg=="], @@ -1219,6 +1690,8 @@ "use-sync-external-store": ["use-sync-external-store@1.6.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w=="], + "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="], + "utils-merge": ["utils-merge@1.0.1", "", {}, "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA=="], "uuid": ["uuid@7.0.3", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg=="], @@ -1247,6 +1720,16 @@ "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], + "which-boxed-primitive": ["which-boxed-primitive@1.1.1", "", { "dependencies": { "is-bigint": "^1.1.0", "is-boolean-object": "^1.2.1", "is-number-object": "^1.1.1", "is-string": "^1.1.1", "is-symbol": "^1.1.1" } }, "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA=="], + + "which-builtin-type": ["which-builtin-type@1.2.1", "", { "dependencies": { "call-bound": "^1.0.2", "function.prototype.name": "^1.1.6", "has-tostringtag": "^1.0.2", "is-async-function": "^2.0.0", "is-date-object": "^1.1.0", "is-finalizationregistry": "^1.1.0", "is-generator-function": "^1.0.10", "is-regex": "^1.2.1", "is-weakref": "^1.0.2", "isarray": "^2.0.5", "which-boxed-primitive": "^1.1.0", "which-collection": "^1.0.2", "which-typed-array": "^1.1.16" } }, "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q=="], + + "which-collection": ["which-collection@1.0.2", "", { "dependencies": { "is-map": "^2.0.3", "is-set": "^2.0.3", "is-weakmap": "^2.0.2", "is-weakset": "^2.0.3" } }, "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw=="], + + "which-typed-array": ["which-typed-array@1.1.20", "", { "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", "call-bound": "^1.0.4", "for-each": "^0.3.5", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-tostringtag": "^1.0.2" } }, "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg=="], + + "word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="], + "wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="], @@ -1257,9 +1740,11 @@ "xcode": ["xcode@3.0.1", "", { "dependencies": { "simple-plist": "^1.1.0", "uuid": "^7.0.3" } }, "sha512-kCz5k7J7XbJtjABOvkc5lJmkiDh8VhjVCGNiqdKCscmVpdVUpEAyXv1xmCLkQJ5dsHqx3IPO4XW+NTDhU/fatA=="], - "xml2js": ["xml2js@0.6.2", "", { "dependencies": { "sax": ">=0.6.0", "xmlbuilder": "~11.0.0" } }, "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA=="], + "xml2js": ["xml2js@0.6.0", "", { "dependencies": { "sax": ">=0.6.0", "xmlbuilder": "~11.0.0" } }, "sha512-eLTh0kA8uHceqesPqSE+VvO1CDDJWMwlQfB6LuN6T8w6MaDJ8Txm8P7s5cHD0miF0V+GGTZrDQfxPZQVsur33w=="], - "xmlbuilder": ["xmlbuilder@11.0.1", "", {}, "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA=="], + "xmlbuilder": ["xmlbuilder@15.1.1", "", {}, "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg=="], + + "xtend": ["xtend@4.0.2", "", {}, "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="], "y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="], @@ -1271,6 +1756,8 @@ "yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="], + "yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="], + "zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], "zustand": ["zustand@5.0.12", "", { "peerDependencies": { "@types/react": ">=18.0.0", "immer": ">=9.0.6", "react": ">=18.0.0", "use-sync-external-store": ">=1.2.0" }, "optionalPeers": ["@types/react", "immer", "react", "use-sync-external-store"] }, "sha512-i77ae3aZq4dhMlRhJVCYgMLKuSiZAaUPAct2AksxQ+gOtimhGMdXljRT21P5BNpeT4kXlLIckvkPM029OljD7g=="], @@ -1283,8 +1770,14 @@ "@babel/helper-create-regexp-features-plugin/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + "@babel/helper-define-polyfill-provider/resolve": ["resolve@1.22.11", "", { "dependencies": { "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ=="], + "@babel/plugin-transform-runtime/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + "@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="], + + "@eslint/eslintrc/globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="], + "@expo/cli/glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" } }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="], "@expo/cli/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="], @@ -1299,26 +1792,24 @@ "@expo/config-plugins/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="], - "@expo/config-plugins/xml2js": ["xml2js@0.6.0", "", { "dependencies": { "sax": ">=0.6.0", "xmlbuilder": "~11.0.0" } }, "sha512-eLTh0kA8uHceqesPqSE+VvO1CDDJWMwlQfB6LuN6T8w6MaDJ8Txm8P7s5cHD0miF0V+GGTZrDQfxPZQVsur33w=="], - "@expo/devcert/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="], "@expo/fingerprint/glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" } }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="], + "@expo/fingerprint/minimatch": ["minimatch@10.2.4", "", { "dependencies": { "brace-expansion": "^5.0.2" } }, "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg=="], + "@expo/fingerprint/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="], "@expo/image-utils/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="], "@expo/metro-config/glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" } }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="], - "@expo/plist/xmlbuilder": ["xmlbuilder@15.1.1", "", {}, "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg=="], - "@expo/prebuild-config/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="], - "@expo/prebuild-config/xml2js": ["xml2js@0.6.0", "", { "dependencies": { "sax": ">=0.6.0", "xmlbuilder": "~11.0.0" } }, "sha512-eLTh0kA8uHceqesPqSE+VvO1CDDJWMwlQfB6LuN6T8w6MaDJ8Txm8P7s5cHD0miF0V+GGTZrDQfxPZQVsur33w=="], - "@istanbuljs/load-nyc-config/camelcase": ["camelcase@5.3.1", "", {}, "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="], + "@istanbuljs/load-nyc-config/find-up": ["find-up@4.1.0", "", { "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" } }, "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw=="], + "@istanbuljs/load-nyc-config/js-yaml": ["js-yaml@3.14.2", "", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg=="], "@radix-ui/react-collection/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], @@ -1331,6 +1822,14 @@ "@react-native/community-cli-plugin/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="], + "@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], + + "@typescript-eslint/typescript-estree/minimatch": ["minimatch@10.2.4", "", { "dependencies": { "brace-expansion": "^5.0.2" } }, "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg=="], + + "@typescript-eslint/typescript-estree/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="], + + "@typescript-eslint/visitor-keys/eslint-visitor-keys": ["eslint-visitor-keys@5.0.1", "", {}, "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA=="], + "ansi-escapes/type-fest": ["type-fest@0.21.3", "", {}, "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w=="], "anymatch/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], @@ -1343,8 +1842,6 @@ "better-opn/open": ["open@8.4.2", "", { "dependencies": { "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", "is-wsl": "^2.2.0" } }, "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ=="], - "chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], - "cliui/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], "compression/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], @@ -1353,6 +1850,20 @@ "connect/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], + "dom-serializer/entities": ["entities@2.2.0", "", {}, "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A=="], + + "eslint-import-resolver-node/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="], + + "eslint-import-resolver-node/resolve": ["resolve@1.22.11", "", { "dependencies": { "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ=="], + + "eslint-module-utils/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="], + + "eslint-plugin-import/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="], + + "eslint-plugin-import/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + + "eslint-plugin-react/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + "expo-modules-autolinking/commander": ["commander@7.2.0", "", {}, "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="], "fbjs/promise": ["promise@7.3.1", "", { "dependencies": { "asap": "~2.0.3" } }, "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg=="], @@ -1367,12 +1878,14 @@ "finalhandler/statuses": ["statuses@1.5.0", "", {}, "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA=="], - "glob/minimatch": ["minimatch@3.1.5", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w=="], - "hoist-non-react-statics/react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="], "hosted-git-info/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], + "import-fresh/resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="], + + "is-bun-module/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="], + "istanbul-lib-instrument/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], "jest-util/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], @@ -1391,16 +1904,20 @@ "micromatch/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], + "node-exports-info/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + "npm-package-arg/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="], "ora/chalk": ["chalk@2.4.2", "", { "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" } }, "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ=="], "path-scurry/lru-cache": ["lru-cache@11.2.7", "", {}, "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA=="], - "plist/xmlbuilder": ["xmlbuilder@15.1.1", "", {}, "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg=="], + "pretty-format/ansi-styles": ["ansi-styles@5.2.0", "", {}, "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA=="], "pretty-format/react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="], + "prop-types/react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="], + "react-native/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="], "react-native-reanimated/react-native-is-edge-to-edge": ["react-native-is-edge-to-edge@1.2.1", "", { "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-FLbPWl/MyYQWz+KwqOZsSyj2JmLKglHatd3xLZWskXOpRaio4LfEDEz8E/A6uD8QoTHW6Aobw1jbEwK7KMgR7Q=="], @@ -1425,16 +1942,30 @@ "terser/commander": ["commander@2.20.3", "", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="], - "test-exclude/minimatch": ["minimatch@3.1.5", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w=="], - - "wrap-ansi/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], + "tsconfig-paths/json5": ["json5@1.0.2", "", { "dependencies": { "minimist": "^1.2.0" }, "bin": { "json5": "lib/cli.js" } }, "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA=="], "wrap-ansi/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + "xml2js/xmlbuilder": ["xmlbuilder@11.0.1", "", {}, "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA=="], + + "@expo/cli/glob/minimatch": ["minimatch@10.2.4", "", { "dependencies": { "brace-expansion": "^5.0.2" } }, "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg=="], + + "@expo/config-plugins/glob/minimatch": ["minimatch@10.2.4", "", { "dependencies": { "brace-expansion": "^5.0.2" } }, "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg=="], + + "@expo/config/glob/minimatch": ["minimatch@10.2.4", "", { "dependencies": { "brace-expansion": "^5.0.2" } }, "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg=="], + + "@expo/fingerprint/minimatch/brace-expansion": ["brace-expansion@5.0.5", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ=="], + + "@expo/metro-config/glob/minimatch": ["minimatch@10.2.4", "", { "dependencies": { "brace-expansion": "^5.0.2" } }, "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg=="], + + "@istanbuljs/load-nyc-config/find-up/locate-path": ["locate-path@5.0.0", "", { "dependencies": { "p-locate": "^4.1.0" } }, "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g=="], + "@istanbuljs/load-nyc-config/js-yaml/argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="], "@react-native/codegen/hermes-parser/hermes-estree": ["hermes-estree@0.32.0", "", {}, "sha512-KWn3BqnlDOl97Xe1Yviur6NbgIZ+IP+UVSpshlZWkq+EtoHg6/cwiDj/osP9PCEgFE15KBm1O55JRwbMEm5ejQ=="], + "@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@5.0.5", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ=="], + "babel-plugin-syntax-hermes-parser/hermes-parser/hermes-estree": ["hermes-estree@0.32.0", "", {}, "sha512-KWn3BqnlDOl97Xe1Yviur6NbgIZ+IP+UVSpshlZWkq+EtoHg6/cwiDj/osP9PCEgFE15KBm1O55JRwbMEm5ejQ=="], "compression/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], @@ -1443,8 +1974,6 @@ "finalhandler/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], - "glob/minimatch/brace-expansion": ["brace-expansion@1.1.13", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w=="], - "lighthouse-logger/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], "log-symbols/chalk/ansi-styles": ["ansi-styles@3.2.1", "", { "dependencies": { "color-convert": "^1.9.0" } }, "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA=="], @@ -1465,9 +1994,19 @@ "send/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], - "test-exclude/minimatch/brace-expansion": ["brace-expansion@1.1.13", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w=="], + "@expo/cli/glob/minimatch/brace-expansion": ["brace-expansion@5.0.5", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ=="], - "glob/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], + "@expo/config-plugins/glob/minimatch/brace-expansion": ["brace-expansion@5.0.5", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ=="], + + "@expo/config/glob/minimatch/brace-expansion": ["brace-expansion@5.0.5", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ=="], + + "@expo/fingerprint/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], + + "@expo/metro-config/glob/minimatch/brace-expansion": ["brace-expansion@5.0.5", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ=="], + + "@istanbuljs/load-nyc-config/find-up/locate-path/p-locate": ["p-locate@4.1.0", "", { "dependencies": { "p-limit": "^2.2.0" } }, "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A=="], + + "@typescript-eslint/typescript-estree/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], "log-symbols/chalk/ansi-styles/color-convert": ["color-convert@1.9.3", "", { "dependencies": { "color-name": "1.1.3" } }, "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg=="], @@ -1477,7 +2016,15 @@ "ora/chalk/supports-color/has-flag": ["has-flag@3.0.0", "", {}, "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="], - "test-exclude/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], + "@expo/cli/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], + + "@expo/config-plugins/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], + + "@expo/config/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], + + "@expo/metro-config/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], + + "@istanbuljs/load-nyc-config/find-up/locate-path/p-locate/p-limit": ["p-limit@2.3.0", "", { "dependencies": { "p-try": "^2.0.0" } }, "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w=="], "log-symbols/chalk/ansi-styles/color-convert/color-name": ["color-name@1.1.3", "", {}, "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="], diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..ba708ed --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,10 @@ +// https://docs.expo.dev/guides/using-eslint/ +const { defineConfig } = require('eslint/config'); +const expoConfig = require("eslint-config-expo/flat"); + +module.exports = defineConfig([ + expoConfig, + { + ignores: ["dist/*"], + } +]); diff --git a/native-route/README.md b/native-route/README.md new file mode 100644 index 0000000..f70b672 --- /dev/null +++ b/native-route/README.md @@ -0,0 +1,263 @@ +# RSSuper - Multi-Platform Native Build System + +This directory contains the build infrastructure for building RSSuper natively across multiple platforms. + +## Architecture + +``` +native-route/ +├── ios/ - iOS/macOS app (Swift/SwiftUI) +│ └── RSSuper/ +│ ├── RSSuper.xcodeproj/ +│ ├── RSSuper/ +│ ├── RSSuperTests/ +│ └── RSSuperUITests/ +├── android/ - Android app (Kotlin/Jetpack Compose) +│ └── (auto-generated on first build) +├── linux/ - Linux app (C/Vala + GTK4) +│ └── (auto-generated on first build) +└── windows/ - Windows app (TODO) +``` + +## Quick Start + +### Build All Platforms + +```bash +# From project root +./scripts/build.sh +``` + +### Build Specific Platform + +```bash +# iOS/macOS only +./scripts/build.sh -p ios + +# Android only +./scripts/build.sh -p android + +# Linux only +./scripts/build.sh -p linux + +# Multiple platforms +./scripts/build.sh -p ios,android +``` + +### Build Types + +```bash +# Debug build (default) +./scripts/build.sh -t debug + +# Release build +./scripts/build.sh -t release +``` + +### Run Tests + +```bash +# Build and test all platforms +./scripts/build.sh --test + +# Test specific platform +./scripts/build.sh -p ios --test +``` + +### Clean Build + +```bash +# Clean all platforms +./scripts/build.sh -a clean + +# Clean specific platform +./scripts/build-ios.sh clean +./scripts/build-android.sh clean +./scripts/build-linux.sh clean +``` + +## Individual Platform Scripts + +### iOS/macOS + +```bash +# Build +./scripts/build-ios.sh [Debug|Release] [iOS|macOS] [destination] [action] + +# Examples +./scripts/build-ios.sh # Debug iOS +./scripts/build-ios.sh Release # Release iOS +./scripts/build-ios.sh Debug iOS "platform=iOS Simulator,name=iPhone 15" +./scripts/build-ios.sh clean +./scripts/build-ios.sh Debug iOS "generic/platform=iOS" test +``` + +### Android + +```bash +# Build +./scripts/build-android.sh [debug|release] [assemble|build|test|clean] + +# Examples +./scripts/build-android.sh # Assemble debug +./scripts/build-android.sh release # Assemble release +./scripts/build-android.sh debug test # Run tests +./scripts/build-android.sh clean # Clean +``` + +### Linux + +```bash +# Build +./scripts/build-linux.sh [debug|release] [build|install|test|clean|setup] + +# Examples +./scripts/build-linux.sh # Build debug +./scripts/build-linux.sh release # Build release +./scripts/build-linux.sh debug setup # Setup build environment +./scripts/build-linux.sh debug install-deps # Install dependencies +./scripts/build-linux.sh debug run # Build and run +./scripts/build-linux.sh clean # Clean +``` + +## Platform-Specific Details + +### iOS/macOS + +- **Language**: Swift +- **UI Framework**: SwiftUI +- **Build System**: Xcode/xcodebuild +- **Minimum Deployment**: iOS 16.0+ +- **Features**: + - SwiftUI for declarative UI + - Combine for reactive programming + - Core Data for persistence + - Background fetch for feed updates + +### Android + +- **Language**: Kotlin +- **UI Framework**: Jetpack Compose +- **Build System**: Gradle +- **Minimum SDK**: 24 (Android 7.0) +- **Features**: + - Jetpack Compose for modern UI + - ViewModel + LiveData for state management + - Room for local database + - Retrofit for networking + +### Linux + +- **Language**: C + Vala +- **UI Framework**: GTK4 + Libadwaita +- **Build System**: Meson + Ninja +- **Dependencies**: + - GTK4 + - Libadwaita + - SQLite3 + - libxml2 + - libsoup-3.0 +- **Features**: + - Native Linux look and feel + - GNOME integration + - System tray support + - Desktop notifications + +## CI/CD + +GitHub Actions workflow is configured in `.github/workflows/ci.yml`: + +- **iOS**: Builds on macos-15 runner +- **Android**: Builds on ubuntu-24.04 runner +- **Linux**: Builds on ubuntu-24.04 runner + +### Workflow Features + +- Automatic builds on push/PR +- Manual trigger with configurable options +- Build artifacts uploaded for download +- Build reports generated +- Test execution (configurable) + +## Project Structure Template + +When you add shared code, use this structure: + +``` +RSSuper/ +├── native-route/ +│ ├── common/ # Shared code (if using a shared language) +│ ├── ios/ +│ │ └── RSSuper/ +│ ├── android/ +│ ├── linux/ +│ └── windows/ +├── scripts/ +│ ├── build.sh # Main build orchestrator +│ ├── build-ios.sh # iOS/macOS builder +│ ├── build-android.sh # Android builder +│ ├── build-linux.sh # Linux builder +│ └── common.sh # Shared utilities +└── .github/ + └── workflows/ + └── ci.yml # CI configuration +``` + +## Migration Notes + +Build scripts adapted from Nessa project: +- Xcode version selection logic +- Build report generation +- Error extraction and display +- CI workflow structure + +## Troubleshooting + +### iOS Build Fails + +```bash +# Check Xcode installation +xcodebuild -version + +# Select Xcode manually +sudo xcode-select -s /Applications/Xcode.app/Contents/Developer + +# Clean DerivedData +rm -rf ~/Library/Developer/Xcode/DerivedData/RSSuper-* +``` + +### Android Build Fails + +```bash +# Check Java installation +java -version + +# Check Android SDK +echo $ANDROID_HOME + +# Run with more verbose output +./scripts/build-android.sh debug assemble --info +``` + +### Linux Build Fails + +```bash +# Install dependencies (Ubuntu/Debian) +sudo apt install meson ninja-build pkg-config libgtk-4-dev libadwaita-1-dev + +# Check meson installation +meson --version + +# Setup build manually +cd native-route/linux +meson setup build --buildtype=debug +``` + +## Future Enhancements + +- [ ] Windows support (Win32 + DirectUI or WebView2) +- [ ] Shared business logic layer +- [ ] Cross-platform test suite +- [ ] Automated code signing +- [ ] App store deployment scripts +- [ ] Performance benchmarking diff --git a/native-route/ios/RSSuper b/native-route/ios/RSSuper new file mode 160000 index 0000000..86e278d --- /dev/null +++ b/native-route/ios/RSSuper @@ -0,0 +1 @@ +Subproject commit 86e278d2729f8d16f5c4b9f43473609a17293f33 diff --git a/package.json b/package.json index e95edd9..6dd72dc 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,8 @@ "devDependencies": { "@types/react": "~19.2.2", "@types/xml2js": "^0.4.14", + "eslint": "^9.0.0", + "eslint-config-expo": "55.0.1-canary-20260328-2049187", "typescript": "~5.9.2" }, "private": true diff --git a/scripts/build-android.sh b/scripts/build-android.sh new file mode 100755 index 0000000..23de3e5 --- /dev/null +++ b/scripts/build-android.sh @@ -0,0 +1,422 @@ +#!/bin/bash +# RSSuper Android Build Script +# Native Android build using Gradle + +set -e + +# Configuration +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" +ANDROID_PROJECT_DIR="$PROJECT_ROOT/native-route/android" + +# Default values +VARIANT="${1:-debug}" +ACTION="${2:-assemble}" + +# Show help +show_help() { + echo "RSSuper Android Build Script" + echo "" + echo "Usage: $0 [VARIANT] [ACTION]" + echo "" + echo "Arguments:" + echo " VARIANT Build variant (debug|release) [Default: debug]" + echo " ACTION Gradle action (assemble|build|test|clean) [Default: assemble]" + echo "" + echo "Examples:" + echo " $0 # Assemble debug APK" + echo " $0 release # Assemble release APK" + echo " $0 debug test # Run tests" + echo " $0 clean # Clean build" +} + +# Check prerequisites +check_prerequisites() { + if [ ! -d "$ANDROID_PROJECT_DIR" ]; then + echo "Error: Android project directory not found: $ANDROID_PROJECT_DIR" + echo "Creating basic Android project structure..." + create_android_project + return 0 + fi + + if [ ! -f "$ANDROID_PROJECT_DIR/build.gradle.kts" ] && [ ! -f "$ANDROID_PROJECT_DIR/build.gradle" ]; then + echo "Warning: No build.gradle found. Creating basic Android project..." + create_android_project + fi + + # Check for Java/JDK + if ! command -v java &> /dev/null; then + echo "Error: Java not found. Please install JDK 17." + exit 1 + fi + + echo "Java version:" + java -version +} + +# Create basic Android project structure +create_android_project() { + echo "Creating Android project structure..." + + mkdir -p "$ANDROID_PROJECT_DIR/app/src/main/java/com/mikefreno/rssuper" + mkdir -p "$ANDROID_PROJECT_DIR/app/src/main/res/values" + mkdir -p "$ANDROID_PROJECT_DIR/app/src/main/res/mipmap-hdpi" + mkdir -p "$ANDROID_PROJECT_DIR/gradle/wrapper" + + # Root build.gradle.kts + cat > "$ANDROID_PROJECT_DIR/build.gradle.kts" << 'EOF' +// Top-level build file where you can add configuration options common to all sub-projects/modules. +plugins { + id("com.android.application") version "8.2.0" apply false + id("org.jetbrains.kotlin.android") version "1.9.0" apply false +} + +allprojects { + repositories { + google() + mavenCentral() + } +} + +task("clean") { + delete(rootProject.buildDir) +} +EOF + + # settings.gradle.kts + cat > "$ANDROID_PROJECT_DIR/settings.gradle.kts" << 'EOF' +pluginManagement { + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} + +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { + google() + mavenCentral() + } +} + +rootProject.name = "RSSuper" +include(":app") +EOF + + # app/build.gradle.kts + cat > "$ANDROID_PROJECT_DIR/app/build.gradle.kts" << 'EOF' +plugins { + id("com.android.application") + id("org.jetbrains.kotlin.android") +} + +android { + namespace = "com.mikefreno.rssuper" + compileSdk = 34 + + defaultConfig { + applicationId = "com.mikefreno.rssuper" + minSdk = 24 + targetSdk = 34 + versionCode = 1 + versionName = "1.0" + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") + } + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } + + kotlinOptions { + jvmTarget = "17" + } +} + +dependencies { + implementation("androidx.core:core-ktx:1.12.0") + implementation("androidx.appcompat:appcompat:1.6.1") + implementation("com.google.android.material:material:1.11.0") + implementation("androidx.constraintlayout:constraintlayout:2.1.4") + + // Navigation + implementation("androidx.navigation:navigation-fragment-ktx:2.7.6") + implementation("androidx.navigation:navigation-ui-ktx:2.7.6") + + // Lifecycle + implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0") + implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.7.0") + + // Coroutines + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3") + + // Networking + implementation("com.squareup.retrofit2:retrofit:2.9.0") + implementation("com.squareup.retrofit2:converter-gson:2.9.0") + implementation("com.squareup.okhttp3:okhttp:4.12.0") + + // Room Database + implementation("androidx.room:room-runtime:2.6.1") + implementation("androidx.room:room-ktx:2.6.1") + + testImplementation("junit:junit:4.13.2") + androidTestImplementation("androidx.test.ext:junit:1.1.5") + androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") +} +EOF + + # gradle.properties + cat > "$ANDROID_PROJECT_DIR/gradle.properties" << 'EOF' +org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 +android.useAndroidX=true +kotlin.code.style=official +android.nonTransitiveRClass=true +EOF + + # gradle wrapper properties + cat > "$ANDROID_PROJECT_DIR/gradle/wrapper/gradle-wrapper.properties" << 'EOF' +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +EOF + + # Main Activity + cat > "$ANDROID_PROJECT_DIR/app/src/main/java/com/mikefreno/rssuper/MainActivity.kt" << 'EOF' +package com.mikefreno.rssuper + +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import com.mikefreno.rssuper.ui.theme.RSSuperTheme + +class MainActivity : ComponentActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContent { + RSSuperTheme { + Surface( + modifier = Modifier.fillMaxSize(), + color = MaterialTheme.colorScheme.background + ) { + Greeting("Android") + } + } + } + } +} + +@Composable +fun Greeting(name: String, modifier: Modifier = Modifier) { + Text( + text = "RSSuper - $name", + modifier = modifier + ) +} + +@Preview(showBackground = true) +@Composable +fun GreetingPreview() { + RSSuperTheme { + Greeting("Android") + } +} +EOF + + # Theme + mkdir -p "$ANDROID_PROJECT_DIR/app/src/main/java/com/mikefreno/rssuper/ui/theme" + cat > "$ANDROID_PROJECT_DIR/app/src/main/java/com/mikefreno/rssuper/ui/theme/Theme.kt" << 'EOF' +package com.mikefreno.rssuper.ui.theme + +import android.app.Activity +import android.os.Build +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.darkColorScheme +import androidx.compose.material3.dynamicDarkColorScheme +import androidx.compose.material3.dynamicLightColorScheme +import androidx.compose.material3.lightColorScheme +import androidx.compose.runtime.Composable +import androidx.compose.runtime.SideEffect +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.toArgb +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalView +import androidx.core.view.WindowCompat + +private val DarkColorScheme = darkColorScheme( + primary = Color(0xFF90CAF9), + secondary = Color(0xFF81D4FA), + tertiary = Color(0xFFA5D6A7) +) + +private val LightColorScheme = lightColorScheme( + primary = Color(0xFF1976D2), + secondary = Color(0xFF03A9F4), + tertiary = Color(0xFF4CAF50) +) + +@Composable +fun RSSuperTheme( + darkTheme: Boolean = isSystemInDarkTheme(), + dynamicColor: Boolean = true, + content: @Composable () -> Unit +) { + val colorScheme = when { + dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { + val context = LocalContext.current + if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) + } + darkTheme -> DarkColorScheme + else -> LightColorScheme + } + + val view = LocalView.current + if (!view.isInEditMode) { + SideEffect { + val window = (view.context as Activity).window + window.statusBarColor = colorScheme.primary.toArgb() + WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = darkTheme + } + } + + MaterialTheme( + colorScheme = colorScheme, + content = content + ) +} +EOF + + # AndroidManifest.xml + cat > "$ANDROID_PROJECT_DIR/app/src/main/AndroidManifest.xml" << 'EOF' + + + + + + + + + + + + + + + + +EOF + + # styles.xml + cat > "$ANDROID_PROJECT_DIR/app/src/main/res/values/styles.xml" << 'EOF' + + + + +EOF + + # proguard-rules.pro + cat > "$ANDROID_PROJECT_DIR/app/proguard-rules.pro" << 'EOF' +# Add project specific ProGuard rules here. +-keepattributes Signature +-keepattributes *Annotation* +-keepattributes RuntimeVisibleAnnotations +-keepattributes RuntimeInvisibleAnnotations +EOF + + # gradlew script + cat > "$ANDROID_PROJECT_DIR/gradlew" << 'EOF' +#!/bin/bash +# Gradle wrapper placeholder +# In a real project, this would be generated by gradle wrapper +# For now, we'll use system gradle if available + +if command -v gradle &> /dev/null; then + exec gradle "$@" +else + echo "Error: Gradle not found. Please install Gradle or use ./gradlew" + exit 1 +fi +EOF + + chmod +x "$ANDROID_PROJECT_DIR/gradlew" + + echo "Android project structure created!" +} + +# Build the project +build_project() { + echo "Building Android $VARIANT..." + + cd "$ANDROID_PROJECT_DIR" + + # Determine gradle task based on variant + local TASK="${ACTION}${VARIANT}"" + if [ "$VARIANT" = "release" ]; then + TASK="${ACTION}Release" + fi + + echo "Running: ./gradlew $TASK" + ./gradlew $TASK +} + +# Run tests +run_tests() { + echo "Running Android tests..." + + cd "$ANDROID_PROJECT_DIR" + ./gradlew test +} + +# Clean build +clean_build() { + echo "Cleaning Android build..." + + cd "$ANDROID_PROJECT_DIR" + ./gradlew clean +} + +# Main +case "$ACTION" in + clean) + check_prerequisites + clean_build + ;; + test) + check_prerequisites + run_tests + ;; + assemble|build|*) + check_prerequisites + build_project + ;; +esac diff --git a/scripts/build-ios.sh b/scripts/build-ios.sh new file mode 100755 index 0000000..19a6b8e --- /dev/null +++ b/scripts/build-ios.sh @@ -0,0 +1,174 @@ +#!/bin/bash +# RSSuper iOS/macOS Build Script +# Adapted from Nessa build scripts + +set -e + +# Configuration +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" +IOS_PROJECT_DIR="$PROJECT_ROOT/native-route/ios/RSSuper" +IOS_PROJECT="$IOS_PROJECT_DIR/RSSuper.xcodeproj" +IOS_SCHEME="RSSuper" + +# Default values +CONFIGURATION="${1:-Debug}" +PLATFORM="${2:-iOS}" +DESTINATION="${3:-generic/platform=iOS}" +ACTION="${4:-build}" + +# Show help +show_help() { + echo "RSSuper iOS/macOS Build Script" + echo "" + echo "Usage: $0 [CONFIGURATION] [PLATFORM] [DESTINATION] [ACTION]" + echo "" + echo "Arguments:" + echo " CONFIGURATION Build configuration (Debug|Release) [Default: Debug]" + echo " PLATFORM Target platform (iOS|macOS) [Default: iOS]" + echo " DESTINATION xcodebuild destination [Default: generic/platform=iOS]" + echo " ACTION Action to perform (build|test|clean) [Default: build]" + echo "" + echo "Examples:" + echo " $0 # Build Debug for iOS" + echo " $0 Release # Build Release for iOS" + echo " $0 Debug iOS 'platform=iOS Simulator,name=iPhone 15' # Build for simulator" + echo " $0 clean # Clean build" +} + +# Check if xcodebuild is available +check_prerequisites() { + if ! command -v xcodebuild &> /dev/null; then + echo "Error: xcodebuild not found. Please install Xcode." + exit 1 + fi + + if [ ! -d "$IOS_PROJECT_DIR" ]; then + echo "Error: iOS project directory not found: $IOS_PROJECT_DIR" + exit 1 + fi + + if [ ! -f "$IOS_PROJECT/project.pbxproj" ]; then + echo "Error: Xcode project not found: $IOS_PROJECT" + exit 1 + fi +} + +# Select appropriate Xcode version +select_xcode() { + echo "Checking Xcode installation..." + + echo "=== Current xcode-select path ===" + xcode-select -p 2>/dev/null || echo "xcode-select failed" + echo "=== Current Xcode version ===" + xcodebuild -version 2>/dev/null || echo "xcodebuild failed" + + # Try common Xcode paths in order of preference + for path in \ + "/Applications/Xcode_16.3.app/Contents/Developer" \ + "/Applications/Xcode_16.2.app/Contents/Developer" \ + "/Applications/Xcode_16.1.app/Contents/Developer" \ + "/Applications/Xcode_16.0.app/Contents/Developer" \ + "/Applications/Xcode_15.4.app/Contents/Developer" \ + "/Applications/Xcode_15.3.app/Contents/Developer" \ + "/Applications/Xcode_15.2.app/Contents/Developer" \ + "/Applications/Xcode_15.1.app/Contents/Developer" \ + "/Applications/Xcode_15.0.app/Contents/Developer" \ + "/Applications/Xcode.app/Contents/Developer" + do + if [ -d "$path" ]; then + CURRENT_PATH=$(xcode-select -p 2>/dev/null || echo "") + if [ "$CURRENT_PATH" != "$path" ]; then + echo "Switching Xcode to: $path" + xcode-select -s "$path" || true + else + echo "Xcode already selected at: $path" + fi + break + fi + done + + echo "=== Selected Xcode ===" + xcodebuild -version +} + +# Clean build artifacts +clean_build() { + echo "Cleaning build artifacts..." + cd "$IOS_PROJECT_DIR" + xcodebuild clean \ + -project "$IOS_PROJECT" \ + -scheme "$IOS_SCHEME" \ + -configuration "$CONFIGURATION" \ + -destination "$DESTINATION" + echo "Clean completed" +} + +# Build the project +build_project() { + echo "Building $PLATFORM $CONFIGURATION..." + + cd "$IOS_PROJECT_DIR" + + # Capture build output + BUILD_LOG=$(mktemp) + + set +e + xcodebuild $ACTION \ + -project "$IOS_PROJECT" \ + -scheme "$IOS_SCHEME" \ + -configuration "$CONFIGURATION" \ + -destination "$DESTINATION" \ + > "$BUILD_LOG" 2>&1 + BUILD_EXIT=$? + set -e + + # Show build output + cat "$BUILD_LOG" + + if [ "$BUILD_EXIT" = "0" ]; then + echo "Build completed successfully!" + return 0 + else + echo "Build failed with exit code: $BUILD_EXIT" + + # Extract and show errors + echo "" + echo "Errors found:" + grep -E "\.swift:[0-9]+:[0-9]+: error:" "$BUILD_LOG" | head -10 || true + return $BUILD_EXIT + fi +} + +# Run tests +run_tests() { + echo "Running tests for $PLATFORM..." + + cd "$IOS_PROJECT_DIR" + + xcodebuild test \ + -project "$IOS_PROJECT" \ + -scheme "$IOS_SCHEME" \ + -configuration "$CONFIGURATION" \ + -destination "$DESTINATION" \ + ONLY_ACTIVE_ARCH=NO +} + +# Main +case "$ACTION" in + clean) + check_prerequisites + select_xcode + clean_build + ;; + test) + check_prerequisites + select_xcode + run_tests + ;; + build|*) + check_prerequisites + select_xcode + build_project + ;; +esac diff --git a/scripts/build-linux.sh b/scripts/build-linux.sh new file mode 100755 index 0000000..b0a6013 --- /dev/null +++ b/scripts/build-linux.sh @@ -0,0 +1,449 @@ +#!/bin/bash +# RSSuper Linux Build Script +# Native Linux build using meson/ninja with GTK4 + +set -e + +# Configuration +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" +LINUX_PROJECT_DIR="$PROJECT_ROOT/native-route/linux" + +# Default values +BUILD_TYPE="${1:-debug}" +ACTION="${2:-build}" + +# Show help +show_help() { + echo "RSSuper Linux Build Script" + echo "" + echo "Usage: $0 [BUILD_TYPE] [ACTION]" + echo "" + echo "Arguments:" + echo " BUILD_TYPE Build type (debug|release) [Default: debug]" + echo " ACTION Action (build|install|test|clean|setup) [Default: build]" + echo "" + echo "Examples:" + echo " $0 # Build debug" + echo " $0 release # Build release" + echo " $0 debug setup # Setup build environment" + echo " $0 debug test # Run tests" + echo " $0 clean # Clean build" +} + +# Check prerequisites +check_prerequisites() { + local MISSING_DEPS=() + + # Check for required tools + for cmd in meson ninja pkg-config; do + if ! command -v $cmd &> /dev/null; then + MISSING_DEPS+=("$cmd") + fi + done + + if [ ${#MISSING_DEPS[@]} -gt 0 ]; then + echo "Error: Missing build tools: ${MISSING_DEPS[*]}" + echo "" + echo "On Ubuntu/Debian:" + echo " sudo apt install meson ninja-build pkg-config" + echo "" + echo "On Fedora:" + echo " sudo dnf install meson ninja-build pkgconf-pkg-config" + echo "" + echo "On Arch:" + echo " sudo pacman -S meson ninja pkgconf" + exit 1 + fi + + echo "Build tools check passed" +} + +# Install development dependencies +install_dependencies() { + echo "Installing Linux development dependencies..." + + local DISTRO=$(lsb_release -i -s 2>/dev/null || echo "unknown") + + case "$DISTRO" in + Ubuntu|Debian) + sudo apt-get update + sudo apt-get install -y \ + build-essential \ + meson \ + ninja-build \ + pkg-config \ + libgtk-4-dev \ + libadwaita-1-dev \ + libsqlite3-dev \ + libxml2-dev \ + libcurl4-openssl-dev \ + libsoup-3-dev \ + valac + ;; + Fedora) + sudo dnf install -y \ + gcc \ + gcc-c++ \ + meson \ + ninja-build \ + pkgconf-pkg-config \ + gtk4-devel \ + libadwaita-1-devel \ + sqlite-devel \ + libxml2-devel \ + libcurl-devel \ + libsoup3-devel \ + vala + ;; + arch) + sudo pacman -S --noconfirm \ + base-devel \ + meson \ + ninja \ + pkgconf \ + gtk4 \ + libadwaita \ + sqlite \ + libxml2 \ + curl \ + libsoup3 \ + vala + ;; + *) + echo "Warning: Unknown distribution ($DISTRO). Please install dependencies manually:" + echo " - meson, ninja-build, pkg-config" + echo " - GTK4 development files" + echo " - SQLite3 development files" + echo " - libxml2 development files" + echo " - curl development files" + ;; + esac + + echo "Dependencies installation complete" +} + +# Create Linux project structure +create_linux_project() { + echo "Creating Linux project structure..." + + mkdir -p "$LINUX_PROJECT_DIR/src/main" + mkdir -p "$LINUX_PROJECT_DIR/src/models" + mkdir -p "$LINUX_PROJECT_DIR/src/services" + mkdir -p "$LINUX_PROJECT_DIR/src/ui" + mkdir -p "$LINUX_PROJECT_DIR/data" + mkdir -p "$LINUX_PROJECT_DIR/build" + + # meson.build (root) + cat > "$LINUX_PROJECT_DIR/meson.build" << 'EOF' +project('rssuper', 'c', 'vala', + version: '1.0.0', + meson_version: '>= 1.0.0', + license: 'MIT', + default_options: [ + 'warning_level=1', + 'werror=false' + ] +) + +# Dependencies +gtk4 = dependency('gtk4', version: '>= 4.0') +adwaita = dependency('libadwaita-1', version: '>= 1.0') +sqlite = dependency('sqlite3') +xml2 = dependency('libxml-2.0') +curl = dependency('libcurl') +soup = dependency('libsoup-3.0') +glib = dependency('glib-2.0', version: '>= 2.70') +gobject = dependency('gobject-2.0') + +# Common compiler and linker arguments +c_args = ['-D_GLIBCXX_USE_C99=1'] +l_args = [] + +# Sources +main_sources = files( + 'src/main/rssuper.c', + 'src/main/window.c', +) + +model_sources = files( + 'src/models/feed.vala', + 'src/models/item.vala', + 'src/models/database.vala', +) + +service_sources = files( + 'src/services/rss-parser.vala', + 'src/services/feed-fetcher.vala', +) + +ui_sources = files( + 'src/ui/feed-list.vala', + 'src/ui/item-list.vala', + 'src/ui/item-view.vala', +) + +# Executable +rssuper_exe = executable( + 'rssuper', + main_sources, + model_sources, + service_sources, + ui_sources, + dependencies: [ + gtk4, + adwaita, + sqlite, + xml2, + curl, + soup, + glib, + gobject, + ], + c_args: c_args, + link_args: l_args, + install: true, +) + +# Data files +install_data( + 'data/rssuper.desktop', + install_dir: get_option('datadir') + '/share/applications' +) + +install_data( + 'data/rssuper.svg', + install_dir: get_option('datadir') + '/share/icons/hicolor/scalable/apps' +) + +# Configuration +configure_file( + input: 'config.h.in', + output: 'config.h', + configuration: meson.current_source_dir() / 'config.cfg' +) +EOF + + # Main C file + cat > "$LINUX_PROJECT_DIR/src/main/rssuper.c" << 'EOF' +#include +#include +#include "config.h" + +static GtkApplication *app; + +static void +activate(GtkApplication *application) +{ + AdwWindow *window; + + window = g_object_new(ADW_TYPE_WINDOW, + "title", "RSSuper", + "default-width", 1200, + "default-height", 800, + "show-mnemonic-label", false, + NULL); + + gtk_application_add_window(GTK_APPLICATION(application), GTK_WINDOW(window)); + gtk_widget_realize(GTK_WIDGET(window)); + gtk_widget_show(GTK_WIDGET(window)); +} + +int +main(int argc, char **argv) +{ + app = gtk_application_new("com.mikefreno.RSSuper", + G_APPLICATION_DEFAULT_FLAGS); + + g_signal_connect(app, "activate", + G_CALLBACK(activate), NULL); + + int status = g_application_run(G_APPLICATION(app), argc, argv); + g_object_unref(app); + + return status; +} +EOF + + # Desktop file + cat > "$LINUX_PROJECT_DIR/data/rssuper.desktop" << 'EOF' +[Desktop Entry] +Name=RSSuper +Comment=A native RSS reader for Linux +Exec=rssuper +Terminal=false +Type=Application +Icon=rssuper +Categories=Network;Reader; +Keywords=rss;feed;reader; +EOF + + # SVG Icon placeholder + cat > "$LINUX_PROJECT_DIR/data/rssuper.svg" << 'EOF' + + + + R + + +EOF + + # Config template + cat > "$LINUX_PROJECT_DIR/config.h.in" << 'EOF' +#ifndef CONFIG_H +#define CONFIG_H + +#define RSSUPER_VERSION "@PROJECT_VERSION@" +#define RSSUPER_APP_ID "com.mikefreno.RSSuper" + +#endif /* CONFIG_H */ +EOF + + echo "Linux project structure created!" +} + +# Setup build directory +setup_build() { + echo "Setting up build directory..." + + cd "$LINUX_PROJECT_DIR" + + local BUILD_DIR="build" + local BUILD_TYPE_FLAG="" + + if [ "$BUILD_TYPE" = "release" ]; then + BUILD_TYPE_FLAG="--buildtype=release" + else + BUILD_TYPE_FLAG="--buildtype=debug" + fi + + # Clean existing build directory + if [ -d "$BUILD_DIR" ]; then + rm -rf "$BUILD_DIR" + fi + + meson setup "$BUILD_DIR" $BUILD_TYPE_FLAG + + echo "Build directory setup complete" +} + +# Build the project +build_project() { + echo "Building Linux $BUILD_TYPE..." + + cd "$LINUX_PROJECT_DIR" + + # Check if build directory exists + if [ ! -d "build" ]; then + echo "Build directory not found. Running setup first..." + setup_build + fi + + meson compile -C build + + echo "Build complete! Executable: $LINUX_PROJECT_DIR/build/rssuper" +} + +# Install the application +install_app() { + echo "Installing RSSuper..." + + cd "$LINUX_PROJECT_DIR" + + if [ ! -d "build" ]; then + echo "Error: Build directory not found. Run build first." + exit 1 + fi + + sudo meson install -C build + + echo "Installation complete!" +} + +# Run tests +run_tests() { + echo "Running Linux tests..." + + cd "$LINUX_PROJECT_DIR" + + if [ ! -d "build" ]; then + echo "Build directory not found. Running setup first..." + setup_build + fi + + meson test -C build +} + +# Clean build +clean_build() { + echo "Cleaning Linux build..." + + cd "$LINUX_PROJECT_DIR" + + if [ -d "build" ]; then + rm -rf build + echo "Build directory removed" + fi +} + +# Run the application +run_app() { + echo "Running RSSuper..." + + cd "$LINUX_PROJECT_DIR" + + if [ ! -f "build/rssuper" ]; then + echo "Executable not found. Building first..." + build_project + fi + + ./build/rssuper +} + +# Main +case "$ACTION" in + setup) + check_prerequisites + if [ ! -d "$LINUX_PROJECT_DIR/src" ]; then + create_linux_project + fi + setup_build + ;; + install-deps) + install_dependencies + ;; + clean) + clean_build + ;; + test) + check_prerequisites + if [ ! -d "$LINUX_PROJECT_DIR/src" ]; then + create_linux_project + fi + setup_build + run_tests + ;; + run) + check_prerequisites + if [ ! -d "$LINUX_PROJECT_DIR/src" ]; then + create_linux_project + fi + setup_build + build_project + run_app + ;; + install) + check_prerequisites + build_project + install_app + ;; + build|*) + check_prerequisites + if [ ! -d "$LINUX_PROJECT_DIR/src" ]; then + create_linux_project + fi + setup_build + build_project + ;; +esac diff --git a/scripts/build.sh b/scripts/build.sh new file mode 100755 index 0000000..682aa31 --- /dev/null +++ b/scripts/build.sh @@ -0,0 +1,279 @@ +#!/bin/bash +# RSSuper Multi-Platform Build Script +# Main entry point for building all platforms + +set -e + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" + +# Source common utilities +source "$SCRIPT_DIR/common.sh" + +# Default values +PLATFORMS="all" +BUILD_TYPE="debug" +ACTION="build" +RUN_TESTS=false + +# Colors +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' + +# Show help +show_help() { + cat << EOF +RSSuper Multi-Platform Build System + +Usage: $0 [OPTIONS] + +Options: + -p, --platforms PLATFORMS Comma-separated platforms (ios,android,linux) or 'all' [Default: all] + -t, --type TYPE Build type (debug|release) [Default: debug] + -a, --action ACTION Action to perform (build|test|clean|install) [Default: build] + --test Run tests after build + -h, --help Show this help message + +Platforms: + ios iOS/macOS (requires macOS) + android Android + linux Linux (GTK4) + +Examples: + $0 # Build all platforms in debug mode + $0 -p ios,android -t release # Build iOS and Android in release mode + $0 -p linux --test # Build and test Linux version + $0 -a clean # Clean all platforms + $0 -p ios -a install # Install iOS app to simulator + +EOF +} + +# Parse arguments +while [[ $# -gt 0 ]]; do + case $1 in + -p|--platforms) + PLATFORMS="$2" + shift 2 + ;; + -t|--type) + BUILD_TYPE="$2" + shift 2 + ;; + -a|--action) + ACTION="$2" + shift 2 + ;; + --test) + RUN_TESTS=true + shift + ;; + -h|--help) + show_help + exit 0 + ;; + *) + echo "Unknown option: $1" + show_help + exit 1 + ;; + esac +done + +# Track build results +declare -A BUILD_RESULTS +TOTAL_PLATFORMS=0 +SUCCESSFUL_BUILDS=0 + +# Build iOS/macOS +build_ios() { + log_info "Building iOS/macOS..." + + if [[ "$OSTYPE" != "darwin"* ]]; then + log_warning "iOS/macOS build requires macOS. Skipping." + BUILD_RESULTS["ios"]="skipped" + return 0 + fi + + cd "$PROJECT_ROOT" + + case "$ACTION" in + clean) + "$SCRIPT_DIR/build-ios.sh" clean + ;; + test) + "$SCRIPT_DIR/build-ios.sh" "$BUILD_TYPE" ios "generic/platform=iOS" test + ;; + build|*) + if "$SCRIPT_DIR/build-ios.sh" "$BUILD_TYPE" ios "generic/platform=iOS" build; then + BUILD_RESULTS["ios"]="success" + ((SUCCESSFUL_BUILDS++)) || true + else + BUILD_RESULTS["ios"]="failed" + fi + + if [ "$RUN_TESTS" = true ]; then + log_info "Running iOS tests..." + "$SCRIPT_DIR/build-ios.sh" "$BUILD_TYPE" ios "generic/platform=iOS" test || true + fi + ;; + esac +} + +# Build Android +build_android() { + log_info "Building Android..." + + cd "$PROJECT_ROOT" + + case "$ACTION" in + clean) + "$SCRIPT_DIR/build-android.sh" "$BUILD_TYPE" clean + ;; + test) + "$SCRIPT_DIR/build-android.sh" "$BUILD_TYPE" test + ;; + build|*) + if "$SCRIPT_DIR/build-android.sh" "$BUILD_TYPE" assemble; then + BUILD_RESULTS["android"]="success" + ((SUCCESSFUL_BUILDS++)) || true + else + BUILD_RESULTS["android"]="failed" + fi + + if [ "$RUN_TESTS" = true ]; then + log_info "Running Android tests..." + "$SCRIPT_DIR/build-android.sh" "$BUILD_TYPE" test || true + fi + ;; + esac +} + +# Build Linux +build_linux() { + log_info "Building Linux..." + + cd "$PROJECT_ROOT" + + case "$ACTION" in + clean) + "$SCRIPT_DIR/build-linux.sh" "$BUILD_TYPE" clean + ;; + test) + "$SCRIPT_DIR/build-linux.sh" "$BUILD_TYPE" test + ;; + build|*) + if "$SCRIPT_DIR/build-linux.sh" "$BUILD_TYPE" build; then + BUILD_RESULTS["linux"]="success" + ((SUCCESSFUL_BUILDS++)) || true + else + BUILD_RESULTS["linux"]="failed" + fi + + if [ "$RUN_TESTS" = true ]; then + log_info "Running Linux tests..." + "$SCRIPT_DIR/build-linux.sh" "$BUILD_TYPE" test || true + fi + ;; + esac +} + +# Print build summary +print_summary() { + echo "" + log_info "=== Build Summary ===" + echo "" + + printf "%-12s | %-10s | %s\n" "Platform" "Status" "Details" + printf "%-12s-+-%-10s-+-%s\n" "------------" "----------" "-------" + + for platform in "${!BUILD_RESULTS[@]}"; do + local status="${BUILD_RESULTS[$platform]}" + local status_symbol="" + + case "$status" in + success) + status_symbol="✅" + ;; + failed) + status_symbol="❌" + ;; + skipped) + status_symbol="â­ī¸" + ;; + esac + + printf "%-12s | %-10s | %s\n" "$platform" "$status" "$status_symbol" + done + + echo "" + echo "Total: $SUCCESSFUL_BUILDS / ${#BUILD_RESULTS[@]} platforms built successfully" + echo "" +} + +# Main +echo "========================================" +echo " RSSuper Multi-Platform Build System" +echo "========================================" +echo "" +echo "Configuration:" +echo " Platforms: $PLATFORMS" +echo " Build Type: $BUILD_TYPE" +echo " Action: $ACTION" +echo " Run Tests: $RUN_TESTS" +echo "" + +# Convert platforms string to array +IFS=',' read -ra PLATFORM_ARRAY <<< "$PLATFORMS" + +# Build each platform +for platform in "${PLATFORM_ARRAY[@]}"; do + platform=$(echo "$platform" | xargs) # Trim whitespace + ((TOTAL_PLATFORMS++)) || true + + case "$platform" in + all) + build_ios + build_android + build_linux + ((TOTAL_PLATFORMS+=2)) || true # Add extra platforms + ;; + ios) + build_ios + ;; + android) + build_android + ;; + linux) + build_linux + ;; + *) + log_error "Unknown platform: $platform" + exit 1 + ;; + esac +done + +# Print summary +print_summary + +# Exit with error if any builds failed +if [ "$SUCCESSFUL_BUILDS" -lt "${#BUILD_RESULTS[@]}" ]; then + # Filter out skipped builds + local actual_builds=0 + for result in "${BUILD_RESULTS[@]}"; do + if [ "$result" != "skipped" ]; then + ((actual_builds++)) || true + fi + done + + if [ "$SUCCESSFUL_BUILDS" -lt "$actual_builds" ]; then + log_error "Some builds failed" + exit 1 + fi +fi + +log_success "All builds completed successfully!" diff --git a/scripts/common.sh b/scripts/common.sh new file mode 100755 index 0000000..0b2d27f --- /dev/null +++ b/scripts/common.sh @@ -0,0 +1,169 @@ +#!/bin/bash +# RSSuper Common Build Utilities +# Shared functions used across all platform build scripts + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Logging functions +log_info() { + echo -e "${BLUE}â„šī¸ $1${NC}" +} + +log_success() { + echo -e "${GREEN}✅ $1${NC}" +} + +log_warning() { + echo -e "${YELLOW}âš ī¸ $1${NC}" +} + +log_error() { + echo -e "${RED}❌ $1${NC}" +} + +# Get project root directory +get_project_root() { + echo "$(cd "$(dirname "$0")/.." && pwd)" +} + +# Get current timestamp in ISO format +get_timestamp() { + date -u "+%Y-%m-%dT%H:%M:%SZ" +} + +# Get human-readable timestamp +get_timestamp_human() { + date -u "+%Y-%m-%d %H:%M:%S UTC" +} + +# Get current git commit hash +get_git_commit() { + git rev-parse HEAD 2>/dev/null || echo "unknown" +} + +# Get short git commit hash +get_git_commit_short() { + local commit=$(get_git_commit) + echo ${commit:0:7} +} + +# Get current git branch +get_git_branch() { + git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown" +} + +# Get git status (clean or modified) +get_git_status() { + if git diff --quiet 2>/dev/null && git diff --cached --quiet 2>/dev/null; then + echo "clean" + else + echo "modified" + fi +} + +# Check if running in CI +is_ci() { + [ -n "$CI" ] +} + +# Check if command exists +command_exists() { + command -v "$1" &> /dev/null +} + +# Create a temporary file with cleanup trap +create_temp_file() { + local temp_file=$(mktemp) + trap "rm -f '$temp_file'" EXIT + echo "$temp_file" +} + +# Parse command line arguments +# Usage: parse_args "option1:value1 option2:value2" +# Sets variables OPTION1, OPTION2 with values +parse_args() { + local options="$1" + shift + + for opt in $options; do + local key=${opt%%:*} + local value=${opt#*:} + export "$key=$value" + done +} + +# Show spinner while command runs (for nice UX) +run_with_spinner() { + local message="$1" + shift + + echo -e "${BLUE}$message...${NC}" + "$@" +} + +# Generate a build report +generate_build_report() { + local platform="$1" + local status="$2" + local details="$3" + + local report_file="${platform}-build-report.md" + local timestamp=$(get_timestamp_human) + local commit=$(get_git_commit_short) + local branch=$(get_git_branch) + + { + echo "# $platform Build Report" + echo "" + echo "| | |" + echo "|---|---|" + echo "| **Status** | $status |" + echo "| **Commit** | \`$commit\` |" + echo "| **Branch** | \`$branch\` |" + echo "| **Time** | $timestamp |" + echo "" + + if [ "$status" = "FAILED" ]; then + echo "## Errors" + echo "" + echo "$details" + else + echo "## Result" + echo "" + echo "$platform build completed successfully." + fi + } > "$report_file" + + echo "Build report written to: $report_file" +} + +# Wait for user input (useful for debugging) +wait_for_input() { + echo "Press Enter to continue..." + read +} + +# Export for use in other scripts +export -f log_info +export -f log_success +export -f log_warning +export -f log_error +export -f get_project_root +export -f get_timestamp +export -f get_timestamp_human +export -f get_git_commit +export -f get_git_commit_short +export -f get_git_branch +export -f get_git_status +export -f is_ci +export -f command_exists +export -f create_temp_file +export -f parse_args +export -f run_with_spinner +export -f generate_build_report +export -f wait_for_input diff --git a/tasks/native-business-logic-migration/03-implement-ios-data-models.md b/tasks/native-business-logic-migration/03-implement-ios-data-models.md new file mode 100644 index 0000000..a8c613c --- /dev/null +++ b/tasks/native-business-logic-migration/03-implement-ios-data-models.md @@ -0,0 +1,42 @@ +# 03. Implement iOS data models (Swift) + +meta: + id: native-business-logic-migration-03 + feature: native-business-logic-migration + priority: P0 + depends_on: [native-business-logic-migration-02] + tags: [implementation, ios, data-models] + +objective: +- Implement all data models in Swift following iOS conventions + +deliverables: +- FeedItem.swift +- Feed.swift +- FeedSubscription.swift +- SearchResult.swift +- SearchFilters.swift +- NotificationPreferences.swift +- ReadingPreferences.swift +- Supporting types and extensions + +tests: +- Unit: Test property encoding/decoding +- Unit: Test custom string interpolation +- Unit: Test equality conformance + +acceptance_criteria: +- All models conform to Codable +- All models have proper equatable conformance +- Date properties use ISO8601 formatter +- Optional properties properly handled +- Custom debug description implemented + +validation: +- Run `swift test` in Xcode +- Verify compilation with no warnings + +notes: +- Use Swift 5.9+ features +- Follow Apple's API design guidelines +- Consider using Identifiable protocol for List conformance diff --git a/tasks/native-business-logic-migration/04-implement-android-data-models.md b/tasks/native-business-logic-migration/04-implement-android-data-models.md new file mode 100644 index 0000000..443cfb6 --- /dev/null +++ b/tasks/native-business-logic-migration/04-implement-android-data-models.md @@ -0,0 +1,42 @@ +# 04. Implement Android data models (Kotlin) + +meta: + id: native-business-logic-migration-04 + feature: native-business-logic-migration + priority: P0 + depends_on: [native-business-logic-migration-02] + tags: [implementation, android, data-models] + +objective: +- Implement all data models in Kotlin following Android conventions + +deliverables: +- FeedItem.kt +- Feed.kt +- FeedSubscription.kt +- SearchResult.kt +- SearchFilters.kt +- NotificationPreferences.kt +- ReadingPreferences.kt +- Supporting data classes and sealed classes + +tests: +- Unit: Test serialization/deserialization with Moshi/Gson +- Unit: Test copy() functionality +- Unit: Test toString() output + +acceptance_criteria: +- All models are data classes +- All models have proper equals/hashCode +- JSON serialization working with Moshi +- Room Entity annotations ready for database models +- Sealed classes for enum types + +validation: +- Run `./gradlew test` +- Verify no lint warnings + +notes: +- Use data classes for immutable value objects +- Use sealed classes for enum-like types +- Consider using Parcelize for UI passing diff --git a/tasks/native-business-logic-migration/05-implement-linux-data-models.md b/tasks/native-business-logic-migration/05-implement-linux-data-models.md new file mode 100644 index 0000000..ebf6b45 --- /dev/null +++ b/tasks/native-business-logic-migration/05-implement-linux-data-models.md @@ -0,0 +1,41 @@ +# 05. Implement Linux data models (C/Vala) + +meta: + id: native-business-logic-migration-05 + feature: native-business-logic-migration + priority: P0 + depends_on: [native-business-logic-migration-02] + tags: [implementation, linux, data-models] + +objective: +- Implement all data models in Vala/C following Linux/GNOME conventions + +deliverables: +- feed-item.vala +- feed.vala +- feed-subscription.vala +- search-result.vala +- search-filters.vala +- notification-preferences.vala +- reading-preferences.vala +- Supporting structs and enums + +tests: +- Unit: Test JSON serialization with Gio +- Unit: Test property accessors +- Unit: Test equality methods + +acceptance_criteria: +- All models properly structured +- JSON serialization working +- Memory management correct (no leaks) +- GObject integration ready + +validation: +- Run `meson test -C build` +- Check with valgrind for memory leaks + +notes: +- Use Vala objects for reference types +- Use structs for value types +- Follow GNOME HIG for naming diff --git a/tasks/native-business-logic-migration/06-implement-ios-database-layer.md b/tasks/native-business-logic-migration/06-implement-ios-database-layer.md new file mode 100644 index 0000000..a9320ff --- /dev/null +++ b/tasks/native-business-logic-migration/06-implement-ios-database-layer.md @@ -0,0 +1,42 @@ +# 06. Implement iOS database layer (Core Data/GRDB) + +meta: + id: native-business-logic-migration-06 + feature: native-business-logic-migration + priority: P0 + depends_on: [native-business-logic-migration-03] + tags: [implementation, ios, database] + +objective: +- Implement database layer using Core Data for iOS + +deliverables: +- RSSuper.xcdatamodeld +- DatabaseManager.swift +- Subscription+CoreDataClass.swift +- FeedItem+CoreDataClass.swift +- SearchHistory+CoreDataClass.swift +- Database migrations +- FTS virtual table implementation + +tests: +- Unit: Test CRUD operations +- Unit: Test relationships +- Unit: Test FTS queries +- Integration: Test database migrations + +acceptance_criteria: +- Core Data model created with all entities +- Relationships properly configured +- FTS search working +- Migrations implemented +- Background context used for writes + +validation: +- Run unit tests +- Verify with Instruments (Core Data editor) + +notes: +- Use NSPersistentContainer +- Implement FTS using SQLite directly or GRDB +- Consider using NSPredicate for queries diff --git a/tasks/native-business-logic-migration/07-implement-android-database-layer.md b/tasks/native-business-logic-migration/07-implement-android-database-layer.md new file mode 100644 index 0000000..8ae1d37 --- /dev/null +++ b/tasks/native-business-logic-migration/07-implement-android-database-layer.md @@ -0,0 +1,45 @@ +# 07. Implement Android database layer (Room) + +meta: + id: native-business-logic-migration-07 + feature: native-business-logic-migration + priority: P0 + depends_on: [native-business-logic-migration-04] + tags: [implementation, android, database] + +objective: +- Implement database layer using Room for Android + +deliverables: +- RssDatabase.kt +- SubscriptionEntity.kt +- FeedItemEntity.kt +- SearchHistoryEntity.kt +- SubscriptionDao.kt +- FeedItemDao.kt +- SearchHistoryDao.kt +- Database migrations +- FTS virtual table implementation + +tests: +- Unit: Test CRUD operations with Room Testing +- Unit: Test relationships +- Unit: Test FTS queries +- Integration: Test database migrations + +acceptance_criteria: +- Room database configured +- All entities annotated +- DAOs with proper queries +- FTS search working +- Migrations implemented +- TypeConverters for custom types + +validation: +- Run `./gradlew test` +- Verify with Room Inspection + +notes: +- Use Room 2.6+ +- Implement FTS using SQLite FTS5 +- Use @Transaction for multi-entity operations diff --git a/tasks/native-business-logic-migration/08-implement-linux-database-layer.md b/tasks/native-business-logic-migration/08-implement-linux-database-layer.md new file mode 100644 index 0000000..d47e282 --- /dev/null +++ b/tasks/native-business-logic-migration/08-implement-linux-database-layer.md @@ -0,0 +1,42 @@ +# 08. Implement Linux database layer (SQLite) + +meta: + id: native-business-logic-migration-08 + feature: native-business-logic-migration + priority: P0 + depends_on: [native-business-logic-migration-05] + tags: [implementation, linux, database] + +objective: +- Implement database layer using SQLite for Linux + +deliverables: +- database.vala +- subscription-store.vala +- feed-item-store.vala +- search-history-store.vala +- schema.sql +- Database migrations +- FTS virtual table implementation + +tests: +- Unit: Test CRUD operations +- Unit: Test relationships +- Unit: Test FTS queries +- Integration: Test database migrations + +acceptance_criteria: +- SQLite database configured +- All tables created +- FTS search working +- Migrations implemented +- Proper error handling + +validation: +- Run `meson test -C build` +- Verify with sqlite3 CLI + +notes: +- Use GLib's GDatabase or direct SQLite bindings +- Implement FTS using SQLite FTS5 +- Use transactions for batch operations diff --git a/tasks/native-business-logic-migration/09-implement-ios-feed-parser.md b/tasks/native-business-logic-migration/09-implement-ios-feed-parser.md new file mode 100644 index 0000000..75e7558 --- /dev/null +++ b/tasks/native-business-logic-migration/09-implement-ios-feed-parser.md @@ -0,0 +1,43 @@ +# 09. Implement iOS RSS/Atom feed parser + +meta: + id: native-business-logic-migration-09 + feature: native-business-logic-migration + priority: P0 + depends_on: [native-business-logic-migration-06] + tags: [implementation, ios, parsing] + +objective: +- Implement RSS 2.0 and Atom 1.0 feed parser for iOS + +deliverables: +- FeedParser.swift +- RSSParser.swift +- AtomParser.swift +- FeedType.swift (enum) +- ParseResult.swift +- XML parsing utilities + +tests: +- Unit: Test RSS 2.0 parsing with sample feeds +- Unit: Test Atom 1.0 parsing with sample feeds +- Unit: Test iTunes namespace handling +- Unit: Test error cases (malformed XML) +- Integration: Test with real-world feeds + +acceptance_criteria: +- RSS 2.0 feeds parse correctly +- Atom 1.0 feeds parse correctly +- iTunes namespace handled +- Enclosures extracted properly +- Error handling for malformed feeds +- Performance: <100ms for typical feed + +validation: +- Run unit tests with sample feeds +- Test with known problematic feeds + +notes: +- Use Swift's XMLParser or SwiftXML +- Handle namespaces properly +- Support both inline and separate content diff --git a/tasks/native-business-logic-migration/10-implement-android-feed-parser.md b/tasks/native-business-logic-migration/10-implement-android-feed-parser.md new file mode 100644 index 0000000..8495d69 --- /dev/null +++ b/tasks/native-business-logic-migration/10-implement-android-feed-parser.md @@ -0,0 +1,43 @@ +# 10. Implement Android RSS/Atom feed parser + +meta: + id: native-business-logic-migration-10 + feature: native-business-logic-migration + priority: P0 + depends_on: [native-business-logic-migration-07] + tags: [implementation, android, parsing] + +objective: +- Implement RSS 2.0 and Atom 1.0 feed parser for Android + +deliverables: +- FeedParser.kt +- RSSParser.kt +- AtomParser.kt +- FeedType.kt (sealed class) +- ParseResult.kt +- XML parsing utilities + +tests: +- Unit: Test RSS 2.0 parsing with sample feeds +- Unit: Test Atom 1.0 parsing with sample feeds +- Unit: Test iTunes namespace handling +- Unit: Test error cases (malformed XML) +- Integration: Test with real-world feeds + +acceptance_criteria: +- RSS 2.0 feeds parse correctly +- Atom 1.0 feeds parse correctly +- iTunes namespace handled +- Enclosures extracted properly +- Error handling for malformed feeds +- Performance: <100ms for typical feed + +validation: +- Run `./gradlew test` +- Test with known problematic feeds + +notes: +- Use kxml or woodstox +- Handle namespaces properly +- Support both inline and separate content diff --git a/tasks/native-business-logic-migration/11-implement-linux-feed-parser.md b/tasks/native-business-logic-migration/11-implement-linux-feed-parser.md new file mode 100644 index 0000000..4fff926 --- /dev/null +++ b/tasks/native-business-logic-migration/11-implement-linux-feed-parser.md @@ -0,0 +1,43 @@ +# 11. Implement Linux RSS/Atom feed parser + +meta: + id: native-business-logic-migration-11 + feature: native-business-logic-migration + priority: P0 + depends_on: [native-business-logic-migration-08] + tags: [implementation, linux, parsing] + +objective: +- Implement RSS 2.0 and Atom 1.0 feed parser for Linux + +deliverables: +- feed-parser.vala +- rss-parser.vala +- atom-parser.vala +- feed-type.vala (enum) +- parse-result.vala +- XML parsing utilities + +tests: +- Unit: Test RSS 2.0 parsing with sample feeds +- Unit: Test Atom 1.0 parsing with sample feeds +- Unit: Test iTunes namespace handling +- Unit: Test error cases (malformed XML) +- Integration: Test with real-world feeds + +acceptance_criteria: +- RSS 2.0 feeds parse correctly +- Atom 1.0 feeds parse correctly +- iTunes namespace handled +- Enclosures extracted properly +- Error handling for malformed feeds +- Performance: <100ms for typical feed + +validation: +- Run `meson test -C build` +- Test with known problematic feeds + +notes: +- Use libxml2 through Vala bindings +- Handle namespaces properly +- Support both inline and separate content diff --git a/tasks/native-business-logic-migration/12-implement-ios-feed-fetcher.md b/tasks/native-business-logic-migration/12-implement-ios-feed-fetcher.md new file mode 100644 index 0000000..f31a002 --- /dev/null +++ b/tasks/native-business-logic-migration/12-implement-ios-feed-fetcher.md @@ -0,0 +1,40 @@ +# 12. Implement iOS feed fetcher service + +meta: + id: native-business-logic-migration-12 + feature: native-business-logic-migration + priority: P0 + depends_on: [native-business-logic-migration-09] + tags: [implementation, ios, networking] + +objective: +- Implement feed fetching service with URLSession + +deliverables: +- FeedFetcher.swift +- HTTPAuthCredentials.swift +- FetchResult.swift +- NetworkError.swift +- Feed caching implementation + +tests: +- Unit: Test URL session configuration +- Unit: Test HTTP auth handling +- Unit: Test error cases (timeout, 404, etc.) +- Integration: Test fetching real feeds + +acceptance_criteria: +- Feeds fetch with proper timeout (15s) +- HTTP auth supported +- Error handling complete +- Response caching implemented +- Performance: <5s for typical feed + +validation: +- Run unit tests +- Test with Network Link Conditioner + +notes: +- Use URLSession with proper configuration +- Implement exponential backoff for retries +- Respect Cache-Control headers diff --git a/tasks/native-business-logic-migration/13-implement-android-feed-fetcher.md b/tasks/native-business-logic-migration/13-implement-android-feed-fetcher.md new file mode 100644 index 0000000..219d507 --- /dev/null +++ b/tasks/native-business-logic-migration/13-implement-android-feed-fetcher.md @@ -0,0 +1,40 @@ +# 13. Implement Android feed fetcher service + +meta: + id: native-business-logic-migration-13 + feature: native-business-logic-migration + priority: P0 + depends_on: [native-business-logic-migration-10] + tags: [implementation, android, networking] + +objective: +- Implement feed fetching service with OkHttp + +deliverables: +- FeedFetcher.kt +- HTTPAuthCredentials.kt +- FetchResult.kt +- NetworkError.kt +- Feed caching implementation + +tests: +- Unit: Test OkHttp configuration +- Unit: Test HTTP auth handling +- Unit: Test error cases (timeout, 404, etc.) +- Integration: Test fetching real feeds + +acceptance_criteria: +- Feeds fetch with proper timeout (15s) +- HTTP auth supported +- Error handling complete +- Response caching implemented +- Performance: <5s for typical feed + +validation: +- Run `./gradlew test` +- Test with network throttling + +notes: +- Use OkHttp with proper configuration +- Implement exponential backoff for retries +- Respect Cache-Control headers diff --git a/tasks/native-business-logic-migration/14-implement-linux-feed-fetcher.md b/tasks/native-business-logic-migration/14-implement-linux-feed-fetcher.md new file mode 100644 index 0000000..7681e73 --- /dev/null +++ b/tasks/native-business-logic-migration/14-implement-linux-feed-fetcher.md @@ -0,0 +1,40 @@ +# 14. Implement Linux feed fetcher service + +meta: + id: native-business-logic-migration-14 + feature: native-business-logic-migration + priority: P0 + depends_on: [native-business-logic-migration-11] + tags: [implementation, linux, networking] + +objective: +- Implement feed fetching service with libsoup + +deliverables: +- feed-fetcher.vala +- http-auth-credentials.vala +- fetch-result.vala +- network-error.vala +- Feed caching implementation + +tests: +- Unit: Test SoupSession configuration +- Unit: Test HTTP auth handling +- Unit: Test error cases (timeout, 404, etc.) +- Integration: Test fetching real feeds + +acceptance_criteria: +- Feeds fetch with proper timeout (15s) +- HTTP auth supported +- Error handling complete +- Response caching implemented +- Performance: <5s for typical feed + +validation: +- Run `meson test -C build` +- Test with network throttling + +notes: +- Use libsoup-3.0 +- Implement exponential backoff for retries +- Respect Cache-Control headers diff --git a/tasks/native-business-logic-migration/15-implement-ios-state-management.md b/tasks/native-business-logic-migration/15-implement-ios-state-management.md new file mode 100644 index 0000000..79cfd61 --- /dev/null +++ b/tasks/native-business-logic-migration/15-implement-ios-state-management.md @@ -0,0 +1,41 @@ +# 15. Implement iOS state management (Combine/Observer) + +meta: + id: native-business-logic-migration-15 + feature: native-business-logic-migration + priority: P0 + depends_on: [native-business-logic-migration-12] + tags: [implementation, ios, state-management] + +objective: +- Implement reactive state management using Combine + +deliverables: +- FeedRepository.swift +- SubscriptionRepository.swift +- FeedViewModel.swift +- SubscriptionViewModel.swift +- State enumeration +- Error handling types + +tests: +- Unit: Test repository methods +- Unit: Test ViewModel state transitions +- Unit: Test Combine publishers +- Integration: Test UI updates + +acceptance_criteria: +- Repositories provide Combine publishers +- ViewModels manage state properly +- Error states handled +- Loading states implemented +- Memory efficient (no retain cycles) + +validation: +- Run unit tests +- Check with Instruments for memory leaks + +notes: +- Use Combine framework +- Follow Repository pattern +- Use @Published for SwiftUI integration diff --git a/tasks/native-business-logic-migration/16-implement-android-state-management.md b/tasks/native-business-logic-migration/16-implement-android-state-management.md new file mode 100644 index 0000000..a8d9f12 --- /dev/null +++ b/tasks/native-business-logic-migration/16-implement-android-state-management.md @@ -0,0 +1,41 @@ +# 16. Implement Android state management (StateFlow/LiveData) + +meta: + id: native-business-logic-migration-16 + feature: native-business-logic-migration + priority: P0 + depends_on: [native-business-logic-migration-13] + tags: [implementation, android, state-management] + +objective: +- Implement reactive state management using StateFlow and LiveData + +deliverables: +- FeedRepository.kt +- SubscriptionRepository.kt +- FeedViewModel.kt +- SubscriptionViewModel.kt +- State sealed class +- Error handling types + +tests: +- Unit: Test repository methods +- Unit: Test ViewModel state transitions +- Unit: Test StateFlow emission +- Integration: Test UI updates + +acceptance_criteria: +- Repositories provide StateFlow +- ViewModels manage state properly +- Error states handled +- Loading states implemented +- Lifecycle-aware updates + +validation: +- Run `./gradlew test` +- Test with Espresso for UI updates + +notes: +- Use StateFlow for new code +- Use LiveData for UI binding +- Follow Repository pattern diff --git a/tasks/native-business-logic-migration/17-implement-linux-state-management.md b/tasks/native-business-logic-migration/17-implement-linux-state-management.md new file mode 100644 index 0000000..9b2906b --- /dev/null +++ b/tasks/native-business-logic-migration/17-implement-linux-state-management.md @@ -0,0 +1,41 @@ +# 17. Implement Linux state management (GObject signals) + +meta: + id: native-business-logic-migration-17 + feature: native-business-logic-migration + priority: P0 + depends_on: [native-business-logic-migration-14] + tags: [implementation, linux, state-management] + +objective: +- Implement reactive state management using GObject signals + +deliverables: +- feed-repository.vala +- subscription-repository.vala +- feed-view-model.vala +- subscription-view-model.vala +- State enumeration +- Error handling types + +tests: +- Unit: Test repository methods +- Unit: Test ViewModel state transitions +- Unit: Test signal emission +- Integration: Test UI updates + +acceptance_criteria: +- Repositories emit signals on changes +- ViewModels manage state properly +- Error states handled +- Loading states implemented +- Proper signal connections + +validation: +- Run `meson test -C build` +- Test signal connections + +notes: +- Use GObject properties with notify signals +- Follow GNOME HIG +- Use Gio for async operations diff --git a/tasks/native-business-logic-migration/18-implement-ios-background-sync.md b/tasks/native-business-logic-migration/18-implement-ios-background-sync.md new file mode 100644 index 0000000..87ec466 --- /dev/null +++ b/tasks/native-business-logic-migration/18-implement-ios-background-sync.md @@ -0,0 +1,39 @@ +# 18. Implement iOS background sync service + +meta: + id: native-business-logic-migration-18 + feature: native-business-logic-migration + priority: P1 + depends_on: [native-business-logic-migration-15] + tags: [implementation, ios, background] + +objective: +- Implement background feed sync using BGTaskScheduler + +deliverables: +- BackgroundSyncService.swift +- SyncScheduler.swift +- SyncWorker.swift +- AppIntent extensions +- Background configuration + +tests: +- Unit: Test scheduler configuration +- Unit: Test task cancellation +- Integration: Test background execution + +acceptance_criteria: +- Background tasks scheduled properly +- Tasks execute within time window +- Battery-efficient scheduling +- Proper task cancellation +- State persisted between runs + +validation: +- Test with Xcode debugger +- Verify with Console app logs + +notes: +- Use BGAppRefreshTask +- Request background modes capability +- Handle time limits gracefully diff --git a/tasks/native-business-logic-migration/19-implement-android-background-sync.md b/tasks/native-business-logic-migration/19-implement-android-background-sync.md new file mode 100644 index 0000000..cbd042c --- /dev/null +++ b/tasks/native-business-logic-migration/19-implement-android-background-sync.md @@ -0,0 +1,39 @@ +# 19. Implement Android background sync service + +meta: + id: native-business-logic-migration-19 + feature: native-business-logic-migration + priority: P1 + depends_on: [native-business-logic-migration-16] + tags: [implementation, android, background] + +objective: +- Implement background feed sync using WorkManager + +deliverables: +- SyncWorker.kt +- SyncScheduler.kt +- SyncConfiguration.kt +- WorkManager configuration +- Foreground service (if needed) + +tests: +- Unit: Test Worker execution +- Unit: Test scheduler configuration +- Integration: Test background execution + +acceptance_criteria: +- Work scheduled properly +- Constraints respected (network, charging) +- Battery-efficient scheduling +- Proper work cancellation +- State persisted between runs + +validation: +- Test with WorkManager TestRule +- Verify with adb commands + +notes: +- Use PeriodicWorkRequest +- Set appropriate constraints +- Handle Doze mode diff --git a/tasks/native-business-logic-migration/20-implement-linux-background-sync.md b/tasks/native-business-logic-migration/20-implement-linux-background-sync.md new file mode 100644 index 0000000..1b5f4fa --- /dev/null +++ b/tasks/native-business-logic-migration/20-implement-linux-background-sync.md @@ -0,0 +1,38 @@ +# 20. Implement Linux background sync service + +meta: + id: native-business-logic-migration-20 + feature: native-business-logic-migration + priority: P1 + depends_on: [native-business-logic-migration-17] + tags: [implementation, linux, background] + +objective: +- Implement background feed sync using GIO Timeout or systemd timer + +deliverables: +- background-sync.vala +- sync-scheduler.vala +- systemd service file +- systemd timer file +- Desktop entry with autostart + +tests: +- Unit: Test scheduler configuration +- Unit: Test timeout handling +- Integration: Test background execution + +acceptance_criteria: +- Sync runs on schedule +- Battery-efficient (only when active) +- Proper cleanup on app close +- State persisted between runs + +validation: +- Test with systemd-timer list +- Verify with journalctl + +notes: +- Use GTimeout for in-app scheduling +- Use systemd timer for system-level +- Respect power management diff --git a/tasks/native-business-logic-migration/21-implement-ios-search-service.md b/tasks/native-business-logic-migration/21-implement-ios-search-service.md new file mode 100644 index 0000000..8655d29 --- /dev/null +++ b/tasks/native-business-logic-migration/21-implement-ios-search-service.md @@ -0,0 +1,40 @@ +# 21. Implement iOS search service (FTS) + +meta: + id: native-business-logic-migration-21 + feature: native-business-logic-migration + priority: P1 + depends_on: [native-business-logic-migration-15] + tags: [implementation, ios, search] + +objective: +- Implement full-text search service using Core Data FTS or SQLite FTS + +deliverables: +- SearchService.swift +- SearchQuery.swift +- SearchResultProvider.swift +- FTS index management +- Search history storage + +tests: +- Unit: Test query parsing +- Unit: Test FTS queries +- Unit: Test result ranking +- Integration: Test search with real data + +acceptance_criteria: +- Full-text search working +- Search history maintained +- Results ranked by relevance +- Performance: <200ms for search +- Fuzzy matching supported + +validation: +- Run unit tests +- Test with large dataset + +notes: +- Use Core Data FTS or GRDB FTS5 +- Implement search suggestions +- Cache frequent queries diff --git a/tasks/native-business-logic-migration/22-implement-android-search-service.md b/tasks/native-business-logic-migration/22-implement-android-search-service.md new file mode 100644 index 0000000..68e2a97 --- /dev/null +++ b/tasks/native-business-logic-migration/22-implement-android-search-service.md @@ -0,0 +1,40 @@ +# 22. Implement Android search service (FTS) + +meta: + id: native-business-logic-migration-22 + feature: native-business-logic-migration + priority: P1 + depends_on: [native-business-logic-migration-16] + tags: [implementation, android, search] + +objective: +- Implement full-text search service using Room FTS + +deliverables: +- SearchService.kt +- SearchQuery.kt +- SearchResultProvider.kt +- FTS index management +- Search history storage + +tests: +- Unit: Test query parsing +- Unit: Test FTS queries +- Unit: Test result ranking +- Integration: Test search with real data + +acceptance_criteria: +- Full-text search working +- Search history maintained +- Results ranked by relevance +- Performance: <200ms for search +- Fuzzy matching supported + +validation: +- Run `./gradlew test` +- Test with large dataset + +notes: +- Use Room FTS5 +- Implement search suggestions +- Cache frequent queries diff --git a/tasks/native-business-logic-migration/23-implement-linux-search-service.md b/tasks/native-business-logic-migration/23-implement-linux-search-service.md new file mode 100644 index 0000000..f74a90d --- /dev/null +++ b/tasks/native-business-logic-migration/23-implement-linux-search-service.md @@ -0,0 +1,40 @@ +# 23. Implement Linux search service (FTS) + +meta: + id: native-business-logic-migration-23 + feature: native-business-logic-migration + priority: P1 + depends_on: [native-business-logic-migration-17] + tags: [implementation, linux, search] + +objective: +- Implement full-text search service using SQLite FTS + +deliverables: +- search-service.vala +- search-query.vala +- search-result-provider.vala +- FTS index management +- Search history storage + +tests: +- Unit: Test query parsing +- Unit: Test FTS queries +- Unit: Test result ranking +- Integration: Test search with real data + +acceptance_criteria: +- Full-text search working +- Search history maintained +- Results ranked by relevance +- Performance: <200ms for search +- Fuzzy matching supported + +validation: +- Run `meson test -C build` +- Test with large dataset + +notes: +- Use SQLite FTS5 +- Implement search suggestions +- Cache frequent queries diff --git a/tasks/native-business-logic-migration/24-implement-ios-notifications.md b/tasks/native-business-logic-migration/24-implement-ios-notifications.md new file mode 100644 index 0000000..d716703 --- /dev/null +++ b/tasks/native-business-logic-migration/24-implement-ios-notifications.md @@ -0,0 +1,39 @@ +# 24. Implement iOS notification service + +meta: + id: native-business-logic-migration-24 + feature: native-business-logic-migration + priority: P1 + depends_on: [native-business-logic-migration-15] + tags: [implementation, ios, notifications] + +objective: +- Implement push and local notification service for iOS + +deliverables: +- NotificationService.swift +- NotificationManager.swift +- NotificationPreferencesStore.swift +- Notification extension (if needed) +- Badge management + +tests: +- Unit: Test notification configuration +- Unit: Test permission handling +- Integration: Test notification delivery + +acceptance_criteria: +- Push notifications received +- Local notifications scheduled +- Badge count updated +- Notification categories working +- Preferences respected + +validation: +- Test with Pusher.app +- Verify in Settings > Notifications + +notes: +- Use UserNotifications framework +- Implement notification categories +- Handle foreground/background differently diff --git a/tasks/native-business-logic-migration/25-implement-android-notifications.md b/tasks/native-business-logic-migration/25-implement-android-notifications.md new file mode 100644 index 0000000..809ff7e --- /dev/null +++ b/tasks/native-business-logic-migration/25-implement-android-notifications.md @@ -0,0 +1,39 @@ +# 25. Implement Android notification service + +meta: + id: native-business-logic-migration-25 + feature: native-business-logic-migration + priority: P1 + depends_on: [native-business-logic-migration-16] + tags: [implementation, android, notifications] + +objective: +- Implement push and local notification service for Android + +deliverables: +- NotificationService.kt +- NotificationManager.kt +- NotificationPreferencesStore.kt +- Notification channels +- Badge management + +tests: +- Unit: Test notification configuration +- Unit: Test permission handling +- Integration: Test notification delivery + +acceptance_criteria: +- Push notifications received +- Local notifications scheduled +- Badge count updated +- Notification channels working +- Preferences respected + +validation: +- Test with Firebase Console +- Verify in Settings > Apps > Notifications + +notes: +- Use NotificationCompat +- Create proper notification channels +- Handle Android 13+ permissions diff --git a/tasks/native-business-logic-migration/26-implement-linux-notifications.md b/tasks/native-business-logic-migration/26-implement-linux-notifications.md new file mode 100644 index 0000000..07d383f --- /dev/null +++ b/tasks/native-business-logic-migration/26-implement-linux-notifications.md @@ -0,0 +1,39 @@ +# 26. Implement Linux notification service + +meta: + id: native-business-logic-migration-26 + feature: native-business-logic-migration + priority: P1 + depends_on: [native-business-logic-migration-17] + tags: [implementation, linux, notifications] + +objective: +- Implement desktop notification service for Linux + +deliverables: +- notification-service.vala +- notification-manager.vala +- notification-preferences-store.vala +- Tray icon integration +- Badge management + +tests: +- Unit: Test notification creation +- Unit: Test notification actions +- Integration: Test notification delivery + +acceptance_criteria: +- Desktop notifications shown +- Notification actions working +- Tray icon updated +- Badge count updated +- Preferences respected + +validation: +- Test with notify-send +- Verify in system settings + +notes: +- Use Gio.Notification +- Follow freedesktop.org spec +- Integrate with system tray diff --git a/tasks/native-business-logic-migration/27-implement-ios-settings-store.md b/tasks/native-business-logic-migration/27-implement-ios-settings-store.md new file mode 100644 index 0000000..418dce8 --- /dev/null +++ b/tasks/native-business-logic-migration/27-implement-ios-settings-store.md @@ -0,0 +1,39 @@ +# 27. Implement iOS settings/preferences store + +meta: + id: native-business-logic-migration-27 + feature: native-business-logic-migration + priority: P1 + depends_on: [native-business-logic-migration-15] + tags: [implementation, ios, settings] + +objective: +- Implement settings store using UserDefaults and App Group + +deliverables: +- SettingsStore.swift +- AppSettings.swift +- ReadingPreferences.swift +- NotificationPreferences.swift +- Settings migration + +tests: +- Unit: Test property storage/retrieval +- Unit: Test defaults +- Unit: Test synchronization + +acceptance_criteria: +- All settings persisted +- Defaults properly set +- Changes observed in real-time +- App Group sync working +- Settings migrated between versions + +validation: +- Run unit tests +- Test with Xcode preferences inspector + +notes: +- Use UserDefaults for simple settings +- Use App Group for shared settings +- Observe changes with notifications diff --git a/tasks/native-business-logic-migration/28-implement-android-settings-store.md b/tasks/native-business-logic-migration/28-implement-android-settings-store.md new file mode 100644 index 0000000..7ecdab3 --- /dev/null +++ b/tasks/native-business-logic-migration/28-implement-android-settings-store.md @@ -0,0 +1,39 @@ +# 28. Implement Android settings/preferences store + +meta: + id: native-business-logic-migration-28 + feature: native-business-logic-migration + priority: P1 + depends_on: [native-business-logic-migration-16] + tags: [implementation, android, settings] + +objective: +- Implement settings store using DataStore and SharedPreferences + +deliverables: +- SettingsStore.kt +- AppSettings.kt +- ReadingPreferences.kt +- NotificationPreferences.kt +- Settings migration + +tests: +- Unit: Test property storage/retrieval +- Unit: Test defaults +- Unit: Test synchronization + +acceptance_criteria: +- All settings persisted +- Defaults properly set +- Changes observed in real-time +- Preferences encrypted if needed +- Settings migrated between versions + +validation: +- Run `./gradlew test` +- Test with Application Info > Preferences + +notes: +- Use DataStore for new code +- Use SharedPreferences for simple values +- Observe changes with Flow diff --git a/tasks/native-business-logic-migration/29-implement-linux-settings-store.md b/tasks/native-business-logic-migration/29-implement-linux-settings-store.md new file mode 100644 index 0000000..9863d7b --- /dev/null +++ b/tasks/native-business-logic-migration/29-implement-linux-settings-store.md @@ -0,0 +1,39 @@ +# 29. Implement Linux settings/preferences store + +meta: + id: native-business-logic-migration-29 + feature: native-business-logic-migration + priority: P1 + depends_on: [native-business-logic-migration-17] + tags: [implementation, linux, settings] + +objective: +- Implement settings store using GSettings and JSON file + +deliverables: +- settings-store.vala +- app-settings.vala +- reading-preferences.vala +- notification-preferences.vala +- GSettings schema + +tests: +- Unit: Test property storage/retrieval +- Unit: Test defaults +- Unit: Test synchronization + +acceptance_criteria: +- All settings persisted +- Defaults properly set +- Changes observed in real-time +- Settings follow XDG spec +- Settings migrated between versions + +validation: +- Run `meson test -C build` +- Test with gsettings CLI + +notes: +- Use GSettings for system integration +- Use JSON file for app-specific +- Follow XDG Base Directory spec diff --git a/tasks/native-business-logic-migration/30-implement-ios-bookmark-store.md b/tasks/native-business-logic-migration/30-implement-ios-bookmark-store.md new file mode 100644 index 0000000..89eba55 --- /dev/null +++ b/tasks/native-business-logic-migration/30-implement-ios-bookmark-store.md @@ -0,0 +1,38 @@ +# 30. Implement iOS bookmark store + +meta: + id: native-business-logic-migration-30 + feature: native-business-logic-migration + priority: P1 + depends_on: [native-business-logic-migration-15] + tags: [implementation, ios, bookmarks] + +objective: +- Implement bookmark store for saving articles + +deliverables: +- BookmarkStore.swift +- Bookmark.swift (model) +- BookmarkRepository.swift +- Bookmark grouping/tagging + +tests: +- Unit: Test bookmark CRUD +- Unit: Test bookmark queries +- Unit: Test bookmark deletion cascade + +acceptance_criteria: +- Bookmarks saved to database +- Bookmarks queryable +- Bookmarks deletable +- Bookmark count accurate +- Integration with feed items + +validation: +- Run unit tests +- Test with Xcode Core Data editor + +notes: +- Store as relationship to FeedItem +- Support tags/categories +- Implement smart folders diff --git a/tasks/native-business-logic-migration/31-implement-android-bookmark-store.md b/tasks/native-business-logic-migration/31-implement-android-bookmark-store.md new file mode 100644 index 0000000..4059051 --- /dev/null +++ b/tasks/native-business-logic-migration/31-implement-android-bookmark-store.md @@ -0,0 +1,38 @@ +# 31. Implement Android bookmark store + +meta: + id: native-business-logic-migration-31 + feature: native-business-logic-migration + priority: P1 + depends_on: [native-business-logic-migration-16] + tags: [implementation, android, bookmarks] + +objective: +- Implement bookmark store for saving articles + +deliverables: +- BookmarkStore.kt +- Bookmark.kt (model) +- BookmarkRepository.kt +- Bookmark grouping/tagging + +tests: +- Unit: Test bookmark CRUD +- Unit: Test bookmark queries +- Unit: Test bookmark deletion cascade + +acceptance_criteria: +- Bookmarks saved to database +- Bookmarks queryable +- Bookmarks deletable +- Bookmark count accurate +- Integration with feed items + +validation: +- Run `./gradlew test` +- Test with Room Inspection + +notes: +- Store as separate entity with foreign key +- Support tags/categories +- Implement smart folders diff --git a/tasks/native-business-logic-migration/32-implement-linux-bookmark-store.md b/tasks/native-business-logic-migration/32-implement-linux-bookmark-store.md new file mode 100644 index 0000000..2059cbb --- /dev/null +++ b/tasks/native-business-logic-migration/32-implement-linux-bookmark-store.md @@ -0,0 +1,38 @@ +# 32. Implement Linux bookmark store + +meta: + id: native-business-logic-migration-32 + feature: native-business-logic-migration + priority: P1 + depends_on: [native-business-logic-migration-17] + tags: [implementation, linux, bookmarks] + +objective: +- Implement bookmark store for saving articles + +deliverables: +- bookmark-store.vala +- bookmark.vala (model) +- bookmark-repository.vala +- Bookmark grouping/tagging + +tests: +- Unit: Test bookmark CRUD +- Unit: Test bookmark queries +- Unit: Test bookmark deletion cascade + +acceptance_criteria: +- Bookmarks saved to database +- Bookmarks queryable +- Bookmarks deletable +- Bookmark count accurate +- Integration with feed items + +validation: +- Run `meson test -C build` +- Test with sqlite3 CLI + +notes: +- Store as separate table with foreign key +- Support tags/categories +- Implement smart folders diff --git a/tasks/native-business-logic-migration/33-integrate-ios-business-logic.md b/tasks/native-business-logic-migration/33-integrate-ios-business-logic.md new file mode 100644 index 0000000..f373b01 --- /dev/null +++ b/tasks/native-business-logic-migration/33-integrate-ios-business-logic.md @@ -0,0 +1,40 @@ +# 33. Integrate business logic with iOS UI + +meta: + id: native-business-logic-migration-33 + feature: native-business-logic-migration + priority: P1 + depends_on: [native-business-logic-migration-30, native-business-logic-migration-15] + tags: [implementation, ios, ui] + +objective: +- Connect business logic layer with SwiftUI views + +deliverables: +- FeedList view connected to ViewModel +- FeedDetail view connected to ViewModel +- AddFeed view connected to services +- Search view connected to SearchService +- Settings view connected to SettingsStore +- Bookmark view connected to BookmarkStore + +tests: +- UI: Test view renders with data +- UI: Test navigation works +- UI: Test error states displayed + +acceptance_criteria: +- All views connected to ViewModels +- Data flows correctly +- User actions trigger updates +- Error states shown properly +- Loading states shown properly + +validation: +- Run app in simulator +- Test all user flows + +notes: +- Use @StateObject for ViewModels +- Use @Query for direct database access +- Implement pull-to-refresh diff --git a/tasks/native-business-logic-migration/34-integrate-android-business-logic.md b/tasks/native-business-logic-migration/34-integrate-android-business-logic.md new file mode 100644 index 0000000..c008f89 --- /dev/null +++ b/tasks/native-business-logic-migration/34-integrate-android-business-logic.md @@ -0,0 +1,40 @@ +# 34. Integrate business logic with Android UI + +meta: + id: native-business-logic-migration-34 + feature: native-business-logic-migration + priority: P1 + depends_on: [native-business-logic-migration-31, native-business-logic-migration-16] + tags: [implementation, android, ui] + +objective: +- Connect business logic layer with Jetpack Compose views + +deliverables: +- FeedList composable connected to ViewModel +- FeedDetail composable connected to ViewModel +- AddFeed composable connected to services +- Search composable connected to SearchService +- Settings composable connected to SettingsStore +- Bookmark composable connected to BookmarkStore + +tests: +- UI: Test composable renders with data +- UI: Test navigation works +- UI: Test error states displayed + +acceptance_criteria: +- All composables connected to ViewModels +- Data flows correctly +- User actions trigger updates +- Error states shown properly +- Loading states shown properly + +validation: +- Run app on emulator +- Test all user flows + +notes: +- Use ViewModel composables +- Use Hilt for dependency injection +- Implement swipe-to-refresh diff --git a/tasks/native-business-logic-migration/35-integrate-linux-business-logic.md b/tasks/native-business-logic-migration/35-integrate-linux-business-logic.md new file mode 100644 index 0000000..2888121 --- /dev/null +++ b/tasks/native-business-logic-migration/35-integrate-linux-business-logic.md @@ -0,0 +1,40 @@ +# 35. Integrate business logic with Linux UI + +meta: + id: native-business-logic-migration-35 + feature: native-business-logic-migration + priority: P1 + depends_on: [native-business-logic-migration-32, native-business-logic-migration-17] + tags: [implementation, linux, ui] + +objective: +- Connect business logic layer with GTK4 views + +deliverables: +- FeedList widget connected to ViewModel +- FeedDetail widget connected to ViewModel +- AddFeed widget connected to services +- Search widget connected to SearchService +- Settings widget connected to SettingsStore +- Bookmark widget connected to BookmarkStore + +tests: +- UI: Test widget renders with data +- UI: Test navigation works +- UI: Test error states displayed + +acceptance_criteria: +- All widgets connected to ViewModels +- Data flows correctly +- User actions trigger updates +- Error states shown properly +- Loading states shown properly + +validation: +- Run app on Linux +- Test all user flows + +notes: +- Use GObject signals for updates +- Follow GNOME HIG +- Implement proper GTK patterns diff --git a/tasks/native-business-logic-migration/36-write-unit-tests-ios.md b/tasks/native-business-logic-migration/36-write-unit-tests-ios.md new file mode 100644 index 0000000..3513a5d --- /dev/null +++ b/tasks/native-business-logic-migration/36-write-unit-tests-ios.md @@ -0,0 +1,42 @@ +# 36. Write unit tests for iOS business logic + +meta: + id: native-business-logic-migration-36 + feature: native-business-logic-migration + priority: P1 + depends_on: [native-business-logic-migration-33] + tags: [testing, ios] + +objective: +- Write comprehensive unit tests for iOS business logic + +deliverables: +- FeedParserTests.swift +- FeedFetcherTests.swift +- DatabaseTests.swift +- RepositoryTests.swift +- ViewModelTests.swift +- BackgroundSyncTests.swift +- SearchServiceTests.swift +- NotificationServiceTests.swift + +tests: +- Unit: All test files compile +- Unit: All tests pass +- Coverage: >80% code coverage + +acceptance_criteria: +- All business logic covered +- Edge cases tested +- Error cases tested +- Performance tests included +- >80% code coverage + +validation: +- Run `xcodebuild test` +- Check coverage report + +notes: +- Use XCTest framework +- Use XCTestExpectations for async +- Mock external dependencies diff --git a/tasks/native-business-logic-migration/37-write-unit-tests-android.md b/tasks/native-business-logic-migration/37-write-unit-tests-android.md new file mode 100644 index 0000000..2064995 --- /dev/null +++ b/tasks/native-business-logic-migration/37-write-unit-tests-android.md @@ -0,0 +1,42 @@ +# 37. Write unit tests for Android business logic + +meta: + id: native-business-logic-migration-37 + feature: native-business-logic-migration + priority: P1 + depends_on: [native-business-logic-migration-34] + tags: [testing, android] + +objective: +- Write comprehensive unit tests for Android business logic + +deliverables: +- FeedParserTest.kt +- FeedFetcherTest.kt +- DatabaseTest.kt +- RepositoryTest.kt +- ViewModelTest.kt +- BackgroundSyncTest.kt +- SearchServiceTest.kt +- NotificationServiceTest.kt + +tests: +- Unit: All test files compile +- Unit: All tests pass +- Coverage: >80% code coverage + +acceptance_criteria: +- All business logic covered +- Edge cases tested +- Error cases tested +- Performance tests included +- >80% code coverage + +validation: +- Run `./gradlew test` +- Check coverage report with Jacoco + +notes: +- Use JUnit 5 +- Use MockK for mocking +- Use Coroutines Test for async diff --git a/tasks/native-business-logic-migration/38-write-unit-tests-linux.md b/tasks/native-business-logic-migration/38-write-unit-tests-linux.md new file mode 100644 index 0000000..ca54dc0 --- /dev/null +++ b/tasks/native-business-logic-migration/38-write-unit-tests-linux.md @@ -0,0 +1,42 @@ +# 38. Write unit tests for Linux business logic + +meta: + id: native-business-logic-migration-38 + feature: native-business-logic-migration + priority: P1 + depends_on: [native-business-logic-migration-35] + tags: [testing, linux] + +objective: +- Write comprehensive unit tests for Linux business logic + +deliverables: +- feed-parser-test.vala +- feed-fetcher-test.vala +- database-test.vala +- repository-test.vala +- view-model-test.vala +- background-sync-test.vala +- search-service-test.vala +- notification-service-test.vala + +tests: +- Unit: All test files compile +- Unit: All tests pass +- Coverage: >80% code coverage + +acceptance_criteria: +- All business logic covered +- Edge cases tested +- Error cases tested +- Performance tests included +- >80% code coverage + +validation: +- Run `meson test -C build` +- Check coverage report + +notes: +- Use GLib's g_test framework +- Use g_assert macros +- Mock external dependencies diff --git a/tasks/native-business-logic-migration/39-write-integration-tests.md b/tasks/native-business-logic-migration/39-write-integration-tests.md new file mode 100644 index 0000000..ac59709 --- /dev/null +++ b/tasks/native-business-logic-migration/39-write-integration-tests.md @@ -0,0 +1,40 @@ +# 39. Write cross-platform integration tests + +meta: + id: native-business-logic-migration-39 + feature: native-business-logic-migration + priority: P1 + depends_on: [native-business-logic-migration-36, native-business-logic-migration-37, native-business-logic-migration-38] + tags: [testing, integration] + +objective: +- Write integration tests that verify cross-platform functionality + +deliverables: +- Integration test suite +- Test fixtures (sample feeds) +- Test data generator +- CI integration + +tests: +- Integration: Feed fetch → parse → store flow +- Integration: Search end-to-end +- Integration: Background sync end-to-end +- Integration: Notification delivery +- Integration: Settings persistence +- Integration: Bookmark CRUD + +acceptance_criteria: +- All integration tests pass +- Test data properly isolated +- Tests can run independently +- Tests included in CI + +validation: +- Run full test suite +- Verify CI passes + +notes: +- Use same test feeds across platforms +- Verify data consistency +- Test error recovery diff --git a/tasks/native-business-logic-migration/40-performance-optimization.md b/tasks/native-business-logic-migration/40-performance-optimization.md new file mode 100644 index 0000000..572db32 --- /dev/null +++ b/tasks/native-business-logic-migration/40-performance-optimization.md @@ -0,0 +1,47 @@ +# 40. Performance optimization and benchmarking + +meta: + id: native-business-logic-migration-40 + feature: native-business-logic-migration + priority: P2 + depends_on: [native-business-logic-migration-39] + tags: [performance, optimization] + +objective: +- Optimize performance and establish benchmarks + +deliverables: +- Performance benchmarks +- Optimization report +- Memory profiling results +- CPU profiling results +- Network profiling results + +tests: +- Benchmark: Feed parsing <100ms +- Benchmark: Feed fetching <5s +- Benchmark: Search <200ms +- Benchmark: Database query <50ms +- Memory: No leaks detected +- CPU: Efficient usage + +acceptance_criteria: +- Feed parsing <100ms for typical feed +- Feed fetching <5s on normal network +- Search <200ms +- Database queries <50ms +- No memory leaks +- Smooth UI at 60fps +- Battery efficient + +validation: +- Run benchmarks on each platform +- Profile with Instruments (iOS) +- Profile with Android Profiler +- Profile with Valgrind (Linux) + +notes: +- Use platform-specific profiling tools +- Establish baseline metrics +- Optimize iteratively +- Document optimizations made diff --git a/tasks/native-business-logic-migration/README.md b/tasks/native-business-logic-migration/README.md new file mode 100644 index 0000000..3da29ef --- /dev/null +++ b/tasks/native-business-logic-migration/README.md @@ -0,0 +1,107 @@ +# Native Business Logic Migration + +Objective: Migrate RSSuper business logic from Expo/TypeScript to native platforms (iOS, Android, Linux) + +Status legend: [ ] todo, [~] in-progress, [x] done + +## Phase 1: Analysis & Design +- [x] 01 — Analyze and document current Expo architecture → `01-analyze-current-architecture.md` +- [x] 02 — Design shared data models for all platforms → `02-design-shared-data-models.md` + +## Phase 2: Data Models (Per Platform) +- [ ] 03 — Implement iOS data models (Swift) → `03-implement-ios-data-models.md` +- [ ] 04 — Implement Android data models (Kotlin) → `04-implement-android-data-models.md` +- [ ] 05 — Implement Linux data models (C/Vala) → `05-implement-linux-data-models.md` + +## Phase 3: Database Layer (Per Platform) +- [ ] 06 — Implement iOS database layer (Core Data/GRDB) → `06-implement-ios-database-layer.md` +- [ ] 07 — Implement Android database layer (Room) → `07-implement-android-database-layer.md` +- [ ] 08 — Implement Linux database layer (SQLite) → `08-implement-linux-database-layer.md` + +## Phase 4: Feed Parsing (Per Platform) +- [ ] 09 — Implement iOS RSS/Atom feed parser → `09-implement-ios-feed-parser.md` +- [ ] 10 — Implement Android RSS/Atom feed parser → `10-implement-android-feed-parser.md` +- [ ] 11 — Implement Linux RSS/Atom feed parser → `11-implement-linux-feed-parser.md` + +## Phase 5: Feed Fetching (Per Platform) +- [ ] 12 — Implement iOS feed fetcher service → `12-implement-ios-feed-fetcher.md` +- [ ] 13 — Implement Android feed fetcher service → `13-implement-android-feed-fetcher.md` +- [ ] 14 — Implement Linux feed fetcher service → `14-implement-linux-feed-fetcher.md` + +## Phase 6: State Management (Per Platform) +- [ ] 15 — Implement iOS state management (Combine/Observer) → `15-implement-ios-state-management.md` +- [ ] 16 — Implement Android state management (StateFlow/LiveData) → `16-implement-android-state-management.md` +- [ ] 17 — Implement Linux state management (GObject signals) → `17-implement-linux-state-management.md` + +## Phase 7: Services (Per Platform) +### Background Sync +- [ ] 18 — Implement iOS background sync service → `18-implement-ios-background-sync.md` +- [ ] 19 — Implement Android background sync service → `19-implement-android-background-sync.md` +- [ ] 20 — Implement Linux background sync service → `20-implement-linux-background-sync.md` + +### Search Service +- [ ] 21 — Implement iOS search service (FTS) → `21-implement-ios-search-service.md` +- [ ] 22 — Implement Android search service (FTS) → `22-implement-android-search-service.md` +- [ ] 23 — Implement Linux search service (FTS) → `23-implement-linux-search-service.md` + +### Notifications +- [ ] 24 — Implement iOS notification service → `24-implement-ios-notifications.md` +- [ ] 25 — Implement Android notification service → `25-implement-android-notifications.md` +- [ ] 26 — Implement Linux notification service → `26-implement-linux-notifications.md` + +### Settings Store +- [ ] 27 — Implement iOS settings/preferences store → `27-implement-ios-settings-store.md` +- [ ] 28 — Implement Android settings/preferences store → `28-implement-android-settings-store.md` +- [ ] 29 — Implement Linux settings/preferences store → `29-implement-linux-settings-store.md` + +### Bookmark Store +- [ ] 30 — Implement iOS bookmark store → `30-implement-ios-bookmark-store.md` +- [ ] 31 — Implement Android bookmark store → `31-implement-android-bookmark-store.md` +- [ ] 32 — Implement Linux bookmark store → `32-implement-linux-bookmark-store.md` + +## Phase 8: UI Integration (Per Platform) +- [ ] 33 — Integrate business logic with iOS UI → `33-integrate-ios-business-logic.md` +- [ ] 34 — Integrate business logic with Android UI → `34-integrate-android-business-logic.md` +- [ ] 35 — Integrate business logic with Linux UI → `35-integrate-linux-business-logic.md` + +## Phase 9: Testing +- [ ] 36 — Write unit tests for iOS business logic → `36-write-unit-tests-ios.md` +- [ ] 37 — Write unit tests for Android business logic → `37-write-unit-tests-android.md` +- [ ] 38 — Write unit tests for Linux business logic → `38-write-unit-tests-linux.md` +- [ ] 39 — Write cross-platform integration tests → `39-write-integration-tests.md` + +## Phase 10: Optimization +- [ ] 40 — Performance optimization and benchmarking → `40-performance-optimization.md` + +## Dependencies +- 01 → 02 (architecture analysis feeds into data model design) +- 02 → 03, 04, 05 (data models depend on shared design) +- 03 → 06 (iOS database depends on iOS models) +- 04 → 07 (Android database depends on Android models) +- 05 → 08 (Linux database depends on Linux models) +- 06, 07, 08 → 09, 10, 11 (feed parsers need database layer) +- 09 → 12 (iOS fetcher depends on iOS parser) +- 10 → 13 (Android fetcher depends on Android parser) +- 11 → 14 (Linux fetcher depends on Linux parser) +- 12, 13, 14 → 15, 16, 17 (state management depends on fetchers) +- 15 → 18, 21, 24, 27, 30 (iOS services depend on state management) +- 16 → 19, 22, 25, 28, 31 (Android services depend on state management) +- 17 → 20, 23, 26, 29, 32 (Linux services depend on state management) +- 30, 31, 32 → 33, 34, 35 (UI integration depends on all stores) +- 36, 37, 38 → 39 (integration tests depend on unit tests) +- 39 → 40 (optimization comes after testing) + +## Exit Criteria +The feature is complete when: +- [ ] All data models implemented and tested on all platforms +- [ ] Database layer fully functional with migrations on all platforms +- [ ] RSS and Atom feed parsing working with >95% accuracy +- [ ] Feed fetching with error handling and retry logic on all platforms +- [ ] Background sync working on all platforms +- [ ] Full-text search functional on all platforms +- [ ] Notifications working for new articles on all platforms +- [ ] Settings persisted and readable on all platforms +- [ ] Bookmarks working across all platforms +- [ ] All unit tests passing (>80% coverage) +- [ ] Integration tests passing +- [ ] Performance benchmarks met (feed parse <100ms, fetch <5s, search <200ms)