Repository: appium-userland/appium-flutter-driver Branch: main Commit: 14599d820b99 Files: 159 Total size: 66.3 MB Directory structure: gitextract_00f0ctj7/ ├── .github/ │ ├── dependabot.yml │ └── workflows/ │ ├── dotnet.yml │ ├── driver-function.yml │ ├── finder-kotlin.yml │ ├── finder-node.js.yml │ ├── finder-python.yml │ ├── finder-ruby.yml │ ├── nodejs.yml │ └── publish.yml ├── .gitignore ├── .vscode/ │ └── launch.json ├── LICENSE ├── README.md ├── driver/ │ ├── .eslintrc.json │ ├── .gitignore │ ├── .npmrc │ ├── .releaserc │ ├── CHANGELOG.md │ ├── eslint.config.mjs │ ├── lib/ │ │ ├── commands/ │ │ │ ├── assertions.ts │ │ │ ├── clipboard.ts │ │ │ ├── context.ts │ │ │ ├── element.ts │ │ │ ├── execute/ │ │ │ │ ├── scroll.ts │ │ │ │ └── wait.ts │ │ │ ├── execute.ts │ │ │ ├── gesture.ts │ │ │ └── screen.ts │ │ ├── desired-caps.ts │ │ ├── doctor/ │ │ │ └── checks.js │ │ ├── driver.ts │ │ ├── ios/ │ │ │ └── app.ts │ │ ├── logger.ts │ │ ├── platform.ts │ │ └── sessions/ │ │ ├── android.ts │ │ ├── base64url.ts │ │ ├── ios.ts │ │ ├── isolate_socket.ts │ │ ├── log-monitor.ts │ │ ├── observatory.ts │ │ └── session.ts │ ├── npm-shrinkwrap.json │ ├── package.json │ ├── release.sh │ ├── scripts/ │ │ └── download-wda-sim.mjs │ └── tsconfig.json ├── example/ │ ├── .gitignore │ ├── dart/ │ │ ├── drag_commands.dart │ │ └── get_text_command.dart │ ├── flutter_app_under_test/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── android/ │ │ │ ├── app/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ ├── debug/ │ │ │ │ │ └── AndroidManifest.xml │ │ │ │ ├── main/ │ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ │ ├── java/ │ │ │ │ │ │ └── com/ │ │ │ │ │ │ └── example/ │ │ │ │ │ │ └── hello_world/ │ │ │ │ │ │ └── MainActivity.java │ │ │ │ │ └── res/ │ │ │ │ │ ├── drawable/ │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ └── values/ │ │ │ │ │ └── styles.xml │ │ │ │ └── profile/ │ │ │ │ └── AndroidManifest.xml │ │ │ ├── build.gradle │ │ │ ├── gradle/ │ │ │ │ └── wrapper/ │ │ │ │ └── gradle-wrapper.properties │ │ │ ├── gradle.properties │ │ │ └── settings.gradle │ │ ├── ios/ │ │ │ ├── Flutter/ │ │ │ │ ├── AppFrameworkInfo.plist │ │ │ │ ├── Debug.xcconfig │ │ │ │ └── Release.xcconfig │ │ │ ├── Runner/ │ │ │ │ ├── AppDelegate.h │ │ │ │ ├── AppDelegate.m │ │ │ │ ├── Assets.xcassets/ │ │ │ │ │ ├── AppIcon.appiconset/ │ │ │ │ │ │ └── Contents.json │ │ │ │ │ └── LaunchImage.imageset/ │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── README.md │ │ │ │ ├── Base.lproj/ │ │ │ │ │ ├── LaunchScreen.storyboard │ │ │ │ │ └── Main.storyboard │ │ │ │ ├── Info.plist │ │ │ │ └── main.m │ │ │ ├── Runner.xcodeproj/ │ │ │ │ ├── project.pbxproj │ │ │ │ ├── project.xcworkspace/ │ │ │ │ │ └── contents.xcworkspacedata │ │ │ │ └── xcshareddata/ │ │ │ │ └── xcschemes/ │ │ │ │ └── Runner.xcscheme │ │ │ └── Runner.xcworkspace/ │ │ │ └── contents.xcworkspacedata │ │ ├── lib/ │ │ │ ├── main.dart │ │ │ ├── main.g.dart │ │ │ └── stream.dart │ │ ├── pubspec.yaml │ │ ├── test/ │ │ │ └── widget_test.dart │ │ └── test_driver/ │ │ └── main_test.dart │ ├── java/ │ │ ├── .gitignore │ │ ├── .vscode/ │ │ │ └── settings.json │ │ ├── pom.xml │ │ └── src/ │ │ └── test/ │ │ └── java/ │ │ └── example/ │ │ └── appium/ │ │ ├── BaseDriver.java │ │ └── FlutterTest.java │ ├── nodejs/ │ │ ├── README.md │ │ ├── package.json │ │ └── src/ │ │ └── index.js │ ├── python/ │ │ ├── example.py │ │ └── requirement.txt │ ├── ruby/ │ │ ├── Gemfile │ │ ├── example.rb │ │ ├── example_sample2.rb │ │ └── example_sample2_ios.rb │ └── sample2/ │ ├── README.md │ └── app-debug.apk ├── finder/ │ ├── dotnet/ │ │ ├── AppiumFlutterFinder/ │ │ │ ├── AppiumFlutterFinder.csproj │ │ │ ├── FlutterBy.cs │ │ │ ├── FlutterDriver.cs │ │ │ ├── FlutterElement.cs │ │ │ ├── FlutterElementFactory.cs │ │ │ ├── License.md │ │ │ └── Readme.md │ │ ├── AppiumFlutterFinderTests/ │ │ │ ├── AppiumFlutterFinderTests.csproj │ │ │ ├── FlutterFinderTests.cs │ │ │ └── Usings.cs │ │ └── DotNetAppiumFlutterFinder.sln │ ├── kotlin/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── build.gradle.kts │ │ ├── gradle/ │ │ │ └── wrapper/ │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ │ ├── gradle.properties │ │ ├── gradlew │ │ ├── gradlew.bat │ │ ├── settings.gradle.kts │ │ └── src/ │ │ ├── main/ │ │ │ └── kotlin/ │ │ │ └── pro/ │ │ │ └── truongsinh/ │ │ │ └── appium_flutter/ │ │ │ ├── FlutterFinder.kt │ │ │ └── finder/ │ │ │ ├── FlutterElement.kt │ │ │ ├── ancestor.kt │ │ │ ├── bySemanticsLabel.kt │ │ │ ├── byTooltip.kt │ │ │ ├── byType.kt │ │ │ ├── byValueKey.kt │ │ │ ├── descendant.kt │ │ │ ├── pageback.kt │ │ │ ├── serializer.kt │ │ │ └── text.kt │ │ └── test/ │ │ └── kotlin/ │ │ └── pro/ │ │ └── truongsinh/ │ │ └── appium_flutter/ │ │ └── finder/ │ │ └── FinderTest.kt │ ├── nodejs/ │ │ ├── LICENSE │ │ ├── README.md │ │ ├── lib/ │ │ │ ├── base64url.ts │ │ │ ├── base64url_test.ts │ │ │ ├── deserializer.ts │ │ │ ├── serializer.ts │ │ │ └── serializer_test.ts │ │ ├── package.json │ │ ├── tsconfig.json │ │ └── tslint.json │ ├── python/ │ │ ├── .pylintrc │ │ ├── README.md │ │ ├── appium_flutter_finder/ │ │ │ ├── __init__.py │ │ │ └── flutter_finder.py │ │ ├── setup.py │ │ └── tests/ │ │ ├── __init__.py │ │ └── flutter_finder_tests.py │ ├── ruby/ │ │ ├── Gemfile │ │ ├── README.md │ │ ├── Rakefile │ │ ├── appium_flutter_finder.gemspec │ │ ├── lib/ │ │ │ ├── appium_flutter_finder/ │ │ │ │ └── version.rb │ │ │ └── appium_flutter_finder.rb │ │ └── test/ │ │ ├── appium_flutter_finder_test.rb │ │ └── test_helper.rb │ └── spec.json └── jitpack.yml ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/dependabot.yml ================================================ # To get started with Dependabot version updates, you'll need to specify which # package ecosystems to update and where the package manifests are located. # Please see the documentation for all configuration options: # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates version: 2 updates: - package-ecosystem: "npm" directory: "/driver" schedule: interval: "weekly" - package-ecosystem: "npm" directory: "/example/nodejs" schedule: interval: "weekly" - package-ecosystem: "npm" directory: "/finder/nodejs" schedule: interval: "weekly" - package-ecosystem: "pip" directory: "/finder/python" schedule: interval: "weekly" - package-ecosystem: "bundler" directory: "/finder/ruby" schedule: interval: "weekly" - package-ecosystem: github-actions directory: "/" schedule: interval: weekly time: "11:00" day: "tuesday" open-pull-requests-limit: 5 commit-message: prefix: "ci" include: "scope" ================================================ FILE: .github/workflows/dotnet.yml ================================================ # This workflow will build a .NET project # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net name: .NET on: workflow_dispatch: push: paths: - 'finder/python/**' branches: [ main ] pull_request: paths: - 'finder/python/**' branches: [ main ] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - name: Setup .NET uses: actions/setup-dotnet@v5 with: dotnet-version: 6.0.x - name: Restore dependencies run: dotnet restore working-directory: finder/dotnet - name: Build run: dotnet build --no-restore working-directory: finder/dotnet - name: Run tests run: dotnet test --no-build --verbosity normal working-directory: finder/dotnet ================================================ FILE: .github/workflows/driver-function.yml ================================================ name: Run quick functionality check on: workflow_dispatch: push: paths: - 'driver/**' branches: [ main ] pull_request: paths: - 'driver/**' branches: [ main ] concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true jobs: ios_test: runs-on: macos-15 env: XCODE_VERSION: 16.4 IOS_DEVICE_NAME: iPhone 16 Plus IOS_VERSION: 18.5 steps: - uses: actions/checkout@v6 - name: Install Node.js uses: actions/setup-node@v6 with: node-version: 'lts/*' - name: Select Xcode uses: maxim-lobanov/setup-xcode@v1 with: xcode-version: ${{ env.XCODE_VERSION }} - run: defaults write com.apple.iphonesimulator PasteboardAutomaticSync -bool false - uses: futureware-tech/simulator-action@v5 with: # https://github.com/actions/runner-images/blob/main/images/macos/macos-15-arm64-Readme.md model: ${{ env.IOS_DEVICE_NAME }} os_version: ${{ env.IOS_VERSION }} # Start Appium - run: npm install -g appium - run: | npm install appium driver install --source=local ./ nohup appium --log-timestamp --log-no-colors > appium.log & working-directory: driver - name: Set up Ruby uses: ruby/setup-ruby@v1 with: ruby-version: 3.2 - name: Install dependencies run: bundle install working-directory: example/ruby - name: Run tests run: ruby example_sample2_ios.rb working-directory: example/ruby - name: Save server output if: ${{ always() }} uses: actions/upload-artifact@master with: name: appium-ios.log path: driver/appium.log android_test: runs-on: ubuntu-latest env: API_LEVEL: 34 ARCH: x86_64 steps: - uses: actions/checkout@v6 - uses: actions/setup-java@v5 with: distribution: 'temurin' java-version: '17' - name: Install Node.js uses: actions/setup-node@v6 with: node-version: 'lts/*' # Start Appium - run: npm install -g appium - run: | npm install nohup appium --log-timestamp --log-no-colors > appium.log & working-directory: driver - name: Enable KVM group perms run: | echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules sudo udevadm control --reload-rules sudo udevadm trigger --name-match=kvm - name: AVD cache uses: actions/cache@v5 id: avd-cache with: path: | ~/.android/avd/* ~/.android/adb* key: avd-${{ env.API_LEVEL }} - name: create AVD and generate snapshot for caching if: steps.avd-cache.outputs.cache-hit != 'true' uses: reactivecircus/android-emulator-runner@v2 with: api-level: ${{ env.API_LEVEL }} arch: ${{ env.ARCH }} target: google_apis force-avd-creation: false emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none disable-animations: false script: echo "Generated AVD snapshot for caching." - name: Set up Ruby uses: ruby/setup-ruby@v1 with: ruby-version: 3.2 - name: Install dependencies run: bundle install working-directory: example/ruby - name: Run tests uses: reactivecircus/android-emulator-runner@v2 with: api-level: ${{ env.API_LEVEL }} arch: ${{ env.ARCH }} script: ruby example/ruby/example_sample2.rb target: google_apis profile: Nexus 5X disable-spellchecker: true disable-animations: true env: ANDROID_SDK_VERSION: ${{ env.API_LEVEL }} APPIUM_DRIVER: ${{matrix.test_targets.automation_name}} IGNORE_VERSION_SKIP: true CI: true - name: Save server output if: ${{ always() }} uses: actions/upload-artifact@master with: name: appium-android.log path: driver/appium.log ================================================ FILE: .github/workflows/finder-kotlin.yml ================================================ name: Kotlin on: workflow_dispatch: push: paths: - 'finder/kotlin/**' branches: [ main ] pull_request: paths: - 'finder/kotlin/**' branches: [ main ] permissions: contents: read jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - name: Set up JDK 11 uses: actions/setup-java@v5 with: java-version: '11' distribution: 'temurin' - name: Run tests run: ./gradlew test working-directory: finder/kotlin ================================================ FILE: .github/workflows/finder-node.js.yml ================================================ # This workflow will do a clean install of node dependencies, cache/restore them, build the source code and run tests across different versions of node # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions name: Finer for NodeJS on: workflow_dispatch: push: branches: [ main ] paths: - 'finder/nodejs/**' pull_request: branches: [ main ] paths: - 'finder/nodejs/**' jobs: prepare_matrix: runs-on: ubuntu-latest outputs: versions: ${{ steps.generate-matrix.outputs.versions }} steps: - name: Select 3 most recent LTS versions of Node.js id: generate-matrix run: echo "versions=$(curl -s https://endoflife.date/api/nodejs.json | jq -c '[[.[] | select(.lts != false)][:3] | .[].cycle | tonumber]')" >> "$GITHUB_OUTPUT" build: needs: - prepare_matrix runs-on: ubuntu-latest strategy: matrix: node-version: ${{ fromJSON(needs.prepare_matrix.outputs.versions) }} # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ steps: - uses: actions/checkout@v6 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v6 with: node-version: ${{ matrix.node-version }} - run: | npm install npm run lint npm run test working-directory: finder/nodejs ================================================ FILE: .github/workflows/finder-python.yml ================================================ name: Python on: workflow_dispatch: push: paths: - 'finder/python/**' branches: [ main ] pull_request: paths: - 'finder/python/**' branches: [ main ] jobs: build: runs-on: ubuntu-latest strategy: matrix: python-version: ['3.9', '3.10', '3.11', '3.12', '3.13'] steps: - uses: actions/checkout@v6 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} - name: Install dependencies run: | python -m pip install --upgrade pip pip install pylint pytest Appium-Python-Client - name: Analyzing the code with pylint run: pylint tests/ appium_flutter_finder/ working-directory: finder/python - name: Run tests run: pytest tests/** working-directory: finder/python ================================================ FILE: .github/workflows/finder-ruby.yml ================================================ # This workflow uses actions that are not certified by GitHub. # They are provided by a third-party and are governed by # separate terms of service, privacy policy, and support # documentation. # This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake # For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby name: Ruby on: workflow_dispatch: push: paths: - 'finder/ruby/**' branches: [ main ] pull_request: paths: - 'finder/ruby/**' branches: [ main ] jobs: test: runs-on: ubuntu-latest strategy: matrix: ruby-version: ['3.1', '3.2', '3.3'] steps: - uses: actions/checkout@v6 - name: Set up Ruby uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby-version }} bundler-cache: true working-directory: finder/ruby - name: Run tests run: bundle exec rake working-directory: finder/ruby ================================================ FILE: .github/workflows/nodejs.yml ================================================ # This workflow will do a clean install of node dependencies, cache/restore them, build the source code and run tests across different versions of node # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions name: Node.js CI on: workflow_dispatch: push: paths: - 'driver/**' branches: [ main ] pull_request: paths: - 'driver/**' branches: [ main ] jobs: node_matrix: uses: appium/appium-workflows/.github/workflows/node-lts-matrix.yml@main build: needs: - node_matrix runs-on: ubuntu-latest strategy: fail-fast: false matrix: node-version: ${{ fromJSON(needs.node_matrix.outputs.versions) }} # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ steps: - uses: actions/checkout@v6 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v6 with: node-version: ${{ matrix.node-version }} - run: | npm install npm run lint npm run format:check working-directory: driver ================================================ FILE: .github/workflows/publish.yml ================================================ # This workflow will run tests using node and then publish a package to GitHub Packages when a release is created # For more information see: https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages name: publish driver # FIXME # npm token kep raising as invalid while it had proper one. on: workflow_dispatch: # push: # branches: [ main ] # # paths: # # - 'driver/**' permissions: contents: write pull-requests: write issues: write id-token: write # to enable use of OIDC for trusted publishing and npm provenance jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - uses: actions/setup-node@v6 with: node-version: lts/* check-latest: true - run: npm install working-directory: driver - run: npm test working-directory: driver publish-npm: needs: build runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 with: fetch-depth: 2 - uses: actions/setup-node@v6 with: node-version: lts/* check-latest: true - run: npm install working-directory: driver - run: npm publish name: Publish the package working-directory: driver ================================================ FILE: .gitignore ================================================ .DS_Store # Logs logs *.log npm-debug.log* package-lock.json* # Runtime data pids *.pid *.seed # Directory for instrumented libs generated by jscoverage/JSCover lib-cov # Coverage directory used by tools like istanbul coverage # nyc test coverage .nyc_output # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) .grunt # node-waf configuration .lock-wscript # Compiled binary addons (http://nodejs.org/api/addons.html) build/Release # Dependency directories node_modules jspm_packages # Optional npm cache directory .npm # Optional REPL history .node_repl_history # Ignore gulped JS build # Pack output *.tgz # python finder/python/build finder/python/dist finder/python/Appium_Flutter_Finder.egg-info #dotnet .vs/ bin/ obj/ ================================================ FILE: .vscode/launch.json ================================================ { // Use IntelliSense to learn about possible attributes. // Hover to view descriptions of existing attributes. // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "type": "node", "request": "launch", "name": "Run test iOS", "env": { "APPIUM_OS": "ios" }, "program": "${workspaceFolder}/example/src/index.js", "outFiles": [ "${workspaceFolder}/**/*.js" ] }, { "type": "node", "request": "launch", "name": "Run test Android", "env": { "APPIUM_OS": "android" }, "program": "${workspaceFolder}/example/src/index.js", "outFiles": [ "${workspaceFolder}/**/*.js" ] } ] } ================================================ FILE: LICENSE ================================================ MIT License ----------- Copyright (c) 2019 TruongSinh Tran-Nguyen Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # Appium Flutter Driver [![NPM version](https://img.shields.io/npm/v/appium-flutter-driver.svg)](https://npmjs.org/package/appium-flutter-driver) [![Downloads](https://img.shields.io/npm/dm/appium-flutter-driver.svg)](https://npmjs.org/package/appium-flutter-driver) Appium Flutter Driver is a test automation tool for [Flutter](https://flutter.dev) apps on multiple platforms/OSes. Appium Flutter Driver is part of the [Appium](https://github.com/appium/appium) mobile test automation tool maintained by the community. Feel free to create PRs to fix issues/improve this driver. ## Flutter Driver vs Appium Flutter Driver Even though Flutter comes with superb integration test support, [Flutter Driver](https://flutter.dev/docs/cookbook/testing/integration/introduction), it does not fit some specific use cases, such as - Writing tests in other languages than Dart - Running integration test for Flutter app with embedded webview or native view, or existing native app with embedded Flutter view - Running tests on multiple devices simultaneously - Running integration tests on device farms that offer Appium support (Please contact the availability for each vendor) Under the hood, Appium Flutter Driver uses the [Dart VM Service Protocol](https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md) with extension `ext.flutter.driver`, similar to Flutter Driver, to control the Flutter app-under-test (AUT). ## Appium drivers for Flutter Appium community currently has two drivers for Flutter environment: - Appium Flutter driver (this driver) - Run Flutter commands over websocket connection against the observaory URL (calls Flutter APIs directly) - Base APIs are [`flutter_driver`](https://api.flutter.dev/flutter/flutter_driver/flutter_driver-library.html) - [`Appium Flutter Integration Driver`](https://github.com/AppiumTestDistribution/appium-flutter-integration-driver) - Run a server on DartVM as part of the application under test in order to call Flutter APIs via the server - Base APIs are [`integration_test`](https://github.com/flutter/flutter/tree/main/packages/integration_test#integration_test) ## Appium Flutter Driver or Appium UiAutomator2/XCUITest driver As a baseline, we recommend using [official testing tools and strategy](https://docs.flutter.dev/testing/overview) to test Flutter apps as possible in Dart. If you'd like to test a release app, which can be released from app store as-is, Appium [UIAutomator2](https://github.com/appium/appium-uiautomator2-driver)/[XCUITest](https://github.com/appium/appium-xcuitest-driver) driver is a good choice. Since Flutter 3.19, Flutter apps can expose [`identifier` for `SemanticsProperties`](https://api.flutter.dev/flutter/semantics/SemanticsProperties/identifier.html) as `resource-id` in Android and `accessibilityIdentifier` in iOS. They should help to achieve automation against release apps with Appium [UIAutomator2](https://github.com/appium/appium-uiautomator2-driver)/[XCUITest](https://github.com/appium/appium-xcuitest-driver) as blackbox testing. - Appium Flutter driver has three contexts to manage the application under test and the device under test. To achieve the `FLUTTER` context, the test package requires testing tools to import. The application under test cannot release as-is. - `FLUTTER` context sends commands to the Dart VM directly over the observatory URL. This allows you to interact with Flutter elements directly. - `NATIVE_APP` context is the same as the regular Appium [UIAutomator2](https://github.com/appium/appium-uiautomator2-driver)/[XCUITest](https://github.com/appium/appium-xcuitest-driver) driver - `WEBVIEW` context manages the WebView contents over Appium UiAutomator2/XCUITest driver - (**Recommended** if possible) Appium [UIAutomator2](https://github.com/appium/appium-uiautomator2-driver)/[XCUITest](https://github.com/appium/appium-xcuitest-driver) driver directly must be sufficient to achieve automation if the application under test had `semanticLabel` properly. Then, the accessibility mechanism in each OS can expose elements for Appium through OS's accessibility features. - In addition to `semanticLabel`, Flutter 3.19+ may have [`identifier` for `SemanticsProperties`](https://api.flutter.dev/flutter/semantics/SemanticsProperties/identifier.html) (introduced by https://github.com/flutter/flutter/pull/138331). It sets `resource-id` and `accessibilityIdentifier` for Android and iOS, then UiAutomator2/XCUITest drivers might also be able to interact with these elements without Appium Flutter Driver. - `"appium:settings[disableIdLocatorAutocompletion]": true` or configuring `disableIdLocatorAutocompletion` via [Settings API](https://appium.io/docs/en/latest/guides/settings/) would be necessary to make `resource-id` idea work without any package name prefix like Android compose. - e.g. https://github.com/flutter/flutter/issues/17988#issuecomment-1867097631 ## Installation Appium Flutter Driver version `3.0.0` requires Appium 3. ``` appium driver install --source=npm appium-flutter-driver ``` As a local: ``` appium driver install --source local /path/to/appium-flutter-driver/driver ``` ## Usage and requirement If you are unfamiliar with running Appium tests, start with [Quickstart Intro](https://appium.io/docs/en/latest/quickstart/) first. Your Flutter application must be compiled in `debug` or `profile` mode. The dependency must have **[`flutter_driver`](https://api.flutter.dev/flutter/flutter_driver/flutter_driver-library.html)** package like the below `pubspec.yaml` example with [`enableFlutterDriverExtension`](https://api.flutter.dev/flutter/flutter_driver_extension/flutter_driver_extension-library.html) configuration in the `main.dart`. ```yaml # pubspec.yaml dev_dependencies: flutter_driver: sdk: flutter ``` This snippet, taken from [example directory](example), is a script written as an appium client with `webdriverio`, and assumes you have `appium` server (with `appium-flutter-driver` installed) running on the same host and default port (`4723`). For more info, see example's [README.md](https://github.com/appium/appium-flutter-driver/tree/main/example/nodejs/README.md) > **Note** > > This means this driver depends on [`flutter_driver`](https://api.flutter.dev/flutter/flutter_driver/flutter_driver-library.html). > In the past, the Flutter team announced replacing `flutter_driver` with `integration_test`, but according to [this ticket](https://github.com/flutter/flutter/issues/148028), this discussion is still ongoing. > So flutter_driver would continue to be maintained for now. Each client needs [each finder](finder) module to handle [Finders](#Finders). Appium Flutter Driver communicates with the Dart VM directory in the `FLUTTER` context. ### Doctor Since driver version 2.4.0 you can automate the validation for the most of the above requirements as well as various optional ones needed by driver extensions by running the `appium driver doctor flutter` server command. The check runs for Android for UIAutomator2 driver and iOS for XCUITest driver. `SKIP_ANDROID` or `SKIP_IOS` environment variable helps to skip these checks. ``` # skip Android check SKIP_ANDROID=1 appium driver doctor flutter # skip iOS check SKIP_IOS=1 appium driver doctor flutter ``` ### Note - Flutter context does not support page source - Please use `getRenderTree` command instead - You can send appium-xcuitest-driver/appium-uiautomator2-driver commands in `NATIVE_APP` context - `scrollUntilVisible` command : An expectation for checking that an element, known to be present on the widget tree, is visible. Using waitFor to wait element - `scrollUntilTapable` command : An expectation for checking an element is visible and enabled such that you can click it. Using waitTapable to wait element - `driver.activateApp(appId)` starts the given app and attaches to the observatory URL in the `FLUTTER` context. The method may raise an exception if no observaotry URL was found. The typical case is the `appId` is already running. Then, the driver will fail to find the observatory URL. - `getClipboard` and `setClipboard` depend on each `NATIVE_APP` context behavior - Launch via `flutter:launchApp` or 3rd party tool (via instrument service) and attach to the Dart VM for an iOS real device (profile build) 1. Do not set `app` nor `bundleId` to start a session without launching apps 2. Start the app process via 3rd party tools such as [go-ios](https://github.com/danielpaulus/go-ios) to start the app process with debug mode in the middle of the new session process in 1) the above. - Then, the appium flutter session establish the WebSocket and proceed the session - keyboard interaction may not work in Android because of https://github.com/flutter/flutter/issues/15415 that is caused by [`flutter_driver`](https://api.flutter.dev/flutter/flutter_driver/flutter_driver-library.html) ## Capabilities ### For the Appium Flutter Driver only | Capability | Description | Example Values | | - | - | -| | appium:retryBackoffTime | The interval to find the observetory url from logs. (default 3000ms)|500| | appium:maxRetryCount | The count to find the observatory url. (default 10) | 20| | appium:observatoryWsUri | The URL to attach to the Dart VM. The Appium Flutter Driver finds the WebSocket URL from the device log by default. You can skip the finding the URL process by specifying this capability. Then, this driver attempt to establish a WebSocket connection against the given WebSocket URL. Note that this capability expects the URL is ready for access by outside an appium session. This flutter driver does not do port-forwarding with this capability. You may need to coordinate the port-forwarding as well. | 'ws://127.0.0.1:60992/aaaaaaaaaaa=/ws' | | appium:isolateId | The isolate id to attach to as the initial attempt. A session can change the isolate with `flutter:setIsolateId` command. The default behavior finds `main` isolate id and attaches it. | `isolates/2978358234363215`, `2978358234363215` | | appium:skipPortForward | Whether skip port forwarding from the flutter driver local to the device under test with `observatoryWsUri` capability. It helps you to manage the application under test, the observatory URL and the port forwarding configuration. The default is `true`. | true, false | | appium:remoteAdbHost | The IP/hostname of the remote host ADB is running on. This capability only makes sense for Android platform. Providing it will implicitly override the host for the Observatory URL if the latter is determined from device logs. localhost be default | 192.168.1.20 | appium:adbPort | The port number ADB server is running on. This capability only makes sense for Android platform. 5037 by default | 9999 | appium:forwardingPort | The port number that will be used to forward the traffic from the device under test to localhost. Only applicable if `skipPortForward` is falsy. Not applicable if the test is executed on iOS Simulator. By default, it is the same as in the provided or autodetected Observatory URL. | 9999 ### UIA2/XCUITest driver Please check each driver's documentation - https://github.com/appium/appium-uiautomator2-driver - https://appium.github.io/appium-xcuitest-driver/latest/capabilities/ ## Context Management Appium Flutter Driver allows you to send [`flutter_driver`](https://api.flutter.dev/flutter/flutter_driver/flutter_driver-library.html) commands to the Dart VM in the `FLUTTER` context, but it does not support native Android/iOS since the Dart VM can handle in the Dart VM contents. `NATIVE_APP` context provides you to use the UIA2 driver for Android and the XCUITest driver for iOS automation. `WEBVIEW_XXXX` context helps WebView testing over the UIA2/XCUITest driver that is not available via the flutter_driver. Thus, you need to switch proper contexts, `FLUTTER`, `NATIVE_APP` or `WEBVIEW_XXXX`, to automate a proper application target. ### Example ```js # webdriverio const wdio = require('webdriverio'); const assert = require('assert'); const { byValueKey } = require('appium-flutter-finder'); const osSpecificOps = process.env.APPIUM_OS === 'android' ? { 'platformName': 'Android', 'appium:deviceName': 'Pixel 2', 'appium:app': __dirname + '/../apps/app-free-debug.apk', }: process.env.APPIUM_OS === 'ios' ? { 'platformName': 'iOS', 'appium:platformVersion': '12.2', 'appium:deviceName': 'iPhone X', 'appium:noReset': true, 'appium:app': __dirname + '/../apps/Runner.zip', } : {}; const opts = { port: 4723, capabilities: { ...osSpecificOps, 'appium:automationName': 'Flutter', 'appium:retryBackoffTime': 500 } }; (async () => { const counterTextFinder = byValueKey('counter'); const buttonFinder = byValueKey('increment'); const driver = await wdio.remote(opts); if (process.env.APPIUM_OS === 'android') { await driver.switchContext('NATIVE_APP'); await (await driver.$('~fab')).click(); await driver.switchContext('FLUTTER'); } else { console.log('Switching context to `NATIVE_APP` is currently only applicable to Android demo app.') } assert.strictEqual(await driver.getElementText(counterTextFinder), '0'); await driver.elementClick(buttonFinder); await driver.touchAction({ action: 'tap', element: { elementId: buttonFinder } }); assert.strictEqual(await driver.getElementText(counterTextFinder), '2'); driver.deleteSession(); })(); ``` Please check [example](example) in this repository for more languages. ## Several ways to start an application You have a couple of methods to start the application under test by establishing the Dart VM connection as below: 1. Start with `app` in the capabilities 1. The most standard method. You may need to start a new session with `app` capability. Then, appium-flutter-driver will start the app, and establish a connection with the Dart VM immediately. 2. Start with `activate_app`: for users who want to start the application under test in the middle of a session 1. Start a session without `app` capability 2. Install the application under test via `driver.install_app` or `mobile:installApp` command 3. Activate the app via `driver.activate_app` or `mobile:activateApp` command - Then, appium-flutter-driver establish a connection with the Dart VM 3. Launch the app outside the driver: for users who want to manage the application under test by yourselves 1. Start a session without `app` capability 2. Install the application under test via `driver.install_app` or `mobile:installApp` command etc 3. Calls `flutter:connectObservatoryWsUrl` command to keep finding an observatory URL to the Dart VM 4. (at the same time) Launch the application under test via outside the appium-flutter-driver - e.g. Launch an iOS process via [ios-go](https://github.com/danielpaulus/go-ios), [iproxy](https://github.com/libimobiledevice/libusbmuxd#iproxy) or [tidevice](https://github.com/alibaba/taobao-iphone-device) 5. Once `flutter:connectObservatoryWsUrl` identify the observatory URL, the command will establish a connection to the Dart VM 4. Launch the app with `flutter:launchApp` for iOS and attach to the Dart VM: for users whom application under test do not print the observatory url via regular launch/activate app method 1. Start a session without `app` capability 2. Install the application under test via `driver.install_app` or `mobile:installApp` command etc 3. Calls `flutter:launchApp` command to start an iOS app via instrument service - `driver.execute_script 'flutter:launchApp', 'com.example.bundleId', {arguments: ['arg1'], environment: {ENV1: 'env'}}` is example usage - This launching method is the same as the above 3rd party method, but does the same thing only via the appium flutter driver. Please make sure the target app process stops before starting the target app with the above. ## Changelog - [appium-flutter-driver](driver/CHANGELOG.md) - [each finder](finder) ## Commands for NATIVE_APP/WEBVIEW context Please check each driver's documentation - https://github.com/appium/appium-uiautomator2-driver - https://appium.github.io/appium-xcuitest-driver/latest ## Commands for FLUTTER context Legend: | Icon | Description | | - | - | | :white_check_mark: | integrated to CI | | :ok: | manual tested without CI | | :warning: | available without manual tested | | :x: | unavailable | ### Finders | Flutter Driver API | Status | WebDriver example | | - | - | - | | [ancestor](https://api.flutter.dev/flutter/flutter_driver/CommonFinders/ancestor.html) | :ok: | | | [bySemanticsLabel](https://api.flutter.dev/flutter/flutter_driver/CommonFinders/bySemanticsLabel.html) | :ok: | | | [byTooltip](https://api.flutter.dev/flutter/flutter_driver/CommonFinders/byTooltip.html) | :ok: | `byTooltip('Increment')` | | [byType](https://api.flutter.dev/flutter/flutter_driver/CommonFinders/byType.html) | :ok: | `byType('TextField')` | | [byValueKey](https://api.flutter.dev/flutter/flutter_driver/CommonFinders/byValueKey.html) | :ok: | [`byValueKey('counter')`](https://github.com/appium/appium-flutter-driver/blob/5df7386b59bb99008cb4cff262552c7259bb2af2/example/src/index.js#L30) | | [descendant](https://api.flutter.dev/flutter/flutter_driver/CommonFinders/descendant.html) | :ok: | | | [pageBack](https://api.flutter.dev/flutter/flutter_driver/CommonFinders/pageBack.html) | :ok: | `pageBack()` | | [text](https://api.flutter.dev/flutter/flutter_driver/CommonFinders/text.html) | :ok: | `byText('foo')` | ### Commands The below _WebDriver example_ is by webdriverio. `flutter:` prefix commands are [`mobile:` command in appium for Android and iOS](https://appium.io/docs/en/latest/guides/execute-methods/). Please replace them properly with your client. | Flutter API | Status | WebDriver example (JavaScript, webdriverio) | Scope | |------------------------------------------------------------------------------------------------------------------------------------| - | - |-------------------| | [FlutterDriver.connectedTo](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/FlutterDriver.connectedTo.html) | :ok: | [`wdio.remote(opts)`](https://github.com/appium/appium-flutter-driver/blob/5df7386b59bb99008cb4cff262552c7259bb2af2/example/src/index.js#L33) | Session | | [checkHealth](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/checkHealth.html) | :ok: | `driver.execute('flutter:checkHealth')` | Session | | clearTextbox | :ok: | `driver.elementClear(find.byType('TextField'))` | Session | | [clearTimeline](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/clearTimeline.html) | :ok: | `driver.execute('flutter:clearTimeline')` | Session | | [enterText](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/enterText.html) | :ok: | `driver.elementSendKeys(find.byType('TextField'), 'I can enter text')` (no focus required)
`driver.elementClick(find.byType('TextField')); driver.execute('flutter:enterText', 'I can enter text')` (focus required by tap/click first) | Session | | [forceGC](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/forceGC.html) | :ok: | `driver.execute('flutter:forceGC')` | Session | | [getBottomLeft](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/getBottomLeft.html) | :ok: | `driver.execute('flutter:getBottomLeft', buttonFinder)` | Widget | | [getBottomRight](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/getBottomRight.html) | :ok: | `driver.execute('flutter:getBottomRight', buttonFinder)` | Widget | | [getCenter](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/getCenter.html) | :ok: | `driver.execute('flutter:getCenter', buttonFinder)` | Widget | | [getRenderObjectDiagnostics](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/getRenderObjectDiagnostics.html) | :ok: | `driver.execute('flutter:getRenderObjectDiagnostics', counterTextFinder, { includeProperties: true, subtreeDepth: 2 })` | Widget | | [getWidgetDiagnostics](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/getWidgetDiagnostics.html) | :ok: (v2.8.0+) | `driver.execute('flutter:getWidgetDiagnostics', counterTextFinder, { includeProperties: true, subtreeDepth: 2 })` | Widget | | [getRenderTree](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/getRenderTree.html) | :ok: | `driver.execute('flutter: getRenderTree')` | Session | | [getSemanticsId](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/getSemanticsId.html) | :ok: | `driver.execute('flutter:getSemanticsId', counterTextFinder)` | Widget | | [getText](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/getText.html) | :ok: | [`driver.getElementText(counterTextFinder)`](https://github.com/appium/appium-flutter-driver/blob/5df7386b59bb99008cb4cff262552c7259bb2af2/example/src/index.js#L44) | Widget | | [getTopLeft](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/getTopLeft.html) | :ok: | `driver.execute('flutter:getTopLeft', buttonFinder)` | Widget | | [getTopRight](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/getTopRight.html) | :ok: | `driver.execute('flutter:getTopRight', buttonFinder)` | Widget | | [getVmFlags](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/getVmFlags.html) | :x: | | Session | | [requestData](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/requestData.html) | :ok: | `driver.execute('flutter:requestData', json.dumps({"deepLink": "myapp://item/id1"}))` | Session | | [runUnsynchronized](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/runUnsynchronized.html) | :x: | | Session | | [setFrameSync](https://api.flutter.dev/flutter/flutter_driver/SetFrameSync-class.html) |:ok:| `driver.execute('flutter:setFrameSync', bool , durationMilliseconds)`| Session | | [screenshot](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/screenshot.html) | :ok: | `driver.takeScreenshot()` | Session | | [screenshot](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/screenshot.html) | :ok: | `driver.saveScreenshot('a.png')` | Session | | [scroll](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/scroll.html) | :ok: | `driver.execute('flutter:scroll', find.byType('ListView'), {dx: 50, dy: -100, durationMilliseconds: 200, frequency: 30})` | Widget | | [scrollIntoView](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/scrollIntoView.html) | :ok: | `driver.execute('flutter:scrollIntoView', find.byType('TextField'), {alignment: 0.1})`
`driver.execute('flutter:scrollIntoView', find.byType('TextField'), {alignment: 0.1, timeout: 30000})` | Widget | | [scrollUntilVisible](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/scrollUntilVisible.html) | :ok: | `driver.execute('flutter:scrollUntilVisible', find.byType('ListView'), {item:find.byType('TextField'), dxScroll: 90, dyScroll: -400});`, `driver.execute('flutter:scrollUntilVisible', find.byType('ListView'), {item:find.byType('TextField'), dxScroll: 90, dyScroll: -400, waitTimeoutMilliseconds: 20000});` | Widget | | [scrollUntilTapable](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/scrollUntilVisible.html) | :ok: | `driver.execute('flutter:scrollUntilTapable', find.byType('ListView'), {item:find.byType('TextField'), dxScroll: 90, dyScroll: -400});`, `driver.execute('flutter:scrollUntilTapable', find.byType('ListView'), {item:find.byType('TextField'), dxScroll: 90, dyScroll: -400, waitTimeoutMilliseconds: 20000});` | Widget | | [setSemantics](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/setSemantics.html) | :x: | | Session | | [setTextEntryEmulation](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/setTextEntryEmulation.html) | :ok: | `driver.execute('flutter:setTextEntryEmulation', false)` | Session | | [startTracing](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/startTracing.html) | :x: | | Session | | [stopTracingAndDownloadTimeline](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/stopTracingAndDownloadTimeline.html) | :x: | | Session | | [tap](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/tap.html) | :ok: | [`driver.elementClick(buttonFinder)`](https://github.com/appium/appium-flutter-driver/blob/5df7386b59bb99008cb4cff262552c7259bb2af2/example/src/index.js#L46) | Widget | | [tap](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/tap.html) | :ok: | [`driver.touchAction({action: 'tap', element: {elementId: buttonFinder}})`](https://github.com/appium/appium-flutter-driver/blob/5df7386b59bb99008cb4cff262552c7259bb2af2/example/src/index.js#L47) | Widget | | [tap](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/tap.html) | :ok: | [`driver.execute('flutter:clickElement', buttonFinder, {timeout:5000})`](https://github.com/appium/appium-flutter-driver/blob/5df7386b59bb99008cb4cff262552c7259bb2af2/example/src/index.js#L47) | Widget | | [traceAction](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/traceAction.html) | :x: | | Session | | [waitFor](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/waitFor.html) | :ok: | `driver.execute('flutter:waitFor', buttonFinder, 100)` | Widget | | [waitForAbsent](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/waitForAbsent.html) | :ok: | `driver.execute('flutter:waitForAbsent', buttonFinder)` | Widget | | [waitForTappable](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/waitForTappable.html) | :ok: | `driver.execute('flutter:waitForTappable', buttonFinder)` | Widget | | [waitUntilNoTransientCallbacks](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/waitUntilNoTransientCallbacks.html) | :x: | | Widget | | - | :ok: | `driver.execute('flutter:getVMInfo')` | System | | - | :ok: | `driver.execute('flutter:setIsolateId', 'isolates/2978358234363215')` | System | | - | :ok: | `driver.execute('flutter:getIsolate', 'isolates/2978358234363215')` or `driver.execute('flutter:getIsolate')` | System | | :question: | :ok: | `driver.execute('flutter:longTap', find.byValueKey('increment'), {durationMilliseconds: 10000, frequency: 30})` | Widget | | :question: | :ok: | `driver.execute('flutter:waitForFirstFrame')` | Widget | | - | :ok: | (Ruby) `driver.execute_script 'flutter:connectObservatoryWsUrl'` | Flutter Driver | | - | :ok: | (Ruby) `driver.execute_script 'flutter:launchApp', 'bundleId', {arguments: ['arg1'], environment: {ENV1: 'env'}}` | Flutter Driver | | dragAndDropWithCommandExtension | :ok: | (Python) `driver.execute_script('flutter:dragAndDropWithCommandExtension', payload)` | Command Extension | # Flutter Visibility Assertions for Appium This module extends the `appium-flutter-driver` with custom visibility-related commands using `driver.execute()`. ## ✅ Supported Shortcut Commands | **Command** | **Status** | **Example Usage** | **Target** | |---------------------|------------|--------------------------------------------------------------------------------------------------------------------------|------------| | `assertVisible` | ✅ | `driver.execute('flutter:assertVisible', { key: 'myKey' })`
`driver.execute('flutter:assertVisible', { text: 'Login' })` | Widget | | `assertNotVisible` | ✅ | `driver.execute('flutter:assertNotVisible', { key: 'hiddenWidget' })` | Widget | | `assertTappable` | ✅ | `driver.execute('flutter:assertTappable', { label: 'Submit' })` | Widget | ## 🔍 Input Formats Each assertion supports the following input formats: - `{ key: 'valueKey' }` - `{ text: 'Text on widget' }` - `{ label: 'Tooltip text' }` These map to Flutter finders: - `byValueKey` - `byText` - `byTooltip` ## 📦 Integration These commands are typically invoked using a client helper method like: ```ts // TypeScript await assertVisible(driver, { key: 'submit_button' }); ``` Or as a flutter command. ```ruby # ruby driver.execute_script 'flutter:assertVisible', {text: 'Tap me!'}, 10000 # This is equivalent to text_finder = by_text 'Tap me!' driver.execute_script 'flutter:assertVisible', text_finder, 10000 # or driver.execute_script 'flutter:waitFor', text_finder, 10000 ``` **NOTE** >`flutter:launchApp` launches an app via instrument service. `mobile:activateApp` and `driver.activate_app` are via XCTest API. They are a bit different. ### `isolate` handling #### Change the flutter engine attach to 1. Get available isolate ids - `id` key in the value of `isolates` by `flutter:getVMInfo` 2. Set the id via `setIsolateId` ```ruby # ruby info = driver.execute_script 'flutter:getVMInfo' # Change the target engine to "info['isolates'][0]['id']" driver.execute_script 'flutter:setIsolateId', info['isolates'][0]['id'] ``` #### Check current isolate, or a particular isolate 1. Get available isolates - `driver.execute('flutter:getVMInfo').isolates` (JS) 2. Get a particular isolate or current isolate - Current isolate: `driver.execute('flutter:getIsolate')` (JS) - Particular isolate: `driver.execute('flutter:getIsolate', 'isolates/2978358234363215')` (JS) ## Commands across contexts These Appium commands can work across context - `deleteSession` - `setContext` - `getCurrentContext` - `getContexts` - `activateApp('appId')`/`mobile:activateApp` - `mobile:activateApp` has `skipAttachObservatoryUrl` key to not try to attach to an observatory url. e.g. `driver.execute_script 'mobile:activateApp', {skipAttachObservatoryUrl: true, appId: 'com.android.chrome'}` - `terminateApp('appId')`/`mobile:terminateApp` - `installApp(appPath, options)` - `getClipboard` - `setClipboard` ## Command Extension (Flutter Driver) This is a command extension for Flutter Driver, utilizing the [CommandExtension-class](https://api.flutter.dev/flutter/flutter_driver_extension/CommandExtension-class.html) within `ext.flutter.driver` Available commands: - `dragAndDropWithCommandExtension` – performs a drag-and-drop action on the screen by specifying the start and end coordinates and the action duration. - `getTextWithCommandExtension` - get text data from Text widget that contains TextSpan widgets. ### How to use Copy the sample dart files to the `lib` folder of your project. Please note that you don't need to copy all files, just copy the file matched with the command you need. - dragAndDropWithCommandExtension: [drag_commands.dart](./example/dart/drag_commands.dart) - getTextWithCommandExtension: [get_text_command.dart](./example/dart/get_text_command.dart) The entry point must include the `List?` commands argument in either `main.dart` or `test_main.dart` to properly handle the command extension. ```dart import 'drag_commands.dart'; import 'get_text_command.dart'; void main() { enableFlutterDriverExtension( commands: [DragCommandExtension(), GetTextCommandExtension()]); runApp(const MyApp()); } ``` #### Simple examples in Python ```python # Extended commands: flutter:dragAndDropWithCommandExtension coord_item_1 = driver.execute_script("flutter:getCenter", item_1) coord_item_2 = driver.execute_script("flutter:getCenter", item_2) start_x = coord_item_1["dx"] start_y = coord_item_1["dy"] end_y = coord_item_2["dy"] payload = { "startX": start_x, "startY": start_y, "endX": "0", "endY": end_y, "duration": "15000" # minimum 15000ms needed to drag n drop } driver.execute_script("flutter:dragAndDropWithCommandExtension", payload) # Extended commands: flutter:getTextWithCommandExtension text_finder = finder.by_value_key('amount') get_text_payload = { 'findBy': text_finder, } result = driver.execute_script('flutter:getTextWithCommandExtension', payload) print(result) ``` #### Simple examples in nodejs ```typescript // Extended commands: flutter:dragAndDropWithCommandExtension const payload = { "startX": "100", "startY": "100", "endX": "100", "endY": "600", "duration": "15000" } const result = await driver.execute("flutter:dragAndDropWithCommandExtension", payload); console.log(JSON.stringify(result)); // Extended commands: flutter:getTextWithCommandExtension import {byValueKey} from "appium-flutter-finder"; const payload = { 'findBy': byValueKey('amount'), }; const getTextResult = await driver.execute('flutter:getTextWithCommandExtension', payload); console.log(JSON.stringify(getTextResult)); ``` For debugging or testing in other programming languages, you can use the APK available in this [repository](https://github.com/Alpaca00/command-driven-list) or build an IPA. ## Troubleshooting - Input texts https://github.com/appium/appium-flutter-driver/issues/417 - Looks hanging in `click` https://github.com/appium/appium-flutter-driver/issues/181#issuecomment-1323684510 - `flutter:setFrameSync` may help - `flutter:waitFor` would help to handle "an element does not exist/is not enabled" behavior. [example issue](https://github.com/appium/appium-flutter-driver/issues/693) - Appium Inspector does not work with FLUTTER context - `enableFlutterDriverExtension()` must be called before calling `WidgetsFlutterBinding.ensureInitialized` to avoid `Binding is already initialized to WidgetsFlutterBinding` error which could cause `"ext.flutter.driver" is not found in "extensionRPCs"` error. [issue](https://github.com/appium/appium-flutter-driver/issues/756) ## TODO? - [ ] switching context between Flutter and [AndroidView](https://api.flutter.dev/flutter/widgets/AndroidView-class.html) - [ ] switching context between Flutter and [UiKitView](https://api.flutter.dev/flutter/widgets/UiKitView-class.html) - [ ] Web: `FLUTTER_WEB` context? - [ ] macOS: with https://github.com/appium/appium-mac2-driver - [ ] Windws? - [ ] Linux? ## Release appium-flutter-driver ``` $ cd driver $ sh release.sh $ npm version # update changelog $ git commit -am 'chore: bump version' $ git tag # e.g. git tag v0.0.32 $ git push origin v0.0.32 $ git push origin main $ npm publish ``` ### Java implementation - https://github.com/appium/appium-flutter-driver/tree/main/finder/kotlin via jitpack - https://github.com/ashwithpoojary98/javaflutterfinder - https://github.com/5v1988/appium-flutter-client ================================================ FILE: driver/.eslintrc.json ================================================ { "extends": ["@appium/eslint-config-appium-ts"] } ================================================ FILE: driver/.gitignore ================================================ # copy from parent dir LICENSE README.md ================================================ FILE: driver/.npmrc ================================================ package-lock=false ================================================ FILE: driver/.releaserc ================================================ { "plugins": [ ["@semantic-release/commit-analyzer", { "preset": "angular", "releaseRules": [ {"type": "chore", "release": "patch"} ] }], ["@semantic-release/release-notes-generator", { "preset": "conventionalcommits", "presetConfig": { "types": [ {"type": "feat", "section": "Features"}, {"type": "fix", "section": "Bug Fixes"}, {"type": "perf", "section": "Performance Improvements"}, {"type": "revert", "section": "Reverts"}, {"type": "chore", "section": "Miscellaneous Chores", "hidden": true}, {"type": "refactor", "section": "Code Refactoring"}, {"type": "docs", "section": "Documentation", "hidden": true}, {"type": "style", "section": "Styles", "hidden": true}, {"type": "test", "section": "Tests", "hidden": true}, {"type": "build", "section": "Build System", "hidden": true}, {"type": "ci", "section": "Continuous Integration", "hidden": true} ] } }], ["@semantic-release/changelog", { "changelogFile": "CHANGELOG.md" }], "@semantic-release/npm", ["@semantic-release/git", { "assets": ["npm-shrinkwrap.json", "package.json", "CHANGELOG.md"], "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" }], "@semantic-release/github" ] } ================================================ FILE: driver/CHANGELOG.md ================================================ # Changelog ## 3.6.0 - Update Appium XCUITest driver dependency to 10.43.1 - Update Appium UIAutomator2 driver dependency to 7.1.2 ## 3.5.0 - Update Appium XCUITest driver dependency to 10.22.0 - Update Appium UIAutomator2 driver dependency to 6.8.2 - Apply formatter ## 3.4.0 - Update Appium XCUITest driver dependency to 10.18.2 - Update Appium UIAutomator2 driver dependency to 6.7.15 - Update asyncbox to 6.0.1 ## 3.3.0 - Update Appium XCUITest driver dependency to 10.11.0 - Update Appium UIAutomator2 driver dependency to 6.7.1 ## 3.2.0 - Fix log finding retry handling - Update Appium XCUITest driver dependency to 10.4.3 - Update Appium UIAutomator2 driver dependency to 6.1.0 ## 3.1.0 - Update Appium UIAutomator2 driver dependency to 6.0.2 ## 3.0.1 - Fix types - Update Appium XCUITest driver dependency to 10.0.1 - Update Appium UIAutomator2 driver dependency to 5.0.3 ## 3.0.0 - Update Appium UIAutomator2 driver dependency to 5.0.0 - Update Appium XCUITest driver dependency to 10.0.0 - Follow Appium 3 - Required Node.js version has been bumped to ^20.19.0 || ^22.12.0 || >=24.0.0 - Required npm version has been bumped to >=10 - Requires **Appium 3.0.0+** ## 2.19.0 - Update Appium UIAutomator2 driver dependency to 4.2.9 - Update Appium XCUITest driver dependency to 9.10.5 ## 2.18.1/2.18.0 - Update Appium UIAutomator2 driver dependency to 4.2.4 - Update Appium XCUITest driver dependency to 9.9.1 - Supports `appium driver run flutter download-wda-sim` command. It requires NodeJS 20+. ## 2.17.0 - Fix ending forwarding port with `forwardingPort` capability on iOS with `terminateApp` - Update Appium XCUITest driver dependency to 9.6.1 ## 2.16.0 - Added shortcut commands below. Please check the README about the usage. - `flutter:assertVisible` - `flutter:assertNotVisible` - `flutter:assertTappable` - Update Appium XCUITest driver dependency to 9.2.5 ## 2.15.2 - Fix device orientation change for iOS - Update Appium XCUITest driver dependency to 9.2.4 ## 2.15.1 - Add a retry logic to check `ext.flutter.driver` module existence ## 2.15.0 - Update Appium UIAutomator2 driver dependency to 4.2.3 - Update Appium XCUITest driver dependency to 9.2.3 ## 2.14.2 - Fix package to include npm-shrinkwrap.json explicitly - Update Appium UIAutomator2 driver dependency to 4.1.1 - Update Appium XCUITest driver dependency to 8.4.1 ## 2.14.1 - Fix lint ## 2.14.0 - Update Appium UIAutomator2 driver dependency to 4.0.3 - Update Appium XCUITest driver dependency to 8.3.2 ## 2.13.0 - Update Appium XCUITest driver dependency to 8.1.0 ## 2.12.0 - Update Appium UIAutomator2 driver dependency to 3.10.0 - Update Appium XCUITest driver dependency to 7.35.1 ## 2.11.0 - Adds `flutter:getTextWithCommandExtension` command. Please check the README about how to use the command properly. - Update Appium UIAutomator2 driver dependency to 3.9.1 - Update Appium XCUITest driver dependency to 7.32.0 ## 2.10.0 - Adds `flutter:dragAndDropWithCommandExtension` command. Please check the README about how to use the command properly. - Update Appium UIAutomator2 driver dependency to 3.8.1 - Update Appium XCUITest driver dependency to 7.28.3 ## 2.9.2 - Fix observatory url finding after an app activation - Bring `appium:maxRetryCount` and `appium:retryBackoffTime` back to use for the observaotry url findings. ## 2.9.0 (2.9.1) - Tune syslog scanning to find the observatory url - Drop `appium:maxRetryCount` and `appium:retryBackoffTime` as no usage - Update Appium UIAutomation2 driver dependency to 3.7.4 - Update XCUITest driver dependency to 7.24.1 ## 2.8.0 - Support `getWidgetDiagnostics` ## 2.7.1 - add logs around set context ## 2.7.0 - Update Appium UIAutomation2 driver dependency to 3.5.4 - Update Appium XCUITest driver dependency to 7.17.5 ## 2.6.0 - Update Appium XCUITest driver dependency to 7.11.1 - `doctor` command can skip Android or iOS with environment variables ## 2.5.1 - fix: scroll until visible + scroll until tapable [#671](https://github.com/appium/appium-flutter-driver/pull/671) ## 2.5.0 - Update Appium XCUITest driver dependency to 6.0.1 ## 2.4.2 - Removed unused dependencies ## 2.4.1 - Removed unused dependencies ## 2.4.0 - Update Appium UIAutomation2 driver dependency to 2.42.1 - Update Appium XCUITest driver dependency to 5.14.0 - Add `doctor` command ## 2.3.0 - Update Appium UIAutomation2 driver dependency to 2.37.0 - Update Appium XCUITest driver dependency to 5.12.1 ## 2.2.3 - fix leftover portforward ## 2.2.2 - fix: scrollUntilVisible and scrollUntilTapable https://github.com/appium/appium-flutter-driver/pull/622 ## 2.2.1 - fix: typescript syntaxes ## 2.2.0 - Update Appium UIAutomation2 driver dependency to 2.34.1 - Update Appium XCUITest driver dependency to 5.7.0 ## 2.1.0 - Update Appium XCUITest driver dependency to 5.6.0 ## 2.0.0 - Update Appium XCUITest driver dependency to 5.2.0. It supports iOS 15+. ## 1.23.0 - try the latest observatory url every attempt in connectSocket ## 1.22.0 - `skipAttachObservatoryUrl` option for `mobile:activateApp` to prevent trying to attach to an observatory url after activating the app. ## 1.21.1 - `appium:maxRetryCount` is 10 by default as optimization ## 1.21.0 - Add `isolateId` capability to configure it ## 1.20.2 (1.20.0, 1.20.1 had broken lock file) - Add `adbPort`, `remoteAdbHost` and `forwardingPort` support ## 1.19.1 - Use XCUITest driver: 4.31.0 - Last iOS 14 and lower one work version ## 1.19.0 - Add `flutter:launchApp` to start an app via instrument service natively for iOS ## 1.18.1 - Keep using XCUITest driver v4.27.0 for iOS versions lower than 15. ## 1.18.0 - Add `flutter:connectObservatoryWsUrl` command to observe the url in the middle ## 1.17.1 - Make `mobile:activateApp` and `mobile:terminateApp` behavior same as `activateApp` and `terminateApp` ## 1.17.0 - Proxy device orientation api to NATIVE_APP context ## 1.16.0 - Update dependencies - UIA2 driver: 2.29.2 - XCUITest driver: 4.32.19 - Added `clickElement` as execute script. It is the same as other `tap` commands - Update `peerDependencies` as Appium 2.0 ## 1.15.0 - Update dependencies such as UIA2/XCUITest drivers ## 1.14.4 - Fix element parsing for w3c element ## 1.14.2, 1.14.3 (the same) - Add debug log when an exception occurred in the observatory url finding ## 1.14.1 - Bump the UIA2 version ## 1.14.0 - Fix proxyCommand for plugins [#425](https://github.com/appium-userland/appium-flutter-driver/pull/425) - Fix startNewCommandTimeout call [#426](https://github.com/appium-userland/appium-flutter-driver/pull/426) ## 1.13.1 - Fix no `waitTimeoutMilliseconds` argument case for scrollUntilVisible/scrollUntilTapable ## 1.13.0 - Add arguments in scrollUntilVisible/scrollUntilTapable - `waitTimeoutMilliseconds`: The timeout to try scroll up to the timeout - `durationMilliseconds`: The duration to do a scroll action. `timeout` in [scroll](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/scroll.html). - `frequency`: The frequency to for the move events in [scroll](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/scroll.html). ## 1.12.0 - Support `setClipboard` and `getClipboard` by always proxying the request to the NATIVE_APP context - Support non-`app` and non-`bundleId` nor non-`appPackage` session starts as `FLUTTER` context - Add `installApp` to install the test target after the new session request ## 1.11.0 - Add `activateApp` support to start an app ## 1.10.0 - Add `terminateApp` support to stop the running application - The behavior is the same as when you call the same endpoint in NATIVE_APP context ## 1.9.1 - Improved error message when no observatory url found ## 1.9.0 - **Breaking change** - Revert [#306](https://github.com/appium-userland/appium-flutter-driver/pull/306) (added in v1.5.0). `scrollUntilVisible` uses `waitFor` as same as before v1.5.0. - Please use `scrollUntilTapable` instead since this version - Added `scrollUntilTapable` command to scroll with `waitForTappable` [#360](https://github.com/appium-userland/appium-flutter-driver/pull/360) ## 1.8.0 Appium `2.0.0-beta.46` and higher is needed as dependencies update in dependent Appium UIA2/XCUITest drivers - Added `timeout` argument for scrollIntoView [#358](https://github.com/appium-userland/appium-flutter-driver/pull/358) - Added `skipPortForward` capability [#343](https://github.com/appium-userland/appium-flutter-driver/pull/343) ## 1.7.2 (1.7.1) - Fixed `* 1000` in `scroll` [#330](https://github.com/appium-userland/appium-flutter-driver/pull/330) ## 1.7.0 - **Breaking change** - Do not calculate `* 1000` internally for milliseconds arguments to set them properly as same as README/examples. [#319](https://github.com/appium-userland/appium-flutter-driver/issues/319) ## 1.6.0 - Update for newer Appium 2 beta ## 1.5.0 - Use `waitForTappable` in `scrollUntilVisible` [#306](https://github.com/appium-userland/appium-flutter-driver/pull/306) ## 1.4.0 - Added `flutter:getIsolate` to get the isolate information [#298](https://github.com/appium-userland/appium-flutter-driver/pull/298) ## 1.3.0 - Added `flutter:getVMInfo` and `flutter:setIsolateId` commands to allow a session to switch the target isolate id [#292](https://github.com/appium-userland/appium-flutter-driver/pull/292) ## 1.2.0 - Added `waitForTappable` [#289](https://github.com/appium-userland/appium-flutter-driver/pull/289) ## 1.1.2 (1.1.1) - Fixed checking observatory URL every trial [#287](https://github.com/appium-userland/appium-flutter-driver/pull/287) ## 1.1.0 - Support processLogToGetobservatory for Flutter >= 3.0.0 [#283](https://github.com/appium-userland/appium-flutter-driver/pull/283) ================================================ FILE: driver/eslint.config.mjs ================================================ import appiumConfig from '@appium/eslint-config-appium-ts'; export default [ ...appiumConfig ]; ================================================ FILE: driver/lib/commands/assertions.ts ================================================ import {FlutterDriver} from '../driver'; import {byValueKey, byText, byTooltip} from 'appium-flutter-finder'; import type {SerializableFinder} from 'appium-flutter-finder'; export type FinderInput = | {key: string} | {text: string} | {label: string} | SerializableFinder | string | {getRawFinder: () => SerializableFinder}; // FlutterElement-like input // Serialize a finder to base64 const serializeFinder = (finder: SerializableFinder): string => Buffer.from(JSON.stringify(finder)).toString('base64'); // Type guards const isRawFinder = (input: any): input is SerializableFinder => input && typeof input === 'object' && typeof input.finderType === 'string'; const isFlutterElementLike = (input: any): input is {getRawFinder: () => SerializableFinder} => input && typeof input === 'object' && typeof input.getRawFinder === 'function'; // Convert FinderInput to base64 string function getFinderBase64(input: FinderInput): string { if (typeof input === 'string') { return input; // already base64 } if (isFlutterElementLike(input)) { return serializeFinder(input.getRawFinder()); } if (isRawFinder(input)) { return serializeFinder(input); } if ('key' in input) { return byValueKey(input.key); } if ('text' in input) { return byText(input.text); } if ('label' in input) { return byTooltip(input.label); } throw new Error( 'Invalid finder input: must provide key, text, label, raw finder, or FlutterElement', ); } // Generic helper to wrap assert commands async function executeAssertion( driver: FlutterDriver, command: string, input: FinderInput, timeout = 5000, extraArgs: object = {}, ): Promise { const base64 = getFinderBase64(input); try { await driver.executeElementCommand(command, base64, { timeout, ...extraArgs, }); } catch (err) { throw new Error(`Assertion failed on command "${command}" within ${timeout}ms\n${err}`); } } // Exported assertion commands export const assertVisible = async ( driver: FlutterDriver, input: FinderInput, timeout = 5000, ): Promise => await executeAssertion(driver, 'waitFor', input, timeout, {visible: true}); export const assertNotVisible = async ( driver: FlutterDriver, input: FinderInput, timeout = 5000, ): Promise => await executeAssertion(driver, 'waitForAbsent', input, timeout); export const assertTappable = async ( driver: FlutterDriver, input: FinderInput, timeout = 5000, ): Promise => await executeAssertion(driver, 'waitForTappable', input, timeout); ================================================ FILE: driver/lib/commands/clipboard.ts ================================================ import type {FlutterDriver} from '../driver'; /** * Set clipboard content via each native app driver * @param this the FlutterDriver * @param content the content to get the clipboard * @param contentType the contentType to set the data type */ export const setClipboard = async function ( this: FlutterDriver, content: string, contentType: string, ) { // @ts-expect-error this exist in xcuitestdriver or uia2 driver await this.proxydriver?.setClipboard(content, contentType); }; /** * Get the clipboard content via each native app driver * @param this the FlutterDriver * @param contentType the contentType to set the data type */ export const getClipboard = async function (this: FlutterDriver, contentType: string) { // @ts-expect-error this exist in xcuitestdriver or uia2 driver await this.proxydriver?.getClipboard(contentType); }; ================================================ FILE: driver/lib/commands/context.ts ================================================ import type {FlutterDriver} from '../driver'; import {log} from '../logger'; export const FLUTTER_CONTEXT_NAME = `FLUTTER`; export const NATIVE_CONTEXT_NAME = `NATIVE_APP`; export const getCurrentContext = async function (this: FlutterDriver): Promise { return this.currentContext; }; export const setContext = async function (this: FlutterDriver, context: string) { if ([FLUTTER_CONTEXT_NAME, NATIVE_CONTEXT_NAME].includes(context)) { this.proxyWebViewActive = false; // Set 'native context' when flutter driver sets the context to FLUTTER_CONTEXT_NAME if (this.proxydriver) { log.debug( `Setting downstream drier context to '${NATIVE_CONTEXT_NAME}' in context '${context}'.`, ); // @ts-expect-error this exist in xcuitestdriver or uia2 driver await this.proxydriver.setContext(NATIVE_CONTEXT_NAME); } } else { // this case may be 'webview' if (this.proxydriver) { log.debug(`Setting downstream drier context to '${context}'.`); // @ts-expect-error this exist in xcuitestdriver or uia2 driver await this.proxydriver.setContext(context); this.proxyWebViewActive = true; } } this.currentContext = context; if (context === FLUTTER_CONTEXT_NAME) { log.debug( `Downstream driver context is set as 'NATIVE_APP' in 'FLUTTER' context to handle the native app.`, ); } }; export const getContexts = async function (this: FlutterDriver): Promise { // @ts-expect-error this exist in xcuitestdriver or uia2 driver const nativeContext = await this.proxydriver?.getContexts(); if (nativeContext) { return [...(nativeContext as string[]), FLUTTER_CONTEXT_NAME]; } else { return [FLUTTER_CONTEXT_NAME]; } }; export const driverShouldDoProxyCmd = function (this: FlutterDriver, command: string): boolean { if (!this.proxydriver) { return false; } if (this.currentContext === FLUTTER_CONTEXT_NAME) { return false; } if ([`getCurrentContext`, `setContext`, `getContexts`].includes(command)) { return false; } return true; }; ================================================ FILE: driver/lib/commands/element.ts ================================================ import {FlutterDriver} from '../driver'; export const getText = async function (this: FlutterDriver, el: string): Promise { const response = await this.executeElementCommand(`get_text`, el); return response.text; }; export const setValue = async function ( this: FlutterDriver, textInput: string | [string], el: string, ) { const clickPromise = this.click(el); // acquire focus let text = ``; if (textInput instanceof Array) { text = textInput.reduce((previousValue, currentValue) => `${previousValue}${currentValue}`); } else if (typeof textInput === `string`) { text = textInput; } else { throw new Error(`Invalid textInput: ${textInput}`); } await clickPromise; await this.execute(`flutter:enterText`, [text]); }; export const clear = async function (this: FlutterDriver, el: string) { await this.setValue([``], el); }; ================================================ FILE: driver/lib/commands/execute/scroll.ts ================================================ import _ from 'lodash'; import {FlutterDriver} from '../../driver'; import {waitFor, waitForTappable} from './wait'; export const scroll = async ( self: FlutterDriver, elementBase64: string, opts: { dx: number; dy: number; durationMilliseconds: number; frequency?: number; }, ) => { const {dx, dy, durationMilliseconds, frequency = 60} = opts; if ( typeof dx !== `number` || typeof dy !== `number` || typeof durationMilliseconds !== `number` || typeof frequency !== `number` ) { // @todo BaseDriver's errors.InvalidArgumentError(); throw new Error(`${opts} is not a valid options`); } if (dx === 0 && dy === 0) { // @todo BaseDriver's errors.InvalidArgumentError(); throw new Error(`${opts} is not a valid options`); } return await self.executeElementCommand(`scroll`, elementBase64, { dx, dy, // 'scroll' expects microseconds // https://github.com/flutter/flutter/blob/master/packages/flutter_driver/lib/src/common/gesture.dart#L33-L38 duration: durationMilliseconds * 1000, frequency, }); }; export const longTap = async ( self: FlutterDriver, elementBase64: string, options: { durationMilliseconds: number; frequency?: number; }, ) => { const {durationMilliseconds = 1000, frequency = 60} = options; if (typeof durationMilliseconds !== 'number' || typeof frequency !== 'number') { throw new Error(`Invalid longTap options: ${JSON.stringify(options)}`); } return await self.executeElementCommand('scroll', elementBase64, { dx: 0, dy: 0, duration: durationMilliseconds * 1000, frequency, }); }; const validateOps = (alignment: any, dxScroll: any, dyScroll: any): boolean => { if ( typeof alignment !== `number` || typeof dxScroll !== `number` || typeof dyScroll !== `number` ) { return false; } if (dxScroll === 0 && dyScroll === 0) { return false; } return true; }; const shouldRetry = (startAt: number, waitTimeoutMilliseconds?: number): boolean => { if (!waitTimeoutMilliseconds) { // Then, the scroll should continue infinitely return true; } return Date.now() - startAt < _.toInteger(waitTimeoutMilliseconds); }; export const scrollUntilVisible = async ( self: FlutterDriver, elementBase64: string, opts: { item: string; alignment: number; dxScroll: number; dyScroll: number; durationMilliseconds: number; frequency?: number; waitTimeoutMilliseconds?: number; }, ) => { const { item, alignment = 0.0, dxScroll = 0, dyScroll = 0, durationMilliseconds = 100, frequency, waitTimeoutMilliseconds, } = opts; if (!validateOps(alignment, dxScroll, dyScroll)) { throw new Error(`${opts} is not a valid options`); } // An expectation for checking that an element, known to be present on the widget tree, is visible let isVisible = false; (async () => { try { await waitFor(self, item, waitTimeoutMilliseconds); isVisible = true; } catch {} })(); const startAt = Date.now(); while (!isVisible && shouldRetry(startAt, waitTimeoutMilliseconds)) { try { await scroll(self, elementBase64, { dx: dxScroll, dy: dyScroll, durationMilliseconds, frequency, }); } catch { /* go to the next scroll */ } } if (!isVisible) { throw new Error(`Stop scrolling as timeout ${waitTimeoutMilliseconds}`); } return scrollIntoView(self, item, {alignment}); }; export const scrollUntilTapable = async ( self: FlutterDriver, elementBase64: string, opts: { item: string; alignment: number; dxScroll: number; dyScroll: number; durationMilliseconds: number; frequency?: number; waitTimeoutMilliseconds?: number; }, ) => { const { item, alignment = 0.0, dxScroll = 0, dyScroll = 0, durationMilliseconds = 100, frequency, waitTimeoutMilliseconds, } = opts; if (!validateOps(alignment, dxScroll, dyScroll)) { throw new Error(`${opts} is not a valid options`); } // Kick off an (unawaited) waitForTappable that will complete when the item we're // looking for finally scrolls onscreen and can be hit-tested. We add an initial pause to give it // the chance to complete if the item is already onscreen; if not, scroll // repeatedly until we either find the item or time out. let isVisible = false; (async () => { try { await waitForTappable(self, item, waitTimeoutMilliseconds); isVisible = true; } catch {} })(); const startAt = Date.now(); while (!isVisible && shouldRetry(startAt, waitTimeoutMilliseconds)) { try { await scroll(self, elementBase64, { dx: dxScroll, dy: dyScroll, durationMilliseconds, frequency, }); } catch { /* go to the next scroll */ } } if (!isVisible) { throw new Error(`Stop scrolling as timeout ${waitTimeoutMilliseconds}`); } return scrollIntoView(self, item, {alignment}); }; export const scrollIntoView = async ( self: FlutterDriver, elementBase64: string, opts: { alignment: number; timeout?: number; }, ) => { const {alignment = 0.0, timeout} = opts; if ( typeof alignment !== `number` || (typeof timeout !== `undefined` && typeof timeout !== `number`) ) { // @todo BaseDriver's errors.InvalidArgumentError(); throw new Error(`${opts} is not a valid options`); } const args = typeof timeout === `number` ? {alignment, timeout} : {alignment}; return await self.executeElementCommand(`scrollIntoView`, elementBase64, args); }; ================================================ FILE: driver/lib/commands/execute/wait.ts ================================================ import {FlutterDriver} from '../../driver'; const waitForConstructor = (command: `waitForAbsent` | `waitFor` | `waitForTappable`) => async ( self: FlutterDriver, elementBase64: string, durationMilliseconds?: number, ): Promise => { let args = {}; if (typeof durationMilliseconds === `number`) { args = { timeout: durationMilliseconds, }; } else if (typeof durationMilliseconds !== `undefined`) { // @todo BaseDriver's errors.InvalidArgumentError(); throw new Error(`durationMilliseconds is not a valid options`); } await self.executeElementCommand(command, elementBase64, args); return elementBase64; }; export const waitForAbsent = waitForConstructor(`waitForAbsent`); export const waitFor = waitForConstructor(`waitFor`); export const waitForTappable = waitForConstructor(`waitForTappable`); ================================================ FILE: driver/lib/commands/execute.ts ================================================ /* eslint-disable @typescript-eslint/no-non-null-assertion */ import type {FlutterDriver} from '../driver'; import {reConnectFlutterDriver} from '../sessions/session'; import { longTap, scroll, scrollIntoView, scrollUntilVisible, scrollUntilTapable, } from './execute/scroll'; import {waitFor, waitForAbsent, waitForTappable} from './execute/wait'; import {assertVisible, assertNotVisible, assertTappable, type FinderInput} from './assertions'; import {launchApp} from './../ios/app'; import B from 'bluebird'; const flutterCommandRegex = /^[\s]*flutter[\s]*:(.+)/; // Define types for better type safety type CommandHandler = (driver: FlutterDriver, ...args: any[]) => Promise; type CommandMap = Record; interface DragAndDropParams { startX: string; startY: string; endX: string; endY: string; duration: string; } interface DiagnosticsOptions { subtreeDepth?: number; includeProperties?: boolean; } interface LongTapOptions { durationMilliseconds: number; frequency?: number; } interface OffsetOptions { offsetType: 'bottomLeft' | 'bottomRight' | 'center' | 'topLeft' | 'topRight'; } // Extract command handlers into a separate object for better organization const commandHandlers: CommandMap = { launchApp: async (driver, appId: string, opts = {}) => { const {arguments: args = [], environment: env = {}} = opts; await launchApp(driver.internalCaps.udid!, appId, args, env); await reConnectFlutterDriver.bind(driver)(driver.internalCaps); }, connectObservatoryWsUrl: async (driver) => { await reConnectFlutterDriver.bind(driver)(driver.internalCaps); }, checkHealth: async (driver) => (await driver.executeElementCommand('get_health')).status, getVMInfo: async (driver) => await driver.executeGetVMCommand(), getRenderTree: async (driver) => (await driver.executeElementCommand('get_render_tree')).tree, getOffset: async (driver, elementBase64: string, options: OffsetOptions) => await driver.executeElementCommand('get_offset', elementBase64, options), waitForCondition: async (driver, conditionName: string) => await driver.executeElementCommand('waitForCondition', '', { conditionName, }), forceGC: async (driver) => { const response = (await driver.socket!.call('_collectAllGarbage', { isolateId: driver.socket!.isolateId, })) as {type: string}; if (response.type !== 'Success') { throw new Error(`Could not forceGC, response was ${JSON.stringify(response)}`); } }, setIsolateId: async (driver, isolateId: string) => { driver.socket!.isolateId = isolateId; return await driver.socket!.call('getIsolate', {isolateId}); }, getIsolate: async (driver, isolateId?: string) => await driver.executeGetIsolateCommand(isolateId || driver.socket!.isolateId!), clearTimeline: async (driver) => { const call1 = driver.socket!.call('_clearVMTimeline'); const call2 = driver.socket!.call('clearVMTimeline'); const response = await B.any([call1, call2]); if (response.type !== 'Success') { throw new Error(`Could not clear timeline, response was ${JSON.stringify(response)}`); } }, getRenderObjectDiagnostics: async ( driver, elementBase64: string, opts: DiagnosticsOptions = {}, ) => { const {subtreeDepth = 0, includeProperties = true} = opts; return await driver.executeElementCommand('get_diagnostics_tree', elementBase64, { diagnosticsType: 'renderObject', includeProperties, subtreeDepth, }); }, getWidgetDiagnostics: async (driver, elementBase64: string, opts: DiagnosticsOptions = {}) => { const {subtreeDepth = 0, includeProperties = true} = opts; return await driver.executeElementCommand('get_diagnostics_tree', elementBase64, { diagnosticsType: 'widget', includeProperties, subtreeDepth, }); }, getSemanticsId: async (driver, elementBase64: string) => (await driver.executeElementCommand('get_semantics_id', elementBase64)).id, waitForAbsent: async (driver, finder: string, timeout?: number) => await waitForAbsent(driver, finder, timeout), waitFor: async (driver, finder: string, timeout?: number) => await waitFor(driver, finder, timeout), waitForTappable: async (driver, finder: string, timeout?: number) => await waitForTappable(driver, finder, timeout), scroll: async (driver, finder: string, opts: any) => await scroll(driver, finder, opts), scrollUntilVisible: async (driver, finder: string, opts: any) => await scrollUntilVisible(driver, finder, opts), scrollUntilTapable: async (driver, finder: string, opts: any) => await scrollUntilTapable(driver, finder, opts), scrollIntoView: async (driver, finder: string, opts: any) => await scrollIntoView(driver, finder, opts), setTextEntryEmulation: async (driver, enabled: boolean) => await driver.socket!.executeSocketCommand({ command: 'set_text_entry_emulation', enabled, }), enterText: async (driver, text: string) => await driver.socket!.executeSocketCommand({command: 'enter_text', text}), requestData: async (driver, message: string) => await driver.socket!.executeSocketCommand({ command: 'request_data', message, }), longTap: async (driver, finder: string, durationOrOptions: LongTapOptions) => await longTap(driver, finder, durationOrOptions), waitForFirstFrame: async (driver) => await driver.executeElementCommand('waitForCondition', '', { conditionName: 'FirstFrameRasterizedCondition', }), setFrameSync: async (driver, enabled: boolean, durationMilliseconds: number) => await driver.socket!.executeSocketCommand({ command: 'set_frame_sync', enabled, timeout: durationMilliseconds, }), clickElement: async (driver, finder: string, opts: {timeout?: number} = {}) => { const {timeout = 1000} = opts; return await driver.executeElementCommand('tap', finder, {timeout}); }, dragAndDropWithCommandExtension: async (driver, params: DragAndDropParams) => await driver.socket!.executeSocketCommand({ command: 'dragAndDropWithCommandExtension', ...params, }), assertVisible: async (driver, input: FinderInput, timeout = 5000) => await assertVisible(driver, input, timeout), assertNotVisible: async (driver, input: FinderInput, timeout = 5000) => await assertNotVisible(driver, input, timeout), assertTappable: async (driver, input: FinderInput, timeout = 5000) => await assertTappable(driver, input, timeout), getTextWithCommandExtension: async (driver, params: {findBy: string}) => await driver.socket!.executeSocketCommand({ command: 'getTextWithCommandExtension', findBy: params.findBy, }), }; export const execute = async function (this: FlutterDriver, rawCommand: string, args: any[]) { const matching = rawCommand.match(flutterCommandRegex); if (!matching) { throw new Error(`Command not supported: "${rawCommand}"`); } const command = matching[1].trim(); const handler = commandHandlers[command]; if (!handler) { throw new Error(`Command not supported: "${rawCommand}"`); } return await handler(this, ...args); }; ================================================ FILE: driver/lib/commands/gesture.ts ================================================ import type {FlutterDriver} from '../driver'; import {longTap as longClick} from './execute/scroll'; export const click = async function (this: FlutterDriver, el: string) { const retVal = await this.tapEl(el, false); return retVal; }; export const tapEl = async function (this: FlutterDriver, el: string, longPress: boolean) { // perform a tap on the given element // if longPress is true, the tap becomes a longPress action const commandName = longPress ? `longPress` : `tap`; return await this.executeElementCommand(commandName, el); }; export const tap = async function ( this: FlutterDriver, gestures: Record[], longPress: boolean, ) { // parse the given gestures array to call the appropriate tap method // if longPress is true, the tap is a long press action const elementId = gestures[0].options.element; await this.tapEl(elementId, longPress); }; export const longTap = async function ( this: FlutterDriver, gestures: Record[], ms: number, ) { // pass duration if the wait action given by user. // If wait action is missing taking 10000 ms default const elementId = gestures[0].options.element; return await longClick(this, elementId, { durationMilliseconds: ms, frequency: 30, }); }; export const performTouch = async function (this: FlutterDriver, gestures: Record[]) { if (gestures.length === 3) { if ( gestures[0].action === `longPress` && gestures[1].action === `wait` && gestures[2].action === `release` ) { return await this.longTap(gestures, gestures[1].options.ms); } } else if (gestures.length === 2) { if (gestures[0].action === `press` && gestures[1].action === `release`) { return await this.tap(gestures, false); } else if (gestures[0].action === `longPress` && gestures[1].action === `release`) { return await this.longTap(gestures, 10 * 1000); } } else if (gestures.length === 1) { if (gestures[0].action === `tap`) { return await this.tap(gestures, false); } if (gestures[0].action === `longPress`) { return await this.longTap(gestures, 10 * 1000); } } }; ================================================ FILE: driver/lib/commands/screen.ts ================================================ import type {FlutterDriver} from '../driver'; import {IsolateSocket} from '../sessions/isolate_socket'; export const getScreenshot = async function (this: FlutterDriver) { const response = (await (this.socket as IsolateSocket).call(`_flutter.screenshot`)) as any; return response.screenshot; }; ================================================ FILE: driver/lib/desired-caps.ts ================================================ export const desiredCapConstraints = { app: { isString: true, }, avd: { isString: true, }, maxRetryCount: { isNumber: true, }, platformName: { inclusionCaseInsensitive: ['iOS', 'Android'], isString: true, presence: true, }, retryBackoffTime: { isNumber: true, }, udid: { isString: true, }, observatoryWsUri: { isString: true, }, skipPortForward: { isBoolean: true, }, adbPort: { isNumber: true, }, remoteAdbHost: { isString: true, }, forwardingPort: { isNumber: true, }, } as const; ================================================ FILE: driver/lib/doctor/checks.js ================================================ import {doctor as androidDoctor} from 'appium-android-driver'; import {doctor as iosDoctor} from 'appium-xcuitest-driver'; // shared export const homeEnvVarCheck = /** @type {any} */ (iosDoctor.required.homeEnvVarCheck); let androidHomeCheck; let javaHomeCheck; let javaHomeValueCheck; let androidSdkCheck; let optionalBundletoolCheck; let optionalGstreamerCheck; if (!process.env.SKIP_ANDROID) { androidHomeCheck = androidDoctor.androidHomeCheck; javaHomeCheck = androidDoctor.javaHomeCheck; javaHomeValueCheck = androidDoctor.javaHomeValueCheck; androidSdkCheck = androidDoctor.androidSdkCheck; optionalBundletoolCheck = androidDoctor.optionalBundletoolCheck; optionalGstreamerCheck = androidDoctor.optionalGstreamerCheck; } let xcodeCheck; let xcodeToolsCheck; let envVarAndPathCheck; let optionalApplesimutilsCommandCheck; if (!process.env.SKIP_IOS) { xcodeCheck = iosDoctor.required.xcodeCheck; xcodeToolsCheck = iosDoctor.required.xcodeToolsCheck; envVarAndPathCheck = /** @type {any} */ (iosDoctor.required.homeEnvVarCheck); optionalApplesimutilsCommandCheck = iosDoctor.optional.optionalApplesimutilsCheck; } // shared export const optionalFfmpegCheck = androidDoctor.optionalFfmpegCheck; export { androidHomeCheck, javaHomeCheck, javaHomeValueCheck, androidSdkCheck, optionalBundletoolCheck, optionalGstreamerCheck, xcodeCheck, xcodeToolsCheck, envVarAndPathCheck, optionalApplesimutilsCommandCheck, }; ================================================ FILE: driver/lib/driver.ts ================================================ // @ts-ignore: no 'errors' export module import _ from 'lodash'; import {BaseDriver} from 'appium/driver'; import {log as logger} from './logger'; import { executeElementCommand, executeGetVMCommand, executeGetIsolateCommand, } from './sessions/observatory'; import {PLATFORM} from './platform'; import {createSession, reConnectFlutterDriver} from './sessions/session'; import { driverShouldDoProxyCmd, FLUTTER_CONTEXT_NAME, getContexts, getCurrentContext, NATIVE_CONTEXT_NAME, setContext, } from './commands/context'; import {clear, getText, setValue} from './commands/element'; import {execute} from './commands/execute'; import {click, longTap, performTouch, tap, tapEl} from './commands/gesture'; import {getScreenshot} from './commands/screen'; import {getClipboard, setClipboard} from './commands/clipboard'; import {desiredCapConstraints} from './desired-caps'; import {XCUITestDriver} from 'appium-xcuitest-driver'; import {AndroidUiautomator2Driver} from 'appium-uiautomator2-driver'; import type { DefaultCreateSessionResult, DriverCaps, DriverData, W3CDriverCaps, RouteMatcher, Orientation, } from '@appium/types'; import type {IsolateSocket} from './sessions/isolate_socket'; import type {Server} from 'node:net'; import type {LogMonitor} from './sessions/log-monitor'; type FluttertDriverConstraints = typeof desiredCapConstraints; // Need to not proxy in WebView context const WEBVIEW_NO_PROXY = [ [`GET`, new RegExp(`^/session/[^/]+/appium`)], [`GET`, new RegExp(`^/session/[^/]+/context`)], [`GET`, new RegExp(`^/session/[^/]+/element/[^/]+/rect`)], [`GET`, new RegExp(`^/session/[^/]+/log/types$`)], [`GET`, new RegExp(`^/session/[^/]+/orientation`)], [`POST`, new RegExp(`^/session/[^/]+/appium`)], [`POST`, new RegExp(`^/session/[^/]+/context`)], [`POST`, new RegExp(`^/session/[^/]+/log$`)], [`POST`, new RegExp(`^/session/[^/]+/orientation`)], [`POST`, new RegExp(`^/session/[^/]+/touch/multi/perform`)], [`POST`, new RegExp(`^/session/[^/]+/touch/perform`)], ] as import('@appium/types').RouteMatcher[]; class FlutterDriver extends BaseDriver { public socket: IsolateSocket | null; public locatorStrategies = [`key`, `css selector`]; public proxydriver: XCUITestDriver | AndroidUiautomator2Driver | null; public device: any; public portForwardLocalPort: string | null; public localServer: Server | null; protected _logmon: LogMonitor | null; // Used to keep the capabilities internally public internalCaps: DriverCaps; public receiveAsyncResponse: (...args: any[]) => Promise; // to handle WebView context public proxyWebViewActive = false; // session public executeElementCommand = executeElementCommand; public executeGetVMCommand = executeGetVMCommand; public executeGetIsolateCommand = executeGetIsolateCommand; public execute = execute; public executeAsync = execute; // element public getText = getText; public setValue = setValue; public clear = clear; public getScreenshot = getScreenshot; // gesture public click = click; public longTap = longTap; public tapEl = tapEl; public tap = tap; public performTouch = performTouch; // context public getContexts = getContexts; public getCurrentContext = getCurrentContext; public setContext = setContext; protected currentContext = FLUTTER_CONTEXT_NAME; private driverShouldDoProxyCmd = driverShouldDoProxyCmd; // content public getClipboard = getClipboard; public setClipboard = setClipboard; constructor(opts, shouldValidateCaps: boolean) { super(opts, shouldValidateCaps); this.socket = null; this.device = null; this._logmon = null; this.desiredCapConstraints = desiredCapConstraints; // Used to keep the port for port forward to clear the pair. this.portForwardLocalPort = null; // Used for iOS to end the local server to proxy the request. this.localServer = null; } public async createSession( ...args ): Promise> { const [sessionId, caps] = await super.createSession( ...(JSON.parse(JSON.stringify(args)) as [ W3CDriverCaps, W3CDriverCaps, W3CDriverCaps, DriverData[], ]), ); this.internalCaps = caps; return createSession.bind(this)(sessionId, caps, ...JSON.parse(JSON.stringify(args))); } public async deleteSession() { this.log.info(`Deleting Flutter Driver session`); this._logmon?.stop(); this._logmon = null; this.proxydriver?.eventEmitter?.removeAllListeners('syslogStarted'); this.log.info('Cleanup the port forward'); switch (_.toLower(this.internalCaps.platformName)) { case PLATFORM.IOS: this.localServer?.close(); this.localServer = null; break; case PLATFORM.ANDROID: if (this.portForwardLocalPort) { if (this.proxydriver) { await (this.proxydriver as AndroidUiautomator2Driver).adb?.removePortForward( this.portForwardLocalPort, ); } } break; } if (this.proxydriver) { this.log.info('Deleting the proxy driver session.'); try { await this.proxydriver.deleteSession(this.sessionId || undefined); } catch (e) { this.log.warn(e.message); } this.proxydriver = null; } await super.deleteSession(); } public async installApp(appPath: string, opts = {}) { // @ts-expect-error this exist in xcuitestdriver or uia2 driver this.proxydriver?.installApp(appPath, opts); } public async activateApp(appId: string) { // @ts-expect-error this exist in xcuitestdriver or uia2 driver this.proxydriver?.activateApp(appId); await reConnectFlutterDriver.bind(this)(this.internalCaps); } public async terminateApp(appId: string) { // @ts-expect-error this exist in xcuitestdriver or uia2 driver return await this.proxydriver?.terminateApp(appId); } public async back() { // @ts-expect-error this exist in xcuitestdriver or uia2 driver return await this.proxydriver?.back(); } public async getOrientation(): Promise { if (!this.proxydriver) { return null; } switch (_.toLower(this.internalCaps.platformName)) { case PLATFORM.IOS: return await (this.proxydriver as XCUITestDriver).proxyCommand('/orientation', 'GET'); default: return await (this.proxydriver as AndroidUiautomator2Driver).getOrientation(); } } public async setOrientation(orientation: string) { switch (_.toLower(this.internalCaps.platformName)) { case PLATFORM.IOS: return await (this.proxydriver as XCUITestDriver).proxyCommand('/orientation', 'POST', { orientation, }); default: return await (this.proxydriver as AndroidUiautomator2Driver).setOrientation( orientation as Orientation, ); } } public validateLocatorStrategy(strategy: string) { // @todo refactor DRY if (this.currentContext === `NATIVE_APP`) { return this.proxydriver?.validateLocatorStrategy(strategy); } super.validateLocatorStrategy(strategy, false); } validateDesiredCaps( caps: DriverCaps, ): caps is DriverCaps { // check with the base class, and return if it fails const res = super.validateDesiredCaps(caps); if (!res) { return res; } // finally, return true since the superclass check passed, as did this return true; } public async proxyCommand(url: string, method: string, body = null) { // @ts-expect-error this exist in xcuitestdriver or uia2 driver const result = await this.proxydriver?.proxyCommand(url, method, body); return result; } public async executeCommand( cmd: string, ...args: [string, [{skipAttachObservatoryUrl: string; any: any}]] ) { if (new RegExp(/^[\s]*mobile:[\s]*activateApp$/).test(args[0])) { const {skipAttachObservatoryUrl = false} = args[1][0]; await this.proxydriver?.executeCommand(cmd, ...args); if (skipAttachObservatoryUrl) { return; } await reConnectFlutterDriver.bind(this)(this.internalCaps); return; } else if (new RegExp(/^[\s]*mobile:[\s]*terminateApp$/).test(args[0])) { // to make the behavior as same as this.terminateApp return await this.proxydriver?.executeCommand(cmd, ...args); } else if (cmd === `receiveAsyncResponse`) { logger.debug(`Executing FlutterDriver response '${cmd}'`); return await this.receiveAsyncResponse(...args); } else if ([`setOrientation`, `getOrientation`, `back`].includes(cmd)) { // The `setOrientation` and `getOrientation` commands are handled differently // for iOS and Android platforms. These commands are deferred to the base driver's // implementation (`super.executeCommand`) to ensure compatibility with both platforms // and to leverage the platform-specific logic already implemented in the base driver. logger.debug(`Executing FlutterDriver command '${cmd}'`); return await super.executeCommand(cmd, ...args); } else { if (this.driverShouldDoProxyCmd(cmd)) { logger.debug(`Executing proxied driver command '${cmd}'`); // There are 2 CommandTimeout (FlutterDriver and proxy) // Only FlutterDriver CommandTimeout is used; Proxy is disabled // All proxy commands needs to reset the FlutterDriver CommandTimeout // Here we manually reset the FlutterDriver CommandTimeout for commands that goes to proxy. this.clearNewCommandTimeout(); const result = await this.proxydriver?.executeCommand(cmd, ...args); this.startNewCommandTimeout(); return result; } else { logger.debug(`Executing Flutter driver command '${cmd}'`); return await super.executeCommand(cmd, ...args); } } } public getProxyAvoidList(): RouteMatcher[] { if ([FLUTTER_CONTEXT_NAME, NATIVE_CONTEXT_NAME].includes(this.currentContext)) { return []; } return WEBVIEW_NO_PROXY; } public proxyActive(): boolean { // In WebView context, all request should got to each driver // so that they can handle http request properly. // On iOS, WebView context is handled by XCUITest driver while Android is by chromedriver. // It means XCUITest driver should keep the XCUITest driver as a proxy, // while UIAutomator2 driver should proxy to chromedriver instead of UIA2 proxy. return this.proxyWebViewActive && this.proxydriver?.constructor.name !== XCUITestDriver.name; } public canProxy(): boolean { // As same as proxyActive, all request should got to each driver // so that they can handle http request properly return this.proxyWebViewActive; } } export {FlutterDriver}; ================================================ FILE: driver/lib/ios/app.ts ================================================ import {services, INSTRUMENT_CHANNEL} from 'appium-ios-device'; import {log} from './../logger'; /** * Launch the given bundle id via instrument service. */ export const launchApp = async ( udid: string, bundleId: string, args = [], env = {}, ): Promise => { let instrumentService; try { instrumentService = await services.startInstrumentService(udid); log.info( `Launching app ${bundleId} with arguments ${JSON.stringify(args)} and env ${JSON.stringify(env)} on device ${udid}`, ); await instrumentService.callChannel( INSTRUMENT_CHANNEL.PROCESS_CONTROL, 'launchSuspendedProcessWithDevicePath:bundleIdentifier:environment:arguments:options:', '', bundleId, env, args, {StartSuspendedKey: 0, KillExisting: 1}, ); return true; } catch (err) { log.warn(`Failed to launch '${bundleId}'. Original error: ${err.stderr || err.message}`); return false; } finally { if (instrumentService) { instrumentService.close(); } } }; ================================================ FILE: driver/lib/logger.ts ================================================ import {logger} from '@appium/support'; import {AppiumLogger} from '@appium/types'; export const log: AppiumLogger = logger.getLogger(`FlutterDriver`); ================================================ FILE: driver/lib/platform.ts ================================================ export const PLATFORM = { IOS: 'ios', ANDROID: 'android', } as const; ================================================ FILE: driver/lib/sessions/android.ts ================================================ import {AndroidUiautomator2Driver} from 'appium-uiautomator2-driver'; import {connectSocket, extractObservatoryUrl, OBSERVATORY_URL_PATTERN} from './observatory'; import type {InitialOpts, StringRecord} from '@appium/types'; import type {IsolateSocket} from './isolate_socket'; import {FlutterDriver} from '../driver'; import {LogMonitor} from './log-monitor'; import type {LogEntry} from './log-monitor'; export async function startAndroidSession( this: FlutterDriver, caps: Record, ...args: any[] ): Promise<[AndroidUiautomator2Driver, IsolateSocket | null]> { this.log.info(`Starting an Android proxy session`); const androiddriver = new AndroidUiautomator2Driver({} as InitialOpts); if (!caps.observatoryWsUri) { androiddriver.eventEmitter.once('syslogStarted', (syslog) => { this._logmon = new LogMonitor(syslog, async (entry: LogEntry) => { if (extractObservatoryUrl(entry)) { this.log.debug(`Matched the syslog line '${entry.message}'`); return true; } return false; }); this._logmon.start(); }); } //@ts-ignore Args are ok await androiddriver.createSession(...args); // the session starts without any apps if (caps.app === undefined && caps.appPackage === undefined) { return [androiddriver, null]; } return [androiddriver, await connectAndroidSession.bind(this)(androiddriver, caps)]; } export async function connectAndroidSession( this: FlutterDriver, androiddriver: AndroidUiautomator2Driver, caps: Record, clearLog: boolean = false, ): Promise { const observatoryWsUri = await getObservatoryWsUri.bind(this)(androiddriver, caps, clearLog); return await connectSocket.bind(this)(observatoryWsUri, caps); } export async function getObservatoryWsUri( this: FlutterDriver, proxydriver: AndroidUiautomator2Driver, caps: StringRecord, clearLog: boolean = false, ): Promise { if (clearLog) { this._logmon?.clearlastMatch(); this._logmon?.stop(); this._logmon?.start(); } let urlObject: URL; if (caps.observatoryWsUri) { urlObject = new URL(caps.observatoryWsUri); urlObject.protocol = `ws`; // defaults to skip the port-forwarding as backward compatibility if (caps.skipPortForward === undefined || caps.skipPortForward) { return urlObject.toJSON(); } } else { if (!this._logmon) { throw new Error( `The mandatory logcat service must be running in order to initialize the Flutter driver. ` + `Have you disabled it in capabilities?`, ); } let lastMatch: LogEntry | null = null; try { lastMatch = await this._logmon.waitForLastMatchExist( caps.maxRetryCount, caps.retryBackoffTime, ); } catch (e) { this.log.error(e); } if (!lastMatch) { throw new Error( `No observatory URL matching to '${OBSERVATORY_URL_PATTERN}' was found in the device log. ` + `Please make sure the application under test is configured properly according to ` + `https://github.com/appium/appium-flutter-driver#usage and that it does not crash on startup.`, ); } urlObject = extractObservatoryUrl(lastMatch) as URL; } const remotePort = urlObject.port; this.portForwardLocalPort = caps.forwardingPort ?? remotePort; urlObject.port = this.portForwardLocalPort as string; await proxydriver.adb.forwardPort(this.portForwardLocalPort as string, remotePort); if (!caps.observatoryWsUri && proxydriver.adb.adbHost) { urlObject.host = proxydriver.adb.adbHost; } return urlObject.toJSON(); } ================================================ FILE: driver/lib/sessions/base64url.ts ================================================ import _ from 'lodash'; import {util} from '@appium/support'; export const decode = ( input: string | {ELEMENT: string} | {[util.W3C_WEB_ELEMENT_IDENTIFIER]: string}, ): string => { let base64String: string = ``; if (_.isString(input)) { base64String = input as string; } else if (_.has(input, util.W3C_WEB_ELEMENT_IDENTIFIER)) { base64String = input[util.W3C_WEB_ELEMENT_IDENTIFIER] as string; } else if (_.has(input, 'ELEMENT')) { // @ts-ignore TS2339 base64String = input.ELEMENT as string; } else { throw new Error( `Input is expected to be a base64-encoded string or a valid element object. ` + `${JSON.stringify(input)} has been provided instead`, ); } return Buffer.from(base64String, `base64`).toString(); }; ================================================ FILE: driver/lib/sessions/ios.ts ================================================ import {utilities} from 'appium-ios-device'; import {XCUITestDriver} from 'appium-xcuitest-driver'; import B from 'bluebird'; import net from 'node:net'; import {checkPortStatus} from 'portscanner'; import {connectSocket, extractObservatoryUrl, OBSERVATORY_URL_PATTERN} from './observatory'; import type {IsolateSocket} from './isolate_socket'; import {LogMonitor} from './log-monitor'; import type {LogEntry} from './log-monitor'; import type {FlutterDriver} from '../driver'; import type {XCUITestDriverOpts} from 'appium-xcuitest-driver/build/lib/driver'; const LOCALHOST = `127.0.0.1`; export async function startIOSSession( this: FlutterDriver, caps: Record, ...args: any[] ): Promise<[XCUITestDriver, IsolateSocket | null]> { this.log.info(`Starting an IOS proxy session`); const iosdriver = new XCUITestDriver({} as XCUITestDriverOpts); if (!caps.observatoryWsUri) { iosdriver.eventEmitter.once('syslogStarted', (syslog) => { this._logmon = new LogMonitor(syslog, async (entry: LogEntry) => { if (extractObservatoryUrl(entry)) { this.log.debug(`Matched the syslog line '${entry.message}'`); return true; } return false; }); this._logmon.start(); }); } // @ts-expect-error can be ignored await iosdriver.createSession(...args); // the session starts without any apps if (caps.app === undefined && caps.bundleId === undefined) { return [iosdriver, null]; } return [iosdriver, await connectIOSSession.bind(this)(iosdriver, caps)]; } export async function connectIOSSession( this: FlutterDriver, iosdriver: XCUITestDriver, caps: Record, clearLog: boolean = false, ): Promise { const observatoryWsUri = await getObservatoryWsUri.bind(this)(iosdriver, caps, clearLog); return await connectSocket.bind(this)(observatoryWsUri, iosdriver, caps); } async function requireFreePort(this: FlutterDriver, port: number) { // Try to close existing local server if it exists if (this.localServer) { this.log.info(`Closing existing local server on port ${port}`); await new Promise((resolve) => { this.localServer?.close((err) => { if (err) { this.log.error(`Error occurred while closing the local server: ${err.message}`); return resolve(); // Resolve even if there's an error to avoid hanging } this.log.info(`Previous local server closed`); resolve(); }); }); } if ((await checkPortStatus(port, LOCALHOST)) !== `open`) { return; } this.log.warn(`Port #${port} is busy. Did you quit the previous driver session(s) properly?`); throw new Error( `The port :${port} is occupied by an other process. ` + `You can either quit that process or select another free port.`, ); } export async function getObservatoryWsUri( this: FlutterDriver, proxydriver: XCUITestDriver, caps: Record, clearLog: boolean = false, ): Promise { if (clearLog) { this._logmon?.clearlastMatch(); this._logmon?.stop(); this._logmon?.start(); } let urlObject; if (caps.observatoryWsUri) { urlObject = new URL(caps.observatoryWsUri); urlObject.protocol = `ws`; // defaults to skip the port-forwarding as backward compatibility if (caps.skipPortForward === undefined || caps.skipPortForward) { return urlObject.toJSON(); } } else { if (!this._logmon) { throw new Error( `The mandatory syslog service must be running in order to initialize the Flutter driver. ` + `Have you disabled it in capabilities?`, ); } let lastMatch: LogEntry | null = null; try { lastMatch = await this._logmon.waitForLastMatchExist( caps.maxRetryCount, caps.retryBackoffTime, ); } catch (e) { this.log.error(e); } if (!lastMatch) { throw new Error( `No observatory URL matching to '${OBSERVATORY_URL_PATTERN}' was found in the device log. ` + `Please make sure the application under test is configured properly according to ` + `https://github.com/appium/appium-flutter-driver#usage and that it does not crash on startup.`, ); } urlObject = extractObservatoryUrl(lastMatch) as URL; } if (!proxydriver.isRealDevice()) { this.log.info(`Running on iOS simulator`); return urlObject.toJSON(); } const remotePort = urlObject.port; const localPort = caps.forwardingPort ?? remotePort; urlObject.port = localPort; this.log.info(`Running on iOS real device`); const {udid} = proxydriver.opts; await requireFreePort.bind(this)(localPort); this.localServer = net.createServer(async (localSocket) => { let remoteSocket; try { remoteSocket = await utilities.connectPort(udid, remotePort); } catch { localSocket.destroy(); return; } const destroyCommChannel = () => { remoteSocket.unpipe(localSocket); localSocket.unpipe(remoteSocket); }; remoteSocket.once(`close`, () => { destroyCommChannel(); localSocket.destroy(); }); remoteSocket.on('error', (e) => this.log.debug(e)); localSocket.once(`end`, destroyCommChannel); localSocket.once(`close`, () => { destroyCommChannel(); remoteSocket.destroy(); }); localSocket.on('error', (e) => this.log.warn(e.message)); localSocket.pipe(remoteSocket); remoteSocket.pipe(localSocket); }); const listeningPromise = new B((resolve, reject) => { this.localServer?.once(`listening`, resolve); this.localServer?.once(`error`, reject); }); this.localServer?.listen(localPort); try { await listeningPromise; } catch (e) { this.localServer = null; throw new Error(`Cannot listen on the local port ${localPort}. Original error: ${e.message}`); } this.log.info(`Forwarding the remote port ${remotePort} to the local port ${localPort}`); process.on(`beforeExit`, () => { this.localServer?.close(); this.localServer = null; }); return urlObject.toJSON(); } ================================================ FILE: driver/lib/sessions/isolate_socket.ts ================================================ import {Client} from 'rpc-websockets'; interface ExecuteArgs { command: string; [key: string]: any; } export class IsolateSocket extends Client { public isolateId: number | string = 0; public async executeSocketCommand(args: ExecuteArgs) { // call an RPC method with parameters return this.call(`ext.flutter.driver`, { ...args, isolateId: this.isolateId, }) as Promise<{ isError: boolean; response: any; }>; } } ================================================ FILE: driver/lib/sessions/log-monitor.ts ================================================ import type {EventEmitter} from 'node:events'; import {retryInterval} from 'asyncbox'; export interface LogEntry { timestamp: number; level: string; message: string; } const DEFAULT_MAX_RETRY_COUNT = 10; const DEFAULT_BACKOFF_TIME_MS = 3000; export type Filter = (x: LogEntry) => Promise; export class LogMonitor { private readonly _logsEmitter: EventEmitter; private readonly _filter: Filter; private _lastMatch: LogEntry | null; private _outputListener: ((logEntry: LogEntry) => any) | null; constructor(logsEmitter: EventEmitter, filter: Filter) { this._logsEmitter = logsEmitter; this._outputListener = null; this._filter = filter; this._lastMatch = null; } get started(): boolean { return Boolean(this._outputListener); } clearlastMatch() { this._lastMatch = null; } get lastMatch(): LogEntry | null { return this._lastMatch; } async waitForLastMatchExist( maxRetryCount: number = DEFAULT_MAX_RETRY_COUNT, retryBackoffTime: number = DEFAULT_BACKOFF_TIME_MS, ): Promise { return await retryInterval(maxRetryCount, retryBackoffTime, async () => { if (this._lastMatch !== null) { return this._lastMatch; } throw new Error( `No matched log found with ${retryBackoffTime} ms interval ` + `up to ${maxRetryCount} times. Increasing appium:retryBackoffTime ` + `and appium:maxRetryCount would help.`, ); }); } start(): this { if (this.started) { return this; } this._outputListener = this._onOutput.bind(this); // eslint-disable-next-line @typescript-eslint/no-non-null-assertion this._logsEmitter.on('output', this._outputListener!); return this; } stop(): this { if (!this.started) { return this; } // eslint-disable-next-line @typescript-eslint/no-non-null-assertion this._logsEmitter.off('output', this._outputListener!); this._outputListener = null; return this; } private async _onOutput(logEntry: LogEntry): Promise { if (await this._filter(logEntry)) { this._lastMatch = logEntry; } } } ================================================ FILE: driver/lib/sessions/observatory.ts ================================================ import {URL} from 'node:url'; import _ from 'lodash'; import type {FlutterDriver} from '../driver'; import {IsolateSocket} from './isolate_socket'; import {decode} from './base64url'; import type {LogEntry} from './log-monitor'; import {retryInterval} from 'asyncbox'; const truncateLength = 500; // https://github.com/flutter/flutter/blob/f90b019c68edf4541a4c8273865a2b40c2c01eb3/dev/devicelab/lib/framework/runner.dart#L183 // e.g. 'Observatory listening on http://127.0.0.1:52817/_w_SwaKs9-g=/' // https://github.com/flutter/flutter/blob/52ae102f182afaa0524d0d01d21b2d86d15a11dc/packages/flutter_tools/lib/src/resident_runner.dart#L1386-L1389 // e.g. 'An Observatory debugger and profiler on ${device.device.name} is available at: http://127.0.0.1:52817/_w_SwaKs9-g=/' export const OBSERVATORY_URL_PATTERN = new RegExp( `(Observatory listening on |` + `An Observatory debugger and profiler on\\s.+\\sis available at: |` + `The Dart VM service is listening on )` + `((http|//)[a-zA-Z0-9:/=_\\-.\\[\\]]+)`, ); const moduleCheckIntervalCount = 30; const moduleCheckIntervalMs = 500; // SOCKETS export async function connectSocket( this: FlutterDriver, dartObservatoryURL: string, caps: Record, ): Promise { const isolateId = caps.isolateId; this.log.debug(`Establishing a connection to the Dart Observatory`); const connectedPromise = new Promise((resolve) => { const socket = new IsolateSocket(dartObservatoryURL); const removeListenerAndResolve = (r: IsolateSocket | null) => { socket.removeListener(`error`, onErrorListener); socket.removeListener(`timeout`, onTimeoutListener); socket.removeListener(`open`, onOpenListener); resolve(r); }; // Add an 'error' event handler for the client socket const onErrorListener = (ex: Error) => { this.log.error(`Connection to ${dartObservatoryURL} got an error: ${ex.message}`); removeListenerAndResolve(null); }; socket.on(`error`, onErrorListener); // Add a 'close' event handler for the client socket socket.on(`close`, () => { this.log.info(`Connection to ${dartObservatoryURL} closed`); // @todo do we need to set this.socket = null? }); // Add a 'timeout' event handler for the client socket const onTimeoutListener = () => { this.log.error(`Connection to ${dartObservatoryURL} timed out`); removeListenerAndResolve(null); }; socket.on(`timeout`, onTimeoutListener); const onOpenListener = async () => { const originalSocketCall = socket.call; socket.call = async (...args: any) => { try { // `await` is needed so that rejected promise will be thrown and caught return await originalSocketCall.apply(socket, args); } catch (e) { this.log.errorWithException(new Error(JSON.stringify(e))); } }; this.log.info(`Connecting to Dart Observatory: ${dartObservatoryURL}`); if (isolateId) { this.log.info(`Listing the given isolate id: ${isolateId}`); socket.isolateId = isolateId; } else { const vm = (await socket.call(`getVM`)) as { isolates: [ { name: string; id: number; }, ]; }; this.log.info(`Listing all isolates: ${JSON.stringify(vm.isolates)}`); // To accept 'main.dart:main()' and 'main' const mainIsolateData = vm.isolates.find((e) => e.name.includes(`main`)); if (!mainIsolateData) { this.log.error(`Cannot get Dart main isolate info`); removeListenerAndResolve(null); socket.close(); return; } // e.g. 'isolates/2978358234363215', '2978358234363215' socket.isolateId = mainIsolateData.id; } // It could take time to load the expected module. try { await retryInterval(moduleCheckIntervalCount, moduleCheckIntervalMs, async () => { const isolate = (await socket.call(`getIsolate`, { isolateId: `${socket.isolateId}`, })) as { extensionRPCs: [string] | null; } | null; if (!isolate) { throw new Error(`Cannot get main Dart Isolate`); } if (!Array.isArray(isolate.extensionRPCs)) { throw new Error( `Cannot get Dart extensionRPCs from isolate ${JSON.stringify(isolate)}`, ); } if (isolate.extensionRPCs.indexOf(`ext.flutter.driver`) < 0) { throw new Error( `"ext.flutter.driver" is not found in "extensionRPCs" ${JSON.stringify(isolate.extensionRPCs)}`, ); } }); } catch (e) { this.log.error(e.message); removeListenerAndResolve(null); return; } removeListenerAndResolve(socket); }; socket.on(`open`, onOpenListener); }); const connectedSocket = await connectedPromise; if (connectedSocket) { return connectedSocket; } throw new Error( `Cannot connect to the Dart Observatory URL ${dartObservatoryURL}. ` + `Check the server log for more details`, ); } export async function executeGetIsolateCommand(this: FlutterDriver, isolateId: string | number) { this.log.debug(`>>> getIsolate`); const isolate = await (this.socket as IsolateSocket).call(`getIsolate`, { isolateId: `${isolateId}`, }); this.log.debug(`<<< ${_.truncate(JSON.stringify(isolate), {length: truncateLength})}`); return isolate; } export async function executeGetVMCommand(this: FlutterDriver) { this.log.debug(`>>> getVM`); const vm = (await (this.socket as IsolateSocket).call(`getVM`)) as { isolates: [ { name: string; id: number; }, ]; }; this.log.debug(`<<< ${_.truncate(JSON.stringify(vm), {length: truncateLength})}`); return vm; } export async function executeElementCommand( this: FlutterDriver, command: string, elementBase64?: string, extraArgs = {}, ) { const elementObject = elementBase64 ? JSON.parse(decode(elementBase64)) : {}; const serializedCommand = {command, ...elementObject, ...extraArgs}; this.log.debug(`>>> ${JSON.stringify(serializedCommand)}`); const data = await (this.socket as IsolateSocket).executeSocketCommand(serializedCommand); this.log.debug(`<<< ${JSON.stringify(data)} | previous command ${command}`); if (data.isError) { throw new Error( `Cannot execute command ${command}, server response ${JSON.stringify(data, null, 2)}`, ); } return data.response; } export function extractObservatoryUrl(logEntry: LogEntry): URL | null { const match = logEntry.message.match(OBSERVATORY_URL_PATTERN); if (!match) { return null; } try { const result = new URL(match[2]); result.protocol = `ws`; result.pathname += `ws`; return result; } catch { return null; } } ================================================ FILE: driver/lib/sessions/session.ts ================================================ import type {FlutterDriver} from '../driver'; import _ from 'lodash'; import {startAndroidSession, connectAndroidSession} from './android'; import {startIOSSession, connectIOSSession} from './ios'; import {PLATFORM} from '../platform'; import type {XCUITestDriver} from 'appium-xcuitest-driver'; import type {AndroidUiautomator2Driver} from 'appium-uiautomator2-driver'; export const reConnectFlutterDriver = async function ( this: FlutterDriver, caps: Record, ) { // setup proxies - if platformName is not empty, make it less case sensitive if (!caps.platformName) { this.log.errorWithException(new Error(`No platformName was given`)); } switch (_.toLower(caps.platformName)) { case PLATFORM.IOS: this.socket = await connectIOSSession.bind(this)(this.proxydriver, caps, true); break; case PLATFORM.ANDROID: this.socket = await connectAndroidSession.bind(this)(this.proxydriver, caps, true); break; default: this.log.errorWithException( new Error( `Unsupported platformName: ${caps.platformName}. ` + `Only the following platforms are supported: ${_.keys(PLATFORM)}`, ), ); } }; export const createSession: any = async function ( this: FlutterDriver, sessionId: string, caps, ...args ) { try { // setup proxies - if platformName is not empty, make it less case sensitive switch (_.toLower(caps.platformName)) { case PLATFORM.IOS: [this.proxydriver, this.socket] = await startIOSSession.bind(this)(caps, ...args); (this.proxydriver as XCUITestDriver).relaxedSecurityEnabled = this.relaxedSecurityEnabled; (this.proxydriver as XCUITestDriver).denyInsecure = this.denyInsecure; (this.proxydriver as XCUITestDriver).allowInsecure = this.allowInsecure; break; case PLATFORM.ANDROID: [this.proxydriver, this.socket] = await startAndroidSession.bind(this)(caps, ...args); (this.proxydriver as AndroidUiautomator2Driver).relaxedSecurityEnabled = this.relaxedSecurityEnabled; (this.proxydriver as AndroidUiautomator2Driver).denyInsecure = this.denyInsecure; (this.proxydriver as AndroidUiautomator2Driver).allowInsecure = this.allowInsecure; break; default: this.log.errorWithException( new Error( `Unsupported platformName: ${caps.platformName}. ` + `Only the following platforms are supported: ${_.keys(PLATFORM)}`, ), ); } return [sessionId, this.opts]; } catch (e) { await this.deleteSession(); throw e; } }; ================================================ FILE: driver/npm-shrinkwrap.json ================================================ { "name": "appium-flutter-driver", "version": "3.6.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "appium-flutter-driver", "version": "3.6.0", "license": "MIT", "dependencies": { "appium-android-driver": "^13.0.0", "appium-flutter-finder": "^0.2.0", "appium-ios-device": "^3.0.0", "appium-uiautomator2-driver": "^7.0.0", "appium-xcuitest-driver": "^10.0.0", "asyncbox": "^6.0.1", "bluebird": "^3.1.1", "lodash": "^4.0.0", "portscanner": "^2.2.0", "rpc-websockets": "^10.0.0" }, "devDependencies": { "@appium/eslint-config-appium-ts": "^3.0.0", "@appium/tsconfig": "^1.0.0", "@appium/types": "^1.0.0", "@semantic-release/changelog": "^6.0.3", "@semantic-release/git": "^10.0.1", "prettier": "^3.0.0", "semantic-release": "^25.0.2", "ts-node": "^10.9.1", "typescript": "~5.9" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" }, "peerDependencies": { "appium": "^3.0.0" } }, "node_modules/@appium/base-driver": { "version": "10.3.0", "resolved": "https://registry.npmjs.org/@appium/base-driver/-/base-driver-10.3.0.tgz", "integrity": "sha512-9r+1f9EtcJt9NXIlyHdFMoD7DsAZPzpRq4Kj1hGZf7+26q1SFEyyMAuWxvlWGY7EoyPtPRyMUkM4dHiSK3Q9+w==", "license": "Apache-2.0", "dependencies": { "@appium/support": "7.1.0", "@appium/types": "1.3.0", "@colors/colors": "1.6.0", "async-lock": "1.4.1", "asyncbox": "6.1.0", "axios": "1.15.0", "bluebird": "3.7.2", "body-parser": "2.2.2", "express": "5.2.1", "fastest-levenshtein": "1.0.16", "http-status-codes": "2.3.0", "lodash": "4.18.1", "lru-cache": "11.3.3", "method-override": "3.0.0", "morgan": "1.10.1", "path-to-regexp": "8.4.2", "serve-favicon": "2.5.1", "type-fest": "5.5.0" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" }, "optionalDependencies": { "spdy": "4.0.2" } }, "node_modules/@appium/logger": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@appium/logger/-/logger-2.0.6.tgz", "integrity": "sha512-9e8n9CtINBwi1ASEU5OyswmR2F7OnbrGfmf9yTy9i+rx4GR9RJlEp0/arsxvuyWCep67tOmM4FiRyXxxHjOK5Q==", "license": "ISC", "dependencies": { "console-control-strings": "1.1.0", "lodash": "4.18.1", "lru-cache": "11.3.3", "set-blocking": "2.0.0" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" } }, "node_modules/@appium/schema": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@appium/schema/-/schema-1.1.0.tgz", "integrity": "sha512-m0vTLU7mhC9RR294Nz84g+FhEQ0iZKq6p3rfz1+qfEqCXRXUvDbllSOu2tCVpBKMIoEFZAmkwjuwXobJpCnilQ==", "license": "Apache-2.0", "dependencies": { "json-schema": "0.4.0" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" } }, "node_modules/@appium/support": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/@appium/support/-/support-7.1.0.tgz", "integrity": "sha512-kY4Qv4TzLCYmZnN2eNptEa8RiRzpbimIQ6tKuDaqLC2Y3q5Al4NumL/xRQAvfXJq/hNezq2Jh8NwciEW8zX/0g==", "license": "Apache-2.0", "dependencies": { "@appium/logger": "2.0.6", "@appium/tsconfig": "1.1.2", "@appium/types": "1.3.0", "@colors/colors": "1.6.0", "archiver": "7.0.1", "asyncbox": "6.1.0", "axios": "1.15.0", "base64-stream": "1.0.0", "bluebird": "3.7.2", "bplist-creator": "0.1.1", "bplist-parser": "0.3.2", "form-data": "4.0.5", "get-stream": "9.0.1", "glob": "13.0.6", "jsftp": "2.1.3", "klaw": "4.1.0", "lockfile": "1.0.4", "lodash": "4.18.1", "log-symbols": "7.0.1", "ncp": "2.0.0", "package-directory": "8.2.0", "plist": "3.1.0", "pluralize": "8.0.0", "read-pkg": "10.1.0", "resolve-from": "5.0.0", "sanitize-filename": "1.6.4", "semver": "7.7.4", "shell-quote": "1.8.3", "supports-color": "10.2.2", "teen_process": "4.1.0", "type-fest": "5.5.0", "uuid": "13.0.0", "which": "6.0.1", "yauzl": "3.3.0" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" }, "optionalDependencies": { "sharp": "0.34.5" } }, "node_modules/@appium/tsconfig": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@appium/tsconfig/-/tsconfig-1.1.2.tgz", "integrity": "sha512-lHKBm7hXCROc1Ha/cBxS4o3iQkeY96Pz7qM9Uh9vFDkdpTGBk56V1lmc3iGcgBYKBlaRT/LZmTsqClvHoiXhvw==", "license": "Apache-2.0", "dependencies": { "@tsconfig/node20": "20.1.9" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" } }, "node_modules/@appium/types": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@appium/types/-/types-1.3.0.tgz", "integrity": "sha512-Gv4ev/5K5N7TvAHqem2DmB50zipC951QlmCDpuxDNHQl2dtCr20vJgnN8if7upqLcBX/6yNp3udR+f1n99zgcQ==", "license": "Apache-2.0", "dependencies": { "@appium/logger": "2.0.6", "@appium/schema": "1.1.0", "@appium/tsconfig": "1.1.2", "type-fest": "5.5.0" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" } }, "node_modules/@babel/code-frame": { "version": "7.29.0", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", "license": "MIT", "dependencies": { "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { "version": "7.28.5", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@colors/colors": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==", "license": "MIT", "engines": { "node": ">=0.1.90" } }, "node_modules/@img/colour": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", "license": "MIT", "optional": true, "engines": { "node": ">=18" } }, "node_modules/@img/sharp-darwin-arm64": { "version": "0.34.5", "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz", "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==", "cpu": [ "arm64" ], "license": "Apache-2.0", "optional": true, "os": [ "darwin" ], "engines": { "node": "^18.17.0 || ^20.3.0 || >=21.0.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.2.4" } }, "node_modules/@img/sharp-libvips-darwin-arm64": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz", "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==", "cpu": [ "arm64" ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ "darwin" ], "funding": { "url": "https://opencollective.com/libvips" } }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", "license": "ISC", "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", "strip-ansi": "^7.0.1", "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", "wrap-ansi": "^8.1.0", "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" }, "engines": { "node": ">=12" } }, "node_modules/@isaacs/cliui/node_modules/ansi-styles": { "version": "6.2.3", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", "license": "MIT", "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/@isaacs/cliui/node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "license": "MIT" }, "node_modules/@isaacs/cliui/node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "license": "MIT", "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" }, "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/@isaacs/cliui/node_modules/strip-ansi": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", "license": "MIT", "dependencies": { "ansi-regex": "^6.2.2" }, "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", "license": "MIT", "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", "strip-ansi": "^7.0.1" }, "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", "license": "MIT", "optional": true, "engines": { "node": ">=14" } }, "node_modules/@sec-ant/readable-stream": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==", "license": "MIT" }, "node_modules/@swc/helpers": { "version": "0.5.21", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.21.tgz", "integrity": "sha512-jI/VAmtdjB/RnI8GTnokyX7Ug8c+g+ffD6QRLa6XQewtnGyukKkKSk3wLTM3b5cjt1jNh9x0jfVlagdN2gDKQg==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.8.0" } }, "node_modules/@tsconfig/node20": { "version": "20.1.9", "resolved": "https://registry.npmjs.org/@tsconfig/node20/-/node20-20.1.9.tgz", "integrity": "sha512-IjlTv1RsvnPtUcjTqtVsZExKVq+KQx4g5pCP5tI7rAs6Xesl2qFwSz/tPDBC4JajkL/MlezBu3gPUwqRHl+RIg==", "license": "MIT" }, "node_modules/@types/node": { "version": "25.6.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-25.6.0.tgz", "integrity": "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==", "license": "MIT", "dependencies": { "undici-types": "~7.19.0" } }, "node_modules/@types/normalize-package-data": { "version": "2.4.4", "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", "license": "MIT" }, "node_modules/@types/uuid": { "version": "8.3.4", "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==", "license": "MIT" }, "node_modules/@types/ws": { "version": "8.18.1", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@xmldom/xmldom": { "version": "0.9.9", "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.9.9.tgz", "integrity": "sha512-qycIHAucxy/LXAYIjmLmtQ8q9GPnMbnjG1KXhWm9o5sCr6pOYDATkMPiTNa6/v8eELyqOQ2FsEqeoFYmgv/gJg==", "license": "MIT", "engines": { "node": ">=14.6" } }, "node_modules/abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", "license": "MIT", "dependencies": { "event-target-shim": "^5.0.0" }, "engines": { "node": ">=6.5" } }, "node_modules/accepts": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", "license": "MIT", "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" }, "engines": { "node": ">= 0.6" } }, "node_modules/ansi-regex": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "license": "MIT", "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, "node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/appium-adb": { "version": "14.3.2", "resolved": "https://registry.npmjs.org/appium-adb/-/appium-adb-14.3.2.tgz", "integrity": "sha512-V3YLPzHHG8vjw8oQ7d7sR6OvbadLIYwv5WYji3/YBrAe0NTRzhzj07e/m3XML+ipDOweZhKBebAclavdgkJWWg==", "license": "Apache-2.0", "dependencies": { "@appium/support": "^7.0.0-rc.1", "async-lock": "^1.0.0", "asyncbox": "^6.0.1", "bluebird": "^3.4.7", "ini": "^6.0.0", "lodash": "^4.0.0", "lru-cache": "^11.1.0", "semver": "^7.0.0", "teen_process": "^4.0.4" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" } }, "node_modules/appium-android-driver": { "version": "13.1.2", "resolved": "https://registry.npmjs.org/appium-android-driver/-/appium-android-driver-13.1.2.tgz", "integrity": "sha512-ZzzJvGjxhGSNEwgK3DS8zs5yXAQ9u7n+vRV25dYN2Dt1ORrvsbEBnKhv9+5a/FeV9ivKg47J6r2kDV8DcDL8LQ==", "license": "Apache-2.0", "dependencies": { "@appium/support": "^7.0.0-rc.1", "@colors/colors": "^1.6.0", "appium-adb": "^14.3.0", "appium-chromedriver": "^8.2.25", "asyncbox": "^6.1.0", "axios": "^1.x", "bluebird": "^3.4.7", "io.appium.settings": "^7.0.4", "lodash": "^4.17.4", "lru-cache": "^11.1.0", "moment": "^2.24.0", "moment-timezone": "^0.x", "portscanner": "^2.2.0", "semver": "^7.0.0", "teen_process": "^4.0.7", "ws": "^8.0.0" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" }, "peerDependencies": { "appium": "^3.0.0-rc.2" } }, "node_modules/appium-chromedriver": { "version": "8.2.26", "resolved": "https://registry.npmjs.org/appium-chromedriver/-/appium-chromedriver-8.2.26.tgz", "integrity": "sha512-/H+N52PPmv5j7FJnOHIdtaKeKxAXdo9SOB1QCXnGb4Qi9dDc5KupJZFykKuy03/c9uaHqyga3wrT+rmkRl5Nug==", "license": "Apache-2.0", "dependencies": { "@appium/base-driver": "^10.0.0-rc.2", "@appium/support": "^7.0.0-rc.1", "@xmldom/xmldom": "^0.x", "appium-adb": "^14.0.0", "asyncbox": "^6.0.1", "axios": "^1.6.5", "bluebird": "^3.5.1", "compare-versions": "^6.0.0", "lodash": "^4.17.4", "semver": "^7.0.0", "teen_process": "^4.0.4", "xpath": "^0.x" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" } }, "node_modules/appium-flutter-finder": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/appium-flutter-finder/-/appium-flutter-finder-0.2.0.tgz", "integrity": "sha512-klwh74phzhU6OhSf/arHVHP7AF6fyQGZ2GgzX/wO+gPKIS+rNWOQgizPPimki3H4goB7wB0TaicamN/DCqLmRA==", "license": "MIT" }, "node_modules/appium-ios-device": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/appium-ios-device/-/appium-ios-device-3.1.10.tgz", "integrity": "sha512-2oE7yQtLSdrcZ9YArqgGguzDuiplHj0GXSMlTfwTXl0n22DEzkV0M1mXdaNaWNuzVBJ5VDc1EuYv38p1ruuk2g==", "license": "Apache-2.0", "dependencies": { "@appium/support": "^7.0.0-rc.1", "asyncbox": "^6.0.1", "axios": "^1.6.7", "bluebird": "^3.1.1", "bplist-creator": "^0.x", "bplist-parser": "^0.x", "lodash": "^4.17.15", "semver": "^7.0.0" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" } }, "node_modules/appium-uiautomator2-driver": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/appium-uiautomator2-driver/-/appium-uiautomator2-driver-7.1.2.tgz", "integrity": "sha512-exm8loSaNFh61DMTf/BeFL/J6xY6w+Ta24g8exKEchowCWpm4zimGC4y8BRoP6+1iQ+R88x4fMIvAx8Uf9M7bQ==", "hasShrinkwrap": true, "license": "Apache-2.0", "dependencies": { "appium-adb": "^14.0.0", "appium-android-driver": "^13.1.1", "appium-uiautomator2-server": "^9.11.1", "asyncbox": "^6.0.1", "axios": "^1.13.5", "bluebird": "^3.5.1", "css-selector-parser": "^3.0.0", "io.appium.settings": "^7.0.1", "lodash": "^4.17.4", "portscanner": "^2.2.0", "teen_process": "^4.0.4" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" }, "peerDependencies": { "appium": "^3.0.0-rc.2" } }, "node_modules/appium-uiautomator2-driver/node_modules/@appium/base-driver": { "version": "10.3.0", "resolved": "https://registry.npmjs.org/@appium/base-driver/-/base-driver-10.3.0.tgz", "integrity": "sha512-9r+1f9EtcJt9NXIlyHdFMoD7DsAZPzpRq4Kj1hGZf7+26q1SFEyyMAuWxvlWGY7EoyPtPRyMUkM4dHiSK3Q9+w==", "license": "Apache-2.0", "dependencies": { "@appium/support": "7.1.0", "@appium/types": "1.3.0", "@colors/colors": "1.6.0", "async-lock": "1.4.1", "asyncbox": "6.1.0", "axios": "1.15.0", "bluebird": "3.7.2", "body-parser": "2.2.2", "express": "5.2.1", "fastest-levenshtein": "1.0.16", "http-status-codes": "2.3.0", "lodash": "4.18.1", "lru-cache": "11.3.3", "method-override": "3.0.0", "morgan": "1.10.1", "path-to-regexp": "8.4.2", "serve-favicon": "2.5.1", "type-fest": "5.5.0" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" }, "optionalDependencies": { "spdy": "4.0.2" } }, "node_modules/appium-uiautomator2-driver/node_modules/@appium/logger": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@appium/logger/-/logger-2.0.6.tgz", "integrity": "sha512-9e8n9CtINBwi1ASEU5OyswmR2F7OnbrGfmf9yTy9i+rx4GR9RJlEp0/arsxvuyWCep67tOmM4FiRyXxxHjOK5Q==", "license": "ISC", "dependencies": { "console-control-strings": "1.1.0", "lodash": "4.18.1", "lru-cache": "11.3.3", "set-blocking": "2.0.0" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" } }, "node_modules/appium-uiautomator2-driver/node_modules/@appium/schema": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@appium/schema/-/schema-1.1.0.tgz", "integrity": "sha512-m0vTLU7mhC9RR294Nz84g+FhEQ0iZKq6p3rfz1+qfEqCXRXUvDbllSOu2tCVpBKMIoEFZAmkwjuwXobJpCnilQ==", "license": "Apache-2.0", "dependencies": { "json-schema": "0.4.0" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" } }, "node_modules/appium-uiautomator2-driver/node_modules/@appium/support": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/@appium/support/-/support-7.1.0.tgz", "integrity": "sha512-kY4Qv4TzLCYmZnN2eNptEa8RiRzpbimIQ6tKuDaqLC2Y3q5Al4NumL/xRQAvfXJq/hNezq2Jh8NwciEW8zX/0g==", "license": "Apache-2.0", "dependencies": { "@appium/logger": "2.0.6", "@appium/tsconfig": "1.1.2", "@appium/types": "1.3.0", "@colors/colors": "1.6.0", "archiver": "7.0.1", "asyncbox": "6.1.0", "axios": "1.15.0", "base64-stream": "1.0.0", "bluebird": "3.7.2", "bplist-creator": "0.1.1", "bplist-parser": "0.3.2", "form-data": "4.0.5", "get-stream": "9.0.1", "glob": "13.0.6", "jsftp": "2.1.3", "klaw": "4.1.0", "lockfile": "1.0.4", "lodash": "4.18.1", "log-symbols": "7.0.1", "ncp": "2.0.0", "package-directory": "8.2.0", "plist": "3.1.0", "pluralize": "8.0.0", "read-pkg": "10.1.0", "resolve-from": "5.0.0", "sanitize-filename": "1.6.4", "semver": "7.7.4", "shell-quote": "1.8.3", "supports-color": "10.2.2", "teen_process": "4.1.0", "type-fest": "5.5.0", "uuid": "13.0.0", "which": "6.0.1", "yauzl": "3.3.0" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" }, "optionalDependencies": { "sharp": "0.34.5" } }, "node_modules/appium-uiautomator2-driver/node_modules/@appium/tsconfig": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@appium/tsconfig/-/tsconfig-1.1.2.tgz", "integrity": "sha512-lHKBm7hXCROc1Ha/cBxS4o3iQkeY96Pz7qM9Uh9vFDkdpTGBk56V1lmc3iGcgBYKBlaRT/LZmTsqClvHoiXhvw==", "license": "Apache-2.0", "dependencies": { "@tsconfig/node20": "20.1.9" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" } }, "node_modules/appium-uiautomator2-driver/node_modules/@appium/types": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@appium/types/-/types-1.3.0.tgz", "integrity": "sha512-Gv4ev/5K5N7TvAHqem2DmB50zipC951QlmCDpuxDNHQl2dtCr20vJgnN8if7upqLcBX/6yNp3udR+f1n99zgcQ==", "license": "Apache-2.0", "dependencies": { "@appium/logger": "2.0.6", "@appium/schema": "1.1.0", "@appium/tsconfig": "1.1.2", "type-fest": "5.5.0" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" } }, "node_modules/appium-uiautomator2-driver/node_modules/@babel/code-frame": { "version": "7.29.0", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", "license": "MIT", "dependencies": { "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/@babel/helper-validator-identifier": { "version": "7.28.5", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/@colors/colors": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==", "license": "MIT", "engines": { "node": ">=0.1.90" } }, "node_modules/appium-uiautomator2-driver/node_modules/@img/colour": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", "license": "MIT", "optional": true, "engines": { "node": ">=18" } }, "node_modules/appium-uiautomator2-driver/node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", "license": "ISC", "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", "strip-ansi": "^7.0.1", "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", "wrap-ansi": "^8.1.0", "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" }, "engines": { "node": ">=12" } }, "node_modules/appium-uiautomator2-driver/node_modules/@isaacs/cliui/node_modules/ansi-styles": { "version": "6.2.3", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", "license": "MIT", "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/appium-uiautomator2-driver/node_modules/@isaacs/cliui/node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "license": "MIT" }, "node_modules/appium-uiautomator2-driver/node_modules/@isaacs/cliui/node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "license": "MIT", "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" }, "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/appium-uiautomator2-driver/node_modules/@isaacs/cliui/node_modules/strip-ansi": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", "license": "MIT", "dependencies": { "ansi-regex": "^6.2.2" }, "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, "node_modules/appium-uiautomator2-driver/node_modules/@isaacs/cliui/node_modules/wrap-ansi": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", "license": "MIT", "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", "strip-ansi": "^7.0.1" }, "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/appium-uiautomator2-driver/node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", "license": "MIT", "optional": true, "engines": { "node": ">=14" } }, "node_modules/appium-uiautomator2-driver/node_modules/@sec-ant/readable-stream": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==", "license": "MIT" }, "node_modules/appium-uiautomator2-driver/node_modules/@tsconfig/node20": { "version": "20.1.9", "resolved": "https://registry.npmjs.org/@tsconfig/node20/-/node20-20.1.9.tgz", "integrity": "sha512-IjlTv1RsvnPtUcjTqtVsZExKVq+KQx4g5pCP5tI7rAs6Xesl2qFwSz/tPDBC4JajkL/MlezBu3gPUwqRHl+RIg==", "license": "MIT" }, "node_modules/appium-uiautomator2-driver/node_modules/@types/normalize-package-data": { "version": "2.4.4", "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", "license": "MIT" }, "node_modules/appium-uiautomator2-driver/node_modules/@xmldom/xmldom": { "version": "0.9.9", "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.9.9.tgz", "integrity": "sha512-qycIHAucxy/LXAYIjmLmtQ8q9GPnMbnjG1KXhWm9o5sCr6pOYDATkMPiTNa6/v8eELyqOQ2FsEqeoFYmgv/gJg==", "license": "MIT", "engines": { "node": ">=14.6" } }, "node_modules/appium-uiautomator2-driver/node_modules/abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", "license": "MIT", "dependencies": { "event-target-shim": "^5.0.0" }, "engines": { "node": ">=6.5" } }, "node_modules/appium-uiautomator2-driver/node_modules/accepts": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", "license": "MIT", "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" }, "engines": { "node": ">= 0.6" } }, "node_modules/appium-uiautomator2-driver/node_modules/ansi-regex": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "license": "MIT", "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, "node_modules/appium-uiautomator2-driver/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/appium-uiautomator2-driver/node_modules/appium-adb": { "version": "14.3.1", "resolved": "https://registry.npmjs.org/appium-adb/-/appium-adb-14.3.1.tgz", "integrity": "sha512-Pv9Ti0jji0Q0QewBJfjPiECV5IO6ex5qK6YugZknxxjJ5QadLDjt/FW6z4/THGAQJdbYriwqrxTqLxB6+DwqBA==", "license": "Apache-2.0", "dependencies": { "@appium/support": "^7.0.0-rc.1", "async-lock": "^1.0.0", "asyncbox": "^6.0.1", "bluebird": "^3.4.7", "ini": "^6.0.0", "lodash": "^4.0.0", "lru-cache": "^11.1.0", "semver": "^7.0.0", "teen_process": "^4.0.4" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" } }, "node_modules/appium-uiautomator2-driver/node_modules/appium-android-driver": { "version": "13.1.1", "resolved": "https://registry.npmjs.org/appium-android-driver/-/appium-android-driver-13.1.1.tgz", "integrity": "sha512-UZQmkm5YELkuqLE7Rz6wCpXxKhK8WQeDQsFt/9gkOQLgK2yaQdfAj8OM2mP8Gmru3iJFep39VGM2EWYAL2U9Qw==", "license": "Apache-2.0", "dependencies": { "@appium/support": "^7.0.0-rc.1", "@colors/colors": "^1.6.0", "appium-adb": "^14.3.0", "appium-chromedriver": "^8.2.25", "asyncbox": "^6.1.0", "axios": "^1.x", "bluebird": "^3.4.7", "io.appium.settings": "^7.0.4", "lodash": "^4.17.4", "lru-cache": "^11.1.0", "moment": "^2.24.0", "moment-timezone": "^0.x", "portscanner": "^2.2.0", "semver": "^7.0.0", "teen_process": "^4.0.7", "ws": "^8.0.0" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" }, "peerDependencies": { "appium": "^3.0.0-rc.2" } }, "node_modules/appium-uiautomator2-driver/node_modules/appium-chromedriver": { "version": "8.2.25", "resolved": "https://registry.npmjs.org/appium-chromedriver/-/appium-chromedriver-8.2.25.tgz", "integrity": "sha512-fxSDBSUwS1hFoHKMneB0YWT5I0X2sGgXu8PbRLKv+CpveKiZKtomqtG+LlWo7zgJfITrJ4/fi6WCYBSpMG05PQ==", "license": "Apache-2.0", "dependencies": { "@appium/base-driver": "^10.0.0-rc.2", "@appium/support": "^7.0.0-rc.1", "@xmldom/xmldom": "^0.x", "appium-adb": "^14.0.0", "asyncbox": "^6.0.1", "axios": "^1.6.5", "bluebird": "^3.5.1", "compare-versions": "^6.0.0", "lodash": "^4.17.4", "semver": "^7.0.0", "teen_process": "^4.0.4", "xpath": "^0.x" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" } }, "node_modules/appium-uiautomator2-driver/node_modules/appium-uiautomator2-server": { "version": "9.11.1", "resolved": "https://registry.npmjs.org/appium-uiautomator2-server/-/appium-uiautomator2-server-9.11.1.tgz", "integrity": "sha512-MAlnHFhUdQ/gdpzXcJlK5chuMQLjhOqeoD1gPGmsr3raAElPHdKDYzSiaxqvDFu7XRYug6JfWmBsTSfdASy/RQ==", "license": "Apache-2.0", "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" } }, "node_modules/appium-uiautomator2-driver/node_modules/archiver": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/archiver/-/archiver-7.0.1.tgz", "integrity": "sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==", "license": "MIT", "dependencies": { "archiver-utils": "^5.0.2", "async": "^3.2.4", "buffer-crc32": "^1.0.0", "readable-stream": "^4.0.0", "readdir-glob": "^1.1.2", "tar-stream": "^3.0.0", "zip-stream": "^6.0.1" }, "engines": { "node": ">= 14" } }, "node_modules/appium-uiautomator2-driver/node_modules/archiver-utils": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-5.0.2.tgz", "integrity": "sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==", "license": "MIT", "dependencies": { "glob": "^10.0.0", "graceful-fs": "^4.2.0", "is-stream": "^2.0.1", "lazystream": "^1.0.0", "lodash": "^4.17.15", "normalize-path": "^3.0.0", "readable-stream": "^4.0.0" }, "engines": { "node": ">= 14" } }, "node_modules/appium-uiautomator2-driver/node_modules/archiver-utils/node_modules/brace-expansion": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/archiver-utils/node_modules/glob": { "version": "10.5.0", "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/appium-uiautomator2-driver/node_modules/archiver-utils/node_modules/lru-cache": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "license": "ISC" }, "node_modules/appium-uiautomator2-driver/node_modules/archiver-utils/node_modules/minimatch": { "version": "9.0.9", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "license": "ISC", "dependencies": { "brace-expansion": "^2.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/appium-uiautomator2-driver/node_modules/archiver-utils/node_modules/path-scurry": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", "license": "BlueOak-1.0.0", "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { "node": ">=16 || 14 >=14.18" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/appium-uiautomator2-driver/node_modules/async": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", "license": "MIT" }, "node_modules/appium-uiautomator2-driver/node_modules/async-lock": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/async-lock/-/async-lock-1.4.1.tgz", "integrity": "sha512-Az2ZTpuytrtqENulXwO3GGv1Bztugx6TT37NIo7imr/Qo0gsYiGtSdBa2B6fsXhTpVZDNfu1Qn3pk531e3q+nQ==", "license": "MIT" }, "node_modules/appium-uiautomator2-driver/node_modules/asyncbox": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/asyncbox/-/asyncbox-6.1.0.tgz", "integrity": "sha512-KZwKNVnDdDe0ubN+fFMuHhSljZNHnbjdJABImoqFzQP61oIg6sMlhXIqOIu3WRd7YwW89q+eVj2Ty/Ax5dbh2Q==", "license": "Apache-2.0", "dependencies": { "p-limit": "^7.2.0" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" } }, "node_modules/appium-uiautomator2-driver/node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "license": "MIT" }, "node_modules/appium-uiautomator2-driver/node_modules/axios": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/axios/-/axios-1.15.0.tgz", "integrity": "sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q==", "license": "MIT", "dependencies": { "follow-redirects": "^1.15.11", "form-data": "^4.0.5", "proxy-from-env": "^2.1.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/b4a": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.8.0.tgz", "integrity": "sha512-qRuSmNSkGQaHwNbM7J78Wwy+ghLEYF1zNrSeMxj4Kgw6y33O3mXcQ6Ie9fRvfU/YnxWkOchPXbaLb73TkIsfdg==", "license": "Apache-2.0", "peerDependencies": { "react-native-b4a": "*" }, "peerDependenciesMeta": { "react-native-b4a": { "optional": true } } }, "node_modules/appium-uiautomator2-driver/node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "license": "MIT" }, "node_modules/appium-uiautomator2-driver/node_modules/bare-events": { "version": "2.8.2", "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.8.2.tgz", "integrity": "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==", "license": "Apache-2.0", "peerDependencies": { "bare-abort-controller": "*" }, "peerDependenciesMeta": { "bare-abort-controller": { "optional": true } } }, "node_modules/appium-uiautomator2-driver/node_modules/bare-fs": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.7.0.tgz", "integrity": "sha512-xzqKsCFxAek9aezYhjJuJRXBIaYlg/0OGDTZp+T8eYmYMlm66cs6cYko02drIyjN2CBbi+I6L7YfXyqpqtKRXA==", "license": "Apache-2.0", "dependencies": { "bare-events": "^2.5.4", "bare-path": "^3.0.0", "bare-stream": "^2.6.4", "bare-url": "^2.2.2", "fast-fifo": "^1.3.2" }, "engines": { "bare": ">=1.16.0" }, "peerDependencies": { "bare-buffer": "*" }, "peerDependenciesMeta": { "bare-buffer": { "optional": true } } }, "node_modules/appium-uiautomator2-driver/node_modules/bare-os": { "version": "3.8.7", "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.8.7.tgz", "integrity": "sha512-G4Gr1UsGeEy2qtDTZwL7JFLo2wapUarz7iTMcYcMFdS89AIQuBoyjgXZz0Utv7uHs3xA9LckhVbeBi8lEQrC+w==", "license": "Apache-2.0", "engines": { "bare": ">=1.14.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/bare-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz", "integrity": "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==", "license": "Apache-2.0", "dependencies": { "bare-os": "^3.0.1" } }, "node_modules/appium-uiautomator2-driver/node_modules/bare-stream": { "version": "2.12.0", "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.12.0.tgz", "integrity": "sha512-w28i8lkBgREV3rPXGbgK+BO66q+ZpKqRWrZLiCdmmUlLPrQ45CzkvRhN+7lnv00Gpi2zy5naRxnUFAxCECDm9g==", "license": "Apache-2.0", "dependencies": { "streamx": "^2.25.0", "teex": "^1.0.1" }, "peerDependencies": { "bare-abort-controller": "*", "bare-buffer": "*", "bare-events": "*" }, "peerDependenciesMeta": { "bare-abort-controller": { "optional": true }, "bare-buffer": { "optional": true }, "bare-events": { "optional": true } } }, "node_modules/appium-uiautomator2-driver/node_modules/bare-url": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.4.0.tgz", "integrity": "sha512-NSTU5WN+fy/L0DDenfE8SXQna4voXuW0FHM7wH8i3/q9khUSchfPbPezO4zSFMnDGIf9YE+mt/RWhZgNRKRIXA==", "license": "Apache-2.0", "dependencies": { "bare-path": "^3.0.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "license": "MIT" }, "node_modules/appium-uiautomator2-driver/node_modules/base64-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/base64-stream/-/base64-stream-1.0.0.tgz", "integrity": "sha512-BQQZftaO48FcE1Kof9CmXMFaAdqkcNorgc8CxesZv9nMbbTF1EFyQe89UOuh//QMmdtfUDXyO8rgUalemL5ODA==", "license": "MIT" }, "node_modules/appium-uiautomator2-driver/node_modules/basic-auth": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", "license": "MIT", "dependencies": { "safe-buffer": "5.1.2" }, "engines": { "node": ">= 0.8" } }, "node_modules/appium-uiautomator2-driver/node_modules/big-integer": { "version": "1.6.52", "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", "license": "Unlicense", "engines": { "node": ">=0.6" } }, "node_modules/appium-uiautomator2-driver/node_modules/bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", "license": "MIT" }, "node_modules/appium-uiautomator2-driver/node_modules/body-parser": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==", "license": "MIT", "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", "debug": "^4.4.3", "http-errors": "^2.0.0", "iconv-lite": "^0.7.0", "on-finished": "^2.4.1", "qs": "^6.14.1", "raw-body": "^3.0.1", "type-is": "^2.0.1" }, "engines": { "node": ">=18" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, "node_modules/appium-uiautomator2-driver/node_modules/bplist-creator": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.1.1.tgz", "integrity": "sha512-Ese7052fdWrxp/vqSJkydgx/1MdBnNOCV2XVfbmdGWD2H6EYza+Q4pyYSuVSnCUD22hfI/BFI4jHaC3NLXLlJQ==", "license": "MIT", "dependencies": { "stream-buffers": "2.2.x" } }, "node_modules/appium-uiautomator2-driver/node_modules/bplist-parser": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.3.2.tgz", "integrity": "sha512-apC2+fspHGI3mMKj+dGevkGo/tCqVB8jMb6i+OX+E29p0Iposz07fABkRIfVUPNd5A5VbuOz1bZbnmkKLYF+wQ==", "license": "MIT", "dependencies": { "big-integer": "1.6.x" }, "engines": { "node": ">= 5.10.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/buffer-crc32": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz", "integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==", "license": "MIT", "engines": { "node": ">=8.0.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/appium-uiautomator2-driver/node_modules/call-bind-apply-helpers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" }, "engines": { "node": ">= 0.4" } }, "node_modules/appium-uiautomator2-driver/node_modules/call-bound": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/appium-uiautomator2-driver/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, "engines": { "node": ">=7.0.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, "node_modules/appium-uiautomator2-driver/node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" }, "engines": { "node": ">= 0.8" } }, "node_modules/appium-uiautomator2-driver/node_modules/compare-versions": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.1.tgz", "integrity": "sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==", "license": "MIT" }, "node_modules/appium-uiautomator2-driver/node_modules/compress-commons": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-6.0.2.tgz", "integrity": "sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==", "license": "MIT", "dependencies": { "crc-32": "^1.2.0", "crc32-stream": "^6.0.0", "is-stream": "^2.0.1", "normalize-path": "^3.0.0", "readable-stream": "^4.0.0" }, "engines": { "node": ">= 14" } }, "node_modules/appium-uiautomator2-driver/node_modules/console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", "license": "ISC" }, "node_modules/appium-uiautomator2-driver/node_modules/content-disposition": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.1.0.tgz", "integrity": "sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==", "license": "MIT", "engines": { "node": ">=18" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, "node_modules/appium-uiautomator2-driver/node_modules/content-type": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/appium-uiautomator2-driver/node_modules/cookie": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/appium-uiautomator2-driver/node_modules/cookie-signature": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", "license": "MIT", "engines": { "node": ">=6.6.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "license": "MIT" }, "node_modules/appium-uiautomator2-driver/node_modules/crc-32": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", "license": "Apache-2.0", "bin": { "crc32": "bin/crc32.njs" }, "engines": { "node": ">=0.8" } }, "node_modules/appium-uiautomator2-driver/node_modules/crc32-stream": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-6.0.0.tgz", "integrity": "sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==", "license": "MIT", "dependencies": { "crc-32": "^1.2.0", "readable-stream": "^4.0.0" }, "engines": { "node": ">= 14" } }, "node_modules/appium-uiautomator2-driver/node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" }, "engines": { "node": ">= 8" } }, "node_modules/appium-uiautomator2-driver/node_modules/cross-spawn/node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "license": "ISC" }, "node_modules/appium-uiautomator2-driver/node_modules/cross-spawn/node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "bin/node-which" }, "engines": { "node": ">= 8" } }, "node_modules/appium-uiautomator2-driver/node_modules/css-selector-parser": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/css-selector-parser/-/css-selector-parser-3.3.0.tgz", "integrity": "sha512-Y2asgMGFqJKF4fq4xHDSlFYIkeVfRsm69lQC1q9kbEsH5XtnINTMrweLkjYMeaUgiXBy/uvKeO/a1JHTNnmB2g==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/mdevils" }, { "type": "patreon", "url": "https://patreon.com/mdevils" } ], "license": "MIT" }, "node_modules/appium-uiautomator2-driver/node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "license": "MIT", "dependencies": { "ms": "^2.1.3" }, "engines": { "node": ">=6.0" }, "peerDependenciesMeta": { "supports-color": { "optional": true } } }, "node_modules/appium-uiautomator2-driver/node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "license": "MIT", "engines": { "node": ">=0.4.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/appium-uiautomator2-driver/node_modules/detect-libc": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", "license": "Apache-2.0", "optional": true, "engines": { "node": ">=8" } }, "node_modules/appium-uiautomator2-driver/node_modules/detect-node": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", "license": "MIT", "optional": true }, "node_modules/appium-uiautomator2-driver/node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" }, "engines": { "node": ">= 0.4" } }, "node_modules/appium-uiautomator2-driver/node_modules/duplexer": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", "license": "MIT" }, "node_modules/appium-uiautomator2-driver/node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "license": "MIT" }, "node_modules/appium-uiautomator2-driver/node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", "license": "MIT" }, "node_modules/appium-uiautomator2-driver/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "license": "MIT" }, "node_modules/appium-uiautomator2-driver/node_modules/encodeurl": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/appium-uiautomator2-driver/node_modules/es-define-property": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/appium-uiautomator2-driver/node_modules/es-errors": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/appium-uiautomator2-driver/node_modules/es-object-atoms": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0" }, "engines": { "node": ">= 0.4" } }, "node_modules/appium-uiautomator2-driver/node_modules/es-set-tostringtag": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" } }, "node_modules/appium-uiautomator2-driver/node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", "license": "MIT" }, "node_modules/appium-uiautomator2-driver/node_modules/etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/appium-uiautomator2-driver/node_modules/event-target-shim": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/appium-uiautomator2-driver/node_modules/events": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "license": "MIT", "engines": { "node": ">=0.8.x" } }, "node_modules/appium-uiautomator2-driver/node_modules/events-universal": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz", "integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==", "license": "Apache-2.0", "dependencies": { "bare-events": "^2.7.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/express": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", "license": "MIT", "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.1", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", "depd": "^2.0.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "finalhandler": "^2.1.0", "fresh": "^2.0.0", "http-errors": "^2.0.0", "merge-descriptors": "^2.0.0", "mime-types": "^3.0.0", "on-finished": "^2.4.1", "once": "^1.4.0", "parseurl": "^1.3.3", "proxy-addr": "^2.0.7", "qs": "^6.14.0", "range-parser": "^1.2.1", "router": "^2.2.0", "send": "^1.1.0", "serve-static": "^2.2.0", "statuses": "^2.0.1", "type-is": "^2.0.1", "vary": "^1.1.2" }, "engines": { "node": ">= 18" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, "node_modules/appium-uiautomator2-driver/node_modules/fast-fifo": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", "license": "MIT" }, "node_modules/appium-uiautomator2-driver/node_modules/fastest-levenshtein": { "version": "1.0.16", "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", "license": "MIT", "engines": { "node": ">= 4.9.1" } }, "node_modules/appium-uiautomator2-driver/node_modules/finalhandler": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", "license": "MIT", "dependencies": { "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "on-finished": "^2.4.1", "parseurl": "^1.3.3", "statuses": "^2.0.1" }, "engines": { "node": ">= 18.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, "node_modules/appium-uiautomator2-driver/node_modules/find-up-simple": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.1.tgz", "integrity": "sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==", "license": "MIT", "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/appium-uiautomator2-driver/node_modules/follow-redirects": { "version": "1.15.11", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", "funding": [ { "type": "individual", "url": "https://github.com/sponsors/RubenVerborgh" } ], "license": "MIT", "engines": { "node": ">=4.0" }, "peerDependenciesMeta": { "debug": { "optional": true } } }, "node_modules/appium-uiautomator2-driver/node_modules/foreground-child": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", "license": "ISC", "dependencies": { "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" }, "engines": { "node": ">=14" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/appium-uiautomator2-driver/node_modules/foreground-child/node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "license": "ISC", "engines": { "node": ">=14" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/appium-uiautomator2-driver/node_modules/form-data": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.2", "mime-types": "^2.1.12" }, "engines": { "node": ">= 6" } }, "node_modules/appium-uiautomator2-driver/node_modules/form-data/node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/appium-uiautomator2-driver/node_modules/form-data/node_modules/mime-types": { "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "license": "MIT", "dependencies": { "mime-db": "1.52.0" }, "engines": { "node": ">= 0.6" } }, "node_modules/appium-uiautomator2-driver/node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/appium-uiautomator2-driver/node_modules/fresh": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/appium-uiautomator2-driver/node_modules/ftp-response-parser": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ftp-response-parser/-/ftp-response-parser-1.0.1.tgz", "integrity": "sha512-++Ahlo2hs/IC7UVQzjcSAfeUpCwTTzs4uvG5XfGnsinIFkWUYF4xWwPd5qZuK8MJrmUIxFMuHcfqaosCDjvIWw==", "dependencies": { "readable-stream": "^1.0.31" }, "engines": { "node": ">=0.8.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/ftp-response-parser/node_modules/isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", "license": "MIT" }, "node_modules/appium-uiautomator2-driver/node_modules/ftp-response-parser/node_modules/readable-stream": { "version": "1.1.14", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", "isarray": "0.0.1", "string_decoder": "~0.10.x" } }, "node_modules/appium-uiautomator2-driver/node_modules/ftp-response-parser/node_modules/string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", "license": "MIT" }, "node_modules/appium-uiautomator2-driver/node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/appium-uiautomator2-driver/node_modules/get-intrinsic": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/appium-uiautomator2-driver/node_modules/get-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", "license": "MIT", "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" } }, "node_modules/appium-uiautomator2-driver/node_modules/get-stream": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", "license": "MIT", "dependencies": { "@sec-ant/readable-stream": "^0.4.1", "is-stream": "^4.0.1" }, "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/appium-uiautomator2-driver/node_modules/get-stream/node_modules/is-stream": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", "license": "MIT", "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/appium-uiautomator2-driver/node_modules/glob": { "version": "13.0.6", "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", "license": "BlueOak-1.0.0", "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" }, "engines": { "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/appium-uiautomator2-driver/node_modules/glob/node_modules/balanced-match": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", "license": "MIT", "engines": { "node": "18 || 20 || >=22" } }, "node_modules/appium-uiautomator2-driver/node_modules/glob/node_modules/brace-expansion": { "version": "5.0.5", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", "license": "MIT", "dependencies": { "balanced-match": "^4.0.2" }, "engines": { "node": "18 || 20 || >=22" } }, "node_modules/appium-uiautomator2-driver/node_modules/glob/node_modules/minimatch": { "version": "10.2.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", "license": "BlueOak-1.0.0", "dependencies": { "brace-expansion": "^5.0.5" }, "engines": { "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/appium-uiautomator2-driver/node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "license": "MIT", "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/appium-uiautomator2-driver/node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "license": "ISC" }, "node_modules/appium-uiautomator2-driver/node_modules/handle-thing": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", "license": "MIT", "optional": true }, "node_modules/appium-uiautomator2-driver/node_modules/has-symbols": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "license": "MIT", "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/appium-uiautomator2-driver/node_modules/has-tostringtag": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/appium-uiautomator2-driver/node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "license": "MIT", "dependencies": { "function-bind": "^1.1.2" }, "engines": { "node": ">= 0.4" } }, "node_modules/appium-uiautomator2-driver/node_modules/hosted-git-info": { "version": "9.0.2", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-9.0.2.tgz", "integrity": "sha512-M422h7o/BR3rmCQ8UHi7cyyMqKltdP9Uo+J2fXK+RSAY+wTcKOIRyhTuKv4qn+DJf3g+PL890AzId5KZpX+CBg==", "license": "ISC", "dependencies": { "lru-cache": "^11.1.0" }, "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/hpack.js": { "version": "2.1.6", "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", "license": "MIT", "optional": true, "dependencies": { "inherits": "^2.0.1", "obuf": "^1.0.0", "readable-stream": "^2.0.1", "wbuf": "^1.1.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/hpack.js/node_modules/readable-stream": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "license": "MIT", "optional": true, "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "node_modules/appium-uiautomator2-driver/node_modules/hpack.js/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "license": "MIT", "optional": true, "dependencies": { "safe-buffer": "~5.1.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/http-deceiver": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", "license": "MIT", "optional": true }, "node_modules/appium-uiautomator2-driver/node_modules/http-errors": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", "license": "MIT", "dependencies": { "depd": "~2.0.0", "inherits": "~2.0.4", "setprototypeof": "~1.2.0", "statuses": "~2.0.2", "toidentifier": "~1.0.1" }, "engines": { "node": ">= 0.8" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, "node_modules/appium-uiautomator2-driver/node_modules/http-status-codes": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/http-status-codes/-/http-status-codes-2.3.0.tgz", "integrity": "sha512-RJ8XvFvpPM/Dmc5SV+dC4y5PCeOhT3x1Hq0NU3rjGeg5a/CqlhZ7uudknPwZFz4aeAXDcbAyaeP7GAo9lvngtA==", "license": "MIT" }, "node_modules/appium-uiautomator2-driver/node_modules/iconv-lite": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, "engines": { "node": ">=0.10.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, "node_modules/appium-uiautomator2-driver/node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "license": "BSD-3-Clause" }, "node_modules/appium-uiautomator2-driver/node_modules/index-to-position": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/index-to-position/-/index-to-position-1.2.0.tgz", "integrity": "sha512-Yg7+ztRkqslMAS2iFaU+Oa4KTSidr63OsFGlOrJoW981kIYO3CGCS3wA95P1mUi/IVSJkn0D479KTJpVpvFNuw==", "license": "MIT", "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/appium-uiautomator2-driver/node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "license": "ISC" }, "node_modules/appium-uiautomator2-driver/node_modules/ini": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/ini/-/ini-6.0.0.tgz", "integrity": "sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ==", "license": "ISC", "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/io.appium.settings": { "version": "7.0.22", "resolved": "https://registry.npmjs.org/io.appium.settings/-/io.appium.settings-7.0.22.tgz", "integrity": "sha512-LBKquRGIRfYG9qk8Y2CkOhuk4dDRSGNzcPoMy5a2/lopTpHPvJz+FQOXfcPVQ23qgbCE7GJH7chYKvlJrFOPZA==", "license": "Apache-2.0", "dependencies": { "@appium/logger": "^2.0.0-rc.1", "asyncbox": "^6.0.1", "bluebird": "^3.5.1", "lodash": "^4.2.1", "semver": "^7.5.4", "teen_process": "^4.0.4" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" } }, "node_modules/appium-uiautomator2-driver/node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "license": "MIT", "engines": { "node": ">= 0.10" } }, "node_modules/appium-uiautomator2-driver/node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/appium-uiautomator2-driver/node_modules/is-number-like": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/is-number-like/-/is-number-like-1.0.8.tgz", "integrity": "sha512-6rZi3ezCyFcn5L71ywzz2bS5b2Igl1En3eTlZlvKjpz1n3IZLAYMbKYAIQgFmEu0GENg92ziU/faEOA/aixjbA==", "license": "ISC", "dependencies": { "lodash.isfinite": "^3.3.2" } }, "node_modules/appium-uiautomator2-driver/node_modules/is-promise": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", "license": "MIT" }, "node_modules/appium-uiautomator2-driver/node_modules/is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "license": "MIT", "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/appium-uiautomator2-driver/node_modules/is-unicode-supported": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", "license": "MIT", "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/appium-uiautomator2-driver/node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", "license": "MIT" }, "node_modules/appium-uiautomator2-driver/node_modules/isexe": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-4.0.0.tgz", "integrity": "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==", "license": "BlueOak-1.0.0", "engines": { "node": ">=20" } }, "node_modules/appium-uiautomator2-driver/node_modules/jackspeak": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" }, "funding": { "url": "https://github.com/sponsors/isaacs" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "license": "MIT" }, "node_modules/appium-uiautomator2-driver/node_modules/jsftp": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/jsftp/-/jsftp-2.1.3.tgz", "integrity": "sha512-r79EVB8jaNAZbq8hvanL8e8JGu2ZNr2bXdHC4ZdQhRImpSPpnWwm5DYVzQ5QxJmtGtKhNNuvqGgbNaFl604fEQ==", "license": "MIT", "dependencies": { "debug": "^3.1.0", "ftp-response-parser": "^1.0.1", "once": "^1.4.0", "parse-listing": "^1.1.3", "stream-combiner": "^0.2.2", "unorm": "^1.4.1" }, "engines": { "node": ">=6" } }, "node_modules/appium-uiautomator2-driver/node_modules/jsftp/node_modules/debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "license": "MIT", "dependencies": { "ms": "^2.1.1" } }, "node_modules/appium-uiautomator2-driver/node_modules/json-schema": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", "license": "(AFL-2.1 OR BSD-3-Clause)" }, "node_modules/appium-uiautomator2-driver/node_modules/klaw": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/klaw/-/klaw-4.1.0.tgz", "integrity": "sha512-1zGZ9MF9H22UnkpVeuaGKOjfA2t6WrfdrJmGjy16ykcjnKQDmHVX+KI477rpbGevz/5FD4MC3xf1oxylBgcaQw==", "license": "MIT", "engines": { "node": ">=14.14.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/lazystream": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", "license": "MIT", "dependencies": { "readable-stream": "^2.0.5" }, "engines": { "node": ">= 0.6.3" } }, "node_modules/appium-uiautomator2-driver/node_modules/lazystream/node_modules/readable-stream": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "node_modules/appium-uiautomator2-driver/node_modules/lazystream/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/lockfile": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/lockfile/-/lockfile-1.0.4.tgz", "integrity": "sha512-cvbTwETRfsFh4nHsL1eGWapU1XFi5Ot9E85sWAwia7Y7EgB7vfqcZhTKZ+l7hCGxSPoushMv5GKhT5PdLv03WA==", "license": "ISC", "dependencies": { "signal-exit": "^3.0.2" } }, "node_modules/appium-uiautomator2-driver/node_modules/lodash": { "version": "4.18.1", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", "license": "MIT" }, "node_modules/appium-uiautomator2-driver/node_modules/lodash.isfinite": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/lodash.isfinite/-/lodash.isfinite-3.3.2.tgz", "integrity": "sha512-7FGG40uhC8Mm633uKW1r58aElFlBlxCrg9JfSi3P6aYiWmfiWF0PgMd86ZUsxE5GwWPdHoS2+48bwTh2VPkIQA==", "license": "MIT" }, "node_modules/appium-uiautomator2-driver/node_modules/log-symbols": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-7.0.1.tgz", "integrity": "sha512-ja1E3yCr9i/0hmBVaM0bfwDjnGy8I/s6PP4DFp+yP+a+mrHO4Rm7DtmnqROTUkHIkqffC84YY7AeqX6oFk0WFg==", "license": "MIT", "dependencies": { "is-unicode-supported": "^2.0.0", "yoctocolors": "^2.1.1" }, "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/appium-uiautomator2-driver/node_modules/lru-cache": { "version": "11.3.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.3.tgz", "integrity": "sha512-JvNw9Y81y33E+BEYPr0U7omo+U9AySnsMsEiXgwT6yqd31VQWTLNQqmT4ou5eqPFUrTfIDFta2wKhB1hyohtAQ==", "license": "BlueOak-1.0.0", "engines": { "node": "20 || >=22" } }, "node_modules/appium-uiautomator2-driver/node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/appium-uiautomator2-driver/node_modules/media-typer": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/appium-uiautomator2-driver/node_modules/merge-descriptors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", "license": "MIT", "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/appium-uiautomator2-driver/node_modules/method-override": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/method-override/-/method-override-3.0.0.tgz", "integrity": "sha512-IJ2NNN/mSl9w3kzWB92rcdHpz+HjkxhDJWNDBqSlas+zQdP8wBiJzITPg08M/k2uVvMow7Sk41atndNtt/PHSA==", "license": "MIT", "dependencies": { "debug": "3.1.0", "methods": "~1.1.2", "parseurl": "~1.3.2", "vary": "~1.1.2" }, "engines": { "node": ">= 0.10" } }, "node_modules/appium-uiautomator2-driver/node_modules/method-override/node_modules/debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "license": "MIT", "dependencies": { "ms": "2.0.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/method-override/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, "node_modules/appium-uiautomator2-driver/node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/appium-uiautomator2-driver/node_modules/mime-db": { "version": "1.54.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/appium-uiautomator2-driver/node_modules/mime-types": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", "license": "MIT", "dependencies": { "mime-db": "^1.54.0" }, "engines": { "node": ">=18" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, "node_modules/appium-uiautomator2-driver/node_modules/minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", "license": "ISC", "optional": true }, "node_modules/appium-uiautomator2-driver/node_modules/minipass": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", "license": "BlueOak-1.0.0", "engines": { "node": ">=16 || 14 >=14.17" } }, "node_modules/appium-uiautomator2-driver/node_modules/moment": { "version": "2.30.1", "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", "license": "MIT", "engines": { "node": "*" } }, "node_modules/appium-uiautomator2-driver/node_modules/moment-timezone": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.6.1.tgz", "integrity": "sha512-1B9lmAhB9D9/sHaPC1N7wLFEVUoFldxOpOO96lOD1PvJ43vCd0ozDPbu0FEL3++VvawOlDkq8YD373tJmP5JHw==", "license": "MIT", "dependencies": { "moment": "^2.29.4" }, "engines": { "node": "*" } }, "node_modules/appium-uiautomator2-driver/node_modules/morgan": { "version": "1.10.1", "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.1.tgz", "integrity": "sha512-223dMRJtI/l25dJKWpgij2cMtywuG/WiUKXdvwfbhGKBhy1puASqXwFzmWZ7+K73vUPoR7SS2Qz2cI/g9MKw0A==", "license": "MIT", "dependencies": { "basic-auth": "~2.0.1", "debug": "2.6.9", "depd": "~2.0.0", "on-finished": "~2.3.0", "on-headers": "~1.1.0" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/morgan/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "license": "MIT", "dependencies": { "ms": "2.0.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/morgan/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, "node_modules/appium-uiautomator2-driver/node_modules/morgan/node_modules/on-finished": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", "license": "MIT", "dependencies": { "ee-first": "1.1.1" }, "engines": { "node": ">= 0.8" } }, "node_modules/appium-uiautomator2-driver/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, "node_modules/appium-uiautomator2-driver/node_modules/ncp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", "integrity": "sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA==", "license": "MIT", "bin": { "ncp": "bin/ncp" } }, "node_modules/appium-uiautomator2-driver/node_modules/negotiator": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/appium-uiautomator2-driver/node_modules/normalize-package-data": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-8.0.0.tgz", "integrity": "sha512-RWk+PI433eESQ7ounYxIp67CYuVsS1uYSonX3kA6ps/3LWfjVQa/ptEg6Y3T6uAMq1mWpX9PQ+qx+QaHpsc7gQ==", "license": "BSD-2-Clause", "dependencies": { "hosted-git-info": "^9.0.0", "semver": "^7.3.5", "validate-npm-package-license": "^3.0.4" }, "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/object-inspect": { "version": "1.13.4", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", "license": "MIT", "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/appium-uiautomator2-driver/node_modules/obuf": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", "license": "MIT", "optional": true }, "node_modules/appium-uiautomator2-driver/node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "license": "MIT", "dependencies": { "ee-first": "1.1.1" }, "engines": { "node": ">= 0.8" } }, "node_modules/appium-uiautomator2-driver/node_modules/on-headers": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz", "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==", "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/appium-uiautomator2-driver/node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "license": "ISC", "dependencies": { "wrappy": "1" } }, "node_modules/appium-uiautomator2-driver/node_modules/p-limit": { "version": "7.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-7.3.0.tgz", "integrity": "sha512-7cIXg/Z0M5WZRblrsOla88S4wAK+zOQQWeBYfV3qJuJXMr+LnbYjaadrFaS0JILfEDPVqHyKnZ1Z/1d6J9VVUw==", "license": "MIT", "dependencies": { "yocto-queue": "^1.2.1" }, "engines": { "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/appium-uiautomator2-driver/node_modules/package-directory": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/package-directory/-/package-directory-8.2.0.tgz", "integrity": "sha512-qJSu5Mo6tHmRxCy2KCYYKYgcfBdUpy9dwReaZD/xwf608AUk/MoRtIOWzgDtUeGeC7n/55yC3MI1Q+MbSoektw==", "license": "MIT", "dependencies": { "find-up-simple": "^1.0.0" }, "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/appium-uiautomator2-driver/node_modules/package-json-from-dist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", "license": "BlueOak-1.0.0" }, "node_modules/appium-uiautomator2-driver/node_modules/parse-json": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.3.0.tgz", "integrity": "sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.26.2", "index-to-position": "^1.1.0", "type-fest": "^4.39.1" }, "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/appium-uiautomator2-driver/node_modules/parse-json/node_modules/type-fest": { "version": "4.41.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/appium-uiautomator2-driver/node_modules/parse-listing": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/parse-listing/-/parse-listing-1.1.3.tgz", "integrity": "sha512-a1p1i+9Qyc8pJNwdrSvW1g5TPxRH0sywVi6OzVvYHRo6xwF9bDWBxtH0KkxeOOvhUE8vAMtiSfsYQFOuK901eA==", "engines": { "node": ">=0.6.21" } }, "node_modules/appium-uiautomator2-driver/node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/appium-uiautomator2-driver/node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/appium-uiautomator2-driver/node_modules/path-scurry": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", "license": "BlueOak-1.0.0", "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" }, "engines": { "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/appium-uiautomator2-driver/node_modules/path-to-regexp": { "version": "8.4.2", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz", "integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==", "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, "node_modules/appium-uiautomator2-driver/node_modules/pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", "license": "MIT" }, "node_modules/appium-uiautomator2-driver/node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "license": "ISC" }, "node_modules/appium-uiautomator2-driver/node_modules/plist": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz", "integrity": "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==", "license": "MIT", "dependencies": { "@xmldom/xmldom": "^0.8.8", "base64-js": "^1.5.1", "xmlbuilder": "^15.1.1" }, "engines": { "node": ">=10.4.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/plist/node_modules/@xmldom/xmldom": { "version": "0.8.12", "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.12.tgz", "integrity": "sha512-9k/gHF6n/pAi/9tqr3m3aqkuiNosYTurLLUtc7xQ9sxB/wm7WPygCv8GYa6mS0fLJEHhqMC1ATYhz++U/lRHqg==", "license": "MIT", "engines": { "node": ">=10.0.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/pluralize": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/appium-uiautomator2-driver/node_modules/portscanner": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/portscanner/-/portscanner-2.2.0.tgz", "integrity": "sha512-IFroCz/59Lqa2uBvzK3bKDbDDIEaAY8XJ1jFxcLWTqosrsc32//P4VuSB2vZXoHiHqOmx8B5L5hnKOxL/7FlPw==", "license": "MIT", "dependencies": { "async": "^2.6.0", "is-number-like": "^1.0.3" }, "engines": { "node": ">=0.4", "npm": ">=1.0.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/portscanner/node_modules/async": { "version": "2.6.4", "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", "license": "MIT", "dependencies": { "lodash": "^4.17.14" } }, "node_modules/appium-uiautomator2-driver/node_modules/process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", "license": "MIT", "engines": { "node": ">= 0.6.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "license": "MIT" }, "node_modules/appium-uiautomator2-driver/node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "license": "MIT", "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" }, "engines": { "node": ">= 0.10" } }, "node_modules/appium-uiautomator2-driver/node_modules/proxy-from-env": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", "license": "MIT", "engines": { "node": ">=10" } }, "node_modules/appium-uiautomator2-driver/node_modules/qs": { "version": "6.15.1", "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.1.tgz", "integrity": "sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==", "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.1.0" }, "engines": { "node": ">=0.6" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/appium-uiautomator2-driver/node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/appium-uiautomator2-driver/node_modules/raw-body": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", "license": "MIT", "dependencies": { "bytes": "~3.1.2", "http-errors": "~2.0.1", "iconv-lite": "~0.7.0", "unpipe": "~1.0.0" }, "engines": { "node": ">= 0.10" } }, "node_modules/appium-uiautomator2-driver/node_modules/read-pkg": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-10.1.0.tgz", "integrity": "sha512-I8g2lArQiP78ll51UeMZojewtYgIRCKCWqZEgOO8c/uefTI+XDXvCSXu3+YNUaTNvZzobrL5+SqHjBrByRRTdg==", "license": "MIT", "dependencies": { "@types/normalize-package-data": "^2.4.4", "normalize-package-data": "^8.0.0", "parse-json": "^8.3.0", "type-fest": "^5.4.4", "unicorn-magic": "^0.4.0" }, "engines": { "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/appium-uiautomator2-driver/node_modules/readable-stream": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", "license": "MIT", "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", "events": "^3.3.0", "process": "^0.11.10", "string_decoder": "^1.3.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/readable-stream/node_modules/buffer": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "license": "MIT", "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" } }, "node_modules/appium-uiautomator2-driver/node_modules/readdir-glob": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz", "integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==", "license": "Apache-2.0", "dependencies": { "minimatch": "^5.1.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/readdir-glob/node_modules/brace-expansion": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/readdir-glob/node_modules/minimatch": { "version": "5.1.9", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz", "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==", "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, "engines": { "node": ">=10" } }, "node_modules/appium-uiautomator2-driver/node_modules/resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/appium-uiautomator2-driver/node_modules/router": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", "license": "MIT", "dependencies": { "debug": "^4.4.0", "depd": "^2.0.0", "is-promise": "^4.0.0", "parseurl": "^1.3.3", "path-to-regexp": "^8.0.0" }, "engines": { "node": ">= 18" } }, "node_modules/appium-uiautomator2-driver/node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "license": "MIT" }, "node_modules/appium-uiautomator2-driver/node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "license": "MIT" }, "node_modules/appium-uiautomator2-driver/node_modules/sanitize-filename": { "version": "1.6.4", "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.4.tgz", "integrity": "sha512-9ZyI08PsvdQl2r/bBIGubpVdR3RR9sY6RDiWFPreA21C/EFlQhmgo20UZlNjZMMZNubusLhAQozkA0Od5J21Eg==", "license": "WTFPL OR ISC", "dependencies": { "truncate-utf8-bytes": "^1.0.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/select-hose": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", "license": "MIT", "optional": true }, "node_modules/appium-uiautomator2-driver/node_modules/semver": { "version": "7.7.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "license": "ISC", "bin": { "semver": "bin/semver.js" }, "engines": { "node": ">=10" } }, "node_modules/appium-uiautomator2-driver/node_modules/send": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", "license": "MIT", "dependencies": { "debug": "^4.4.3", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "fresh": "^2.0.0", "http-errors": "^2.0.1", "mime-types": "^3.0.2", "ms": "^2.1.3", "on-finished": "^2.4.1", "range-parser": "^1.2.1", "statuses": "^2.0.2" }, "engines": { "node": ">= 18" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, "node_modules/appium-uiautomator2-driver/node_modules/serve-favicon": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/serve-favicon/-/serve-favicon-2.5.1.tgz", "integrity": "sha512-JndLBslCLA/ebr7rS3d+/EKkzTsTi1jI2T9l+vHfAaGJ7A7NhtDpSZ0lx81HCNWnnE0yHncG+SSnVf9IMxOwXQ==", "license": "MIT", "dependencies": { "etag": "~1.8.1", "fresh": "~0.5.2", "ms": "~2.1.3", "parseurl": "~1.3.2", "safe-buffer": "~5.2.1" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/serve-favicon/node_modules/fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/appium-uiautomator2-driver/node_modules/serve-favicon/node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "license": "MIT" }, "node_modules/appium-uiautomator2-driver/node_modules/serve-static": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", "license": "MIT", "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", "send": "^1.2.0" }, "engines": { "node": ">= 18" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, "node_modules/appium-uiautomator2-driver/node_modules/set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", "license": "ISC" }, "node_modules/appium-uiautomator2-driver/node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "license": "ISC" }, "node_modules/appium-uiautomator2-driver/node_modules/sharp": { "version": "0.34.5", "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", "hasInstallScript": true, "license": "Apache-2.0", "optional": true, "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.2", "semver": "^7.7.3" }, "engines": { "node": "^18.17.0 || ^20.3.0 || >=21.0.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.5", "@img/sharp-darwin-x64": "0.34.5", "@img/sharp-libvips-darwin-arm64": "1.2.4", "@img/sharp-libvips-darwin-x64": "1.2.4", "@img/sharp-libvips-linux-arm": "1.2.4", "@img/sharp-libvips-linux-arm64": "1.2.4", "@img/sharp-libvips-linux-ppc64": "1.2.4", "@img/sharp-libvips-linux-riscv64": "1.2.4", "@img/sharp-libvips-linux-s390x": "1.2.4", "@img/sharp-libvips-linux-x64": "1.2.4", "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", "@img/sharp-libvips-linuxmusl-x64": "1.2.4", "@img/sharp-linux-arm": "0.34.5", "@img/sharp-linux-arm64": "0.34.5", "@img/sharp-linux-ppc64": "0.34.5", "@img/sharp-linux-riscv64": "0.34.5", "@img/sharp-linux-s390x": "0.34.5", "@img/sharp-linux-x64": "0.34.5", "@img/sharp-linuxmusl-arm64": "0.34.5", "@img/sharp-linuxmusl-x64": "0.34.5", "@img/sharp-wasm32": "0.34.5", "@img/sharp-win32-arm64": "0.34.5", "@img/sharp-win32-ia32": "0.34.5", "@img/sharp-win32-x64": "0.34.5" } }, "node_modules/appium-uiautomator2-driver/node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, "engines": { "node": ">=8" } }, "node_modules/appium-uiautomator2-driver/node_modules/shebang-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/appium-uiautomator2-driver/node_modules/shell-quote": { "version": "1.8.3", "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", "license": "MIT", "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/appium-uiautomator2-driver/node_modules/side-channel": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", "side-channel-list": "^1.0.0", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/appium-uiautomator2-driver/node_modules/side-channel-list": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.4" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/appium-uiautomator2-driver/node_modules/side-channel-map": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", "license": "MIT", "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/appium-uiautomator2-driver/node_modules/side-channel-weakmap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", "license": "MIT", "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3", "side-channel-map": "^1.0.1" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/appium-uiautomator2-driver/node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "license": "ISC" }, "node_modules/appium-uiautomator2-driver/node_modules/spdx-correct": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", "license": "Apache-2.0", "dependencies": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/spdx-exceptions": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", "license": "CC-BY-3.0" }, "node_modules/appium-uiautomator2-driver/node_modules/spdx-expression-parse": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "license": "MIT", "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/spdx-license-ids": { "version": "3.0.23", "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.23.tgz", "integrity": "sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==", "license": "CC0-1.0" }, "node_modules/appium-uiautomator2-driver/node_modules/spdy": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", "license": "MIT", "optional": true, "dependencies": { "debug": "^4.1.0", "handle-thing": "^2.0.0", "http-deceiver": "^1.2.7", "select-hose": "^2.0.0", "spdy-transport": "^3.0.0" }, "engines": { "node": ">=6.0.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/spdy-transport": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", "license": "MIT", "optional": true, "dependencies": { "debug": "^4.1.0", "detect-node": "^2.0.4", "hpack.js": "^2.1.6", "obuf": "^1.1.2", "readable-stream": "^3.0.6", "wbuf": "^1.7.3" } }, "node_modules/appium-uiautomator2-driver/node_modules/spdy-transport/node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "license": "MIT", "optional": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" }, "engines": { "node": ">= 6" } }, "node_modules/appium-uiautomator2-driver/node_modules/statuses": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/appium-uiautomator2-driver/node_modules/stream-buffers": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz", "integrity": "sha512-uyQK/mx5QjHun80FLJTfaWE7JtwfRMKBLkMne6udYOmvH0CawotVa7TfgYHzAnpphn4+TweIx1QKMnRIbipmUg==", "license": "Unlicense", "engines": { "node": ">= 0.10.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/stream-combiner": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz", "integrity": "sha512-6yHMqgLYDzQDcAkL+tjJDC5nSNuNIx0vZtRZeiPh7Saef7VHX9H5Ijn9l2VIol2zaNYlYEX6KyuT/237A58qEQ==", "license": "MIT", "dependencies": { "duplexer": "~0.1.1", "through": "~2.3.4" } }, "node_modules/appium-uiautomator2-driver/node_modules/streamx": { "version": "2.25.0", "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.25.0.tgz", "integrity": "sha512-0nQuG6jf1w+wddNEEXCF4nTg3LtufWINB5eFEN+5TNZW7KWJp6x87+JFL43vaAUPyCfH1wID+mNVyW6OHtFamg==", "license": "MIT", "dependencies": { "events-universal": "^1.0.0", "fast-fifo": "^1.3.2", "text-decoder": "^1.1.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/string_decoder/node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "license": "MIT" }, "node_modules/appium-uiautomator2-driver/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" }, "engines": { "node": ">=8" } }, "node_modules/appium-uiautomator2-driver/node_modules/string-width-cjs": { "name": "string-width", "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" }, "engines": { "node": ">=8" } }, "node_modules/appium-uiautomator2-driver/node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/appium-uiautomator2-driver/node_modules/strip-ansi-cjs": { "name": "strip-ansi", "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/appium-uiautomator2-driver/node_modules/strip-ansi-cjs/node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/appium-uiautomator2-driver/node_modules/strip-ansi/node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/appium-uiautomator2-driver/node_modules/supports-color": { "version": "10.2.2", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-10.2.2.tgz", "integrity": "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==", "license": "MIT", "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/chalk/supports-color?sponsor=1" } }, "node_modules/appium-uiautomator2-driver/node_modules/tagged-tag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/tagged-tag/-/tagged-tag-1.0.0.tgz", "integrity": "sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==", "license": "MIT", "engines": { "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/appium-uiautomator2-driver/node_modules/tar-stream": { "version": "3.1.8", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.8.tgz", "integrity": "sha512-U6QpVRyCGHva435KoNWy9PRoi2IFYCgtEhq9nmrPPpbRacPs9IH4aJ3gbrFC8dPcXvdSZ4XXfXT5Fshbp2MtlQ==", "license": "MIT", "dependencies": { "b4a": "^1.6.4", "bare-fs": "^4.5.5", "fast-fifo": "^1.2.0", "streamx": "^2.15.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/teen_process": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/teen_process/-/teen_process-4.1.0.tgz", "integrity": "sha512-AN8y3MYPExB3r2mkkX9r0wEF4xPfhKOj6YvcfeIqQai+GVhTIhjjdkPvwI5CFT4z8UQ5aZWldzbJ+jNejYAdGw==", "license": "Apache-2.0", "dependencies": { "lodash": "^4.17.21", "shell-quote": "^1.8.1" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" } }, "node_modules/appium-uiautomator2-driver/node_modules/teex": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz", "integrity": "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==", "license": "MIT", "dependencies": { "streamx": "^2.12.5" } }, "node_modules/appium-uiautomator2-driver/node_modules/text-decoder": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.7.tgz", "integrity": "sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ==", "license": "Apache-2.0", "dependencies": { "b4a": "^1.6.4" } }, "node_modules/appium-uiautomator2-driver/node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "license": "MIT" }, "node_modules/appium-uiautomator2-driver/node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "license": "MIT", "engines": { "node": ">=0.6" } }, "node_modules/appium-uiautomator2-driver/node_modules/truncate-utf8-bytes": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", "integrity": "sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==", "license": "WTFPL", "dependencies": { "utf8-byte-length": "^1.0.1" } }, "node_modules/appium-uiautomator2-driver/node_modules/type-fest": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.5.0.tgz", "integrity": "sha512-PlBfpQwiUvGViBNX84Yxwjsdhd1TUlXr6zjX7eoirtCPIr08NAmxwa+fcYBTeRQxHo9YC9wwF3m9i700sHma8g==", "license": "(MIT OR CC0-1.0)", "dependencies": { "tagged-tag": "^1.0.0" }, "engines": { "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/appium-uiautomator2-driver/node_modules/type-is": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", "license": "MIT", "dependencies": { "content-type": "^1.0.5", "media-typer": "^1.1.0", "mime-types": "^3.0.0" }, "engines": { "node": ">= 0.6" } }, "node_modules/appium-uiautomator2-driver/node_modules/unicorn-magic": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.4.0.tgz", "integrity": "sha512-wH590V9VNgYH9g3lH9wWjTrUoKsjLF6sGLjhR4sH1LWpLmCOH0Zf7PukhDA8BiS7KHe4oPNkcTHqYkj7SOGUOw==", "license": "MIT", "engines": { "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/appium-uiautomator2-driver/node_modules/unorm": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/unorm/-/unorm-1.6.0.tgz", "integrity": "sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA==", "license": "MIT or GPL-2.0", "engines": { "node": ">= 0.4.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/appium-uiautomator2-driver/node_modules/utf8-byte-length": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.5.tgz", "integrity": "sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA==", "license": "(WTFPL OR MIT)" }, "node_modules/appium-uiautomator2-driver/node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "license": "MIT" }, "node_modules/appium-uiautomator2-driver/node_modules/uuid": { "version": "13.0.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-13.0.0.tgz", "integrity": "sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], "license": "MIT", "bin": { "uuid": "dist-node/bin/uuid" } }, "node_modules/appium-uiautomator2-driver/node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "license": "Apache-2.0", "dependencies": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/appium-uiautomator2-driver/node_modules/wbuf": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", "license": "MIT", "optional": true, "dependencies": { "minimalistic-assert": "^1.0.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/which": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/which/-/which-6.0.1.tgz", "integrity": "sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==", "license": "ISC", "dependencies": { "isexe": "^4.0.0" }, "bin": { "node-which": "bin/which.js" }, "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/wrap-ansi-cjs": { "name": "wrap-ansi", "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/appium-uiautomator2-driver/node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "license": "ISC" }, "node_modules/appium-uiautomator2-driver/node_modules/ws": { "version": "8.20.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz", "integrity": "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==", "license": "MIT", "engines": { "node": ">=10.0.0" }, "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "peerDependenciesMeta": { "bufferutil": { "optional": true }, "utf-8-validate": { "optional": true } } }, "node_modules/appium-uiautomator2-driver/node_modules/xmlbuilder": { "version": "15.1.1", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", "license": "MIT", "engines": { "node": ">=8.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/xpath": { "version": "0.0.34", "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.34.tgz", "integrity": "sha512-FxF6+rkr1rNSQrhUNYrAFJpRXNzlDoMxeXN5qI84939ylEv3qqPFKa85Oxr6tDaJKqwW6KKyo2v26TSv3k6LeA==", "license": "MIT", "engines": { "node": ">=0.6.0" } }, "node_modules/appium-uiautomator2-driver/node_modules/yauzl": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-3.3.0.tgz", "integrity": "sha512-PtGEvEP30p7sbIBJKUBjUnqgTVOyMURc4dLo9iNyAJnNIEz9pm88cCXF21w94Kg3k6RXkeZh5DHOGS0qEONvNQ==", "license": "MIT", "dependencies": { "buffer-crc32": "~0.2.3", "pend": "~1.2.0" }, "engines": { "node": ">=12" } }, "node_modules/appium-uiautomator2-driver/node_modules/yauzl/node_modules/buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", "license": "MIT", "engines": { "node": "*" } }, "node_modules/appium-uiautomator2-driver/node_modules/yocto-queue": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.2.tgz", "integrity": "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==", "license": "MIT", "engines": { "node": ">=12.20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/appium-uiautomator2-driver/node_modules/yoctocolors": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.2.tgz", "integrity": "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==", "license": "MIT", "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/appium-uiautomator2-driver/node_modules/zip-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-6.0.1.tgz", "integrity": "sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==", "license": "MIT", "dependencies": { "archiver-utils": "^5.0.0", "compress-commons": "^6.0.2", "readable-stream": "^4.0.0" }, "engines": { "node": ">= 14" } }, "node_modules/appium-xcuitest-driver": { "version": "10.43.1", "resolved": "https://registry.npmjs.org/appium-xcuitest-driver/-/appium-xcuitest-driver-10.43.1.tgz", "integrity": "sha512-MCUSesaNaa2rXP9xLbQmMFV9XmZH2LUK5TO/fD9kiSqQJzT31lxtN+U0elpUgfnu6ZIGkug+MB+x84RQud7Ahg==", "hasShrinkwrap": true, "license": "Apache-2.0", "dependencies": { "@appium/strongbox": "^1.0.0-rc.1", "@colors/colors": "^1.6.0", "appium-idb": "^2.0.0", "appium-ios-device": "^3.0.0", "appium-ios-simulator": "^8.0.0", "appium-remote-debugger": "^15.6.0", "appium-webdriveragent": "^11.4.0", "appium-xcode": "^6.0.2", "async-lock": "^1.4.0", "asyncbox": "^6.0.1", "axios": "^1.4.0", "bluebird": "^3.7.2", "commander": "^14.0.1", "css-selector-parser": "^3.0.0", "js2xmlparser2": "^0.x", "lodash": "^4.17.21", "lru-cache": "^11.1.0", "moment": "^2.29.4", "moment-timezone": "^0.x", "node-devicectl": "^1.1.0", "node-simctl": "^8.1.1", "portscanner": "^2.2.0", "semver": "^7.5.4", "teen_process": "^4.0.4", "winston": "^3.17.0", "ws": "^8.13.0" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" }, "optionalDependencies": { "appium-ios-remotexpc": "^0.x" }, "peerDependencies": { "appium": "^3.0.0-rc.2" } }, "node_modules/appium-xcuitest-driver/node_modules/@appium/base-driver": { "version": "10.3.0", "resolved": "https://registry.npmjs.org/@appium/base-driver/-/base-driver-10.3.0.tgz", "integrity": "sha512-9r+1f9EtcJt9NXIlyHdFMoD7DsAZPzpRq4Kj1hGZf7+26q1SFEyyMAuWxvlWGY7EoyPtPRyMUkM4dHiSK3Q9+w==", "license": "Apache-2.0", "dependencies": { "@appium/support": "7.1.0", "@appium/types": "1.3.0", "@colors/colors": "1.6.0", "async-lock": "1.4.1", "asyncbox": "6.1.0", "axios": "1.15.0", "bluebird": "3.7.2", "body-parser": "2.2.2", "express": "5.2.1", "fastest-levenshtein": "1.0.16", "http-status-codes": "2.3.0", "lodash": "4.18.1", "lru-cache": "11.3.3", "method-override": "3.0.0", "morgan": "1.10.1", "path-to-regexp": "8.4.2", "serve-favicon": "2.5.1", "type-fest": "5.5.0" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" }, "optionalDependencies": { "spdy": "4.0.2" } }, "node_modules/appium-xcuitest-driver/node_modules/@appium/logger": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@appium/logger/-/logger-2.0.6.tgz", "integrity": "sha512-9e8n9CtINBwi1ASEU5OyswmR2F7OnbrGfmf9yTy9i+rx4GR9RJlEp0/arsxvuyWCep67tOmM4FiRyXxxHjOK5Q==", "license": "ISC", "dependencies": { "console-control-strings": "1.1.0", "lodash": "4.18.1", "lru-cache": "11.3.3", "set-blocking": "2.0.0" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" } }, "node_modules/appium-xcuitest-driver/node_modules/@appium/schema": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@appium/schema/-/schema-1.1.0.tgz", "integrity": "sha512-m0vTLU7mhC9RR294Nz84g+FhEQ0iZKq6p3rfz1+qfEqCXRXUvDbllSOu2tCVpBKMIoEFZAmkwjuwXobJpCnilQ==", "license": "Apache-2.0", "dependencies": { "json-schema": "0.4.0" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" } }, "node_modules/appium-xcuitest-driver/node_modules/@appium/strongbox": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@appium/strongbox/-/strongbox-1.1.0.tgz", "integrity": "sha512-X+Ff/6sGiTXHx2W3s+Gg3XyZMbIZe5v3jFSrwUJ9kH7NuGzpzrzEoKx9EMOw7iXVLMV6/NmuDQPq80gzOcRwjA==", "license": "Apache-2.0", "dependencies": { "env-paths": "4.0.0", "slugify": "1.6.9" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" } }, "node_modules/appium-xcuitest-driver/node_modules/@appium/support": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/@appium/support/-/support-7.1.0.tgz", "integrity": "sha512-kY4Qv4TzLCYmZnN2eNptEa8RiRzpbimIQ6tKuDaqLC2Y3q5Al4NumL/xRQAvfXJq/hNezq2Jh8NwciEW8zX/0g==", "license": "Apache-2.0", "dependencies": { "@appium/logger": "2.0.6", "@appium/tsconfig": "1.1.2", "@appium/types": "1.3.0", "@colors/colors": "1.6.0", "archiver": "7.0.1", "asyncbox": "6.1.0", "axios": "1.15.0", "base64-stream": "1.0.0", "bluebird": "3.7.2", "bplist-creator": "0.1.1", "bplist-parser": "0.3.2", "form-data": "4.0.5", "get-stream": "9.0.1", "glob": "13.0.6", "jsftp": "2.1.3", "klaw": "4.1.0", "lockfile": "1.0.4", "lodash": "4.18.1", "log-symbols": "7.0.1", "ncp": "2.0.0", "package-directory": "8.2.0", "plist": "3.1.0", "pluralize": "8.0.0", "read-pkg": "10.1.0", "resolve-from": "5.0.0", "sanitize-filename": "1.6.4", "semver": "7.7.4", "shell-quote": "1.8.3", "supports-color": "10.2.2", "teen_process": "4.1.0", "type-fest": "5.5.0", "uuid": "13.0.0", "which": "6.0.1", "yauzl": "3.3.0" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" }, "optionalDependencies": { "sharp": "0.34.5" } }, "node_modules/appium-xcuitest-driver/node_modules/@appium/tsconfig": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@appium/tsconfig/-/tsconfig-1.1.2.tgz", "integrity": "sha512-lHKBm7hXCROc1Ha/cBxS4o3iQkeY96Pz7qM9Uh9vFDkdpTGBk56V1lmc3iGcgBYKBlaRT/LZmTsqClvHoiXhvw==", "license": "Apache-2.0", "dependencies": { "@tsconfig/node20": "20.1.9" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" } }, "node_modules/appium-xcuitest-driver/node_modules/@appium/types": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@appium/types/-/types-1.3.0.tgz", "integrity": "sha512-Gv4ev/5K5N7TvAHqem2DmB50zipC951QlmCDpuxDNHQl2dtCr20vJgnN8if7upqLcBX/6yNp3udR+f1n99zgcQ==", "license": "Apache-2.0", "dependencies": { "@appium/logger": "2.0.6", "@appium/schema": "1.1.0", "@appium/tsconfig": "1.1.2", "type-fest": "5.5.0" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" } }, "node_modules/appium-xcuitest-driver/node_modules/@babel/code-frame": { "version": "7.29.0", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", "license": "MIT", "dependencies": { "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/appium-xcuitest-driver/node_modules/@babel/helper-validator-identifier": { "version": "7.28.5", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/appium-xcuitest-driver/node_modules/@colors/colors": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==", "license": "MIT", "engines": { "node": ">=0.1.90" } }, "node_modules/appium-xcuitest-driver/node_modules/@dabh/diagnostics": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.8.tgz", "integrity": "sha512-R4MSXTVnuMzGD7bzHdW2ZhhdPC/igELENcq5IjEverBvq5hn1SXCWcsi6eSsdWP0/Ur+SItRRjAktmdoX/8R/Q==", "license": "MIT", "dependencies": { "@so-ric/colorspace": "^1.1.6", "enabled": "2.0.x", "kuler": "^2.0.0" } }, "node_modules/appium-xcuitest-driver/node_modules/@img/colour": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", "license": "MIT", "optional": true, "engines": { "node": ">=18" } }, "node_modules/appium-xcuitest-driver/node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", "license": "ISC", "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", "strip-ansi": "^7.0.1", "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", "wrap-ansi": "^8.1.0", "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" }, "engines": { "node": ">=12" } }, "node_modules/appium-xcuitest-driver/node_modules/@isaacs/cliui/node_modules/ansi-styles": { "version": "6.2.3", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", "license": "MIT", "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/appium-xcuitest-driver/node_modules/@isaacs/cliui/node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/@isaacs/cliui/node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "license": "MIT", "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" }, "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/appium-xcuitest-driver/node_modules/@isaacs/cliui/node_modules/strip-ansi": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", "license": "MIT", "dependencies": { "ansi-regex": "^6.2.2" }, "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, "node_modules/appium-xcuitest-driver/node_modules/@isaacs/cliui/node_modules/wrap-ansi": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", "license": "MIT", "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", "strip-ansi": "^7.0.1" }, "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/appium-xcuitest-driver/node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", "license": "MIT", "optional": true, "engines": { "node": ">=14" } }, "node_modules/appium-xcuitest-driver/node_modules/@sec-ant/readable-stream": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==", "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/@so-ric/colorspace": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/@so-ric/colorspace/-/colorspace-1.1.6.tgz", "integrity": "sha512-/KiKkpHNOBgkFJwu9sh48LkHSMYGyuTcSFK/qMBdnOAlrRJzRSXAOFB5qwzaVQuDl8wAvHVMkaASQDReTahxuw==", "license": "MIT", "dependencies": { "color": "^5.0.2", "text-hex": "1.0.x" } }, "node_modules/appium-xcuitest-driver/node_modules/@tsconfig/node20": { "version": "20.1.9", "resolved": "https://registry.npmjs.org/@tsconfig/node20/-/node20-20.1.9.tgz", "integrity": "sha512-IjlTv1RsvnPtUcjTqtVsZExKVq+KQx4g5pCP5tI7rAs6Xesl2qFwSz/tPDBC4JajkL/MlezBu3gPUwqRHl+RIg==", "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/@types/node": { "version": "25.6.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-25.6.0.tgz", "integrity": "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==", "license": "MIT", "optional": true, "dependencies": { "undici-types": "~7.19.0" } }, "node_modules/appium-xcuitest-driver/node_modules/@types/normalize-package-data": { "version": "2.4.4", "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/@types/triple-beam": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz", "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==", "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/@xmldom/xmldom": { "version": "0.9.9", "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.9.9.tgz", "integrity": "sha512-qycIHAucxy/LXAYIjmLmtQ8q9GPnMbnjG1KXhWm9o5sCr6pOYDATkMPiTNa6/v8eELyqOQ2FsEqeoFYmgv/gJg==", "license": "MIT", "engines": { "node": ">=14.6" } }, "node_modules/appium-xcuitest-driver/node_modules/abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", "license": "MIT", "dependencies": { "event-target-shim": "^5.0.0" }, "engines": { "node": ">=6.5" } }, "node_modules/appium-xcuitest-driver/node_modules/accepts": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", "license": "MIT", "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" }, "engines": { "node": ">= 0.6" } }, "node_modules/appium-xcuitest-driver/node_modules/ansi-regex": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "license": "MIT", "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, "node_modules/appium-xcuitest-driver/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/appium-xcuitest-driver/node_modules/appium-idb": { "version": "2.0.10", "resolved": "https://registry.npmjs.org/appium-idb/-/appium-idb-2.0.10.tgz", "integrity": "sha512-k25bH3dWbir75iU51e4qMwN6UURcX/KY7zz7e8mZ5ESOVdwfeX4Tp7XxbvnIweHFPsbGPPBf7EmazBYC5a+/FQ==", "license": "Apache-2.0", "dependencies": { "@appium/support": "^7.0.0-rc.1", "asyncbox": "^6.1.0", "bluebird": "^3.1.1", "lodash": "^4.0.0", "teen_process": "^4.0.4" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" } }, "node_modules/appium-xcuitest-driver/node_modules/appium-ios-device": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/appium-ios-device/-/appium-ios-device-3.1.10.tgz", "integrity": "sha512-2oE7yQtLSdrcZ9YArqgGguzDuiplHj0GXSMlTfwTXl0n22DEzkV0M1mXdaNaWNuzVBJ5VDc1EuYv38p1ruuk2g==", "license": "Apache-2.0", "dependencies": { "@appium/support": "^7.0.0-rc.1", "asyncbox": "^6.0.1", "axios": "^1.6.7", "bluebird": "^3.1.1", "bplist-creator": "^0.x", "bplist-parser": "^0.x", "lodash": "^4.17.15", "semver": "^7.0.0" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" } }, "node_modules/appium-xcuitest-driver/node_modules/appium-ios-remotexpc": { "version": "0.44.0", "resolved": "https://registry.npmjs.org/appium-ios-remotexpc/-/appium-ios-remotexpc-0.44.0.tgz", "integrity": "sha512-e7DbfRJuobWpsOHTpdtzWPlb2R3HvLEjzist9D5Lzk5bzpEDasYiV+hlr+mvq6VM7gjB7ZHN8lZ3CC5kF3HQAw==", "license": "Apache-2.0", "optional": true, "dependencies": { "@appium/strongbox": "^1.0.0-rc.1", "@appium/support": "^7.0.0-rc.1", "@types/node": "^25.0.2", "@xmldom/xmldom": "^0.9.8", "appium-ios-tuntap": "^0.x", "axios": "^1.12.0", "commander": "^14.0.1", "dnssd": "^0.x", "minimatch": "^10.1.1", "node-devicectl": "^1.2.0", "npm-run-all2": "^8.0.4", "path-to-regexp": "^8.3.0" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" } }, "node_modules/appium-xcuitest-driver/node_modules/appium-ios-simulator": { "version": "8.0.12", "resolved": "https://registry.npmjs.org/appium-ios-simulator/-/appium-ios-simulator-8.0.12.tgz", "integrity": "sha512-ZIq9k0PJTq7MtttQmu8pBkQE7i1TNw/itqklAkwmstld8vTAn2RXv3+hAwFo1aZt01gdSPjky5EFgizNu72//Q==", "license": "Apache-2.0", "dependencies": { "@appium/support": "^7.0.0-rc.1", "@xmldom/xmldom": "^0.x", "appium-xcode": "^6.0.0", "async-lock": "^1.0.0", "asyncbox": "^6.0.1", "bluebird": "^3.5.1", "lodash": "^4.2.1", "node-simctl": "^8.1.1", "semver": "^7.0.0", "teen_process": "^4.0.4" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" } }, "node_modules/appium-xcuitest-driver/node_modules/appium-ios-tuntap": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/appium-ios-tuntap/-/appium-ios-tuntap-0.1.5.tgz", "integrity": "sha512-xvYpeqVGl4VgJTDm7ExtwIEalfkfzYoPgC4Tf8a6mX5zX7R5fDzMBO4K7+87c2VSrsHl4R5sSFmmCFkNkTZKxQ==", "hasInstallScript": true, "license": "Apache-2.0", "optional": true, "dependencies": { "@appium/support": "^7.0.0-rc.1", "node-addon-api": "^8.5.0", "typescript": "^5.8.3" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" } }, "node_modules/appium-xcuitest-driver/node_modules/appium-ios-tuntap/node_modules/typescript": { "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "license": "Apache-2.0", "optional": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { "node": ">=14.17" } }, "node_modules/appium-xcuitest-driver/node_modules/appium-remote-debugger": { "version": "15.6.0", "resolved": "https://registry.npmjs.org/appium-remote-debugger/-/appium-remote-debugger-15.6.0.tgz", "integrity": "sha512-vyN2PO/hQ+/DC9ZuY0r6xjg9zedltkSKuUJx3WfVZpgvv/al9uE/AYzk5C/arlwMjAR6Ci+LJFOHUtfDJweTSA==", "license": "Apache-2.0", "dependencies": { "@appium/base-driver": "^10.0.0-rc.1", "@appium/support": "^7.0.0-rc.1", "appium-ios-device": "^3.0.0", "async-lock": "^1.4.1", "asyncbox": "^6.1.0", "bluebird": "^3.4.7", "glob": "^13.0.0", "lodash": "^4.17.11", "teen_process": "^4.0.4" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" }, "optionalDependencies": { "appium-ios-remotexpc": "^0.x" } }, "node_modules/appium-xcuitest-driver/node_modules/appium-webdriveragent": { "version": "11.4.1", "resolved": "https://registry.npmjs.org/appium-webdriveragent/-/appium-webdriveragent-11.4.1.tgz", "integrity": "sha512-VjYMujzNGmm42SVwL3HwJfZlzVzbguWwAyq7x0nk+6rRb6Y66xghRrWRAxz01vtE4TfUA5Mc6FcXlw4+agB6PA==", "license": "Apache-2.0", "dependencies": { "@appium/base-driver": "^10.0.0-rc.1", "@appium/strongbox": "^1.0.0-rc.1", "@appium/support": "^7.0.0-rc.1", "appium-ios-device": "^3.0.0", "appium-ios-simulator": "^8.0.0", "async-lock": "^1.0.0", "asyncbox": "^6.1.0", "axios": "^1.4.0", "bluebird": "^3.5.5", "lodash": "^4.17.11", "teen_process": "^4.0.7" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" } }, "node_modules/appium-xcuitest-driver/node_modules/appium-xcode": { "version": "6.1.9", "resolved": "https://registry.npmjs.org/appium-xcode/-/appium-xcode-6.1.9.tgz", "integrity": "sha512-m7bQPXMUitycAvPNmNQ/UdoZJhtcH2zCjxXcvQYi4uZTHqexcjy76MpMrVFsESJ7Qd8+0U2vmnMNpfB/M/BupQ==", "license": "Apache-2.0", "dependencies": { "@appium/support": "^7.0.0-rc.1", "asyncbox": "^6.0.1", "bluebird": "^3.7.2", "lodash": "^4.17.4", "plist": "^3.0.1", "semver": "^7.0.0", "teen_process": "^4.0.4" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" } }, "node_modules/appium-xcuitest-driver/node_modules/archiver": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/archiver/-/archiver-7.0.1.tgz", "integrity": "sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==", "license": "MIT", "dependencies": { "archiver-utils": "^5.0.2", "async": "^3.2.4", "buffer-crc32": "^1.0.0", "readable-stream": "^4.0.0", "readdir-glob": "^1.1.2", "tar-stream": "^3.0.0", "zip-stream": "^6.0.1" }, "engines": { "node": ">= 14" } }, "node_modules/appium-xcuitest-driver/node_modules/archiver-utils": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-5.0.2.tgz", "integrity": "sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==", "license": "MIT", "dependencies": { "glob": "^10.0.0", "graceful-fs": "^4.2.0", "is-stream": "^2.0.1", "lazystream": "^1.0.0", "lodash": "^4.17.15", "normalize-path": "^3.0.0", "readable-stream": "^4.0.0" }, "engines": { "node": ">= 14" } }, "node_modules/appium-xcuitest-driver/node_modules/archiver-utils/node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/archiver-utils/node_modules/brace-expansion": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/appium-xcuitest-driver/node_modules/archiver-utils/node_modules/glob": { "version": "10.5.0", "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/appium-xcuitest-driver/node_modules/archiver-utils/node_modules/lru-cache": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "license": "ISC" }, "node_modules/appium-xcuitest-driver/node_modules/archiver-utils/node_modules/minimatch": { "version": "9.0.9", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "license": "ISC", "dependencies": { "brace-expansion": "^2.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/appium-xcuitest-driver/node_modules/archiver-utils/node_modules/path-scurry": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", "license": "BlueOak-1.0.0", "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { "node": ">=16 || 14 >=14.18" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/appium-xcuitest-driver/node_modules/async": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/async-lock": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/async-lock/-/async-lock-1.4.1.tgz", "integrity": "sha512-Az2ZTpuytrtqENulXwO3GGv1Bztugx6TT37NIo7imr/Qo0gsYiGtSdBa2B6fsXhTpVZDNfu1Qn3pk531e3q+nQ==", "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/asyncbox": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/asyncbox/-/asyncbox-6.1.0.tgz", "integrity": "sha512-KZwKNVnDdDe0ubN+fFMuHhSljZNHnbjdJABImoqFzQP61oIg6sMlhXIqOIu3WRd7YwW89q+eVj2Ty/Ax5dbh2Q==", "license": "Apache-2.0", "dependencies": { "p-limit": "^7.2.0" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" } }, "node_modules/appium-xcuitest-driver/node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/axios": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/axios/-/axios-1.15.0.tgz", "integrity": "sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q==", "license": "MIT", "dependencies": { "follow-redirects": "^1.15.11", "form-data": "^4.0.5", "proxy-from-env": "^2.1.0" } }, "node_modules/appium-xcuitest-driver/node_modules/b4a": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.8.0.tgz", "integrity": "sha512-qRuSmNSkGQaHwNbM7J78Wwy+ghLEYF1zNrSeMxj4Kgw6y33O3mXcQ6Ie9fRvfU/YnxWkOchPXbaLb73TkIsfdg==", "license": "Apache-2.0", "peerDependencies": { "react-native-b4a": "*" }, "peerDependenciesMeta": { "react-native-b4a": { "optional": true } } }, "node_modules/appium-xcuitest-driver/node_modules/balanced-match": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", "license": "MIT", "engines": { "node": "18 || 20 || >=22" } }, "node_modules/appium-xcuitest-driver/node_modules/bare-events": { "version": "2.8.2", "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.8.2.tgz", "integrity": "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==", "license": "Apache-2.0", "peerDependencies": { "bare-abort-controller": "*" }, "peerDependenciesMeta": { "bare-abort-controller": { "optional": true } } }, "node_modules/appium-xcuitest-driver/node_modules/bare-fs": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.7.0.tgz", "integrity": "sha512-xzqKsCFxAek9aezYhjJuJRXBIaYlg/0OGDTZp+T8eYmYMlm66cs6cYko02drIyjN2CBbi+I6L7YfXyqpqtKRXA==", "license": "Apache-2.0", "dependencies": { "bare-events": "^2.5.4", "bare-path": "^3.0.0", "bare-stream": "^2.6.4", "bare-url": "^2.2.2", "fast-fifo": "^1.3.2" }, "engines": { "bare": ">=1.16.0" }, "peerDependencies": { "bare-buffer": "*" }, "peerDependenciesMeta": { "bare-buffer": { "optional": true } } }, "node_modules/appium-xcuitest-driver/node_modules/bare-os": { "version": "3.8.7", "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.8.7.tgz", "integrity": "sha512-G4Gr1UsGeEy2qtDTZwL7JFLo2wapUarz7iTMcYcMFdS89AIQuBoyjgXZz0Utv7uHs3xA9LckhVbeBi8lEQrC+w==", "license": "Apache-2.0", "engines": { "bare": ">=1.14.0" } }, "node_modules/appium-xcuitest-driver/node_modules/bare-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz", "integrity": "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==", "license": "Apache-2.0", "dependencies": { "bare-os": "^3.0.1" } }, "node_modules/appium-xcuitest-driver/node_modules/bare-stream": { "version": "2.12.0", "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.12.0.tgz", "integrity": "sha512-w28i8lkBgREV3rPXGbgK+BO66q+ZpKqRWrZLiCdmmUlLPrQ45CzkvRhN+7lnv00Gpi2zy5naRxnUFAxCECDm9g==", "license": "Apache-2.0", "dependencies": { "streamx": "^2.25.0", "teex": "^1.0.1" }, "peerDependencies": { "bare-abort-controller": "*", "bare-buffer": "*", "bare-events": "*" }, "peerDependenciesMeta": { "bare-abort-controller": { "optional": true }, "bare-buffer": { "optional": true }, "bare-events": { "optional": true } } }, "node_modules/appium-xcuitest-driver/node_modules/bare-url": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.4.0.tgz", "integrity": "sha512-NSTU5WN+fy/L0DDenfE8SXQna4voXuW0FHM7wH8i3/q9khUSchfPbPezO4zSFMnDGIf9YE+mt/RWhZgNRKRIXA==", "license": "Apache-2.0", "dependencies": { "bare-path": "^3.0.0" } }, "node_modules/appium-xcuitest-driver/node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/base64-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/base64-stream/-/base64-stream-1.0.0.tgz", "integrity": "sha512-BQQZftaO48FcE1Kof9CmXMFaAdqkcNorgc8CxesZv9nMbbTF1EFyQe89UOuh//QMmdtfUDXyO8rgUalemL5ODA==", "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/basic-auth": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", "license": "MIT", "dependencies": { "safe-buffer": "5.1.2" }, "engines": { "node": ">= 0.8" } }, "node_modules/appium-xcuitest-driver/node_modules/big-integer": { "version": "1.6.52", "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", "license": "Unlicense", "engines": { "node": ">=0.6" } }, "node_modules/appium-xcuitest-driver/node_modules/bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/body-parser": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==", "license": "MIT", "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", "debug": "^4.4.3", "http-errors": "^2.0.0", "iconv-lite": "^0.7.0", "on-finished": "^2.4.1", "qs": "^6.14.1", "raw-body": "^3.0.1", "type-is": "^2.0.1" }, "engines": { "node": ">=18" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, "node_modules/appium-xcuitest-driver/node_modules/bplist-creator": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.1.1.tgz", "integrity": "sha512-Ese7052fdWrxp/vqSJkydgx/1MdBnNOCV2XVfbmdGWD2H6EYza+Q4pyYSuVSnCUD22hfI/BFI4jHaC3NLXLlJQ==", "license": "MIT", "dependencies": { "stream-buffers": "2.2.x" } }, "node_modules/appium-xcuitest-driver/node_modules/bplist-parser": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.3.2.tgz", "integrity": "sha512-apC2+fspHGI3mMKj+dGevkGo/tCqVB8jMb6i+OX+E29p0Iposz07fABkRIfVUPNd5A5VbuOz1bZbnmkKLYF+wQ==", "license": "MIT", "dependencies": { "big-integer": "1.6.x" }, "engines": { "node": ">= 5.10.0" } }, "node_modules/appium-xcuitest-driver/node_modules/brace-expansion": { "version": "5.0.5", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", "license": "MIT", "dependencies": { "balanced-match": "^4.0.2" }, "engines": { "node": "18 || 20 || >=22" } }, "node_modules/appium-xcuitest-driver/node_modules/buffer-crc32": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz", "integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==", "license": "MIT", "engines": { "node": ">=8.0.0" } }, "node_modules/appium-xcuitest-driver/node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/appium-xcuitest-driver/node_modules/call-bind-apply-helpers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" }, "engines": { "node": ">= 0.4" } }, "node_modules/appium-xcuitest-driver/node_modules/call-bound": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/appium-xcuitest-driver/node_modules/color": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/color/-/color-5.0.3.tgz", "integrity": "sha512-ezmVcLR3xAVp8kYOm4GS45ZLLgIE6SPAFoduLr6hTDajwb3KZ2F46gulK3XpcwRFb5KKGCSezCBAY4Dw4HsyXA==", "license": "MIT", "dependencies": { "color-convert": "^3.1.3", "color-string": "^2.1.3" }, "engines": { "node": ">=18" } }, "node_modules/appium-xcuitest-driver/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, "engines": { "node": ">=7.0.0" } }, "node_modules/appium-xcuitest-driver/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/color-string": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/color-string/-/color-string-2.1.4.tgz", "integrity": "sha512-Bb6Cq8oq0IjDOe8wJmi4JeNn763Xs9cfrBcaylK1tPypWzyoy2G3l90v9k64kjphl/ZJjPIShFztenRomi8WTg==", "license": "MIT", "dependencies": { "color-name": "^2.0.0" }, "engines": { "node": ">=18" } }, "node_modules/appium-xcuitest-driver/node_modules/color-string/node_modules/color-name": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz", "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==", "license": "MIT", "engines": { "node": ">=12.20" } }, "node_modules/appium-xcuitest-driver/node_modules/color/node_modules/color-convert": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-3.1.3.tgz", "integrity": "sha512-fasDH2ont2GqF5HpyO4w0+BcewlhHEZOFn9c1ckZdHpJ56Qb7MHhH/IcJZbBGgvdtwdwNbLvxiBEdg336iA9Sg==", "license": "MIT", "dependencies": { "color-name": "^2.0.0" }, "engines": { "node": ">=14.6" } }, "node_modules/appium-xcuitest-driver/node_modules/color/node_modules/color-name": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz", "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==", "license": "MIT", "engines": { "node": ">=12.20" } }, "node_modules/appium-xcuitest-driver/node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" }, "engines": { "node": ">= 0.8" } }, "node_modules/appium-xcuitest-driver/node_modules/commander": { "version": "14.0.3", "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz", "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==", "license": "MIT", "engines": { "node": ">=20" } }, "node_modules/appium-xcuitest-driver/node_modules/compress-commons": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-6.0.2.tgz", "integrity": "sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==", "license": "MIT", "dependencies": { "crc-32": "^1.2.0", "crc32-stream": "^6.0.0", "is-stream": "^2.0.1", "normalize-path": "^3.0.0", "readable-stream": "^4.0.0" }, "engines": { "node": ">= 14" } }, "node_modules/appium-xcuitest-driver/node_modules/console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", "license": "ISC" }, "node_modules/appium-xcuitest-driver/node_modules/content-disposition": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.1.0.tgz", "integrity": "sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==", "license": "MIT", "engines": { "node": ">=18" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, "node_modules/appium-xcuitest-driver/node_modules/content-type": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/appium-xcuitest-driver/node_modules/cookie": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/appium-xcuitest-driver/node_modules/cookie-signature": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", "license": "MIT", "engines": { "node": ">=6.6.0" } }, "node_modules/appium-xcuitest-driver/node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/crc-32": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", "license": "Apache-2.0", "bin": { "crc32": "bin/crc32.njs" }, "engines": { "node": ">=0.8" } }, "node_modules/appium-xcuitest-driver/node_modules/crc32-stream": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-6.0.0.tgz", "integrity": "sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==", "license": "MIT", "dependencies": { "crc-32": "^1.2.0", "readable-stream": "^4.0.0" }, "engines": { "node": ">= 14" } }, "node_modules/appium-xcuitest-driver/node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" }, "engines": { "node": ">= 8" } }, "node_modules/appium-xcuitest-driver/node_modules/cross-spawn/node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "license": "ISC" }, "node_modules/appium-xcuitest-driver/node_modules/cross-spawn/node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "bin/node-which" }, "engines": { "node": ">= 8" } }, "node_modules/appium-xcuitest-driver/node_modules/css-selector-parser": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/css-selector-parser/-/css-selector-parser-3.3.0.tgz", "integrity": "sha512-Y2asgMGFqJKF4fq4xHDSlFYIkeVfRsm69lQC1q9kbEsH5XtnINTMrweLkjYMeaUgiXBy/uvKeO/a1JHTNnmB2g==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/mdevils" }, { "type": "patreon", "url": "https://patreon.com/mdevils" } ], "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "license": "MIT", "dependencies": { "ms": "^2.1.3" }, "engines": { "node": ">=6.0" }, "peerDependenciesMeta": { "supports-color": { "optional": true } } }, "node_modules/appium-xcuitest-driver/node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "license": "MIT", "engines": { "node": ">=0.4.0" } }, "node_modules/appium-xcuitest-driver/node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/appium-xcuitest-driver/node_modules/detect-libc": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", "license": "Apache-2.0", "optional": true, "engines": { "node": ">=8" } }, "node_modules/appium-xcuitest-driver/node_modules/detect-node": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", "license": "MIT", "optional": true }, "node_modules/appium-xcuitest-driver/node_modules/dnssd": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/dnssd/-/dnssd-0.4.1.tgz", "integrity": "sha512-mEz5Ii+o+k3kYHTXY6fTLOjCwraX8TQowIgUySAbEYuGqtSMbfBc/tvDZ8wGPywnmlLE6/XeXi6qPcAKVTvPUQ==", "license": "MIT", "optional": true, "bin": { "dnssd-js": "bin/bin.js" } }, "node_modules/appium-xcuitest-driver/node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" }, "engines": { "node": ">= 0.4" } }, "node_modules/appium-xcuitest-driver/node_modules/duplexer": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/enabled": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==", "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/encodeurl": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/appium-xcuitest-driver/node_modules/env-paths": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-4.0.0.tgz", "integrity": "sha512-pxP8eL2SwwaTRi/KHYwLYXinDs7gL3jxFcBYmEdYfZmZXbaVDvdppd0XBU8qVz03rDfKZMXg1omHCbsJjZrMsw==", "license": "MIT", "dependencies": { "is-safe-filename": "^0.1.0" }, "engines": { "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/appium-xcuitest-driver/node_modules/es-define-property": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/appium-xcuitest-driver/node_modules/es-errors": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/appium-xcuitest-driver/node_modules/es-object-atoms": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0" }, "engines": { "node": ">= 0.4" } }, "node_modules/appium-xcuitest-driver/node_modules/es-set-tostringtag": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" } }, "node_modules/appium-xcuitest-driver/node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/appium-xcuitest-driver/node_modules/event-target-shim": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/appium-xcuitest-driver/node_modules/events": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "license": "MIT", "engines": { "node": ">=0.8.x" } }, "node_modules/appium-xcuitest-driver/node_modules/events-universal": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz", "integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==", "license": "Apache-2.0", "dependencies": { "bare-events": "^2.7.0" } }, "node_modules/appium-xcuitest-driver/node_modules/express": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", "license": "MIT", "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.1", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", "depd": "^2.0.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "finalhandler": "^2.1.0", "fresh": "^2.0.0", "http-errors": "^2.0.0", "merge-descriptors": "^2.0.0", "mime-types": "^3.0.0", "on-finished": "^2.4.1", "once": "^1.4.0", "parseurl": "^1.3.3", "proxy-addr": "^2.0.7", "qs": "^6.14.0", "range-parser": "^1.2.1", "router": "^2.2.0", "send": "^1.1.0", "serve-static": "^2.2.0", "statuses": "^2.0.1", "type-is": "^2.0.1", "vary": "^1.1.2" }, "engines": { "node": ">= 18" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, "node_modules/appium-xcuitest-driver/node_modules/fast-fifo": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/fastest-levenshtein": { "version": "1.0.16", "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", "license": "MIT", "engines": { "node": ">= 4.9.1" } }, "node_modules/appium-xcuitest-driver/node_modules/fecha": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==", "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/finalhandler": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", "license": "MIT", "dependencies": { "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "on-finished": "^2.4.1", "parseurl": "^1.3.3", "statuses": "^2.0.1" }, "engines": { "node": ">= 18.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, "node_modules/appium-xcuitest-driver/node_modules/find-up-simple": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.1.tgz", "integrity": "sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==", "license": "MIT", "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/appium-xcuitest-driver/node_modules/fn.name": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==", "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/follow-redirects": { "version": "1.15.11", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", "funding": [ { "type": "individual", "url": "https://github.com/sponsors/RubenVerborgh" } ], "license": "MIT", "engines": { "node": ">=4.0" }, "peerDependenciesMeta": { "debug": { "optional": true } } }, "node_modules/appium-xcuitest-driver/node_modules/foreground-child": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", "license": "ISC", "dependencies": { "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" }, "engines": { "node": ">=14" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/appium-xcuitest-driver/node_modules/foreground-child/node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "license": "ISC", "engines": { "node": ">=14" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/appium-xcuitest-driver/node_modules/form-data": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.2", "mime-types": "^2.1.12" }, "engines": { "node": ">= 6" } }, "node_modules/appium-xcuitest-driver/node_modules/form-data/node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/appium-xcuitest-driver/node_modules/form-data/node_modules/mime-types": { "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "license": "MIT", "dependencies": { "mime-db": "1.52.0" }, "engines": { "node": ">= 0.6" } }, "node_modules/appium-xcuitest-driver/node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/appium-xcuitest-driver/node_modules/fresh": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/appium-xcuitest-driver/node_modules/ftp-response-parser": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ftp-response-parser/-/ftp-response-parser-1.0.1.tgz", "integrity": "sha512-++Ahlo2hs/IC7UVQzjcSAfeUpCwTTzs4uvG5XfGnsinIFkWUYF4xWwPd5qZuK8MJrmUIxFMuHcfqaosCDjvIWw==", "dependencies": { "readable-stream": "^1.0.31" }, "engines": { "node": ">=0.8.0" } }, "node_modules/appium-xcuitest-driver/node_modules/ftp-response-parser/node_modules/isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/ftp-response-parser/node_modules/readable-stream": { "version": "1.1.14", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", "isarray": "0.0.1", "string_decoder": "~0.10.x" } }, "node_modules/appium-xcuitest-driver/node_modules/ftp-response-parser/node_modules/string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/appium-xcuitest-driver/node_modules/get-intrinsic": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/appium-xcuitest-driver/node_modules/get-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", "license": "MIT", "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" } }, "node_modules/appium-xcuitest-driver/node_modules/get-stream": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", "license": "MIT", "dependencies": { "@sec-ant/readable-stream": "^0.4.1", "is-stream": "^4.0.1" }, "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/appium-xcuitest-driver/node_modules/get-stream/node_modules/is-stream": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", "license": "MIT", "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/appium-xcuitest-driver/node_modules/glob": { "version": "13.0.6", "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", "license": "BlueOak-1.0.0", "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" }, "engines": { "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/appium-xcuitest-driver/node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "license": "MIT", "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/appium-xcuitest-driver/node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "license": "ISC" }, "node_modules/appium-xcuitest-driver/node_modules/handle-thing": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", "license": "MIT", "optional": true }, "node_modules/appium-xcuitest-driver/node_modules/has-symbols": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "license": "MIT", "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/appium-xcuitest-driver/node_modules/has-tostringtag": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/appium-xcuitest-driver/node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "license": "MIT", "dependencies": { "function-bind": "^1.1.2" }, "engines": { "node": ">= 0.4" } }, "node_modules/appium-xcuitest-driver/node_modules/hosted-git-info": { "version": "9.0.2", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-9.0.2.tgz", "integrity": "sha512-M422h7o/BR3rmCQ8UHi7cyyMqKltdP9Uo+J2fXK+RSAY+wTcKOIRyhTuKv4qn+DJf3g+PL890AzId5KZpX+CBg==", "license": "ISC", "dependencies": { "lru-cache": "^11.1.0" }, "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/appium-xcuitest-driver/node_modules/hpack.js": { "version": "2.1.6", "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", "license": "MIT", "optional": true, "dependencies": { "inherits": "^2.0.1", "obuf": "^1.0.0", "readable-stream": "^2.0.1", "wbuf": "^1.1.0" } }, "node_modules/appium-xcuitest-driver/node_modules/hpack.js/node_modules/readable-stream": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "license": "MIT", "optional": true, "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "node_modules/appium-xcuitest-driver/node_modules/hpack.js/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "license": "MIT", "optional": true, "dependencies": { "safe-buffer": "~5.1.0" } }, "node_modules/appium-xcuitest-driver/node_modules/http-deceiver": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", "license": "MIT", "optional": true }, "node_modules/appium-xcuitest-driver/node_modules/http-errors": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", "license": "MIT", "dependencies": { "depd": "~2.0.0", "inherits": "~2.0.4", "setprototypeof": "~1.2.0", "statuses": "~2.0.2", "toidentifier": "~1.0.1" }, "engines": { "node": ">= 0.8" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, "node_modules/appium-xcuitest-driver/node_modules/http-status-codes": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/http-status-codes/-/http-status-codes-2.3.0.tgz", "integrity": "sha512-RJ8XvFvpPM/Dmc5SV+dC4y5PCeOhT3x1Hq0NU3rjGeg5a/CqlhZ7uudknPwZFz4aeAXDcbAyaeP7GAo9lvngtA==", "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/iconv-lite": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, "engines": { "node": ">=0.10.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, "node_modules/appium-xcuitest-driver/node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "license": "BSD-3-Clause" }, "node_modules/appium-xcuitest-driver/node_modules/index-to-position": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/index-to-position/-/index-to-position-1.2.0.tgz", "integrity": "sha512-Yg7+ztRkqslMAS2iFaU+Oa4KTSidr63OsFGlOrJoW981kIYO3CGCS3wA95P1mUi/IVSJkn0D479KTJpVpvFNuw==", "license": "MIT", "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/appium-xcuitest-driver/node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "license": "ISC" }, "node_modules/appium-xcuitest-driver/node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "license": "MIT", "engines": { "node": ">= 0.10" } }, "node_modules/appium-xcuitest-driver/node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/appium-xcuitest-driver/node_modules/is-number-like": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/is-number-like/-/is-number-like-1.0.8.tgz", "integrity": "sha512-6rZi3ezCyFcn5L71ywzz2bS5b2Igl1En3eTlZlvKjpz1n3IZLAYMbKYAIQgFmEu0GENg92ziU/faEOA/aixjbA==", "license": "ISC", "dependencies": { "lodash.isfinite": "^3.3.2" } }, "node_modules/appium-xcuitest-driver/node_modules/is-promise": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/is-safe-filename": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-safe-filename/-/is-safe-filename-0.1.1.tgz", "integrity": "sha512-4SrR7AdnY11LHfDKTZY1u6Ga3RuxZdl3YKWWShO5iyuG5h8QS4GD2tOb04peBJ5I7pXbR+CGBNEhTcwK+FzN3g==", "license": "MIT", "engines": { "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/appium-xcuitest-driver/node_modules/is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "license": "MIT", "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/appium-xcuitest-driver/node_modules/is-unicode-supported": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", "license": "MIT", "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/appium-xcuitest-driver/node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/isexe": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-4.0.0.tgz", "integrity": "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==", "license": "BlueOak-1.0.0", "engines": { "node": ">=20" } }, "node_modules/appium-xcuitest-driver/node_modules/jackspeak": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" }, "funding": { "url": "https://github.com/sponsors/isaacs" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "node_modules/appium-xcuitest-driver/node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/js2xmlparser2": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/js2xmlparser2/-/js2xmlparser2-0.2.0.tgz", "integrity": "sha512-SzFGc1hQqzpDcalKmrM5gobSMGRSRg2lgaZrHGIfowrmd8+uaI+PWW62jcCGIqI+b4wdyYK0VKMhvVtJfkD0cg==", "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/jsftp": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/jsftp/-/jsftp-2.1.3.tgz", "integrity": "sha512-r79EVB8jaNAZbq8hvanL8e8JGu2ZNr2bXdHC4ZdQhRImpSPpnWwm5DYVzQ5QxJmtGtKhNNuvqGgbNaFl604fEQ==", "license": "MIT", "dependencies": { "debug": "^3.1.0", "ftp-response-parser": "^1.0.1", "once": "^1.4.0", "parse-listing": "^1.1.3", "stream-combiner": "^0.2.2", "unorm": "^1.4.1" }, "engines": { "node": ">=6" } }, "node_modules/appium-xcuitest-driver/node_modules/jsftp/node_modules/debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "license": "MIT", "dependencies": { "ms": "^2.1.1" } }, "node_modules/appium-xcuitest-driver/node_modules/json-parse-even-better-errors": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-4.0.0.tgz", "integrity": "sha512-lR4MXjGNgkJc7tkQ97kb2nuEMnNCyU//XYVH0MKTGcXEiSudQ5MKGKen3C5QubYy0vmq+JGitUg92uuywGEwIA==", "license": "MIT", "optional": true, "engines": { "node": "^18.17.0 || >=20.5.0" } }, "node_modules/appium-xcuitest-driver/node_modules/json-schema": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", "license": "(AFL-2.1 OR BSD-3-Clause)" }, "node_modules/appium-xcuitest-driver/node_modules/klaw": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/klaw/-/klaw-4.1.0.tgz", "integrity": "sha512-1zGZ9MF9H22UnkpVeuaGKOjfA2t6WrfdrJmGjy16ykcjnKQDmHVX+KI477rpbGevz/5FD4MC3xf1oxylBgcaQw==", "license": "MIT", "engines": { "node": ">=14.14.0" } }, "node_modules/appium-xcuitest-driver/node_modules/kuler": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==", "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/lazystream": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", "license": "MIT", "dependencies": { "readable-stream": "^2.0.5" }, "engines": { "node": ">= 0.6.3" } }, "node_modules/appium-xcuitest-driver/node_modules/lazystream/node_modules/readable-stream": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "node_modules/appium-xcuitest-driver/node_modules/lazystream/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" } }, "node_modules/appium-xcuitest-driver/node_modules/lockfile": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/lockfile/-/lockfile-1.0.4.tgz", "integrity": "sha512-cvbTwETRfsFh4nHsL1eGWapU1XFi5Ot9E85sWAwia7Y7EgB7vfqcZhTKZ+l7hCGxSPoushMv5GKhT5PdLv03WA==", "license": "ISC", "dependencies": { "signal-exit": "^3.0.2" } }, "node_modules/appium-xcuitest-driver/node_modules/lodash": { "version": "4.18.1", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/lodash.isfinite": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/lodash.isfinite/-/lodash.isfinite-3.3.2.tgz", "integrity": "sha512-7FGG40uhC8Mm633uKW1r58aElFlBlxCrg9JfSi3P6aYiWmfiWF0PgMd86ZUsxE5GwWPdHoS2+48bwTh2VPkIQA==", "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/log-symbols": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-7.0.1.tgz", "integrity": "sha512-ja1E3yCr9i/0hmBVaM0bfwDjnGy8I/s6PP4DFp+yP+a+mrHO4Rm7DtmnqROTUkHIkqffC84YY7AeqX6oFk0WFg==", "license": "MIT", "dependencies": { "is-unicode-supported": "^2.0.0", "yoctocolors": "^2.1.1" }, "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/appium-xcuitest-driver/node_modules/logform": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/logform/-/logform-2.7.0.tgz", "integrity": "sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ==", "license": "MIT", "dependencies": { "@colors/colors": "1.6.0", "@types/triple-beam": "^1.3.2", "fecha": "^4.2.0", "ms": "^2.1.1", "safe-stable-stringify": "^2.3.1", "triple-beam": "^1.3.0" }, "engines": { "node": ">= 12.0.0" } }, "node_modules/appium-xcuitest-driver/node_modules/lru-cache": { "version": "11.3.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.3.tgz", "integrity": "sha512-JvNw9Y81y33E+BEYPr0U7omo+U9AySnsMsEiXgwT6yqd31VQWTLNQqmT4ou5eqPFUrTfIDFta2wKhB1hyohtAQ==", "license": "BlueOak-1.0.0", "engines": { "node": "20 || >=22" } }, "node_modules/appium-xcuitest-driver/node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/appium-xcuitest-driver/node_modules/media-typer": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/appium-xcuitest-driver/node_modules/memorystream": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", "optional": true, "engines": { "node": ">= 0.10.0" } }, "node_modules/appium-xcuitest-driver/node_modules/merge-descriptors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", "license": "MIT", "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/appium-xcuitest-driver/node_modules/method-override": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/method-override/-/method-override-3.0.0.tgz", "integrity": "sha512-IJ2NNN/mSl9w3kzWB92rcdHpz+HjkxhDJWNDBqSlas+zQdP8wBiJzITPg08M/k2uVvMow7Sk41atndNtt/PHSA==", "license": "MIT", "dependencies": { "debug": "3.1.0", "methods": "~1.1.2", "parseurl": "~1.3.2", "vary": "~1.1.2" }, "engines": { "node": ">= 0.10" } }, "node_modules/appium-xcuitest-driver/node_modules/method-override/node_modules/debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "license": "MIT", "dependencies": { "ms": "2.0.0" } }, "node_modules/appium-xcuitest-driver/node_modules/method-override/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/appium-xcuitest-driver/node_modules/mime-db": { "version": "1.54.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/appium-xcuitest-driver/node_modules/mime-types": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", "license": "MIT", "dependencies": { "mime-db": "^1.54.0" }, "engines": { "node": ">=18" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, "node_modules/appium-xcuitest-driver/node_modules/minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", "license": "ISC", "optional": true }, "node_modules/appium-xcuitest-driver/node_modules/minimatch": { "version": "10.2.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", "license": "BlueOak-1.0.0", "dependencies": { "brace-expansion": "^5.0.5" }, "engines": { "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/appium-xcuitest-driver/node_modules/minipass": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", "license": "BlueOak-1.0.0", "engines": { "node": ">=16 || 14 >=14.17" } }, "node_modules/appium-xcuitest-driver/node_modules/moment": { "version": "2.30.1", "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", "license": "MIT", "engines": { "node": "*" } }, "node_modules/appium-xcuitest-driver/node_modules/moment-timezone": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.6.1.tgz", "integrity": "sha512-1B9lmAhB9D9/sHaPC1N7wLFEVUoFldxOpOO96lOD1PvJ43vCd0ozDPbu0FEL3++VvawOlDkq8YD373tJmP5JHw==", "license": "MIT", "dependencies": { "moment": "^2.29.4" }, "engines": { "node": "*" } }, "node_modules/appium-xcuitest-driver/node_modules/morgan": { "version": "1.10.1", "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.1.tgz", "integrity": "sha512-223dMRJtI/l25dJKWpgij2cMtywuG/WiUKXdvwfbhGKBhy1puASqXwFzmWZ7+K73vUPoR7SS2Qz2cI/g9MKw0A==", "license": "MIT", "dependencies": { "basic-auth": "~2.0.1", "debug": "2.6.9", "depd": "~2.0.0", "on-finished": "~2.3.0", "on-headers": "~1.1.0" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/appium-xcuitest-driver/node_modules/morgan/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "license": "MIT", "dependencies": { "ms": "2.0.0" } }, "node_modules/appium-xcuitest-driver/node_modules/morgan/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/morgan/node_modules/on-finished": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", "license": "MIT", "dependencies": { "ee-first": "1.1.1" }, "engines": { "node": ">= 0.8" } }, "node_modules/appium-xcuitest-driver/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/ncp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", "integrity": "sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA==", "license": "MIT", "bin": { "ncp": "bin/ncp" } }, "node_modules/appium-xcuitest-driver/node_modules/negotiator": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/appium-xcuitest-driver/node_modules/node-addon-api": { "version": "8.7.0", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.7.0.tgz", "integrity": "sha512-9MdFxmkKaOYVTV+XVRG8ArDwwQ77XIgIPyKASB1k3JPq3M8fGQQQE3YpMOrKm6g//Ktx8ivZr8xo1Qmtqub+GA==", "license": "MIT", "optional": true, "engines": { "node": "^18 || ^20 || >= 21" } }, "node_modules/appium-xcuitest-driver/node_modules/node-devicectl": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/node-devicectl/-/node-devicectl-1.2.0.tgz", "integrity": "sha512-9ZHN1eQGdZu38+/3z4mVxxqr1Ah1kX8FFYxvCLx38HRI+eDd13ut+Z8YDiodtkVJLqwiFpqgio/b2cjGJDQJzQ==", "license": "Apache-2.0", "dependencies": { "@appium/logger": "^2.0.0-rc.1", "lodash": "^4.2.1", "teen_process": "^4.1.0" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" } }, "node_modules/appium-xcuitest-driver/node_modules/node-simctl": { "version": "8.1.6", "resolved": "https://registry.npmjs.org/node-simctl/-/node-simctl-8.1.6.tgz", "integrity": "sha512-SSwNzq4Tl575EaVFCIotDvDDV5XYR7676aN78lv/fhdxOQ+ZM6QZdIa/ZTXiDMc/Jd3wQ4L24E0d4Cqb6jy+Ew==", "license": "Apache-2.0", "dependencies": { "@appium/logger": "^2.0.0-rc.1", "asyncbox": "^6.0.1", "bluebird": "^3.5.1", "lodash": "^4.2.1", "rimraf": "^6.0.1", "semver": "^7.0.0", "teen_process": "^4.0.4", "uuid": "^13.0.0", "which": "^6.0.0" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" } }, "node_modules/appium-xcuitest-driver/node_modules/normalize-package-data": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-8.0.0.tgz", "integrity": "sha512-RWk+PI433eESQ7ounYxIp67CYuVsS1uYSonX3kA6ps/3LWfjVQa/ptEg6Y3T6uAMq1mWpX9PQ+qx+QaHpsc7gQ==", "license": "BSD-2-Clause", "dependencies": { "hosted-git-info": "^9.0.0", "semver": "^7.3.5", "validate-npm-package-license": "^3.0.4" }, "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/appium-xcuitest-driver/node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/appium-xcuitest-driver/node_modules/npm-normalize-package-bin": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-4.0.0.tgz", "integrity": "sha512-TZKxPvItzai9kN9H/TkmCtx/ZN/hvr3vUycjlfmH0ootY9yFBzNOpiXAdIn1Iteqsvk4lQn6B5PTrt+n6h8k/w==", "license": "ISC", "optional": true, "engines": { "node": "^18.17.0 || >=20.5.0" } }, "node_modules/appium-xcuitest-driver/node_modules/npm-run-all2": { "version": "8.0.4", "resolved": "https://registry.npmjs.org/npm-run-all2/-/npm-run-all2-8.0.4.tgz", "integrity": "sha512-wdbB5My48XKp2ZfJUlhnLVihzeuA1hgBnqB2J9ahV77wLS+/YAJAlN8I+X3DIFIPZ3m5L7nplmlbhNiFDmXRDA==", "license": "MIT", "optional": true, "dependencies": { "ansi-styles": "^6.2.1", "cross-spawn": "^7.0.6", "memorystream": "^0.3.1", "picomatch": "^4.0.2", "pidtree": "^0.6.0", "read-package-json-fast": "^4.0.0", "shell-quote": "^1.7.3", "which": "^5.0.0" }, "bin": { "npm-run-all": "bin/npm-run-all/index.js", "npm-run-all2": "bin/npm-run-all/index.js", "run-p": "bin/run-p/index.js", "run-s": "bin/run-s/index.js" }, "engines": { "node": "^20.5.0 || >=22.0.0", "npm": ">= 10" } }, "node_modules/appium-xcuitest-driver/node_modules/npm-run-all2/node_modules/ansi-styles": { "version": "6.2.3", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", "license": "MIT", "optional": true, "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/appium-xcuitest-driver/node_modules/npm-run-all2/node_modules/isexe": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.5.tgz", "integrity": "sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w==", "license": "BlueOak-1.0.0", "optional": true, "engines": { "node": ">=18" } }, "node_modules/appium-xcuitest-driver/node_modules/npm-run-all2/node_modules/which": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", "license": "ISC", "optional": true, "dependencies": { "isexe": "^3.1.1" }, "bin": { "node-which": "bin/which.js" }, "engines": { "node": "^18.17.0 || >=20.5.0" } }, "node_modules/appium-xcuitest-driver/node_modules/object-inspect": { "version": "1.13.4", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", "license": "MIT", "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/appium-xcuitest-driver/node_modules/obuf": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", "license": "MIT", "optional": true }, "node_modules/appium-xcuitest-driver/node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "license": "MIT", "dependencies": { "ee-first": "1.1.1" }, "engines": { "node": ">= 0.8" } }, "node_modules/appium-xcuitest-driver/node_modules/on-headers": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz", "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==", "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/appium-xcuitest-driver/node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "license": "ISC", "dependencies": { "wrappy": "1" } }, "node_modules/appium-xcuitest-driver/node_modules/one-time": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", "license": "MIT", "dependencies": { "fn.name": "1.x.x" } }, "node_modules/appium-xcuitest-driver/node_modules/p-limit": { "version": "7.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-7.3.0.tgz", "integrity": "sha512-7cIXg/Z0M5WZRblrsOla88S4wAK+zOQQWeBYfV3qJuJXMr+LnbYjaadrFaS0JILfEDPVqHyKnZ1Z/1d6J9VVUw==", "license": "MIT", "dependencies": { "yocto-queue": "^1.2.1" }, "engines": { "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/appium-xcuitest-driver/node_modules/package-directory": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/package-directory/-/package-directory-8.2.0.tgz", "integrity": "sha512-qJSu5Mo6tHmRxCy2KCYYKYgcfBdUpy9dwReaZD/xwf608AUk/MoRtIOWzgDtUeGeC7n/55yC3MI1Q+MbSoektw==", "license": "MIT", "dependencies": { "find-up-simple": "^1.0.0" }, "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/appium-xcuitest-driver/node_modules/package-json-from-dist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", "license": "BlueOak-1.0.0" }, "node_modules/appium-xcuitest-driver/node_modules/parse-json": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.3.0.tgz", "integrity": "sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.26.2", "index-to-position": "^1.1.0", "type-fest": "^4.39.1" }, "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/appium-xcuitest-driver/node_modules/parse-json/node_modules/type-fest": { "version": "4.41.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/appium-xcuitest-driver/node_modules/parse-listing": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/parse-listing/-/parse-listing-1.1.3.tgz", "integrity": "sha512-a1p1i+9Qyc8pJNwdrSvW1g5TPxRH0sywVi6OzVvYHRo6xwF9bDWBxtH0KkxeOOvhUE8vAMtiSfsYQFOuK901eA==", "engines": { "node": ">=0.6.21" } }, "node_modules/appium-xcuitest-driver/node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/appium-xcuitest-driver/node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/appium-xcuitest-driver/node_modules/path-scurry": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", "license": "BlueOak-1.0.0", "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" }, "engines": { "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/appium-xcuitest-driver/node_modules/path-to-regexp": { "version": "8.4.2", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz", "integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==", "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, "node_modules/appium-xcuitest-driver/node_modules/pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "license": "ISC" }, "node_modules/appium-xcuitest-driver/node_modules/picomatch": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "license": "MIT", "optional": true, "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/appium-xcuitest-driver/node_modules/pidtree": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz", "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==", "license": "MIT", "optional": true, "bin": { "pidtree": "bin/pidtree.js" }, "engines": { "node": ">=0.10" } }, "node_modules/appium-xcuitest-driver/node_modules/plist": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz", "integrity": "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==", "license": "MIT", "dependencies": { "@xmldom/xmldom": "^0.8.8", "base64-js": "^1.5.1", "xmlbuilder": "^15.1.1" }, "engines": { "node": ">=10.4.0" } }, "node_modules/appium-xcuitest-driver/node_modules/plist/node_modules/@xmldom/xmldom": { "version": "0.8.12", "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.12.tgz", "integrity": "sha512-9k/gHF6n/pAi/9tqr3m3aqkuiNosYTurLLUtc7xQ9sxB/wm7WPygCv8GYa6mS0fLJEHhqMC1ATYhz++U/lRHqg==", "license": "MIT", "engines": { "node": ">=10.0.0" } }, "node_modules/appium-xcuitest-driver/node_modules/pluralize": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/appium-xcuitest-driver/node_modules/portscanner": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/portscanner/-/portscanner-2.2.0.tgz", "integrity": "sha512-IFroCz/59Lqa2uBvzK3bKDbDDIEaAY8XJ1jFxcLWTqosrsc32//P4VuSB2vZXoHiHqOmx8B5L5hnKOxL/7FlPw==", "license": "MIT", "dependencies": { "async": "^2.6.0", "is-number-like": "^1.0.3" }, "engines": { "node": ">=0.4", "npm": ">=1.0.0" } }, "node_modules/appium-xcuitest-driver/node_modules/portscanner/node_modules/async": { "version": "2.6.4", "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", "license": "MIT", "dependencies": { "lodash": "^4.17.14" } }, "node_modules/appium-xcuitest-driver/node_modules/process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", "license": "MIT", "engines": { "node": ">= 0.6.0" } }, "node_modules/appium-xcuitest-driver/node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "license": "MIT", "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" }, "engines": { "node": ">= 0.10" } }, "node_modules/appium-xcuitest-driver/node_modules/proxy-from-env": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", "license": "MIT", "engines": { "node": ">=10" } }, "node_modules/appium-xcuitest-driver/node_modules/qs": { "version": "6.15.1", "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.1.tgz", "integrity": "sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==", "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.1.0" }, "engines": { "node": ">=0.6" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/appium-xcuitest-driver/node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/appium-xcuitest-driver/node_modules/raw-body": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", "license": "MIT", "dependencies": { "bytes": "~3.1.2", "http-errors": "~2.0.1", "iconv-lite": "~0.7.0", "unpipe": "~1.0.0" }, "engines": { "node": ">= 0.10" } }, "node_modules/appium-xcuitest-driver/node_modules/read-package-json-fast": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-4.0.0.tgz", "integrity": "sha512-qpt8EwugBWDw2cgE2W+/3oxC+KTez2uSVR8JU9Q36TXPAGCaozfQUs59v4j4GFpWTaw0i6hAZSvOmu1J0uOEUg==", "license": "ISC", "optional": true, "dependencies": { "json-parse-even-better-errors": "^4.0.0", "npm-normalize-package-bin": "^4.0.0" }, "engines": { "node": "^18.17.0 || >=20.5.0" } }, "node_modules/appium-xcuitest-driver/node_modules/read-pkg": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-10.1.0.tgz", "integrity": "sha512-I8g2lArQiP78ll51UeMZojewtYgIRCKCWqZEgOO8c/uefTI+XDXvCSXu3+YNUaTNvZzobrL5+SqHjBrByRRTdg==", "license": "MIT", "dependencies": { "@types/normalize-package-data": "^2.4.4", "normalize-package-data": "^8.0.0", "parse-json": "^8.3.0", "type-fest": "^5.4.4", "unicorn-magic": "^0.4.0" }, "engines": { "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/appium-xcuitest-driver/node_modules/readable-stream": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", "license": "MIT", "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", "events": "^3.3.0", "process": "^0.11.10", "string_decoder": "^1.3.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/appium-xcuitest-driver/node_modules/readable-stream/node_modules/buffer": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "license": "MIT", "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" } }, "node_modules/appium-xcuitest-driver/node_modules/readdir-glob": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz", "integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==", "license": "Apache-2.0", "dependencies": { "minimatch": "^5.1.0" } }, "node_modules/appium-xcuitest-driver/node_modules/readdir-glob/node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/readdir-glob/node_modules/brace-expansion": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/appium-xcuitest-driver/node_modules/readdir-glob/node_modules/minimatch": { "version": "5.1.9", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz", "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==", "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, "engines": { "node": ">=10" } }, "node_modules/appium-xcuitest-driver/node_modules/resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/appium-xcuitest-driver/node_modules/rimraf": { "version": "6.1.3", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.3.tgz", "integrity": "sha512-LKg+Cr2ZF61fkcaK1UdkH2yEBBKnYjTyWzTJT6KNPcSPaiT7HSdhtMXQuN5wkTX0Xu72KQ1l8S42rlmexS2hSA==", "license": "BlueOak-1.0.0", "dependencies": { "glob": "^13.0.3", "package-json-from-dist": "^1.0.1" }, "bin": { "rimraf": "dist/esm/bin.mjs" }, "engines": { "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/appium-xcuitest-driver/node_modules/router": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", "license": "MIT", "dependencies": { "debug": "^4.4.0", "depd": "^2.0.0", "is-promise": "^4.0.0", "parseurl": "^1.3.3", "path-to-regexp": "^8.0.0" }, "engines": { "node": ">= 18" } }, "node_modules/appium-xcuitest-driver/node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/safe-stable-stringify": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", "license": "MIT", "engines": { "node": ">=10" } }, "node_modules/appium-xcuitest-driver/node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/sanitize-filename": { "version": "1.6.4", "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.4.tgz", "integrity": "sha512-9ZyI08PsvdQl2r/bBIGubpVdR3RR9sY6RDiWFPreA21C/EFlQhmgo20UZlNjZMMZNubusLhAQozkA0Od5J21Eg==", "license": "WTFPL OR ISC", "dependencies": { "truncate-utf8-bytes": "^1.0.0" } }, "node_modules/appium-xcuitest-driver/node_modules/select-hose": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", "license": "MIT", "optional": true }, "node_modules/appium-xcuitest-driver/node_modules/semver": { "version": "7.7.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "license": "ISC", "bin": { "semver": "bin/semver.js" }, "engines": { "node": ">=10" } }, "node_modules/appium-xcuitest-driver/node_modules/send": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", "license": "MIT", "dependencies": { "debug": "^4.4.3", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "fresh": "^2.0.0", "http-errors": "^2.0.1", "mime-types": "^3.0.2", "ms": "^2.1.3", "on-finished": "^2.4.1", "range-parser": "^1.2.1", "statuses": "^2.0.2" }, "engines": { "node": ">= 18" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, "node_modules/appium-xcuitest-driver/node_modules/serve-favicon": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/serve-favicon/-/serve-favicon-2.5.1.tgz", "integrity": "sha512-JndLBslCLA/ebr7rS3d+/EKkzTsTi1jI2T9l+vHfAaGJ7A7NhtDpSZ0lx81HCNWnnE0yHncG+SSnVf9IMxOwXQ==", "license": "MIT", "dependencies": { "etag": "~1.8.1", "fresh": "~0.5.2", "ms": "~2.1.3", "parseurl": "~1.3.2", "safe-buffer": "~5.2.1" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/appium-xcuitest-driver/node_modules/serve-favicon/node_modules/fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/appium-xcuitest-driver/node_modules/serve-favicon/node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/serve-static": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", "license": "MIT", "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", "send": "^1.2.0" }, "engines": { "node": ">= 18" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, "node_modules/appium-xcuitest-driver/node_modules/set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", "license": "ISC" }, "node_modules/appium-xcuitest-driver/node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "license": "ISC" }, "node_modules/appium-xcuitest-driver/node_modules/sharp": { "version": "0.34.5", "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", "hasInstallScript": true, "license": "Apache-2.0", "optional": true, "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.2", "semver": "^7.7.3" }, "engines": { "node": "^18.17.0 || ^20.3.0 || >=21.0.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.5", "@img/sharp-darwin-x64": "0.34.5", "@img/sharp-libvips-darwin-arm64": "1.2.4", "@img/sharp-libvips-darwin-x64": "1.2.4", "@img/sharp-libvips-linux-arm": "1.2.4", "@img/sharp-libvips-linux-arm64": "1.2.4", "@img/sharp-libvips-linux-ppc64": "1.2.4", "@img/sharp-libvips-linux-riscv64": "1.2.4", "@img/sharp-libvips-linux-s390x": "1.2.4", "@img/sharp-libvips-linux-x64": "1.2.4", "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", "@img/sharp-libvips-linuxmusl-x64": "1.2.4", "@img/sharp-linux-arm": "0.34.5", "@img/sharp-linux-arm64": "0.34.5", "@img/sharp-linux-ppc64": "0.34.5", "@img/sharp-linux-riscv64": "0.34.5", "@img/sharp-linux-s390x": "0.34.5", "@img/sharp-linux-x64": "0.34.5", "@img/sharp-linuxmusl-arm64": "0.34.5", "@img/sharp-linuxmusl-x64": "0.34.5", "@img/sharp-wasm32": "0.34.5", "@img/sharp-win32-arm64": "0.34.5", "@img/sharp-win32-ia32": "0.34.5", "@img/sharp-win32-x64": "0.34.5" } }, "node_modules/appium-xcuitest-driver/node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, "engines": { "node": ">=8" } }, "node_modules/appium-xcuitest-driver/node_modules/shebang-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/appium-xcuitest-driver/node_modules/shell-quote": { "version": "1.8.3", "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", "license": "MIT", "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/appium-xcuitest-driver/node_modules/side-channel": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", "side-channel-list": "^1.0.0", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/appium-xcuitest-driver/node_modules/side-channel-list": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.4" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/appium-xcuitest-driver/node_modules/side-channel-map": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", "license": "MIT", "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/appium-xcuitest-driver/node_modules/side-channel-weakmap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", "license": "MIT", "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3", "side-channel-map": "^1.0.1" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/appium-xcuitest-driver/node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "license": "ISC" }, "node_modules/appium-xcuitest-driver/node_modules/slugify": { "version": "1.6.9", "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.9.tgz", "integrity": "sha512-vZ7rfeehZui7wQs438JXBckYLkIIdfHOXsaVEUMyS5fHo1483l1bMdo0EDSWYclY0yZKFOipDy4KHuKs6ssvdg==", "license": "MIT", "engines": { "node": ">=8.0.0" } }, "node_modules/appium-xcuitest-driver/node_modules/spdx-correct": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", "license": "Apache-2.0", "dependencies": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" } }, "node_modules/appium-xcuitest-driver/node_modules/spdx-exceptions": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", "license": "CC-BY-3.0" }, "node_modules/appium-xcuitest-driver/node_modules/spdx-expression-parse": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "license": "MIT", "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, "node_modules/appium-xcuitest-driver/node_modules/spdx-license-ids": { "version": "3.0.23", "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.23.tgz", "integrity": "sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==", "license": "CC0-1.0" }, "node_modules/appium-xcuitest-driver/node_modules/spdy": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", "license": "MIT", "optional": true, "dependencies": { "debug": "^4.1.0", "handle-thing": "^2.0.0", "http-deceiver": "^1.2.7", "select-hose": "^2.0.0", "spdy-transport": "^3.0.0" }, "engines": { "node": ">=6.0.0" } }, "node_modules/appium-xcuitest-driver/node_modules/spdy-transport": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", "license": "MIT", "optional": true, "dependencies": { "debug": "^4.1.0", "detect-node": "^2.0.4", "hpack.js": "^2.1.6", "obuf": "^1.1.2", "readable-stream": "^3.0.6", "wbuf": "^1.7.3" } }, "node_modules/appium-xcuitest-driver/node_modules/spdy-transport/node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "license": "MIT", "optional": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" }, "engines": { "node": ">= 6" } }, "node_modules/appium-xcuitest-driver/node_modules/stack-trace": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", "license": "MIT", "engines": { "node": "*" } }, "node_modules/appium-xcuitest-driver/node_modules/statuses": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/appium-xcuitest-driver/node_modules/stream-buffers": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz", "integrity": "sha512-uyQK/mx5QjHun80FLJTfaWE7JtwfRMKBLkMne6udYOmvH0CawotVa7TfgYHzAnpphn4+TweIx1QKMnRIbipmUg==", "license": "Unlicense", "engines": { "node": ">= 0.10.0" } }, "node_modules/appium-xcuitest-driver/node_modules/stream-combiner": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz", "integrity": "sha512-6yHMqgLYDzQDcAkL+tjJDC5nSNuNIx0vZtRZeiPh7Saef7VHX9H5Ijn9l2VIol2zaNYlYEX6KyuT/237A58qEQ==", "license": "MIT", "dependencies": { "duplexer": "~0.1.1", "through": "~2.3.4" } }, "node_modules/appium-xcuitest-driver/node_modules/streamx": { "version": "2.25.0", "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.25.0.tgz", "integrity": "sha512-0nQuG6jf1w+wddNEEXCF4nTg3LtufWINB5eFEN+5TNZW7KWJp6x87+JFL43vaAUPyCfH1wID+mNVyW6OHtFamg==", "license": "MIT", "dependencies": { "events-universal": "^1.0.0", "fast-fifo": "^1.3.2", "text-decoder": "^1.1.0" } }, "node_modules/appium-xcuitest-driver/node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" } }, "node_modules/appium-xcuitest-driver/node_modules/string_decoder/node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" }, "engines": { "node": ">=8" } }, "node_modules/appium-xcuitest-driver/node_modules/string-width-cjs": { "name": "string-width", "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" }, "engines": { "node": ">=8" } }, "node_modules/appium-xcuitest-driver/node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/appium-xcuitest-driver/node_modules/strip-ansi-cjs": { "name": "strip-ansi", "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/appium-xcuitest-driver/node_modules/strip-ansi-cjs/node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/appium-xcuitest-driver/node_modules/strip-ansi/node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/appium-xcuitest-driver/node_modules/supports-color": { "version": "10.2.2", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-10.2.2.tgz", "integrity": "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==", "license": "MIT", "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/chalk/supports-color?sponsor=1" } }, "node_modules/appium-xcuitest-driver/node_modules/tagged-tag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/tagged-tag/-/tagged-tag-1.0.0.tgz", "integrity": "sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==", "license": "MIT", "engines": { "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/appium-xcuitest-driver/node_modules/tar-stream": { "version": "3.1.8", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.8.tgz", "integrity": "sha512-U6QpVRyCGHva435KoNWy9PRoi2IFYCgtEhq9nmrPPpbRacPs9IH4aJ3gbrFC8dPcXvdSZ4XXfXT5Fshbp2MtlQ==", "license": "MIT", "dependencies": { "b4a": "^1.6.4", "bare-fs": "^4.5.5", "fast-fifo": "^1.2.0", "streamx": "^2.15.0" } }, "node_modules/appium-xcuitest-driver/node_modules/teen_process": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/teen_process/-/teen_process-4.1.0.tgz", "integrity": "sha512-AN8y3MYPExB3r2mkkX9r0wEF4xPfhKOj6YvcfeIqQai+GVhTIhjjdkPvwI5CFT4z8UQ5aZWldzbJ+jNejYAdGw==", "license": "Apache-2.0", "dependencies": { "lodash": "^4.17.21", "shell-quote": "^1.8.1" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" } }, "node_modules/appium-xcuitest-driver/node_modules/teex": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz", "integrity": "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==", "license": "MIT", "dependencies": { "streamx": "^2.12.5" } }, "node_modules/appium-xcuitest-driver/node_modules/text-decoder": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.7.tgz", "integrity": "sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ==", "license": "Apache-2.0", "dependencies": { "b4a": "^1.6.4" } }, "node_modules/appium-xcuitest-driver/node_modules/text-hex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==", "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "license": "MIT", "engines": { "node": ">=0.6" } }, "node_modules/appium-xcuitest-driver/node_modules/triple-beam": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz", "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==", "license": "MIT", "engines": { "node": ">= 14.0.0" } }, "node_modules/appium-xcuitest-driver/node_modules/truncate-utf8-bytes": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", "integrity": "sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==", "license": "WTFPL", "dependencies": { "utf8-byte-length": "^1.0.1" } }, "node_modules/appium-xcuitest-driver/node_modules/type-fest": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.5.0.tgz", "integrity": "sha512-PlBfpQwiUvGViBNX84Yxwjsdhd1TUlXr6zjX7eoirtCPIr08NAmxwa+fcYBTeRQxHo9YC9wwF3m9i700sHma8g==", "license": "(MIT OR CC0-1.0)", "dependencies": { "tagged-tag": "^1.0.0" }, "engines": { "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/appium-xcuitest-driver/node_modules/type-is": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", "license": "MIT", "dependencies": { "content-type": "^1.0.5", "media-typer": "^1.1.0", "mime-types": "^3.0.0" }, "engines": { "node": ">= 0.6" } }, "node_modules/appium-xcuitest-driver/node_modules/undici-types": { "version": "7.19.2", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.19.2.tgz", "integrity": "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==", "license": "MIT", "optional": true }, "node_modules/appium-xcuitest-driver/node_modules/unicorn-magic": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.4.0.tgz", "integrity": "sha512-wH590V9VNgYH9g3lH9wWjTrUoKsjLF6sGLjhR4sH1LWpLmCOH0Zf7PukhDA8BiS7KHe4oPNkcTHqYkj7SOGUOw==", "license": "MIT", "engines": { "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/appium-xcuitest-driver/node_modules/unorm": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/unorm/-/unorm-1.6.0.tgz", "integrity": "sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA==", "license": "MIT or GPL-2.0", "engines": { "node": ">= 0.4.0" } }, "node_modules/appium-xcuitest-driver/node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/appium-xcuitest-driver/node_modules/utf8-byte-length": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.5.tgz", "integrity": "sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA==", "license": "(WTFPL OR MIT)" }, "node_modules/appium-xcuitest-driver/node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "license": "MIT" }, "node_modules/appium-xcuitest-driver/node_modules/uuid": { "version": "13.0.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-13.0.0.tgz", "integrity": "sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], "license": "MIT", "bin": { "uuid": "dist-node/bin/uuid" } }, "node_modules/appium-xcuitest-driver/node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "license": "Apache-2.0", "dependencies": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" } }, "node_modules/appium-xcuitest-driver/node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/appium-xcuitest-driver/node_modules/wbuf": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", "license": "MIT", "optional": true, "dependencies": { "minimalistic-assert": "^1.0.0" } }, "node_modules/appium-xcuitest-driver/node_modules/which": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/which/-/which-6.0.1.tgz", "integrity": "sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==", "license": "ISC", "dependencies": { "isexe": "^4.0.0" }, "bin": { "node-which": "bin/which.js" }, "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/appium-xcuitest-driver/node_modules/winston": { "version": "3.19.0", "resolved": "https://registry.npmjs.org/winston/-/winston-3.19.0.tgz", "integrity": "sha512-LZNJgPzfKR+/J3cHkxcpHKpKKvGfDZVPS4hfJCc4cCG0CgYzvlD6yE/S3CIL/Yt91ak327YCpiF/0MyeZHEHKA==", "license": "MIT", "dependencies": { "@colors/colors": "^1.6.0", "@dabh/diagnostics": "^2.0.8", "async": "^3.2.3", "is-stream": "^2.0.0", "logform": "^2.7.0", "one-time": "^1.0.0", "readable-stream": "^3.4.0", "safe-stable-stringify": "^2.3.1", "stack-trace": "0.0.x", "triple-beam": "^1.3.0", "winston-transport": "^4.9.0" }, "engines": { "node": ">= 12.0.0" } }, "node_modules/appium-xcuitest-driver/node_modules/winston-transport": { "version": "4.9.0", "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.9.0.tgz", "integrity": "sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A==", "license": "MIT", "dependencies": { "logform": "^2.7.0", "readable-stream": "^3.6.2", "triple-beam": "^1.3.0" }, "engines": { "node": ">= 12.0.0" } }, "node_modules/appium-xcuitest-driver/node_modules/winston-transport/node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "license": "MIT", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" }, "engines": { "node": ">= 6" } }, "node_modules/appium-xcuitest-driver/node_modules/winston/node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "license": "MIT", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" }, "engines": { "node": ">= 6" } }, "node_modules/appium-xcuitest-driver/node_modules/wrap-ansi-cjs": { "name": "wrap-ansi", "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/appium-xcuitest-driver/node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "license": "ISC" }, "node_modules/appium-xcuitest-driver/node_modules/ws": { "version": "8.20.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz", "integrity": "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==", "license": "MIT", "engines": { "node": ">=10.0.0" }, "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "peerDependenciesMeta": { "bufferutil": { "optional": true }, "utf-8-validate": { "optional": true } } }, "node_modules/appium-xcuitest-driver/node_modules/xmlbuilder": { "version": "15.1.1", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", "license": "MIT", "engines": { "node": ">=8.0" } }, "node_modules/appium-xcuitest-driver/node_modules/yauzl": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-3.3.0.tgz", "integrity": "sha512-PtGEvEP30p7sbIBJKUBjUnqgTVOyMURc4dLo9iNyAJnNIEz9pm88cCXF21w94Kg3k6RXkeZh5DHOGS0qEONvNQ==", "license": "MIT", "dependencies": { "buffer-crc32": "~0.2.3", "pend": "~1.2.0" }, "engines": { "node": ">=12" } }, "node_modules/appium-xcuitest-driver/node_modules/yauzl/node_modules/buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", "license": "MIT", "engines": { "node": "*" } }, "node_modules/appium-xcuitest-driver/node_modules/yocto-queue": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.2.tgz", "integrity": "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==", "license": "MIT", "engines": { "node": ">=12.20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/appium-xcuitest-driver/node_modules/yoctocolors": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.2.tgz", "integrity": "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==", "license": "MIT", "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/appium-xcuitest-driver/node_modules/zip-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-6.0.1.tgz", "integrity": "sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==", "license": "MIT", "dependencies": { "archiver-utils": "^5.0.0", "compress-commons": "^6.0.2", "readable-stream": "^4.0.0" }, "engines": { "node": ">= 14" } }, "node_modules/archiver": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/archiver/-/archiver-7.0.1.tgz", "integrity": "sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==", "license": "MIT", "dependencies": { "archiver-utils": "^5.0.2", "async": "^3.2.4", "buffer-crc32": "^1.0.0", "readable-stream": "^4.0.0", "readdir-glob": "^1.1.2", "tar-stream": "^3.0.0", "zip-stream": "^6.0.1" }, "engines": { "node": ">= 14" } }, "node_modules/archiver-utils": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-5.0.2.tgz", "integrity": "sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==", "license": "MIT", "dependencies": { "glob": "^10.0.0", "graceful-fs": "^4.2.0", "is-stream": "^2.0.1", "lazystream": "^1.0.0", "lodash": "^4.17.15", "normalize-path": "^3.0.0", "readable-stream": "^4.0.0" }, "engines": { "node": ">= 14" } }, "node_modules/archiver-utils/node_modules/brace-expansion": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz", "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/archiver-utils/node_modules/glob": { "version": "10.5.0", "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/archiver-utils/node_modules/lru-cache": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "license": "ISC" }, "node_modules/archiver-utils/node_modules/minimatch": { "version": "9.0.9", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "license": "ISC", "dependencies": { "brace-expansion": "^2.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/archiver-utils/node_modules/path-scurry": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", "license": "BlueOak-1.0.0", "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { "node": ">=16 || 14 >=14.18" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "extraneous": true, "license": "Python-2.0" }, "node_modules/async": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", "license": "MIT" }, "node_modules/async-lock": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/async-lock/-/async-lock-1.4.1.tgz", "integrity": "sha512-Az2ZTpuytrtqENulXwO3GGv1Bztugx6TT37NIo7imr/Qo0gsYiGtSdBa2B6fsXhTpVZDNfu1Qn3pk531e3q+nQ==", "license": "MIT" }, "node_modules/asyncbox": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/asyncbox/-/asyncbox-6.1.0.tgz", "integrity": "sha512-KZwKNVnDdDe0ubN+fFMuHhSljZNHnbjdJABImoqFzQP61oIg6sMlhXIqOIu3WRd7YwW89q+eVj2Ty/Ax5dbh2Q==", "license": "Apache-2.0", "dependencies": { "p-limit": "^7.2.0" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" } }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "license": "MIT" }, "node_modules/axios": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/axios/-/axios-1.15.0.tgz", "integrity": "sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q==", "license": "MIT", "dependencies": { "follow-redirects": "^1.15.11", "form-data": "^4.0.5", "proxy-from-env": "^2.1.0" } }, "node_modules/b4a": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.8.0.tgz", "integrity": "sha512-qRuSmNSkGQaHwNbM7J78Wwy+ghLEYF1zNrSeMxj4Kgw6y33O3mXcQ6Ie9fRvfU/YnxWkOchPXbaLb73TkIsfdg==", "license": "Apache-2.0", "peerDependencies": { "react-native-b4a": "*" }, "peerDependenciesMeta": { "react-native-b4a": { "optional": true } } }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "license": "MIT" }, "node_modules/bare-events": { "version": "2.8.2", "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.8.2.tgz", "integrity": "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==", "license": "Apache-2.0", "peerDependencies": { "bare-abort-controller": "*" }, "peerDependenciesMeta": { "bare-abort-controller": { "optional": true } } }, "node_modules/bare-fs": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.7.0.tgz", "integrity": "sha512-xzqKsCFxAek9aezYhjJuJRXBIaYlg/0OGDTZp+T8eYmYMlm66cs6cYko02drIyjN2CBbi+I6L7YfXyqpqtKRXA==", "license": "Apache-2.0", "dependencies": { "bare-events": "^2.5.4", "bare-path": "^3.0.0", "bare-stream": "^2.6.4", "bare-url": "^2.2.2", "fast-fifo": "^1.3.2" }, "engines": { "bare": ">=1.16.0" }, "peerDependencies": { "bare-buffer": "*" }, "peerDependenciesMeta": { "bare-buffer": { "optional": true } } }, "node_modules/bare-os": { "version": "3.8.7", "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.8.7.tgz", "integrity": "sha512-G4Gr1UsGeEy2qtDTZwL7JFLo2wapUarz7iTMcYcMFdS89AIQuBoyjgXZz0Utv7uHs3xA9LckhVbeBi8lEQrC+w==", "license": "Apache-2.0", "engines": { "bare": ">=1.14.0" } }, "node_modules/bare-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz", "integrity": "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==", "license": "Apache-2.0", "dependencies": { "bare-os": "^3.0.1" } }, "node_modules/bare-stream": { "version": "2.13.0", "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.13.0.tgz", "integrity": "sha512-3zAJRZMDFGjdn+RVnNpF9kuELw+0Fl3lpndM4NcEOhb9zwtSo/deETfuIwMSE5BXanA0FrN1qVjffGwAg2Y7EA==", "license": "Apache-2.0", "dependencies": { "streamx": "^2.25.0", "teex": "^1.0.1" }, "peerDependencies": { "bare-abort-controller": "*", "bare-buffer": "*", "bare-events": "*" }, "peerDependenciesMeta": { "bare-abort-controller": { "optional": true }, "bare-buffer": { "optional": true }, "bare-events": { "optional": true } } }, "node_modules/bare-url": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.4.0.tgz", "integrity": "sha512-NSTU5WN+fy/L0DDenfE8SXQna4voXuW0FHM7wH8i3/q9khUSchfPbPezO4zSFMnDGIf9YE+mt/RWhZgNRKRIXA==", "license": "Apache-2.0", "dependencies": { "bare-path": "^3.0.0" } }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "license": "MIT" }, "node_modules/base64-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/base64-stream/-/base64-stream-1.0.0.tgz", "integrity": "sha512-BQQZftaO48FcE1Kof9CmXMFaAdqkcNorgc8CxesZv9nMbbTF1EFyQe89UOuh//QMmdtfUDXyO8rgUalemL5ODA==", "license": "MIT" }, "node_modules/basic-auth": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", "license": "MIT", "dependencies": { "safe-buffer": "5.1.2" }, "engines": { "node": ">= 0.8" } }, "node_modules/big-integer": { "version": "1.6.52", "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", "license": "Unlicense", "engines": { "node": ">=0.6" } }, "node_modules/bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", "license": "MIT" }, "node_modules/body-parser": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==", "license": "MIT", "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", "debug": "^4.4.3", "http-errors": "^2.0.0", "iconv-lite": "^0.7.0", "on-finished": "^2.4.1", "qs": "^6.14.1", "raw-body": "^3.0.1", "type-is": "^2.0.1" }, "engines": { "node": ">=18" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, "node_modules/bplist-creator": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.1.1.tgz", "integrity": "sha512-Ese7052fdWrxp/vqSJkydgx/1MdBnNOCV2XVfbmdGWD2H6EYza+Q4pyYSuVSnCUD22hfI/BFI4jHaC3NLXLlJQ==", "license": "MIT", "dependencies": { "stream-buffers": "2.2.x" } }, "node_modules/bplist-parser": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.3.2.tgz", "integrity": "sha512-apC2+fspHGI3mMKj+dGevkGo/tCqVB8jMb6i+OX+E29p0Iposz07fABkRIfVUPNd5A5VbuOz1bZbnmkKLYF+wQ==", "license": "MIT", "dependencies": { "big-integer": "1.6.x" }, "engines": { "node": ">= 5.10.0" } }, "node_modules/buffer-crc32": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz", "integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==", "license": "MIT", "engines": { "node": ">=8.0.0" } }, "node_modules/bufferutil": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.1.0.tgz", "integrity": "sha512-ZMANVnAixE6AWWnPzlW2KpUrxhm9woycYvPOo67jWHyFowASTEd9s+QN1EIMsSDtwhIxN4sWE1jotpuDUIgyIw==", "hasInstallScript": true, "license": "MIT", "optional": true, "dependencies": { "node-gyp-build": "^4.3.0" }, "engines": { "node": ">=6.14.2" } }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" }, "engines": { "node": ">= 0.4" } }, "node_modules/call-bound": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "extraneous": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/chalk/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "extraneous": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/cliui": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz", "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==", "extraneous": true, "license": "ISC", "dependencies": { "string-width": "^7.2.0", "strip-ansi": "^7.1.0", "wrap-ansi": "^9.0.0" }, "engines": { "node": ">=20" } }, "node_modules/cliui/node_modules/emoji-regex": { "version": "10.6.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", "extraneous": true, "license": "MIT" }, "node_modules/cliui/node_modules/string-width": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", "extraneous": true, "license": "MIT", "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" }, "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/cliui/node_modules/strip-ansi": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", "extraneous": true, "license": "MIT", "dependencies": { "ansi-regex": "^6.2.2" }, "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, "engines": { "node": ">=7.0.0" } }, "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" }, "engines": { "node": ">= 0.8" } }, "node_modules/compare-versions": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.1.tgz", "integrity": "sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==", "license": "MIT" }, "node_modules/compress-commons": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-6.0.2.tgz", "integrity": "sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==", "license": "MIT", "dependencies": { "crc-32": "^1.2.0", "crc32-stream": "^6.0.0", "is-stream": "^2.0.1", "normalize-path": "^3.0.0", "readable-stream": "^4.0.0" }, "engines": { "node": ">= 14" } }, "node_modules/console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", "license": "ISC" }, "node_modules/content-disposition": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.1.0.tgz", "integrity": "sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==", "license": "MIT", "engines": { "node": ">=18" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, "node_modules/content-type": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/cookie": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/cookie-signature": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", "license": "MIT", "engines": { "node": ">=6.6.0" } }, "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "license": "MIT" }, "node_modules/crc-32": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", "license": "Apache-2.0", "bin": { "crc32": "bin/crc32.njs" }, "engines": { "node": ">=0.8" } }, "node_modules/crc32-stream": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-6.0.0.tgz", "integrity": "sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==", "license": "MIT", "dependencies": { "crc-32": "^1.2.0", "readable-stream": "^4.0.0" }, "engines": { "node": ">= 14" } }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" }, "engines": { "node": ">= 8" } }, "node_modules/cross-spawn/node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "license": "ISC" }, "node_modules/cross-spawn/node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "bin/node-which" }, "engines": { "node": ">= 8" } }, "node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "license": "MIT", "dependencies": { "ms": "^2.1.3" }, "engines": { "node": ">=6.0" }, "peerDependenciesMeta": { "supports-color": { "optional": true } } }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "license": "MIT", "engines": { "node": ">=0.4.0" } }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/detect-libc": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", "license": "Apache-2.0", "optional": true, "engines": { "node": ">=8" } }, "node_modules/detect-node": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", "license": "MIT", "optional": true }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" }, "engines": { "node": ">= 0.4" } }, "node_modules/duplexer": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", "license": "MIT" }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "license": "MIT" }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", "license": "MIT" }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "license": "MIT" }, "node_modules/encodeurl": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/es-define-property": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/es-errors": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/es-object-atoms": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0" }, "engines": { "node": ">= 0.4" } }, "node_modules/es-set-tostringtag": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" } }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "extraneous": true, "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", "license": "MIT" }, "node_modules/etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/event-target-shim": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/eventemitter3": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", "license": "MIT" }, "node_modules/events": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "license": "MIT", "engines": { "node": ">=0.8.x" } }, "node_modules/events-universal": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz", "integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==", "license": "Apache-2.0", "dependencies": { "bare-events": "^2.7.0" } }, "node_modules/express": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", "license": "MIT", "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.1", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", "depd": "^2.0.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "finalhandler": "^2.1.0", "fresh": "^2.0.0", "http-errors": "^2.0.0", "merge-descriptors": "^2.0.0", "mime-types": "^3.0.0", "on-finished": "^2.4.1", "once": "^1.4.0", "parseurl": "^1.3.3", "proxy-addr": "^2.0.7", "qs": "^6.14.0", "range-parser": "^1.2.1", "router": "^2.2.0", "send": "^1.1.0", "serve-static": "^2.2.0", "statuses": "^2.0.1", "type-is": "^2.0.1", "vary": "^1.1.2" }, "engines": { "node": ">= 18" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, "node_modules/fast-fifo": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", "license": "MIT" }, "node_modules/fastest-levenshtein": { "version": "1.0.16", "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", "license": "MIT", "engines": { "node": ">= 4.9.1" } }, "node_modules/finalhandler": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", "license": "MIT", "dependencies": { "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "on-finished": "^2.4.1", "parseurl": "^1.3.3", "statuses": "^2.0.1" }, "engines": { "node": ">= 18.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, "node_modules/find-up-simple": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.1.tgz", "integrity": "sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==", "license": "MIT", "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/follow-redirects": { "version": "1.15.11", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", "funding": [ { "type": "individual", "url": "https://github.com/sponsors/RubenVerborgh" } ], "license": "MIT", "engines": { "node": ">=4.0" }, "peerDependenciesMeta": { "debug": { "optional": true } } }, "node_modules/foreground-child": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", "license": "ISC", "dependencies": { "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" }, "engines": { "node": ">=14" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/foreground-child/node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "license": "ISC", "engines": { "node": ">=14" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/form-data": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.2", "mime-types": "^2.1.12" }, "engines": { "node": ">= 6" } }, "node_modules/form-data/node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/form-data/node_modules/mime-types": { "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "license": "MIT", "dependencies": { "mime-db": "1.52.0" }, "engines": { "node": ">= 0.6" } }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/fresh": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/ftp-response-parser": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ftp-response-parser/-/ftp-response-parser-1.0.1.tgz", "integrity": "sha512-++Ahlo2hs/IC7UVQzjcSAfeUpCwTTzs4uvG5XfGnsinIFkWUYF4xWwPd5qZuK8MJrmUIxFMuHcfqaosCDjvIWw==", "dependencies": { "readable-stream": "^1.0.31" }, "engines": { "node": ">=0.8.0" } }, "node_modules/ftp-response-parser/node_modules/isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", "license": "MIT" }, "node_modules/ftp-response-parser/node_modules/readable-stream": { "version": "1.1.14", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", "isarray": "0.0.1", "string_decoder": "~0.10.x" } }, "node_modules/ftp-response-parser/node_modules/string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", "license": "MIT" }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "extraneous": true, "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } }, "node_modules/get-east-asian-width": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.5.0.tgz", "integrity": "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==", "extraneous": true, "license": "MIT", "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/get-intrinsic": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/get-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", "license": "MIT", "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" } }, "node_modules/get-stream": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", "license": "MIT", "dependencies": { "@sec-ant/readable-stream": "^0.4.1", "is-stream": "^4.0.1" }, "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/get-stream/node_modules/is-stream": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", "license": "MIT", "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/glob": { "version": "13.0.6", "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", "license": "BlueOak-1.0.0", "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" }, "engines": { "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/glob/node_modules/balanced-match": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", "license": "MIT", "engines": { "node": "18 || 20 || >=22" } }, "node_modules/glob/node_modules/brace-expansion": { "version": "5.0.5", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", "license": "MIT", "dependencies": { "balanced-match": "^4.0.2" }, "engines": { "node": "18 || 20 || >=22" } }, "node_modules/glob/node_modules/minimatch": { "version": "10.2.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", "license": "BlueOak-1.0.0", "dependencies": { "brace-expansion": "^5.0.5" }, "engines": { "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "license": "MIT", "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "license": "ISC" }, "node_modules/handle-thing": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", "license": "MIT", "optional": true }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "extraneous": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/has-symbols": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "license": "MIT", "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-tostringtag": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "license": "MIT", "dependencies": { "function-bind": "^1.1.2" }, "engines": { "node": ">= 0.4" } }, "node_modules/hosted-git-info": { "version": "9.0.2", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-9.0.2.tgz", "integrity": "sha512-M422h7o/BR3rmCQ8UHi7cyyMqKltdP9Uo+J2fXK+RSAY+wTcKOIRyhTuKv4qn+DJf3g+PL890AzId5KZpX+CBg==", "license": "ISC", "dependencies": { "lru-cache": "^11.1.0" }, "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/hpack.js": { "version": "2.1.6", "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", "license": "MIT", "optional": true, "dependencies": { "inherits": "^2.0.1", "obuf": "^1.0.0", "readable-stream": "^2.0.1", "wbuf": "^1.1.0" } }, "node_modules/hpack.js/node_modules/readable-stream": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "license": "MIT", "optional": true, "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "node_modules/hpack.js/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "license": "MIT", "optional": true, "dependencies": { "safe-buffer": "~5.1.0" } }, "node_modules/http-deceiver": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", "license": "MIT", "optional": true }, "node_modules/http-errors": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", "license": "MIT", "dependencies": { "depd": "~2.0.0", "inherits": "~2.0.4", "setprototypeof": "~1.2.0", "statuses": "~2.0.2", "toidentifier": "~1.0.1" }, "engines": { "node": ">= 0.8" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, "node_modules/http-status-codes": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/http-status-codes/-/http-status-codes-2.3.0.tgz", "integrity": "sha512-RJ8XvFvpPM/Dmc5SV+dC4y5PCeOhT3x1Hq0NU3rjGeg5a/CqlhZ7uudknPwZFz4aeAXDcbAyaeP7GAo9lvngtA==", "license": "MIT" }, "node_modules/iconv-lite": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, "engines": { "node": ">=0.10.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "license": "BSD-3-Clause" }, "node_modules/index-to-position": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/index-to-position/-/index-to-position-1.2.0.tgz", "integrity": "sha512-Yg7+ztRkqslMAS2iFaU+Oa4KTSidr63OsFGlOrJoW981kIYO3CGCS3wA95P1mUi/IVSJkn0D479KTJpVpvFNuw==", "license": "MIT", "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "license": "ISC" }, "node_modules/ini": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/ini/-/ini-6.0.0.tgz", "integrity": "sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ==", "license": "ISC", "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/io.appium.settings": { "version": "7.0.22", "resolved": "https://registry.npmjs.org/io.appium.settings/-/io.appium.settings-7.0.22.tgz", "integrity": "sha512-LBKquRGIRfYG9qk8Y2CkOhuk4dDRSGNzcPoMy5a2/lopTpHPvJz+FQOXfcPVQ23qgbCE7GJH7chYKvlJrFOPZA==", "license": "Apache-2.0", "dependencies": { "@appium/logger": "^2.0.0-rc.1", "asyncbox": "^6.0.1", "bluebird": "^3.5.1", "lodash": "^4.2.1", "semver": "^7.5.4", "teen_process": "^4.0.4" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" } }, "node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "license": "MIT", "engines": { "node": ">= 0.10" } }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/is-number-like": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/is-number-like/-/is-number-like-1.0.8.tgz", "integrity": "sha512-6rZi3ezCyFcn5L71ywzz2bS5b2Igl1En3eTlZlvKjpz1n3IZLAYMbKYAIQgFmEu0GENg92ziU/faEOA/aixjbA==", "license": "ISC", "dependencies": { "lodash.isfinite": "^3.3.2" } }, "node_modules/is-promise": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", "license": "MIT" }, "node_modules/is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "license": "MIT", "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-unicode-supported": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", "license": "MIT", "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", "license": "MIT" }, "node_modules/isexe": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-4.0.0.tgz", "integrity": "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==", "license": "BlueOak-1.0.0", "engines": { "node": ">=20" } }, "node_modules/jackspeak": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" }, "funding": { "url": "https://github.com/sponsors/isaacs" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "license": "MIT" }, "node_modules/jsftp": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/jsftp/-/jsftp-2.1.3.tgz", "integrity": "sha512-r79EVB8jaNAZbq8hvanL8e8JGu2ZNr2bXdHC4ZdQhRImpSPpnWwm5DYVzQ5QxJmtGtKhNNuvqGgbNaFl604fEQ==", "license": "MIT", "dependencies": { "debug": "^3.1.0", "ftp-response-parser": "^1.0.1", "once": "^1.4.0", "parse-listing": "^1.1.3", "stream-combiner": "^0.2.2", "unorm": "^1.4.1" }, "engines": { "node": ">=6" } }, "node_modules/jsftp/node_modules/debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "license": "MIT", "dependencies": { "ms": "^2.1.1" } }, "node_modules/json-schema": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", "license": "(AFL-2.1 OR BSD-3-Clause)" }, "node_modules/klaw": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/klaw/-/klaw-4.1.0.tgz", "integrity": "sha512-1zGZ9MF9H22UnkpVeuaGKOjfA2t6WrfdrJmGjy16ykcjnKQDmHVX+KI477rpbGevz/5FD4MC3xf1oxylBgcaQw==", "license": "MIT", "engines": { "node": ">=14.14.0" } }, "node_modules/lazystream": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", "license": "MIT", "dependencies": { "readable-stream": "^2.0.5" }, "engines": { "node": ">= 0.6.3" } }, "node_modules/lazystream/node_modules/readable-stream": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "node_modules/lazystream/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" } }, "node_modules/lockfile": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/lockfile/-/lockfile-1.0.4.tgz", "integrity": "sha512-cvbTwETRfsFh4nHsL1eGWapU1XFi5Ot9E85sWAwia7Y7EgB7vfqcZhTKZ+l7hCGxSPoushMv5GKhT5PdLv03WA==", "license": "ISC", "dependencies": { "signal-exit": "^3.0.2" } }, "node_modules/lodash": { "version": "4.18.1", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", "license": "MIT" }, "node_modules/lodash.isfinite": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/lodash.isfinite/-/lodash.isfinite-3.3.2.tgz", "integrity": "sha512-7FGG40uhC8Mm633uKW1r58aElFlBlxCrg9JfSi3P6aYiWmfiWF0PgMd86ZUsxE5GwWPdHoS2+48bwTh2VPkIQA==", "license": "MIT" }, "node_modules/log-symbols": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-7.0.1.tgz", "integrity": "sha512-ja1E3yCr9i/0hmBVaM0bfwDjnGy8I/s6PP4DFp+yP+a+mrHO4Rm7DtmnqROTUkHIkqffC84YY7AeqX6oFk0WFg==", "license": "MIT", "dependencies": { "is-unicode-supported": "^2.0.0", "yoctocolors": "^2.1.1" }, "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/lru-cache": { "version": "11.3.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.3.tgz", "integrity": "sha512-JvNw9Y81y33E+BEYPr0U7omo+U9AySnsMsEiXgwT6yqd31VQWTLNQqmT4ou5eqPFUrTfIDFta2wKhB1hyohtAQ==", "license": "BlueOak-1.0.0", "engines": { "node": "20 || >=22" } }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/media-typer": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/merge-descriptors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", "license": "MIT", "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/method-override": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/method-override/-/method-override-3.0.0.tgz", "integrity": "sha512-IJ2NNN/mSl9w3kzWB92rcdHpz+HjkxhDJWNDBqSlas+zQdP8wBiJzITPg08M/k2uVvMow7Sk41atndNtt/PHSA==", "license": "MIT", "dependencies": { "debug": "3.1.0", "methods": "~1.1.2", "parseurl": "~1.3.2", "vary": "~1.1.2" }, "engines": { "node": ">= 0.10" } }, "node_modules/method-override/node_modules/debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "license": "MIT", "dependencies": { "ms": "2.0.0" } }, "node_modules/method-override/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, "node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/mime-db": { "version": "1.54.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", "license": "MIT", "dependencies": { "mime-db": "^1.54.0" }, "engines": { "node": ">=18" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, "node_modules/mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "extraneous": true, "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", "license": "ISC", "optional": true }, "node_modules/minipass": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", "license": "BlueOak-1.0.0", "engines": { "node": ">=16 || 14 >=14.17" } }, "node_modules/moment": { "version": "2.30.1", "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", "license": "MIT", "engines": { "node": "*" } }, "node_modules/moment-timezone": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.6.1.tgz", "integrity": "sha512-1B9lmAhB9D9/sHaPC1N7wLFEVUoFldxOpOO96lOD1PvJ43vCd0ozDPbu0FEL3++VvawOlDkq8YD373tJmP5JHw==", "license": "MIT", "dependencies": { "moment": "^2.29.4" }, "engines": { "node": "*" } }, "node_modules/morgan": { "version": "1.10.1", "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.1.tgz", "integrity": "sha512-223dMRJtI/l25dJKWpgij2cMtywuG/WiUKXdvwfbhGKBhy1puASqXwFzmWZ7+K73vUPoR7SS2Qz2cI/g9MKw0A==", "license": "MIT", "dependencies": { "basic-auth": "~2.0.1", "debug": "2.6.9", "depd": "~2.0.0", "on-finished": "~2.3.0", "on-headers": "~1.1.0" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/morgan/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "license": "MIT", "dependencies": { "ms": "2.0.0" } }, "node_modules/morgan/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, "node_modules/morgan/node_modules/on-finished": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", "license": "MIT", "dependencies": { "ee-first": "1.1.1" }, "engines": { "node": ">= 0.8" } }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, "node_modules/ncp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", "integrity": "sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA==", "license": "MIT", "bin": { "ncp": "bin/ncp" } }, "node_modules/negotiator": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/node-gyp-build": { "version": "4.8.4", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", "license": "MIT", "optional": true, "bin": { "node-gyp-build": "bin.js", "node-gyp-build-optional": "optional.js", "node-gyp-build-test": "build-test.js" } }, "node_modules/normalize-package-data": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-8.0.0.tgz", "integrity": "sha512-RWk+PI433eESQ7ounYxIp67CYuVsS1uYSonX3kA6ps/3LWfjVQa/ptEg6Y3T6uAMq1mWpX9PQ+qx+QaHpsc7gQ==", "license": "BSD-2-Clause", "dependencies": { "hosted-git-info": "^9.0.0", "semver": "^7.3.5", "validate-npm-package-license": "^3.0.4" }, "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/object-inspect": { "version": "1.13.4", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", "license": "MIT", "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/obuf": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", "license": "MIT", "optional": true }, "node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "license": "MIT", "dependencies": { "ee-first": "1.1.1" }, "engines": { "node": ">= 0.8" } }, "node_modules/on-headers": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz", "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==", "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "license": "ISC", "dependencies": { "wrappy": "1" } }, "node_modules/onetime": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "extraneous": true, "license": "MIT", "dependencies": { "mimic-fn": "^2.1.0" }, "engines": { "node": ">=6" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-limit": { "version": "7.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-7.3.0.tgz", "integrity": "sha512-7cIXg/Z0M5WZRblrsOla88S4wAK+zOQQWeBYfV3qJuJXMr+LnbYjaadrFaS0JILfEDPVqHyKnZ1Z/1d6J9VVUw==", "license": "MIT", "dependencies": { "yocto-queue": "^1.2.1" }, "engines": { "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/package-directory": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/package-directory/-/package-directory-8.2.0.tgz", "integrity": "sha512-qJSu5Mo6tHmRxCy2KCYYKYgcfBdUpy9dwReaZD/xwf608AUk/MoRtIOWzgDtUeGeC7n/55yC3MI1Q+MbSoektw==", "license": "MIT", "dependencies": { "find-up-simple": "^1.0.0" }, "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/package-json-from-dist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", "license": "BlueOak-1.0.0" }, "node_modules/parse-json": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.3.0.tgz", "integrity": "sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.26.2", "index-to-position": "^1.1.0", "type-fest": "^4.39.1" }, "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/parse-json/node_modules/type-fest": { "version": "4.41.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/parse-listing": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/parse-listing/-/parse-listing-1.1.3.tgz", "integrity": "sha512-a1p1i+9Qyc8pJNwdrSvW1g5TPxRH0sywVi6OzVvYHRo6xwF9bDWBxtH0KkxeOOvhUE8vAMtiSfsYQFOuK901eA==", "engines": { "node": ">=0.6.21" } }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/path-scurry": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", "license": "BlueOak-1.0.0", "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" }, "engines": { "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/path-to-regexp": { "version": "8.4.2", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz", "integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==", "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, "node_modules/pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", "license": "MIT" }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "license": "ISC" }, "node_modules/plist": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz", "integrity": "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==", "license": "MIT", "dependencies": { "@xmldom/xmldom": "^0.8.8", "base64-js": "^1.5.1", "xmlbuilder": "^15.1.1" }, "engines": { "node": ">=10.4.0" } }, "node_modules/plist/node_modules/@xmldom/xmldom": { "version": "0.8.12", "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.12.tgz", "integrity": "sha512-9k/gHF6n/pAi/9tqr3m3aqkuiNosYTurLLUtc7xQ9sxB/wm7WPygCv8GYa6mS0fLJEHhqMC1ATYhz++U/lRHqg==", "license": "MIT", "engines": { "node": ">=10.0.0" } }, "node_modules/pluralize": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/portscanner": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/portscanner/-/portscanner-2.2.0.tgz", "integrity": "sha512-IFroCz/59Lqa2uBvzK3bKDbDDIEaAY8XJ1jFxcLWTqosrsc32//P4VuSB2vZXoHiHqOmx8B5L5hnKOxL/7FlPw==", "license": "MIT", "dependencies": { "async": "^2.6.0", "is-number-like": "^1.0.3" }, "engines": { "node": ">=0.4", "npm": ">=1.0.0" } }, "node_modules/portscanner/node_modules/async": { "version": "2.6.4", "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", "license": "MIT", "dependencies": { "lodash": "^4.17.14" } }, "node_modules/process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", "license": "MIT", "engines": { "node": ">= 0.6.0" } }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "license": "MIT" }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "license": "MIT", "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" }, "engines": { "node": ">= 0.10" } }, "node_modules/proxy-from-env": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", "license": "MIT", "engines": { "node": ">=10" } }, "node_modules/qs": { "version": "6.15.1", "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.1.tgz", "integrity": "sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==", "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.1.0" }, "engines": { "node": ">=0.6" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/raw-body": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", "license": "MIT", "dependencies": { "bytes": "~3.1.2", "http-errors": "~2.0.1", "iconv-lite": "~0.7.0", "unpipe": "~1.0.0" }, "engines": { "node": ">= 0.10" } }, "node_modules/read-pkg": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-10.1.0.tgz", "integrity": "sha512-I8g2lArQiP78ll51UeMZojewtYgIRCKCWqZEgOO8c/uefTI+XDXvCSXu3+YNUaTNvZzobrL5+SqHjBrByRRTdg==", "license": "MIT", "dependencies": { "@types/normalize-package-data": "^2.4.4", "normalize-package-data": "^8.0.0", "parse-json": "^8.3.0", "type-fest": "^5.4.4", "unicorn-magic": "^0.4.0" }, "engines": { "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/readable-stream": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", "license": "MIT", "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", "events": "^3.3.0", "process": "^0.11.10", "string_decoder": "^1.3.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/readable-stream/node_modules/buffer": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "license": "MIT", "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" } }, "node_modules/readdir-glob": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz", "integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==", "license": "Apache-2.0", "dependencies": { "minimatch": "^5.1.0" } }, "node_modules/readdir-glob/node_modules/brace-expansion": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz", "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/readdir-glob/node_modules/minimatch": { "version": "5.1.9", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz", "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==", "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, "engines": { "node": ">=10" } }, "node_modules/resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/router": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", "license": "MIT", "dependencies": { "debug": "^4.4.0", "depd": "^2.0.0", "is-promise": "^4.0.0", "parseurl": "^1.3.3", "path-to-regexp": "^8.0.0" }, "engines": { "node": ">= 18" } }, "node_modules/rpc-websockets": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-10.0.0.tgz", "integrity": "sha512-ci68pI2x0TZdrRbpFx8oiBosNUKR1a2Y9kADVwwhX6UUq+B1E9oqNXnxq20WvTwR7+3Dsow1qAtU8pPGoZE4sw==", "deprecated": "deprecate 10.0.0", "license": "LGPL-3.0-only", "dependencies": { "@swc/helpers": "^0.5.11", "@types/uuid": "^8.3.4", "@types/ws": "^8.2.2", "buffer": "^6.0.3", "eventemitter3": "^5.0.1", "uuid": "^8.3.2", "ws": "^8.5.0" }, "funding": { "type": "paypal", "url": "https://paypal.me/kozjak" }, "optionalDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" } }, "node_modules/rpc-websockets/node_modules/buffer": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "license": "MIT", "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" } }, "node_modules/rpc-websockets/node_modules/uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "license": "MIT" }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "license": "MIT" }, "node_modules/sanitize-filename": { "version": "1.6.4", "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.4.tgz", "integrity": "sha512-9ZyI08PsvdQl2r/bBIGubpVdR3RR9sY6RDiWFPreA21C/EFlQhmgo20UZlNjZMMZNubusLhAQozkA0Od5J21Eg==", "license": "WTFPL OR ISC", "dependencies": { "truncate-utf8-bytes": "^1.0.0" } }, "node_modules/select-hose": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", "license": "MIT", "optional": true }, "node_modules/semver": { "version": "7.7.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "license": "ISC", "bin": { "semver": "bin/semver.js" }, "engines": { "node": ">=10" } }, "node_modules/send": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", "license": "MIT", "dependencies": { "debug": "^4.4.3", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "fresh": "^2.0.0", "http-errors": "^2.0.1", "mime-types": "^3.0.2", "ms": "^2.1.3", "on-finished": "^2.4.1", "range-parser": "^1.2.1", "statuses": "^2.0.2" }, "engines": { "node": ">= 18" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, "node_modules/serve-favicon": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/serve-favicon/-/serve-favicon-2.5.1.tgz", "integrity": "sha512-JndLBslCLA/ebr7rS3d+/EKkzTsTi1jI2T9l+vHfAaGJ7A7NhtDpSZ0lx81HCNWnnE0yHncG+SSnVf9IMxOwXQ==", "license": "MIT", "dependencies": { "etag": "~1.8.1", "fresh": "~0.5.2", "ms": "~2.1.3", "parseurl": "~1.3.2", "safe-buffer": "~5.2.1" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/serve-favicon/node_modules/fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/serve-favicon/node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "license": "MIT" }, "node_modules/serve-static": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", "license": "MIT", "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", "send": "^1.2.0" }, "engines": { "node": ">= 18" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, "node_modules/set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", "license": "ISC" }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "license": "ISC" }, "node_modules/sharp": { "version": "0.34.5", "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", "hasInstallScript": true, "license": "Apache-2.0", "optional": true, "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.2", "semver": "^7.7.3" }, "engines": { "node": "^18.17.0 || ^20.3.0 || >=21.0.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.5", "@img/sharp-darwin-x64": "0.34.5", "@img/sharp-libvips-darwin-arm64": "1.2.4", "@img/sharp-libvips-darwin-x64": "1.2.4", "@img/sharp-libvips-linux-arm": "1.2.4", "@img/sharp-libvips-linux-arm64": "1.2.4", "@img/sharp-libvips-linux-ppc64": "1.2.4", "@img/sharp-libvips-linux-riscv64": "1.2.4", "@img/sharp-libvips-linux-s390x": "1.2.4", "@img/sharp-libvips-linux-x64": "1.2.4", "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", "@img/sharp-libvips-linuxmusl-x64": "1.2.4", "@img/sharp-linux-arm": "0.34.5", "@img/sharp-linux-arm64": "0.34.5", "@img/sharp-linux-ppc64": "0.34.5", "@img/sharp-linux-riscv64": "0.34.5", "@img/sharp-linux-s390x": "0.34.5", "@img/sharp-linux-x64": "0.34.5", "@img/sharp-linuxmusl-arm64": "0.34.5", "@img/sharp-linuxmusl-x64": "0.34.5", "@img/sharp-wasm32": "0.34.5", "@img/sharp-win32-arm64": "0.34.5", "@img/sharp-win32-ia32": "0.34.5", "@img/sharp-win32-x64": "0.34.5" } }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, "engines": { "node": ">=8" } }, "node_modules/shebang-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/shell-quote": { "version": "1.8.3", "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", "license": "MIT", "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/side-channel": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", "side-channel-list": "^1.0.0", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/side-channel-list": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.4" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/side-channel-map": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", "license": "MIT", "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/side-channel-weakmap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", "license": "MIT", "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3", "side-channel-map": "^1.0.1" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "license": "ISC" }, "node_modules/spdx-correct": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", "license": "Apache-2.0", "dependencies": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" } }, "node_modules/spdx-exceptions": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", "license": "CC-BY-3.0" }, "node_modules/spdx-expression-parse": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "license": "MIT", "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, "node_modules/spdx-license-ids": { "version": "3.0.23", "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.23.tgz", "integrity": "sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==", "license": "CC0-1.0" }, "node_modules/spdy": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", "license": "MIT", "optional": true, "dependencies": { "debug": "^4.1.0", "handle-thing": "^2.0.0", "http-deceiver": "^1.2.7", "select-hose": "^2.0.0", "spdy-transport": "^3.0.0" }, "engines": { "node": ">=6.0.0" } }, "node_modules/spdy-transport": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", "license": "MIT", "optional": true, "dependencies": { "debug": "^4.1.0", "detect-node": "^2.0.4", "hpack.js": "^2.1.6", "obuf": "^1.1.2", "readable-stream": "^3.0.6", "wbuf": "^1.7.3" } }, "node_modules/spdy-transport/node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "license": "MIT", "optional": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" }, "engines": { "node": ">= 6" } }, "node_modules/statuses": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/stream-buffers": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz", "integrity": "sha512-uyQK/mx5QjHun80FLJTfaWE7JtwfRMKBLkMne6udYOmvH0CawotVa7TfgYHzAnpphn4+TweIx1QKMnRIbipmUg==", "license": "Unlicense", "engines": { "node": ">= 0.10.0" } }, "node_modules/stream-combiner": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz", "integrity": "sha512-6yHMqgLYDzQDcAkL+tjJDC5nSNuNIx0vZtRZeiPh7Saef7VHX9H5Ijn9l2VIol2zaNYlYEX6KyuT/237A58qEQ==", "license": "MIT", "dependencies": { "duplexer": "~0.1.1", "through": "~2.3.4" } }, "node_modules/streamx": { "version": "2.25.0", "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.25.0.tgz", "integrity": "sha512-0nQuG6jf1w+wddNEEXCF4nTg3LtufWINB5eFEN+5TNZW7KWJp6x87+JFL43vaAUPyCfH1wID+mNVyW6OHtFamg==", "license": "MIT", "dependencies": { "events-universal": "^1.0.0", "fast-fifo": "^1.3.2", "text-decoder": "^1.1.0" } }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" } }, "node_modules/string_decoder/node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "license": "MIT" }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" }, "engines": { "node": ">=8" } }, "node_modules/string-width-cjs": { "name": "string-width", "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" }, "engines": { "node": ">=8" } }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/strip-ansi-cjs": { "name": "strip-ansi", "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/strip-ansi/node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/supports-color": { "version": "10.2.2", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-10.2.2.tgz", "integrity": "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==", "license": "MIT", "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/chalk/supports-color?sponsor=1" } }, "node_modules/tagged-tag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/tagged-tag/-/tagged-tag-1.0.0.tgz", "integrity": "sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==", "license": "MIT", "engines": { "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/tar-stream": { "version": "3.1.8", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.8.tgz", "integrity": "sha512-U6QpVRyCGHva435KoNWy9PRoi2IFYCgtEhq9nmrPPpbRacPs9IH4aJ3gbrFC8dPcXvdSZ4XXfXT5Fshbp2MtlQ==", "license": "MIT", "dependencies": { "b4a": "^1.6.4", "bare-fs": "^4.5.5", "fast-fifo": "^1.2.0", "streamx": "^2.15.0" } }, "node_modules/teen_process": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/teen_process/-/teen_process-4.1.0.tgz", "integrity": "sha512-AN8y3MYPExB3r2mkkX9r0wEF4xPfhKOj6YvcfeIqQai+GVhTIhjjdkPvwI5CFT4z8UQ5aZWldzbJ+jNejYAdGw==", "license": "Apache-2.0", "dependencies": { "lodash": "^4.17.21", "shell-quote": "^1.8.1" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" } }, "node_modules/teex": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz", "integrity": "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==", "license": "MIT", "dependencies": { "streamx": "^2.12.5" } }, "node_modules/text-decoder": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.7.tgz", "integrity": "sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ==", "license": "Apache-2.0", "dependencies": { "b4a": "^1.6.4" } }, "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "license": "MIT" }, "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "license": "MIT", "engines": { "node": ">=0.6" } }, "node_modules/truncate-utf8-bytes": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", "integrity": "sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==", "license": "WTFPL", "dependencies": { "utf8-byte-length": "^1.0.1" } }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "license": "0BSD" }, "node_modules/type-fest": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.5.0.tgz", "integrity": "sha512-PlBfpQwiUvGViBNX84Yxwjsdhd1TUlXr6zjX7eoirtCPIr08NAmxwa+fcYBTeRQxHo9YC9wwF3m9i700sHma8g==", "license": "(MIT OR CC0-1.0)", "dependencies": { "tagged-tag": "^1.0.0" }, "engines": { "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/type-is": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", "license": "MIT", "dependencies": { "content-type": "^1.0.5", "media-typer": "^1.1.0", "mime-types": "^3.0.0" }, "engines": { "node": ">= 0.6" } }, "node_modules/undici-types": { "version": "7.19.2", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.19.2.tgz", "integrity": "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==", "license": "MIT" }, "node_modules/unicorn-magic": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.4.0.tgz", "integrity": "sha512-wH590V9VNgYH9g3lH9wWjTrUoKsjLF6sGLjhR4sH1LWpLmCOH0Zf7PukhDA8BiS7KHe4oPNkcTHqYkj7SOGUOw==", "license": "MIT", "engines": { "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/unorm": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/unorm/-/unorm-1.6.0.tgz", "integrity": "sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA==", "license": "MIT or GPL-2.0", "engines": { "node": ">= 0.4.0" } }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/utf-8-validate": { "version": "5.0.10", "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz", "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==", "hasInstallScript": true, "license": "MIT", "optional": true, "dependencies": { "node-gyp-build": "^4.3.0" }, "engines": { "node": ">=6.14.2" } }, "node_modules/utf8-byte-length": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.5.tgz", "integrity": "sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA==", "license": "(WTFPL OR MIT)" }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "license": "MIT" }, "node_modules/uuid": { "version": "13.0.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-13.0.0.tgz", "integrity": "sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], "license": "MIT", "bin": { "uuid": "dist-node/bin/uuid" } }, "node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "license": "Apache-2.0", "dependencies": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" } }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/wbuf": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", "license": "MIT", "optional": true, "dependencies": { "minimalistic-assert": "^1.0.0" } }, "node_modules/which": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/which/-/which-6.0.1.tgz", "integrity": "sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==", "license": "ISC", "dependencies": { "isexe": "^4.0.0" }, "bin": { "node-which": "bin/which.js" }, "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/wrap-ansi": { "version": "9.0.2", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", "extraneous": true, "license": "MIT", "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", "strip-ansi": "^7.1.0" }, "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/wrap-ansi-cjs": { "name": "wrap-ansi", "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/wrap-ansi/node_modules/ansi-styles": { "version": "6.2.3", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", "extraneous": true, "license": "MIT", "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/wrap-ansi/node_modules/emoji-regex": { "version": "10.6.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", "extraneous": true, "license": "MIT" }, "node_modules/wrap-ansi/node_modules/string-width": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", "extraneous": true, "license": "MIT", "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" }, "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/wrap-ansi/node_modules/strip-ansi": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", "extraneous": true, "license": "MIT", "dependencies": { "ansi-regex": "^6.2.2" }, "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "license": "ISC" }, "node_modules/ws": { "version": "8.20.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz", "integrity": "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==", "license": "MIT", "engines": { "node": ">=10.0.0" }, "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "peerDependenciesMeta": { "bufferutil": { "optional": true }, "utf-8-validate": { "optional": true } } }, "node_modules/xmlbuilder": { "version": "15.1.1", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", "license": "MIT", "engines": { "node": ">=8.0" } }, "node_modules/xpath": { "version": "0.0.34", "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.34.tgz", "integrity": "sha512-FxF6+rkr1rNSQrhUNYrAFJpRXNzlDoMxeXN5qI84939ylEv3qqPFKa85Oxr6tDaJKqwW6KKyo2v26TSv3k6LeA==", "license": "MIT", "engines": { "node": ">=0.6.0" } }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "extraneous": true, "license": "ISC", "engines": { "node": ">=10" } }, "node_modules/yargs": { "version": "18.0.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.0.0.tgz", "integrity": "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==", "extraneous": true, "license": "MIT", "dependencies": { "cliui": "^9.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "string-width": "^7.2.0", "y18n": "^5.0.5", "yargs-parser": "^22.0.0" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=23" } }, "node_modules/yargs-parser": { "version": "22.0.0", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz", "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==", "extraneous": true, "license": "ISC", "engines": { "node": "^20.19.0 || ^22.12.0 || >=23" } }, "node_modules/yargs/node_modules/emoji-regex": { "version": "10.6.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", "extraneous": true, "license": "MIT" }, "node_modules/yargs/node_modules/string-width": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", "extraneous": true, "license": "MIT", "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" }, "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/yargs/node_modules/strip-ansi": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", "extraneous": true, "license": "MIT", "dependencies": { "ansi-regex": "^6.2.2" }, "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, "node_modules/yauzl": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-3.3.0.tgz", "integrity": "sha512-PtGEvEP30p7sbIBJKUBjUnqgTVOyMURc4dLo9iNyAJnNIEz9pm88cCXF21w94Kg3k6RXkeZh5DHOGS0qEONvNQ==", "license": "MIT", "dependencies": { "buffer-crc32": "~0.2.3", "pend": "~1.2.0" }, "engines": { "node": ">=12" } }, "node_modules/yauzl/node_modules/buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", "license": "MIT", "engines": { "node": "*" } }, "node_modules/yocto-queue": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.2.tgz", "integrity": "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==", "license": "MIT", "engines": { "node": ">=12.20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/yoctocolors": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.2.tgz", "integrity": "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==", "license": "MIT", "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/zip-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-6.0.1.tgz", "integrity": "sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==", "license": "MIT", "dependencies": { "archiver-utils": "^5.0.0", "compress-commons": "^6.0.2", "readable-stream": "^4.0.0" }, "engines": { "node": ">= 14" } } } } ================================================ FILE: driver/package.json ================================================ { "name": "appium-flutter-driver", "description": "Appium Flutter driver", "keywords": [ "appium", "flutter" ], "version": "3.6.0", "author": "TruongSinh Tran-Nguyen ", "license": "MIT", "repository": { "type": "git", "url": "git+https://github.com/appium/appium-flutter-driver.git" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": ">=10" }, "main": "./build/lib/driver.js", "types": "./build/lib/index.d.ts", "appium": { "driverName": "flutter", "automationName": "Flutter", "platformNames": [ "iOS", "Android" ], "mainClass": "FlutterDriver", "doctor": { "checks": [ "./build/lib/doctor/checks.js" ] }, "scripts": { "download-wda-sim": "./scripts/download-wda-sim.mjs" } }, "bin": {}, "directories": { "lib": "lib" }, "files": [ "lib", "build", "!build/tsconfig.tsbuildinfo", "LICENSE", "npm-shrinkwrap.json", "scripts" ], "scripts": { "build": "tsc -b", "dev": "npm run build -- --watch", "clean": "npm run build -- --clean", "lint": "eslint .", "lint:fix": "npm run lint -- --fix", "format": "prettier -w ./lib", "format:check": "prettier --check ./lib", "prepublishOnly": "cp ../README.md ../LICENSE ./", "prepare": "npm run clean && npm run build", "test": "echo no test", "clean-dependency": "rm -rf node_modules && rm -f package-lock.json" }, "peerDependencies": { "appium": "^3.0.0" }, "devDependencies": { "@appium/eslint-config-appium-ts": "^3.0.0", "@appium/tsconfig": "^1.0.0", "@appium/types": "^1.0.0", "@semantic-release/changelog": "^6.0.3", "@semantic-release/git": "^10.0.1", "prettier": "^3.0.0", "semantic-release": "^25.0.2", "ts-node": "^10.9.1", "typescript": "~6.0" }, "dependencies": { "appium-android-driver": "^13.0.0", "appium-flutter-finder": "^0.2.0", "appium-ios-device": "^3.0.0", "appium-uiautomator2-driver": "^7.0.0", "appium-xcuitest-driver": "^10.0.0", "asyncbox": "^6.0.1", "bluebird": "^3.1.1", "lodash": "^4.0.0", "portscanner": "^2.2.0", "rpc-websockets": "^10.0.0" }, "prettier": { "bracketSpacing": false, "printWidth": 100, "singleQuote": true } } ================================================ FILE: driver/release.sh ================================================ # !/bin/sh echo "refreshing dependencies" rm npm-shrinkwrap.json APPIUM_SKIP_CHROMEDRIVER_INSTALL=1 npm run clean-dependency npm install --production npm prune --omit=dev --omit=peer rm -rf node_modules/appium npm shrinkwrap --omit=dev --omit=peer # to install types again npm install --only=dev --no-package-lock echo "complete the refreshment" ================================================ FILE: driver/scripts/download-wda-sim.mjs ================================================ // TODO: Please revert '@appium/support' to 'appium/support.js' and "@appium/support" dependency // in Appium 3 based version import {fs, logger, zip, net, node} from '@appium/support'; import _ from 'lodash'; import os from 'node:os'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; const log = logger.getLogger('download-wda-sim'); const wdaUrl = (version, zipFileName) => `https://github.com/appium/WebDriverAgent/releases/download/v${version}/${zipFileName}`; const destZip = (platform) => { const scheme = `WebDriverAgentRunner${_.toLower(platform) === 'tvos' ? '_tvOS' : ''}`; return `${scheme}-Build-Sim-${os.arch() === 'arm64' ? 'arm64' : 'x86_64'}.zip`; }; /** * Get the value of the given argument name. * * @param {string} argName * @returns {string?} The value of the given 'argName'. */ export function parseArgValue(argName) { const argNamePattern = new RegExp(`^--${argName}\\b`); for (let i = 1; i < process.argv.length; ++i) { const arg = process.argv[i]; if (argNamePattern.test(arg)) { return arg.includes('=') ? arg.split('=')[1] : process.argv[i + 1]; } } return null; } /** * Return installed appium-webdriveragent package version * @returns {number} */ async function webdriveragentPkgVersion() { const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const pkgPath = path.join( node.getModuleRootSync('appium-flutter-driver', __dirname), 'node_modules', 'appium-xcuitest-driver', 'node_modules', 'appium-webdriveragent', 'package.json' ); return JSON.parse(await fs.readFile(pkgPath, 'utf8')).version; }; /** * Prepare the working root directory. * @returns {string} Root directory to download and unzip. */ async function prepareRootDir() { const destDirRoot = parseArgValue('outdir'); if (!destDirRoot) { throw new Error(`--outdir is required`); } const destDir = path.resolve(process.cwd(), destDirRoot); if (await fs.exists(destDir)) { throw new Error(`${destDir} already exists`); } await fs.mkdir(destDir, {recursive: true}); return destDir; } async function getWDAPrebuiltPackage() { const destDir = await prepareRootDir(); const platform = parseArgValue('platform'); const zipFileName = destZip(platform); const wdaVersion = await webdriveragentPkgVersion(); const urlToDownload = wdaUrl(wdaVersion, zipFileName); const downloadedZipFile = path.join(destDir, zipFileName); try { log.info(`Downloading ${urlToDownload}`); await net.downloadFile(urlToDownload, downloadedZipFile); log.info(`Unpacking ${downloadedZipFile} into ${destDir}`); await zip.extractAllTo(downloadedZipFile, destDir); log.info(`Deleting ${downloadedZipFile}`); } finally { if (await fs.exists(downloadedZipFile)) { await fs.unlink(downloadedZipFile); } } } (async () => await getWDAPrebuiltPackage())(); ================================================ FILE: driver/tsconfig.json ================================================ { "$schema": "https://json.schemastore.org/tsconfig", "extends": "@appium/tsconfig/tsconfig.json", "compilerOptions": { "esModuleInterop": true, "strict": false, // TODO: make this flag true "outDir": "build", "types": ["node"], "checkJs": true }, "include": ["lib"] } ================================================ FILE: example/.gitignore ================================================ apps/ ================================================ FILE: example/dart/drag_commands.dart ================================================ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_driver/driver_extension.dart'; import 'package:flutter_driver/src/common/message.dart'; import 'package:flutter_driver/src/extension/extension.dart'; import 'package:flutter_test/flutter_test.dart'; class DragCommand extends Command { final double startX; final double startY; final double endX; final double endY; final Duration duration; DragCommand(this.startX, this.startY, this.endX, this.endY, this.duration); @override String get kind => 'dragAndDropWithCommandExtension'; DragCommand.deserialize(Map params) : startX = double.parse(params['startX']!), startY = double.parse(params['startY']!), endX = double.parse(params['endX']!), endY = double.parse(params['endY']!), duration = Duration(milliseconds: int.parse(params['duration']!)); } class DragResult extends Result { final bool success; const DragResult(this.success); @override Map toJson() { return { 'success': success, }; } } class DragCommandExtension extends CommandExtension { @override Future call(Command command, WidgetController prober, CreateFinderFactory finderFactory, CommandHandlerFactory handlerFactory) async { final DragCommand dragCommand = command as DragCommand; final Offset startLocation = Offset(dragCommand.startX, dragCommand.startY); final Offset offset = Offset(dragCommand.endX - dragCommand.startX, dragCommand.endY - dragCommand.startY); await prober.timedDragFrom(startLocation, offset, dragCommand.duration); return const DragResult(true); } @override String get commandKind => 'dragAndDropWithCommandExtension'; @override Command deserialize( Map params, DeserializeFinderFactory finderFactory, DeserializeCommandFactory commandFactory) { return DragCommand.deserialize(params); } } ================================================ FILE: example/dart/get_text_command.dart ================================================ import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_driver/driver_extension.dart'; import 'package:flutter_driver/src/common/find.dart'; import 'package:flutter_driver/src/common/message.dart'; import 'package:flutter_test/flutter_test.dart'; class Base64URL { static String encode(String str) { String base64 = base64Encode(utf8.encode(str)); return base64.replaceAll('+', '-').replaceAll('/', '_').replaceAll('=', ''); } static String decode(String str) { String base64 = str.replaceAll('-', '+').replaceAll('_', '/'); // Add padding if needed switch (base64.length % 4) { case 2: base64 += '=='; break; case 3: base64 += '='; break; } return utf8.decode(base64Decode(base64)); } } class FinderHelper { static SerializableFinder deserializeBase64(String base64Str) { try { // Decode base64 to JSON string final jsonStr = Base64URL.decode(base64Str); // Parse JSON final dynamic finderData = json.decode(jsonStr); if (finderData is! Map) { throw Exception('finder is not valid'); } if (!finderData.containsKey('finderType')) { throw Exception('Invalid finder format: missing finderType'); } final String finderType = finderData['finderType'] as String; switch (finderType) { case 'ByText': return ByText(finderData['text'] as String); case 'ByType': return ByType(finderData['type'] as String); case 'ByValueKey': final keyType = finderData['keyValueType'] as String?; final keyValue = finderData['keyValueString'] as String; if (keyType == 'int') { return ByValueKey(int.parse(keyValue)); } return ByValueKey(keyValue); case 'Ancestor': // Parse of and matching which are JSON strings final ofJson = json.decode(finderData['of'] as String); final matchingJson = json.decode(finderData['matching'] as String); return Ancestor( of: deserializeBase64(Base64URL.encode(json.encode(ofJson))), matching: deserializeBase64(Base64URL.encode(json.encode(matchingJson))), matchRoot: finderData['matchRoot'] == 'true', firstMatchOnly: finderData['firstMatchOnly'] == 'true', ); case 'Descendant': final ofJson = json.decode(finderData['of'] as String); final matchingJson = json.decode(finderData['matching'] as String); return Descendant( of: deserializeBase64(Base64URL.encode(json.encode(ofJson))), matching: deserializeBase64(Base64URL.encode(json.encode(matchingJson))), matchRoot: finderData['matchRoot'] == 'true', firstMatchOnly: finderData['firstMatchOnly'] == 'true', ); default: throw Exception('Unsupported finder type: $finderType'); } } catch (e) { throw Exception('Error deserializing finder: $e'); } } } class GetTextCommandExtension extends CommandExtension { String? getTextFromWidget(Text widget) { return widget.data ?? widget.textSpan?.toPlainText(); } @override Future call( Command command, WidgetController prober, CreateFinderFactory finderFactory, CommandHandlerFactory handlerFactory) async { final GetTextCommand dragCommand = command as GetTextCommand; // Create finder for Text widget final type = dragCommand.base64Element; // decodeBase64 to json SerializableFinder serializableFinder = FinderHelper.deserializeBase64(type); final Finder finder = finderFactory.createFinder(serializableFinder); // Get the widget element final Element element = prober.element(finder); // if element is not a Text widget, return false with error if (element.widget is! Text) { return const GetTextResult(false, data: { 'errorCode': 'NOT_A_TEXT_WIDGET', 'error': 'Found element is not a Text widget' }); } final text = getTextFromWidget(element.widget as Text); return text != null ? GetTextResult(true, data: {'text': text}) : const GetTextResult(false, data: { 'errorCode': 'NO_TEXT_CONTENT', 'error': 'No text content found' }); } @override String get commandKind => 'getTextWithCommandExtension'; @override Command deserialize( Map params, DeserializeFinderFactory finderFactory, DeserializeCommandFactory commandFactory) { return GetTextCommand.deserialize(params); } } class GetTextCommand extends Command { final String base64Element; GetTextCommand(this.base64Element); @override String get kind => 'getTextWithCommandExtension'; GetTextCommand.deserialize(Map params) : base64Element = params['findBy']!; } class GetTextResult extends Result { final bool success; final Map? data; const GetTextResult(this.success, {this.data}); @override Map toJson() { return { 'success': success, if (data != null) ...data!, }; } } ================================================ FILE: example/flutter_app_under_test/.gitignore ================================================ # Miscellaneous *.class *.log *.pyc *.swp .DS_Store .atom/ .buildlog/ .history .svn/ # IntelliJ related *.iml *.ipr *.iws .idea/ # Visual Studio Code related .vscode/ # Flutter/Dart/Pub related **/doc/api/ .dart_tool/ .flutter-plugins .packages .pub-cache/ .pub/ /build/ # Android related **/android/**/gradle-wrapper.jar **/android/.gradle **/android/captures/ **/android/gradlew **/android/gradlew.bat **/android/local.properties **/android/**/GeneratedPluginRegistrant.java # iOS/XCode related **/ios/**/*.mode1v3 **/ios/**/*.mode2v3 **/ios/**/*.moved-aside **/ios/**/*.pbxuser **/ios/**/*.perspectivev3 **/ios/**/*sync/ **/ios/**/.sconsign.dblite **/ios/**/.tags* **/ios/**/.vagrant/ **/ios/**/DerivedData/ **/ios/**/Icon? **/ios/**/Pods/ **/ios/**/.symlinks/ **/ios/**/profile **/ios/**/xcuserdata **/ios/.generated/ **/ios/Flutter/App.framework **/ios/Flutter/Flutter.framework **/ios/Flutter/Generated.xcconfig **/ios/Flutter/app.flx **/ios/Flutter/app.zip **/ios/Flutter/flutter_assets/ **/ios/ServiceDefinitions.json **/ios/Runner/GeneratedPluginRegistrant.* # Exceptions to above rules. !**/ios/**/default.mode1v3 !**/ios/**/default.mode2v3 !**/ios/**/default.pbxuser !**/ios/**/default.perspectivev3 !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages ================================================ FILE: example/flutter_app_under_test/README.md ================================================ # hello_world A new Flutter project. ## Getting Started This project is a starting point for a Flutter application. A few resources to get you started if this is your first Flutter project: - [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) For help getting started with Flutter, view our [online documentation](https://flutter.dev/docs), which offers tutorials, samples, guidance on mobile development, and a full API reference. ================================================ FILE: example/flutter_app_under_test/android/app/build.gradle ================================================ def localProperties = new Properties() def localPropertiesFile = rootProject.file('local.properties') if (localPropertiesFile.exists()) { localPropertiesFile.withReader('UTF-8') { reader -> localProperties.load(reader) } } def flutterRoot = localProperties.getProperty('flutter.sdk') if (flutterRoot == null) { throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") } def flutterVersionCode = localProperties.getProperty('flutter.versionCode') if (flutterVersionCode == null) { flutterVersionCode = '1' } def flutterVersionName = localProperties.getProperty('flutter.versionName') if (flutterVersionName == null) { flutterVersionName = '1.0' } apply plugin: 'com.android.application' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { compileSdkVersion 28 lintOptions { disable 'InvalidPackage' } defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.example.hello_world" minSdkVersion 16 targetSdkVersion 28 versionCode flutterVersionCode.toInteger() versionName flutterVersionName testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { // TODO: Add your own signing config for the release build. // Signing with the debug keys for now, so `flutter run --release` works. signingConfig signingConfigs.debug } } } flutter { source '../..' } dependencies { testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' } ================================================ FILE: example/flutter_app_under_test/android/app/src/debug/AndroidManifest.xml ================================================ ================================================ FILE: example/flutter_app_under_test/android/app/src/main/AndroidManifest.xml ================================================ ================================================ FILE: example/flutter_app_under_test/android/app/src/main/java/com/example/hello_world/MainActivity.java ================================================ package com.example.hello_world; import android.os.Bundle; import io.flutter.app.FlutterActivity; import io.flutter.plugins.GeneratedPluginRegistrant; public class MainActivity extends FlutterActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); GeneratedPluginRegistrant.registerWith(this); } } ================================================ FILE: example/flutter_app_under_test/android/app/src/main/res/drawable/launch_background.xml ================================================ ================================================ FILE: example/flutter_app_under_test/android/app/src/main/res/values/styles.xml ================================================ ================================================ FILE: example/flutter_app_under_test/android/app/src/profile/AndroidManifest.xml ================================================ ================================================ FILE: example/flutter_app_under_test/android/build.gradle ================================================ buildscript { repositories { google() jcenter() } dependencies { classpath 'com.android.tools.build:gradle:3.2.1' } } allprojects { repositories { google() jcenter() } } rootProject.buildDir = '../build' subprojects { project.buildDir = "${rootProject.buildDir}/${project.name}" } subprojects { project.evaluationDependsOn(':app') } task clean(type: Delete) { delete rootProject.buildDir } ================================================ FILE: example/flutter_app_under_test/android/gradle/wrapper/gradle-wrapper.properties ================================================ #Fri Jun 23 08:50:38 CEST 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip ================================================ FILE: example/flutter_app_under_test/android/gradle.properties ================================================ org.gradle.jvmargs=-Xmx1536M ================================================ FILE: example/flutter_app_under_test/android/settings.gradle ================================================ include ':app' def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() def plugins = new Properties() def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') if (pluginsFile.exists()) { pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } } plugins.each { name, path -> def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() include ":$name" project(":$name").projectDir = pluginDirectory } ================================================ FILE: example/flutter_app_under_test/ios/Flutter/AppFrameworkInfo.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable App CFBundleIdentifier io.flutter.flutter.app CFBundleInfoDictionaryVersion 6.0 CFBundleName App CFBundlePackageType FMWK CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1.0 MinimumOSVersion 8.0 ================================================ FILE: example/flutter_app_under_test/ios/Flutter/Debug.xcconfig ================================================ #include "Generated.xcconfig" ================================================ FILE: example/flutter_app_under_test/ios/Flutter/Release.xcconfig ================================================ #include "Generated.xcconfig" ================================================ FILE: example/flutter_app_under_test/ios/Runner/AppDelegate.h ================================================ #import #import @interface AppDelegate : FlutterAppDelegate @end ================================================ FILE: example/flutter_app_under_test/ios/Runner/AppDelegate.m ================================================ #include "AppDelegate.h" #include "GeneratedPluginRegistrant.h" @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [GeneratedPluginRegistrant registerWithRegistry:self]; // Override point for customization after application launch. return [super application:application didFinishLaunchingWithOptions:launchOptions]; } @end ================================================ FILE: example/flutter_app_under_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json ================================================ { "images" : [ { "size" : "20x20", "idiom" : "iphone", "filename" : "Icon-App-20x20@2x.png", "scale" : "2x" }, { "size" : "20x20", "idiom" : "iphone", "filename" : "Icon-App-20x20@3x.png", "scale" : "3x" }, { "size" : "29x29", "idiom" : "iphone", "filename" : "Icon-App-29x29@1x.png", "scale" : "1x" }, { "size" : "29x29", "idiom" : "iphone", "filename" : "Icon-App-29x29@2x.png", "scale" : "2x" }, { "size" : "29x29", "idiom" : "iphone", "filename" : "Icon-App-29x29@3x.png", "scale" : "3x" }, { "size" : "40x40", "idiom" : "iphone", "filename" : "Icon-App-40x40@2x.png", "scale" : "2x" }, { "size" : "40x40", "idiom" : "iphone", "filename" : "Icon-App-40x40@3x.png", "scale" : "3x" }, { "size" : "60x60", "idiom" : "iphone", "filename" : "Icon-App-60x60@2x.png", "scale" : "2x" }, { "size" : "60x60", "idiom" : "iphone", "filename" : "Icon-App-60x60@3x.png", "scale" : "3x" }, { "size" : "20x20", "idiom" : "ipad", "filename" : "Icon-App-20x20@1x.png", "scale" : "1x" }, { "size" : "20x20", "idiom" : "ipad", "filename" : "Icon-App-20x20@2x.png", "scale" : "2x" }, { "size" : "29x29", "idiom" : "ipad", "filename" : "Icon-App-29x29@1x.png", "scale" : "1x" }, { "size" : "29x29", "idiom" : "ipad", "filename" : "Icon-App-29x29@2x.png", "scale" : "2x" }, { "size" : "40x40", "idiom" : "ipad", "filename" : "Icon-App-40x40@1x.png", "scale" : "1x" }, { "size" : "40x40", "idiom" : "ipad", "filename" : "Icon-App-40x40@2x.png", "scale" : "2x" }, { "size" : "76x76", "idiom" : "ipad", "filename" : "Icon-App-76x76@1x.png", "scale" : "1x" }, { "size" : "76x76", "idiom" : "ipad", "filename" : "Icon-App-76x76@2x.png", "scale" : "2x" }, { "size" : "83.5x83.5", "idiom" : "ipad", "filename" : "Icon-App-83.5x83.5@2x.png", "scale" : "2x" }, { "size" : "1024x1024", "idiom" : "ios-marketing", "filename" : "Icon-App-1024x1024@1x.png", "scale" : "1x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: example/flutter_app_under_test/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "LaunchImage.png", "scale" : "1x" }, { "idiom" : "universal", "filename" : "LaunchImage@2x.png", "scale" : "2x" }, { "idiom" : "universal", "filename" : "LaunchImage@3x.png", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: example/flutter_app_under_test/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md ================================================ # Launch Screen Assets You can customize the launch screen with your own desired assets by replacing the image files in this directory. You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. ================================================ FILE: example/flutter_app_under_test/ios/Runner/Base.lproj/LaunchScreen.storyboard ================================================ ================================================ FILE: example/flutter_app_under_test/ios/Runner/Base.lproj/Main.storyboard ================================================ ================================================ FILE: example/flutter_app_under_test/ios/Runner/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName hello_world CFBundlePackageType APPL CFBundleShortVersionString $(FLUTTER_BUILD_NAME) CFBundleSignature ???? CFBundleVersion $(FLUTTER_BUILD_NUMBER) LSRequiresIPhoneOS UILaunchStoryboardName LaunchScreen UIMainStoryboardFile Main UISupportedInterfaceOrientations UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UISupportedInterfaceOrientations~ipad UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIViewControllerBasedStatusBarAppearance ================================================ FILE: example/flutter_app_under_test/ios/Runner/main.m ================================================ #import #import #import "AppDelegate.h" int main(int argc, char* argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } } ================================================ FILE: example/flutter_app_under_test/ios/Runner.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXBuildFile section */ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ 9705A1C41CF9048500538489 /* Embed Frameworks */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; dstSubfolderSpec = 10; files = ( 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 97C146EB1CF9000F007C117D /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( 3B80C3931E831B6300D905FE /* App.framework */, 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 9740EEBA1CF902C7004384FC /* Flutter.framework */, 9740EEB21CF90195004384FC /* Debug.xcconfig */, 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 9740EEB31CF90195004384FC /* Generated.xcconfig */, ); name = Flutter; sourceTree = ""; }; 97C146E51CF9000F007C117D = { isa = PBXGroup; children = ( 9740EEB11CF90186004384FC /* Flutter */, 97C146F01CF9000F007C117D /* Runner */, 97C146EF1CF9000F007C117D /* Products */, CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, ); sourceTree = ""; }; 97C146EF1CF9000F007C117D /* Products */ = { isa = PBXGroup; children = ( 97C146EE1CF9000F007C117D /* Runner.app */, ); name = Products; sourceTree = ""; }; 97C146F01CF9000F007C117D /* Runner */ = { isa = PBXGroup; children = ( 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, 97C146FA1CF9000F007C117D /* Main.storyboard */, 97C146FD1CF9000F007C117D /* Assets.xcassets */, 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 97C147021CF9000F007C117D /* Info.plist */, 97C146F11CF9000F007C117D /* Supporting Files */, 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, ); path = Runner; sourceTree = ""; }; 97C146F11CF9000F007C117D /* Supporting Files */ = { isa = PBXGroup; children = ( 97C146F21CF9000F007C117D /* main.m */, ); name = "Supporting Files"; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ 97C146ED1CF9000F007C117D /* Runner */ = { isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, ); buildRules = ( ); dependencies = ( ); name = Runner; productName = Runner; productReference = 97C146EE1CF9000F007C117D /* Runner.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 97C146E61CF9000F007C117D /* Project object */ = { isa = PBXProject; attributes = { LastUpgradeCheck = 0910; ORGANIZATIONNAME = "The Chromium Authors"; TargetAttributes = { 97C146ED1CF9000F007C117D = { CreatedOnToolsVersion = 7.3.1; }; }; }; buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( en, Base, ); mainGroup = 97C146E51CF9000F007C117D; productRefGroup = 97C146EF1CF9000F007C117D /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( 97C146ED1CF9000F007C117D /* Runner */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ 97C146EC1CF9000F007C117D /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); name = "Thin Binary"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); name = "Run Script"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 97C146EA1CF9000F007C117D /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, 97C146F31CF9000F007C117D /* main.m in Sources */, 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */ 97C146FA1CF9000F007C117D /* Main.storyboard */ = { isa = PBXVariantGroup; children = ( 97C146FB1CF9000F007C117D /* Base */, ); name = Main.storyboard; sourceTree = ""; }; 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { isa = PBXVariantGroup; children = ( 97C147001CF9000F007C117D /* Base */, ); name = LaunchScreen.storyboard; sourceTree = ""; }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ 249021D3217E4FDB00AE95B9 /* Profile */ = { isa = XCBuildConfiguration; baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; name = Profile; }; 249021D4217E4FDB00AE95B9 /* Profile */ = { isa = XCBuildConfiguration; baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; DEVELOPMENT_TEAM = S8QB4VV633; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Flutter", ); INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Flutter", ); PRODUCT_BUNDLE_IDENTIFIER = com.example.helloWorld; PRODUCT_NAME = "$(TARGET_NAME)"; VERSIONING_SYSTEM = "apple-generic"; }; name = Profile; }; 97C147031CF9000F007C117D /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; 97C147041CF9000F007C117D /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; name = Release; }; 97C147061CF9000F007C117D /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Flutter", ); INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Flutter", ); PRODUCT_BUNDLE_IDENTIFIER = com.example.helloWorld; PRODUCT_NAME = "$(TARGET_NAME)"; VERSIONING_SYSTEM = "apple-generic"; }; name = Debug; }; 97C147071CF9000F007C117D /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Flutter", ); INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Flutter", ); PRODUCT_BUNDLE_IDENTIFIER = com.example.helloWorld; PRODUCT_NAME = "$(TARGET_NAME)"; VERSIONING_SYSTEM = "apple-generic"; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { isa = XCConfigurationList; buildConfigurations = ( 97C147031CF9000F007C117D /* Debug */, 97C147041CF9000F007C117D /* Release */, 249021D3217E4FDB00AE95B9 /* Profile */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { isa = XCConfigurationList; buildConfigurations = ( 97C147061CF9000F007C117D /* Debug */, 97C147071CF9000F007C117D /* Release */, 249021D4217E4FDB00AE95B9 /* Profile */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = 97C146E61CF9000F007C117D /* Project object */; } ================================================ FILE: example/flutter_app_under_test/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: example/flutter_app_under_test/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme ================================================ ================================================ FILE: example/flutter_app_under_test/ios/Runner.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: example/flutter_app_under_test/lib/main.dart ================================================ import 'package:flutter/material.dart'; import 'package:flutter_driver/driver_extension.dart'; import 'package:functional_widget_annotation/functional_widget_annotation.dart'; import 'package:hello_world/stream.dart'; part 'main.g.dart'; void main() { enableFlutterDriverExtension(); init(); runApp(MyApp()); } @widget Widget myApp() => MaterialApp( title: 'Counter App', home: MyHomePage(title: 'Counter App Home Page'), ); @widget Widget myHomePage(BuildContext context, {String title}) => Scaffold( appBar: AppBar( title: Text(title), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( 'You have pushed the button this many times:', ), Tooltip( message: 'counter_tooltip', child: StreamBuilder( stream: counterStream, builder: (context, snapshot) { return Text( '${snapshot.data}', key: Key('counter'), style: Theme.of(context).textTheme.display1, semanticsLabel: 'counter_semantic', ); } ), ), FlatButton( onPressed: () { Navigator.push( context, MaterialPageRoute( builder: (context) => Scaffold( appBar: AppBar( title: Text("Second Route"), ), body: Center( child: SecondPage(), ), )), ); }, child: Text( 'Go to next route', key: Key('next_route_key'), ), ), ], ), ), floatingActionButton: FloatingActionButton( // Provide a Key to this button. This allows finding this // specific button inside the test suite, and tapping it. key: Key('increment'), onPressed: () => plusClickSink.add(null), tooltip: 'Increment', child: Icon(Icons.add), ), ); @widget Widget secondPage() => ListView( padding: const EdgeInsets.all(8.0), children: [ Container( height: 100, color: Colors.amber[600], child: const Center(child: Text('This is 2nd route')), ), Container( height: 200, color: Colors.amber[500], child: const Center(child: Text('Entry B')), ), Container( height: 500, color: Colors.amber[100], child: const Center(child: Text('Entry C')), ), Container( height: 1000, color: Colors.amber[100], child: const Center(child: Text('Entry D')), ), Container( height: 1000, color: Colors.amber[100], child: const Center( child: TextField( decoration: InputDecoration( border: OutlineInputBorder(), labelText: 'Sample Input', ), )), ), ], ); ================================================ FILE: example/flutter_app_under_test/lib/main.g.dart ================================================ // GENERATED CODE - DO NOT MODIFY BY HAND part of 'main.dart'; // ************************************************************************** // FunctionalWidgetGenerator // ************************************************************************** class MyApp extends StatelessWidget { const MyApp({Key key}) : super(key: key); @override Widget build(BuildContext _context) => myApp(); } class MyHomePage extends StatelessWidget { const MyHomePage({Key key, this.title}) : super(key: key); final String title; @override Widget build(BuildContext _context) => myHomePage(_context, title: title); } class SecondPage extends StatelessWidget { const SecondPage({Key key}) : super(key: key); @override Widget build(BuildContext _context) => secondPage(); } ================================================ FILE: example/flutter_app_under_test/lib/stream.dart ================================================ import 'dart:async' show StreamSink; import 'package:rxdart/rxdart.dart' show BehaviorSubject; final counterSubject = new BehaviorSubject.seeded(0); final counterStream = counterSubject.stream; final plusClickSubject = new BehaviorSubject(); final StreamSink plusClickSink = plusClickSubject; void init() { plusClickSubject.stream.withLatestFrom( counterSubject, (_, a) => a + 1, ).pipe(counterSubject); } ================================================ FILE: example/flutter_app_under_test/pubspec.yaml ================================================ name: hello_world description: A new Flutter project. version: 1.0.0+1 environment: sdk: ">=2.1.0 <3.0.0" dependencies: functional_widget_annotation: ^0.5.0 rxdart: 0.22.1+1 flutter: sdk: flutter dev_dependencies: test: any flutter_test: sdk: flutter flutter_driver: sdk: flutter flutter: uses-material-design: true builders: functional_widget: ^0.6.0 ================================================ FILE: example/flutter_app_under_test/test/widget_test.dart ================================================ // This is a basic Flutter widget test. // // To perform an interaction with a widget in your test, use the WidgetTester // utility that Flutter provides. For example, you can send tap and scroll // gestures. You can also use WidgetTester to find child widgets in the widget // tree, read text, and verify that the values of widget properties are correct. import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:hello_world/main.dart'; void main() { testWidgets('Counter increments smoke test', (WidgetTester tester) async { // Build our app and trigger a frame. await tester.pumpWidget(MyApp()); // Verify that our counter starts at 0. expect(find.text('0'), findsOneWidget); expect(find.text('1'), findsNothing); // Tap the '+' icon and trigger a frame. await tester.tap(find.byIcon(Icons.add)); await tester.pump(); // Verify that our counter has incremented. expect(find.text('0'), findsNothing); expect(find.text('1'), findsOneWidget); }); } ================================================ FILE: example/flutter_app_under_test/test_driver/main_test.dart ================================================ // Imports the Flutter Driver API. import 'package:flutter_driver/flutter_driver.dart'; import 'package:test/test.dart'; void main() { group('Counter App', () { // First, define the Finders and use them to locate widgets from the // test suite. Note: the Strings provided to the `byValueKey` method must // be the same as the Strings we used for the Keys in step 1. final counterTextFinder = find.byValueKey('counter'); final buttonFinder = find.byValueKey('increment'); FlutterDriver driver; // Connect to the Flutter driver before running any tests. setUpAll(() async { driver = await FlutterDriver.connect( printCommunication: true, ); }); // Close the connection to the driver after the tests have completed. tearDownAll(() async { if (driver != null) { driver.close(); } }); test('starts at 0', () async { final h = await driver.checkHealth(); expect(h.status, HealthStatus.ok); await driver.clearTimeline(); final renderObject = await driver.getRenderObjectDiagnostics(counterTextFinder, subtreeDepth: 2, includeProperties: true); // Use the `driver.getText` method to verify the counter starts at 0. expect(await driver.getText(counterTextFinder), "0"); await driver.getBottomLeft(counterTextFinder); await driver.getTopRight(counterTextFinder); }); test('increments the counter', () async { // First, tap the button. await driver.tap(buttonFinder); await driver.tap(buttonFinder); // Then, verify the counter text is incremented by 1. expect(await driver.getText(counterTextFinder), "2"); }); test(' ', () async { await driver.tap(find.byTooltip('Increment')); expect( await driver.getText(find.descendant( of: find.byTooltip('counter_tooltip'), matching: find.byValueKey('counter'))), '3'); await driver.tap(find.byType('FlatButton')); await driver.waitForAbsent(find.byTooltip('counter_tooltip')); expect(await driver.getText(find.text('This is 2nd route')), 'This is 2nd route'); await driver.scrollUntilVisible(find.byType('ListView'), find.byType('TextField'), dxScroll: 90, dyScroll: -400); await driver.scroll(find.byType('ListView'), 50, 100, Duration(milliseconds: 200), frequency: 30); await driver.scrollIntoView(find.byType('ListView'), alignment: 1.4); await driver.tap(find.byType('TextField')); await driver.enterText('I can enter text'); await driver.waitFor(find.text('I can enter text')); // verify text appears on UI await driver.tap(find.pageBack()); await driver.waitFor(find.byTooltip('counter_tooltip')); expect( await driver.getText( find.descendant( of: find.ancestor( of: find.bySemanticsLabel(RegExp('counter_semantic')), matching: find.byType('Tooltip')), matching: find.byType('Text'), ), ), '3'); }); }); } ================================================ FILE: example/java/.gitignore ================================================ target/* .settings/* .classpath .project ================================================ FILE: example/java/.vscode/settings.json ================================================ { "java.configuration.updateBuildConfiguration": "automatic" } ================================================ FILE: example/java/pom.xml ================================================ 4.0.0 com.saucelabs sauce_appium_junit 0.0.1-SNAPSHOT sauce_appium_junit Sample Appium tests using JUnit junit junit 4.13.1 test io.appium java-client 5.0.0-BETA8 com.googlecode.json-simple json-simple 1.1 test commons-lang commons-lang 2.6 test com.saucelabs sauce_junit 2.1.23 test com.google.code.gson gson 2.8.9 io.appium java-client 4.1.2 com.github.appium appium-flutter-driver main-SNAPSHOT org.apache.maven.plugins maven-surefire-plugin maven-compiler-plugin 1.8 1.8 saucelabs-repository https://repository-saucelabs.forge.cloudbees.com/release true true jitpack.io https://jitpack.io ================================================ FILE: example/java/src/test/java/example/appium/BaseDriver.java ================================================ package example.appium; import io.appium.java_client.AppiumDriver; import io.appium.java_client.MobileElement; import io.appium.java_client.ios.IOSDriver; import io.appium.java_client.service.local.AppiumDriverLocalService; import io.appium.java_client.service.local.AppiumServerHasNotBeenStartedLocallyException; import org.junit.After; import org.junit.Before; import org.openqa.selenium.remote.DesiredCapabilities; import org.openqa.selenium.support.ui.WebDriverWait; import java.io.File; public class BaseDriver { public AppiumDriver driver; public WebDriverWait wait; private static AppiumDriverLocalService service; @Before public void setUp() throws Exception { service = AppiumDriverLocalService.buildDefaultService(); service.start(); if (service == null || !service.isRunning()) { throw new AppiumServerHasNotBeenStartedLocallyException("An appium server node is not started!"); } DesiredCapabilities capabilities = new DesiredCapabilities(); capabilities.setCapability("platformVersion", "12.2"); capabilities.setCapability("deviceName", "iPhone X"); capabilities.setCapability("noReset", true); File classpathRoot = new File(System.getProperty("user.dir")); File appDir = new File(classpathRoot, "/../apps"); File app = new File(appDir.getCanonicalPath(), "ios-sim-debug.zip"); System.out.println(app.getAbsolutePath()); capabilities.setCapability("app", app.getAbsolutePath()); capabilities.setCapability("automationName", "Flutter"); driver = new IOSDriver(service.getUrl(), capabilities); wait = new WebDriverWait(driver, 10); waitForFirstFrame(); } @After public void tearDown() throws Exception { if (driver != null) { driver.quit(); } if (service != null) { service.stop(); } } public void waitForFirstFrame(){ driver.executeScript("flutter:waitForFirstFrame"); } } ================================================ FILE: example/java/src/test/java/example/appium/FlutterTest.java ================================================ package example.appium; import org.junit.Before; import org.junit.Test; import static org.junit.Assert.assertEquals; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.regex.Pattern; import java.io.File; import org.openqa.selenium.OutputType; import io.appium.java_client.MobileElement; import pro.truongsinh.appium_flutter.FlutterFinder; import pro.truongsinh.appium_flutter.finder.FlutterElement; public class FlutterTest extends BaseDriver { protected FlutterFinder find; @Before public void setUp() throws Exception { super.setUp(); find = new FlutterFinder(driver); } @Test public void basicTest () throws InterruptedException { String buttonFinderKey = "increment"; FlutterElement counterTextFinder = find.byValueKey("counter"); MobileElement buttonFinder = waitFor(buttonFinderKey); validateElementPosition(buttonFinder); assertEquals(driver.executeScript("flutter:checkHealth"), "ok"); driver.executeScript("flutter:clearTimeline"); driver.executeScript("flutter:forceGC"); Map renderObjectDiagnostics = (Map) driver.executeScript( "flutter:getRenderObjectDiagnostics", counterTextFinder.getId(), new HashMap() {{ put("includeProperties", true); put("subtreeDepth", 2); }} ); assertEquals(renderObjectDiagnostics.get("type"), "DiagnosticableTreeNode"); assertEquals(((List)renderObjectDiagnostics.get("children")).size(), 1); Object semanticsId = driver.executeScript( "flutter:getSemanticsId", counterTextFinder ); assertEquals(semanticsId, 4L); String treeString = (String) driver.executeScript("flutter: getRenderTree"); assertEquals(treeString.substring(0, 11), "RenderView#"); driver.context("NATIVE_APP"); File f1 = driver.getScreenshotAs(OutputType.FILE); f1.renameTo(new File("./native-screenshot.png")); driver.context("FLUTTER"); File f2 = driver.getScreenshotAs(OutputType.FILE); f2.renameTo(new File("./flutter-screenshot.png")); assertEquals(counterTextFinder.getText(), "0"); clickToElement(buttonFinderKey); // @todo tap not working? // buttonFinder.tap(1, 100); clickToElement(buttonFinderKey); assertEquals(counterTextFinder.getText(), "2"); find.byTooltip("Increment").click(); assertEquals(find.descendant(find.byTooltip("counter_tooltip"), find.byValueKey("counter"), false, false).getText(), "3"); find.byType("FlatButton").click(); driver.executeScript("flutter:waitForAbsent", buttonFinder); assertEquals(find.text("This is 2nd route").getText(), "This is 2nd route"); driver.executeScript("flutter:scrollUntilVisible", find.byType("ListView"), new HashMap() {{ put("item", find.byType("TextField")); put("dxScroll", 90); put("dyScroll", -400); }}); driver.executeScript("flutter:scroll", find.byType("ListView"), new HashMap() {{ put("item", find.byType("TextField")); put("dx", 50); put("dy", 100); put("durationMilliseconds", 200); put("frequency", 30); }}); driver.executeScript("flutter:scrollIntoView", find.byType("ListView"), new HashMap() {{ put("alignment", 0.1); }}); find.byType("TextField").sendKeys("I can enter text"); // enter text driver.executeScript("flutter:waitFor", find.text("I can enter text")); // verify text appears on UI find.pageBack().click(); driver.executeScript("flutter:waitFor", buttonFinder); find.descendant( find.ancestor( find.bySemanticsLabel(Pattern.compile("counter_semantic")), find.byType("Tooltip"), false, false ), find.byType("Text"), false, false ) .click() ; driver.quit(); } private void clickToElement(String locator){ MobileElement el = waitFor(locator); el.click(); } private MobileElement waitFor(String locator){ return (MobileElement) driver.executeScript("flutter:waitFor", find.byValueKey(locator), 30); } private void validateElementPosition(MobileElement buttonFinder) { Map bottomLeft = (Map) driver.executeScript("flutter:getBottomLeft", buttonFinder); assertEquals(bottomLeft.get("dx") instanceof Long, true); assertEquals(bottomLeft.get("dy") instanceof Long, true); Map bottomRight = (Map) driver.executeScript("flutter:getBottomRight", buttonFinder); assertEquals(bottomRight.get("dx") instanceof Long, true); assertEquals(bottomRight.get("dy") instanceof Long, true); Map center = (Map) driver.executeScript("flutter:getCenter", buttonFinder); assertEquals(center.get("dx") instanceof Long, true); assertEquals(center.get("dy") instanceof Long, true); Map topLeft = (Map) driver.executeScript("flutter:getTopLeft", buttonFinder); assertEquals(topLeft.get("dx") instanceof Long, true); assertEquals(topLeft.get("dy") instanceof Long, true); Map topRight = (Map) driver.executeScript("flutter:getTopRight", buttonFinder); assertEquals(topRight.get("dx") instanceof Long, true); assertEquals(topRight.get("dy") instanceof Long, true); } } ================================================ FILE: example/nodejs/README.md ================================================ # To run the automation locally 1. Make sure node and npm are installed locally 2. cd to ./driver 3. `npm install -g typescript` for typescript compile to work globally 4. `npm install` to install node modules 5. run `npm link` 6. install Appium globally by running `npm i -g appium` 7. run appium server by running `appium` (in a seperate terminal) 8. create a dir called `apps`, and put example files as download from https://github.com/truongsinh/appium-flutter-driver/releases/tag/v0.0.4 into that dir: - (Android) https://github.com/truongsinh/appium-flutter-driver/releases/download/v0.0.4/android-real-debug.apk - (iOS) https://github.com/truongsinh/appium-flutter-driver/releases/download/v0.0.4/ios-sim-debug.zip 9. Modify the path for apk/ipa appropriately at https://github.com/appium/appium-flutter-driver/blob/main/example/nodejs/src/index.js#L13 10. either run `APPIUM_OS=android npm start` or `APPIUM_OS=ios npm start` ================================================ FILE: example/nodejs/package.json ================================================ { "name": "appium", "version": "1.0.0", "description": "", "main": "index.js", "dependencies": { "appium-flutter-finder": "^0.2.0", "webdriverio": "^9.0.1" }, "scripts": { "start": "node src/index.js", "ios": "APPIUM_OS=ios npm start", "android": "APPIUM_OS=android npm start", "test": "echo \"Error: no test specified\" && exit 1" }, "author": "TruongSinh Tran-Nguyen { const counterTextFinder = find.byValueKey('counter'); const buttonFinder = find.byValueKey('increment'); const driver = await wdio.remote(opts); await validateElementPosition(driver, buttonFinder); assert.strictEqual(await driver.execute('flutter:checkHealth'), 'ok'); await driver.execute('flutter:clearTimeline'); await driver.execute('flutter:forceGC'); const renderObjectDiagnostics = await driver.execute( 'flutter:getRenderObjectDiagnostics', counterTextFinder, { includeProperties: true, subtreeDepth: 2 } ); assert.strictEqual(renderObjectDiagnostics.type, 'DiagnosticableTreeNode'); assert.strictEqual(renderObjectDiagnostics.children.length, 1); const semanticsId = await driver.execute( 'flutter:getSemanticsId', counterTextFinder ); assert.strictEqual(semanticsId, 4); const treeString = await driver.execute('flutter: getRenderTree'); assert.strictEqual(treeString.substr(0, 11), 'RenderView#'); await driver.switchContext('NATIVE_APP'); await driver.saveScreenshot('./native-screenshot.png'); await driver.switchContext('FLUTTER'); await driver.saveScreenshot('./flutter-screenshot.png'); /* new example if (process.env.APPIUM_OS === 'android') { await driver.switchContext('NATIVE_APP'); await (await driver.$('~fab')).click(); await driver.switchContext('FLUTTER'); } else { console.log( 'Switching context to `NATIVE_APP` is currently only applicable to Android demo app.' ); } */ assert.strictEqual(await driver.getElementText(counterTextFinder), '0'); //Long Press using flutter command on Increment button, it should visible 'increment' tooltip after longTap await driver.execute('flutter:longTap', find.byValueKey('increment'), {durationMilliseconds: 10000, frequency: 30}); //Long Press using TouchAction with wait await driver.touchAction([ { action: 'longPress', element: { elementId: buttonFinder } }, { action: 'wait', ms: 10000 }, { action: 'release' } ]); //Long Press using TouchAction without wait await driver.touchAction([ { action: 'longPress', element: { elementId: buttonFinder } }, { action: 'release' } ]); //Long Press using TouchAction without wait and release await driver.touchAction([ { action: 'longPress', element: { elementId: buttonFinder } }, ]); await driver.saveScreenshot('./flutter-longPress.png'); await driver.elementClick(buttonFinder); await driver.touchAction({ action: 'tap', element: { elementId: buttonFinder } }); assert.strictEqual(await driver.getElementText(counterTextFinder), '2'); await driver.elementClick(find.byTooltip('Increment')); assert.strictEqual( await driver.getElementText( find.descendant({ of: find.byTooltip('counter_tooltip'), matching: find.byValueKey('counter') }) ), '3' ); await driver.elementClick(find.byType('FlatButton')); let firstWaitForAbsentError; try { await driver.execute('flutter:waitForAbsent', buttonFinder, {durationMilliseconds: 1}); } catch(e) { firstWaitForAbsentError = e; } finally { // @todo } try { await driver.execute('flutter:waitForAbsent', buttonFinder, {durationMilliseconds: 'malformed input'}); } catch(e) { firstWaitForAbsentError = e; } finally { // @todo } await driver.execute('flutter:waitForAbsent', buttonFinder); assert.strictEqual( await driver.getElementText(find.byText('This is 2nd route')), 'This is 2nd route' ); await driver.execute('flutter:scrollUntilVisible', find.byType('ListView'), {item:find.byType('TextField'), dxScroll: 90, dyScroll: -400}); await driver.execute('flutter:scroll', find.byType('ListView'), {dx: 50, dy: 100, durationMilliseconds: 200, frequency: 30}); await driver.execute('flutter:scrollIntoView', find.byType('TextField'), {alignment: 0.1}); await driver.elementSendKeys(find.byType('TextField'), 'I can enter text'); await driver.execute('flutter:waitFor', find.byText('I can enter text')); // verify text appears on UI await driver.elementClear(find.byType('TextField')); //It can Clear the text field await driver.elementClick(find.pageBack()); await driver.execute( 'flutter:waitFor', buttonFinder ); assert.strictEqual( await driver.getElementText( find.descendant({ of: find.ancestor({ of: find.bySemanticsLabel(RegExp('counter_semantic')), matching: find.byType('Tooltip') }), matching: find.byType('Text') }) ), '3' ); driver.deleteSession(); })(); const validateElementPosition = async (driver, buttonFinder) => { const bottomLeft = await driver.execute( 'flutter:getBottomLeft', buttonFinder ); assert.strictEqual(typeof bottomLeft.dx, 'number'); assert.strictEqual(typeof bottomLeft.dy, 'number'); const bottomRight = await driver.execute( 'flutter:getBottomRight', buttonFinder ); assert.strictEqual(typeof bottomRight.dx, 'number'); assert.strictEqual(typeof bottomRight.dy, 'number'); const center = await driver.execute('flutter:getCenter', buttonFinder); assert.strictEqual(typeof center.dx, 'number'); assert.strictEqual(typeof center.dy, 'number'); const topLeft = await driver.execute('flutter:getTopLeft', buttonFinder); assert.strictEqual(typeof topLeft.dx, 'number'); assert.strictEqual(typeof topLeft.dy, 'number'); const topRight = await driver.execute('flutter:getTopRight', buttonFinder); assert.strictEqual(typeof topRight.dx, 'number'); assert.strictEqual(typeof topRight.dy, 'number'); }; ================================================ FILE: example/python/example.py ================================================ import os from appium.webdriver import Remote # from appium.options.common.base import AppiumOptions # AppiumOptions also can be used, but this may not have iOS specific commands. from appium.options.ios.xcuitest.base import XCUITestOptions from appium_flutter_finder.flutter_finder import FlutterElement, FlutterFinder # Example options = XCUITestOptions() options.automation_name = 'flutter' options.platform_name = 'ios' options.set_capability('platformVersion', '17.0') options.set_capability('deviceName', 'iPhone 15') options.set_capability('app', f'{os.path.dirname(os.path.realpath(__file__))}/../sample2/IOSFullScreen.zip') driver = Remote('http://localhost:4723', options=options) driver.quit() # below tests are different from the 'IOSFullScreen.zip' finder = FlutterFinder() text_finder = finder.by_text('You have pushed the button this many times:') text_element = FlutterElement(driver, text_finder) print(text_element.text) key_finder = finder.by_value_key("next_route_key") goto_next_route_element = FlutterElement(driver, key_finder) print(goto_next_route_element.text) goto_next_route_element.click() back_finder = finder.page_back() back_element = FlutterElement(driver, back_finder) back_element.click() tooltip_finder = finder.by_tooltip("Increment") driver.execute_script('flutter:waitFor', tooltip_finder, 100) floating_button_element = FlutterElement(driver, tooltip_finder) floating_button_element.click() counter_finder = finder.by_value_key("counter") counter_element = FlutterElement(driver, counter_finder) print(counter_element.text) ================================================ FILE: example/python/requirement.txt ================================================ Appium-Flutter-Finder ~= 0.7.0 Appium-Python-Client ~= 4.0.0 ================================================ FILE: example/ruby/Gemfile ================================================ source 'https://rubygems.org' gem 'appium_flutter_finder' gem 'appium_lib_core' gem 'minitest', '~> 5.0' ================================================ FILE: example/ruby/example.rb ================================================ require 'appium_lib_core' require 'appium_flutter_finder' require 'minitest/autorun' class ExampleTests < Minitest::Test include ::Appium::Flutter::Finder IOS_CAPS = { caps: { platformName: 'iOS', automationName: 'flutter', platformVersion: '15.5', deviceName: 'iPhone 13', app: "#{Dir.pwd}/../app/app/Runner.zip" }, appium_lib: { export_session: true, wait_timeout: 20, wait_interval: 1 } } def test_run_example_ios_scenario @core = ::Appium::Core.for(IOS_CAPS) @driver = @core.start_driver text_finder = by_text 'You have pushed the button this many times:' element = ::Appium::Flutter::Element.new(@driver, finder: text_finder) assert_equal 'You have pushed the button this many times:', element.text @driver.execute_script 'flutter:getRenderTree' assert_equal 'ok', @driver.execute_script('flutter:checkHealth', {}) key_finder = by_value_key 'next_route_key' goto_next_route_element = ::Appium::Flutter::Element.new(@driver, finder: key_finder) goto_next_route_element.click back_element = ::Appium::Flutter::Element.new(@driver, finder: page_back) back_element.click tooltip_finder = by_tooltip 'Increment' @driver.execute_script('flutter:waitFor', tooltip_finder, 100) floating_button_element = ::Appium::Flutter::Element.new(@driver, finder: tooltip_finder) floating_button_element.click counter_finder = by_value_key 'counter' counter_element = ::Appium::Flutter::Element.new(@driver, finder: counter_finder) assert_equal '1', counter_element.text end end ================================================ FILE: example/ruby/example_sample2.rb ================================================ require 'appium_lib_core' require 'appium_flutter_finder' require 'minitest/autorun' class ExampleTests < Minitest::Test include ::Appium::Flutter::Finder CAPS = { caps: { platformName: 'Android', automationName: 'flutter', udid: 'emulator-5554', deviceName: 'Android', app: "#{Dir.pwd}/example/sample2/app-debug.apk", maxRetryCount: 60, retryBackoffTime: 10000, }, appium_lib: { export_session: true, wait_timeout: 20, wait_interval: 1 } } def setup @core = ::Appium::Core.for(CAPS) @driver = @core.start_driver server_url: 'http://localhost:4723' end def teardown @driver&.quit end def test_run_example_android @driver.context = 'NATIVE_APP' element = @driver.find_element :id, 'dev.flutter.example.androidfullscreen:id/launch_button' element.click @driver.orientation = :landscape assert_equal @driver.orientation, :landscape @driver.orientation = :portrait assert_equal @driver.orientation, :portrait @driver.context = 'FLUTTER' text_finder = by_text 'Tap me!' @driver.execute_script 'flutter:assertVisible', {text: 'Tap me!'}, 10000 element = ::Appium::Flutter::Element.new(@driver, finder: text_finder) # @driver.execute_script('flutter:waitForTappable', text_finder, 10000) assert_equal 'Tap me!', element.text element.click @driver.execute_script 'flutter:clickElement', text_finder, {timeout:10000} text_finder = by_text 'Taps: 2' element = ::Appium::Flutter::Element.new(@driver, finder: text_finder) assert_equal 'Taps: 2', element.text text_finder = by_text 'Exit this screen' element = ::Appium::Flutter::Element.new(@driver, finder: text_finder) element.click @driver.context = 'NATIVE_APP' element = @driver.wait_until { |d| d.find_element :id, 'dev.flutter.example.androidfullscreen:id/counter_label' } assert_equal 'Current count: 2', element.text @driver.context = 'FLUTTER' @driver.terminate_app 'dev.flutter.example.androidfullscreen' @driver.activate_app 'dev.flutter.example.androidfullscreen' text_finder = by_text 'Tap me!' element = ::Appium::Flutter::Element.new(@driver, finder: text_finder) assert_equal 'Tap me!', element.text @driver.back end end ================================================ FILE: example/ruby/example_sample2_ios.rb ================================================ require 'appium_lib_core' require 'appium_flutter_finder' require 'minitest/autorun' class ExampleTests < Minitest::Test include ::Appium::Flutter::Finder CAPS = { caps: { platformName: 'iOS', automationName: 'flutter', platformVersion: ENV["IOS_VERSION"] || '18.4', deviceName: ENV["IOS_DEVICE_NAME"] || 'iPhone 16 Plus', app: "#{Dir.pwd}/../sample2/iOSFullScreen.zip", wdaLaunchTimeout: 600_000, maxRetryCount: 60, retryBackoffTime: 10000, }, appium_lib: { export_session: true, wait_timeout: 20, wait_interval: 1 } } def setup @core = ::Appium::Core.for(CAPS) @driver = @core.start_driver server_url: 'http://localhost:4723' end def teardown @driver&.quit end def test_run_example_ios @driver.context = 'NATIVE_APP' @driver.orientation = :landscape assert_equal @driver.orientation, :landscape @driver.orientation = :portrait assert_equal @driver.orientation, :portrait element = @driver.find_element :accessibility_id, 'launchFlutter' element.click @driver.context = 'FLUTTER' text_finder = by_text 'Tap me!' element = ::Appium::Flutter::Element.new(@driver, finder: text_finder) assert_equal 'Tap me!', element.text element.click element.click text_finder = by_text 'Taps: 2' element = ::Appium::Flutter::Element.new(@driver, finder: text_finder) assert_equal 'Taps: 2', element.text text_finder = by_text 'Exit this screen' element = ::Appium::Flutter::Element.new(@driver, finder: text_finder) element.click @driver.context = 'NATIVE_APP' element = @driver.wait_until { |d| d.find_element :accessibility_id, 'currentCounter' } assert_equal 'Current counter: 2', element.text @driver.context = 'FLUTTER' @driver.terminate_app 'samples.flutter.example.IOSFullScreen' @driver.activate_app 'samples.flutter.example.IOSFullScreen' text_finder = by_text 'Tap me!' element = ::Appium::Flutter::Element.new(@driver, finder: text_finder) assert_equal 'Tap me!', element.text end end ================================================ FILE: example/sample2/README.md ================================================ Sample app in https://github.com/flutter/samples/tree/master/add_to_app/fullscreen ## Diff The sample app has `enableFlutterDriverExtension` in the main.dart for testing purpose. ```diff --- a/add_to_app/fullscreen/flutter_module/lib/main.dart +++ b/add_to_app/fullscreen/flutter_module/lib/main.dart @@ -6,8 +6,14 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:provider/provider.dart'; +import 'package:flutter_driver/driver_extension.dart'; + /// The entrypoint for the flutter module. void main() { + + // for testing example + enableFlutterDriverExtension(); + // This call ensures the Flutter binding has been set up before creating the // MethodChannel-based model. ``` ## iOS app changes Add accessibility labels for `Current counter` -> `currentCounter` `Launch FLutter ViewController` -> `launchFlutter` ================================================ FILE: example/sample2/app-debug.apk ================================================ [File too large to display: 65.6 MB] ================================================ FILE: finder/dotnet/AppiumFlutterFinder/AppiumFlutterFinder.csproj ================================================ net6.0 enable enable Appium Flutter Finder Ibrahim Taha Appium Flutter Finder https://github.com/ikharoub/appium-flutter-driver/tree/AddDotNetFlutterFinder/finder/dotnet https://github.com/ikharoub/appium-flutter-driver/tree/AddDotNetFlutterFinder/finder/dotnet License.md automation;flutter;appium;testing README.md True \ True \ ================================================ FILE: finder/dotnet/AppiumFlutterFinder/FlutterBy.cs ================================================ using OpenQA.Selenium; using System.Text; using System.Text.RegularExpressions; namespace AppiumFlutterFinder { public class FlutterBy : By { internal string SerializedSearchCriteria => Convert.ToBase64String(Encoding.UTF8.GetBytes(JsonSearchCriteria)); internal string JsonSearchCriteria => Newtonsoft.Json.JsonConvert.SerializeObject(_searchCriteria); dynamic _searchCriteria; private FlutterBy(dynamic searchCriteria) { _searchCriteria = searchCriteria; } public static FlutterBy ByKeyValue(string key) => new FlutterBy(new { finderType = "ByValueKey", keyValueString = key, keyValueType = "String", }); public static FlutterBy ByKeyValue(int key) => new FlutterBy(new { finderType = "ByValueKey", keyValueString = key, keyValueType = "int", }); public static FlutterBy ByText(string text) => new FlutterBy(new { finderType = "ByText", text }); public static FlutterBy ByTooltip(string text) => new FlutterBy(new { finderType = "ByTooltipMessage", text }); public static FlutterBy ByType(string type) => new FlutterBy(new { finderType = "ByType", type }); public static FlutterBy BySemanticsLabel(string label) => new FlutterBy(new { finderType = "BySemanticsLabel", isRegExp = false, label }); public static FlutterBy BySemanticsLabel(Regex pattern) => new FlutterBy(new { finderType = "BySemanticsLabel", isRegExp = true, label = pattern.ToString() }); public static FlutterBy PageBack() => new FlutterBy(new { finderType = "PageBack" }); public static FlutterBy ByAnscestor(FlutterBy of, FlutterBy matching, bool matchRoot = false, bool firstMatchOnly = false) => new FlutterBy(new { finderType = "Ancestor", matchRoot = matchRoot.ToString().ToLower(), firstMatchOnly = firstMatchOnly.ToString().ToLower(), of = of.JsonSearchCriteria, matching = matching.JsonSearchCriteria, }); public static FlutterBy ByDescendant(FlutterBy of, FlutterBy matching, bool matchRoot = false, bool firstMatchOnly = false) => new FlutterBy(new { finderType = "Descendant", matchRoot = matchRoot.ToString().ToLower(), firstMatchOnly = firstMatchOnly.ToString().ToLower(), of = of.JsonSearchCriteria, matching = matching.JsonSearchCriteria, }); } } ================================================ FILE: finder/dotnet/AppiumFlutterFinder/FlutterDriver.cs ================================================ using AppiumFlutterFinder; using OpenQA.Selenium; using OpenQA.Selenium.Appium; using OpenQA.Selenium.Appium.Android; using OpenQA.Selenium.Appium.MultiTouch; using OpenQA.Selenium.Appium.Service; using OpenQA.Selenium.Remote; using OpenQA.Selenium.Support.UI; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AppiumFlutterFinder { public class FlutterDriver : AppiumDriver { #region Overrides public FlutterDriver(ICapabilities appiumOptions) : base(appiumOptions) { } public FlutterDriver(ICommandExecutor commandExecutor, ICapabilities appiumOptions) : base(commandExecutor, appiumOptions) { } public FlutterDriver(ICapabilities appiumOptions, TimeSpan commandTimeout) : base(appiumOptions, commandTimeout) { } public FlutterDriver(AppiumServiceBuilder builder, ICapabilities appiumOptions) : base(builder, appiumOptions) { } public FlutterDriver(Uri remoteAddress, ICapabilities appiumOptions) : base(remoteAddress, appiumOptions) { } public FlutterDriver(AppiumLocalService service, ICapabilities appiumOptions) : base(service, appiumOptions) { } public FlutterDriver(AppiumServiceBuilder builder, ICapabilities appiumOptions, TimeSpan commandTimeout) : base(builder, appiumOptions, commandTimeout) { } public FlutterDriver(Uri remoteAddress, ICapabilities appiumOptions, TimeSpan commandTimeout) : base(remoteAddress, appiumOptions, commandTimeout) { } protected override RemoteWebElementFactory CreateElementFactory() => new FlutterElementFactory(this); public FlutterDriver(AppiumLocalService service, ICapabilities appiumOptions, TimeSpan commandTimeout) : base(service, appiumOptions, commandTimeout) { } #endregion public void WaitForFirstFrame() { ExecuteScript("flutter:waitForFirstFrame"); } public void SwitchToAndroidDriver() => Context = "NATIVE_APP"; public void SwitchToFlutterDriver() => Context = "FLUTTER"; public FlutterElement WaitForElementToBeVisible(FlutterBy by, int wait = 60) { var id = (string)ExecuteScript("flutter:waitFor", by.SerializedSearchCriteria, wait * 1000); return new FlutterElement(this, id); } public FlutterElement WaitForElementToBeClickable(FlutterBy by, int wait = 60) { var id = (string)ExecuteScript("flutter:waitForTappable", by.SerializedSearchCriteria, wait * 1000); return new FlutterElement(this, id); } public void SetFrameSync(bool isSet, int wait = 60) { ExecuteScript("flutter:setFrameSync", isSet, wait * 1000); } public void WaitForAbscense(FlutterBy by, int wait = 60) => ExecuteScript("flutter:waitForAbsent", by.SerializedSearchCriteria, wait * 1000); public void SaveScreenshot(string name) { var screenshot = GetScreenshot(); screenshot.SaveAsFile(name); } public void RunUnsynchronized(Action action) { SetFrameSync(false); action.Invoke(); SetFrameSync(true); } public void Click(FlutterBy by) => new FlutterElement(this, by.SerializedSearchCriteria).Click(); public void Tap(double x, double y, long? count = null) { SwitchToAndroidDriver(); new TouchAction(this).Tap(x, y, count).Perform(); SwitchToFlutterDriver(); } public void PageBack() => new FlutterElement(this, FlutterBy.PageBack().SerializedSearchCriteria).Click(); } } ================================================ FILE: finder/dotnet/AppiumFlutterFinder/FlutterElement.cs ================================================ using OpenQA.Selenium.Appium; using OpenQA.Selenium.Remote; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AppiumFlutterFinder { public class FlutterElement : AppiumWebElement { public FlutterElement(RemoteWebDriver parent, FlutterBy by) : base(parent, by.SerializedSearchCriteria) { } public FlutterElement(RemoteWebDriver parent, string id) : base(parent, id) { } public void FocusAndSendKeys(string text) { Click(); SendKeys(text); } } } ================================================ FILE: finder/dotnet/AppiumFlutterFinder/FlutterElementFactory.cs ================================================ using OpenQA.Selenium.Appium.Android; using OpenQA.Selenium.Appium; using OpenQA.Selenium.Remote; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AppiumFlutterFinder { public class FlutterElementFactory : CachedElementFactory { public FlutterElementFactory(RemoteWebDriver parentDriver): base(parentDriver) { } protected override FlutterElement CreateCachedElement(RemoteWebDriver parentDriver, string elementId) { return new FlutterElement(parentDriver, id: elementId); } } } ================================================ FILE: finder/dotnet/AppiumFlutterFinder/License.md ================================================ MIT License Copyright (c) [year] [fullname] Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: finder/dotnet/AppiumFlutterFinder/Readme.md ================================================ .NET FLUTTER FINDER. ================================================ FILE: finder/dotnet/AppiumFlutterFinderTests/AppiumFlutterFinderTests.csproj ================================================ net6.0 enable enable false true ================================================ FILE: finder/dotnet/AppiumFlutterFinderTests/FlutterFinderTests.cs ================================================ using AppiumFlutterFinder; using System.Text.RegularExpressions; namespace AppiumFlutterFinderTests { public class Tests { [Test] public void TestByAncestor() { var element = new FlutterElement(null, FlutterBy.ByAnscestor( FlutterBy.ByAnscestor(FlutterBy.PageBack(), FlutterBy.PageBack()), FlutterBy.ByAnscestor(FlutterBy.PageBack(), FlutterBy.PageBack()), firstMatchOnly: true )); Assert.AreEqual("eyJmaW5kZXJUeXBlIjoiQW5jZXN0b3IiLCJtYXRjaFJvb3QiOiJmYWxzZSIsImZpcnN0TWF0Y2hPbmx5IjoidHJ1ZSIsIm9mIjoie1wiZmluZGVyVHlwZVwiOlwiQW5jZXN0b3JcIixcIm1hdGNoUm9vdFwiOlwiZmFsc2VcIixcImZpcnN0TWF0Y2hPbmx5XCI6XCJmYWxzZVwiLFwib2ZcIjpcIntcXFwiZmluZGVyVHlwZVxcXCI6XFxcIlBhZ2VCYWNrXFxcIn1cIixcIm1hdGNoaW5nXCI6XCJ7XFxcImZpbmRlclR5cGVcXFwiOlxcXCJQYWdlQmFja1xcXCJ9XCJ9IiwibWF0Y2hpbmciOiJ7XCJmaW5kZXJUeXBlXCI6XCJBbmNlc3RvclwiLFwibWF0Y2hSb290XCI6XCJmYWxzZVwiLFwiZmlyc3RNYXRjaE9ubHlcIjpcImZhbHNlXCIsXCJvZlwiOlwie1xcXCJmaW5kZXJUeXBlXFxcIjpcXFwiUGFnZUJhY2tcXFwifVwiLFwibWF0Y2hpbmdcIjpcIntcXFwiZmluZGVyVHlwZVxcXCI6XFxcIlBhZ2VCYWNrXFxcIn1cIn0ifQ==", element.Id); } [Test] public void TestBydescendant() { var element = new FlutterElement(null, FlutterBy.ByDescendant( FlutterBy.ByDescendant(FlutterBy.PageBack(), FlutterBy.PageBack()), FlutterBy.ByDescendant(FlutterBy.PageBack(), FlutterBy.PageBack()) )); Assert.AreEqual("eyJmaW5kZXJUeXBlIjoiRGVzY2VuZGFudCIsIm1hdGNoUm9vdCI6ImZhbHNlIiwiZmlyc3RNYXRjaE9ubHkiOiJmYWxzZSIsIm9mIjoie1wiZmluZGVyVHlwZVwiOlwiRGVzY2VuZGFudFwiLFwibWF0Y2hSb290XCI6XCJmYWxzZVwiLFwiZmlyc3RNYXRjaE9ubHlcIjpcImZhbHNlXCIsXCJvZlwiOlwie1xcXCJmaW5kZXJUeXBlXFxcIjpcXFwiUGFnZUJhY2tcXFwifVwiLFwibWF0Y2hpbmdcIjpcIntcXFwiZmluZGVyVHlwZVxcXCI6XFxcIlBhZ2VCYWNrXFxcIn1cIn0iLCJtYXRjaGluZyI6IntcImZpbmRlclR5cGVcIjpcIkRlc2NlbmRhbnRcIixcIm1hdGNoUm9vdFwiOlwiZmFsc2VcIixcImZpcnN0TWF0Y2hPbmx5XCI6XCJmYWxzZVwiLFwib2ZcIjpcIntcXFwiZmluZGVyVHlwZVxcXCI6XFxcIlBhZ2VCYWNrXFxcIn1cIixcIm1hdGNoaW5nXCI6XCJ7XFxcImZpbmRlclR5cGVcXFwiOlxcXCJQYWdlQmFja1xcXCJ9XCJ9In0=", element.Id); } [Test] public void test_by_semantics_label() { var element = new FlutterElement(null, FlutterBy.BySemanticsLabel("simple")); Assert.AreEqual("eyJmaW5kZXJUeXBlIjoiQnlTZW1hbnRpY3NMYWJlbCIsImlzUmVnRXhwIjpmYWxzZSwibGFiZWwiOiJzaW1wbGUifQ==", element.Id); } [Test] public void TestBySemanticsLabelRegex() { var element = new FlutterElement(null, FlutterBy.BySemanticsLabel(new Regex("complicated"))); Assert.AreEqual("eyJmaW5kZXJUeXBlIjoiQnlTZW1hbnRpY3NMYWJlbCIsImlzUmVnRXhwIjp0cnVlLCJsYWJlbCI6ImNvbXBsaWNhdGVkIn0=", element.Id); } [Test] public void TestByTooltip() { var element = new FlutterElement(null, FlutterBy.ByTooltip("myText")); Assert.AreEqual("eyJmaW5kZXJUeXBlIjoiQnlUb29sdGlwTWVzc2FnZSIsInRleHQiOiJteVRleHQifQ==", element.Id); } [Test] public void TestByType() { var element = new FlutterElement(null, FlutterBy.ByType("myText")); Assert.AreEqual("eyJmaW5kZXJUeXBlIjoiQnlUeXBlIiwidHlwZSI6Im15VGV4dCJ9", element.Id); } [Test] public void TestByValueKeyInt() { var element = new FlutterElement(null, FlutterBy.ByKeyValue(42)); Assert.AreEqual("eyJmaW5kZXJUeXBlIjoiQnlWYWx1ZUtleSIsImtleVZhbHVlU3RyaW5nIjo0Miwia2V5VmFsdWVUeXBlIjoiaW50In0=", element.Id); } [Test] public void TestByValueKeyString() { var element = new FlutterElement(null, FlutterBy.ByKeyValue("42")); Assert.AreEqual("eyJmaW5kZXJUeXBlIjoiQnlWYWx1ZUtleSIsImtleVZhbHVlU3RyaW5nIjoiNDIiLCJrZXlWYWx1ZVR5cGUiOiJTdHJpbmcifQ==", element.Id); } [Test] public void TestPageBack() { var element = new FlutterElement(null, FlutterBy.PageBack()); Assert.AreEqual("eyJmaW5kZXJUeXBlIjoiUGFnZUJhY2sifQ==", element.Id); } [Test] public void TestByText() { var element = new FlutterElement(null, FlutterBy.ByText("This is 2nd route")); Assert.AreEqual("eyJmaW5kZXJUeXBlIjoiQnlUZXh0IiwidGV4dCI6IlRoaXMgaXMgMm5kIHJvdXRlIn0=", element.Id); } } } ================================================ FILE: finder/dotnet/AppiumFlutterFinderTests/Usings.cs ================================================ global using NUnit.Framework; ================================================ FILE: finder/dotnet/DotNetAppiumFlutterFinder.sln ================================================  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.6.33815.320 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AppiumFlutterFinder", "AppiumFlutterFinder\AppiumFlutterFinder.csproj", "{1E8B7B00-E283-4348-B76B-14E9AE262287}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AppiumFlutterFinderTests", "AppiumFlutterFinderTests\AppiumFlutterFinderTests.csproj", "{C19777E3-48D1-455C-90CB-8665983CE719}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {1E8B7B00-E283-4348-B76B-14E9AE262287}.Debug|Any CPU.ActiveCfg = Release|Any CPU {1E8B7B00-E283-4348-B76B-14E9AE262287}.Debug|Any CPU.Build.0 = Release|Any CPU {1E8B7B00-E283-4348-B76B-14E9AE262287}.Release|Any CPU.ActiveCfg = Release|Any CPU {1E8B7B00-E283-4348-B76B-14E9AE262287}.Release|Any CPU.Build.0 = Release|Any CPU {C19777E3-48D1-455C-90CB-8665983CE719}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C19777E3-48D1-455C-90CB-8665983CE719}.Debug|Any CPU.Build.0 = Debug|Any CPU {C19777E3-48D1-455C-90CB-8665983CE719}.Release|Any CPU.ActiveCfg = Release|Any CPU {C19777E3-48D1-455C-90CB-8665983CE719}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {0EB4511B-CB82-4980-B254-C5C88491BE79} EndGlobalSection EndGlobal ================================================ FILE: finder/kotlin/.gitignore ================================================ .gradle/* build/* ================================================ FILE: finder/kotlin/README.md ================================================ # AppiumFlutterFinder Kotlin finder elements for https://github.com/appium/appium-flutter-driver ## Installation This is available via Jitpack, or the local dependencies. https://jitpack.io/#appium/appium-flutter-driver An example of snapshot of the `main`. - `settings.gradle` ```groovy dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { mavenCentral() maven { url 'https://jitpack.io' } } } ``` - gradle file ```groovy dependencies { testImplementation 'com.github.appium:appium-flutter-driver:main-SNAPSHOT' } ``` ```groovy dependencies { testImplementation 'com.github.appium:appium-flutter-driver:kotlin-finder-0.0.7' } ``` Please check https://docs.jitpack.io/ for more details about the jitpack usage. ## Package name `pro.truongsinh.appium_flutter` is this project's package name space. ## Changlogs - 0.0.7 - Available via jitpack # Other Java implementations - https://github.com/ashwithpoojary98/javaflutterfinder - https://github.com/5v1988/appium-flutter-client ================================================ FILE: finder/kotlin/build.gradle.kts ================================================ import org.gradle.jvm.tasks.Jar group = "pro.truongsinh" version = "0.0.6" plugins { id("kotlinx-serialization") version "1.3.40" `maven-publish` kotlin("jvm") version "1.3.40" } repositories { mavenCentral() } dependencies { implementation(kotlin("stdlib")) implementation ("org.jetbrains.kotlinx:kotlinx-serialization-runtime:0.14.0") implementation ("io.appium:java-client:8.0.0") implementation("org.seleniumhq.selenium:selenium-support:4.1.1") testImplementation("junit:junit:4.12") } publishing { publications { create("default") { from(components["java"]) } } repositories { maven { url = uri("$buildDir/repository") } } } ================================================ FILE: finder/kotlin/gradle/wrapper/gradle-wrapper.properties ================================================ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists ================================================ FILE: finder/kotlin/gradle.properties ================================================ # Project-wide Gradle settings. # IDE (e.g. Android Studio) users: # Gradle settings configured through the IDE *will override* # any settings specified in this file. # For more details on how to configure your build environment visit # http://www.gradle.org/docs/current/userguide/build_environment.html # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. org.gradle.jvmargs=-Xmx1536m # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true org.gradle.configureondemand=false android.useAndroidX=true org.gradle.vfs.watch=true org.gradle.caching=true # https://youtrack.jetbrains.com/issue/KT-46708 kotlin.stdlib.default.dependency=false kotlin.experimental=true ================================================ FILE: finder/kotlin/gradlew ================================================ #!/usr/bin/env sh # # Copyright 2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ############################################################################## ## ## Gradle start up script for UN*X ## ############################################################################## # Attempt to set APP_HOME # Resolve links: $0 may be a link PRG="$0" # Need this for relative symlinks. while [ -h "$PRG" ] ; do ls=`ls -ld "$PRG"` link=`expr "$ls" : '.*-> \(.*\)$'` if expr "$link" : '/.*' > /dev/null; then PRG="$link" else PRG=`dirname "$PRG"`"/$link" fi done SAVED="`pwd`" cd "`dirname \"$PRG\"`/" >/dev/null APP_HOME="`pwd -P`" cd "$SAVED" >/dev/null APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" warn () { echo "$*" } die () { echo echo "$*" echo exit 1 } # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false case "`uname`" in CYGWIN* ) cygwin=true ;; Darwin* ) darwin=true ;; MINGW* ) msys=true ;; NONSTOP* ) nonstop=true ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables JAVACMD="$JAVA_HOME/jre/sh/java" else JAVACMD="$JAVA_HOME/bin/java" fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else JAVACMD="java" which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi # Increase the maximum file descriptors if we can. if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then MAX_FD_LIMIT=`ulimit -H -n` if [ $? -eq 0 ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then MAX_FD="$MAX_FD_LIMIT" fi ulimit -n $MAX_FD if [ $? -ne 0 ] ; then warn "Could not set maximum file descriptor limit: $MAX_FD" fi else warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" fi fi # For Darwin, add options to specify how the application appears in the dock if $darwin; then GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" fi # For Cygwin or MSYS, switch paths to Windows format before running java if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` SEP="" for dir in $ROOTDIRSRAW ; do ROOTDIRS="$ROOTDIRS$SEP$dir" SEP="|" done OURCYGPATTERN="(^($ROOTDIRS))" # Add a user-defined pattern to the cygpath arguments if [ "$GRADLE_CYGPATTERN" != "" ] ; then OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" fi # Now convert the arguments - kludge to limit ourselves to /bin/sh i=0 for arg in "$@" ; do CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` else eval `echo args$i`="\"$arg\"" fi i=`expr $i + 1` done case $i in 0) set -- ;; 1) set -- "$args0" ;; 2) set -- "$args0" "$args1" ;; 3) set -- "$args0" "$args1" "$args2" ;; 4) set -- "$args0" "$args1" "$args2" "$args3" ;; 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; esac fi # Escape application args save () { for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done echo " " } APP_ARGS=`save "$@"` # Collect all arguments for the java command, following the shell quoting and substitution rules eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" exec "$JAVACMD" "$@" ================================================ FILE: finder/kotlin/gradlew.bat ================================================ @rem @rem Copyright 2015 the original author or authors. @rem @rem Licensed under the Apache License, Version 2.0 (the "License"); @rem you may not use this file except in compliance with the License. @rem You may obtain a copy of the License at @rem @rem https://www.apache.org/licenses/LICENSE-2.0 @rem @rem Unless required by applicable law or agreed to in writing, software @rem distributed under the License is distributed on an "AS IS" BASIS, @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem @if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @rem @rem ########################################################################## @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @rem Resolve any "." and ".." in APP_HOME to make it shorter. for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if "%ERRORLEVEL%" == "0" goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo. echo Please set the JAVA_HOME variable in your environment to match the echo location of your Java installation. goto fail :findJavaFromJavaHome set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo. echo Please set the JAVA_HOME variable in your environment to match the echo location of your Java installation. goto fail :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell if "%ERRORLEVEL%"=="0" goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 exit /b 1 :mainEnd if "%OS%"=="Windows_NT" endlocal :omega ================================================ FILE: finder/kotlin/settings.gradle.kts ================================================ rootProject.name = "appium-flutter-finder" pluginManagement { resolutionStrategy { eachPlugin { if (requested.id.id == "kotlinx-serialization") { useModule("org.jetbrains.kotlin:kotlin-serialization:${requested.version}") } } } repositories { gradlePluginPortal() maven("https://kotlin.bintray.com/kotlinx") } } ================================================ FILE: finder/kotlin/src/main/kotlin/pro/truongsinh/appium_flutter/FlutterFinder.kt ================================================ package pro.truongsinh.appium_flutter import java.util.regex.Pattern import org.openqa.selenium.remote.RemoteWebDriver import org.openqa.selenium.remote.FileDetector import pro.truongsinh.appium_flutter.finder.FlutterElement import pro.truongsinh.appium_flutter.finder.ancestor as _ancestor import pro.truongsinh.appium_flutter.finder.bySemanticsLabel as _bySemanticsLabel import pro.truongsinh.appium_flutter.finder.byTooltip as _byTooltip import pro.truongsinh.appium_flutter.finder.byType as _byType import pro.truongsinh.appium_flutter.finder.byValueKey as _byValueKey import pro.truongsinh.appium_flutter.finder.descendant as _descendant import pro.truongsinh.appium_flutter.finder.pageBack as _pageBack import pro.truongsinh.appium_flutter.finder.text as _text public class FlutterFinder(private val driver: RemoteWebDriver) { private val fileDetector = FileDetector { _ -> null } fun ancestor(of: FlutterElement, matching: FlutterElement): FlutterElement { val f = _ancestor(of, matching, matchRoot = false, firstMatchOnly = false) f.setParent(driver) f.setFileDetector(fileDetector) return f } fun ancestor(of: FlutterElement, matching: FlutterElement, matchRoot: Boolean = false, firstMatchOnly: Boolean = false): FlutterElement { val f = _ancestor(of, matching, matchRoot, firstMatchOnly) f.setParent(driver) f.setFileDetector(fileDetector) return f } fun bySemanticsLabel(label: String): FlutterElement { val f = _bySemanticsLabel(label) f.setParent(driver) f.setFileDetector(fileDetector) return f } fun bySemanticsLabel(label: Pattern): FlutterElement { val f = _bySemanticsLabel(label) f.setParent(driver) f.setFileDetector(fileDetector) return f } fun byTooltip(input: String): FlutterElement { val f = _byTooltip(input) f.setParent(driver) f.setFileDetector(fileDetector) return f } fun byType(input: String): FlutterElement { val f = _byType(input) f.setParent(driver) f.setFileDetector(fileDetector) return f } fun byValueKey(input: String): FlutterElement { val f = _byValueKey(input) f.setParent(driver) f.setFileDetector(fileDetector) return f } fun byValueKey(input: Int): FlutterElement { val f = _byValueKey(input) f.setParent(driver) f.setFileDetector(fileDetector) return f } fun descendant(of: FlutterElement, matching: FlutterElement): FlutterElement { return _descendant(of, matching, matchRoot = false, firstMatchOnly = false) } fun descendant(of: FlutterElement, matching: FlutterElement, matchRoot: Boolean = false, firstMatchOnly: Boolean = false): FlutterElement { val f = _descendant(of, matching, matchRoot, firstMatchOnly) f.setParent(driver) f.setFileDetector(fileDetector) return f } fun pageBack(): FlutterElement { val f = _pageBack() f.setParent(driver) f.setFileDetector(fileDetector) return f } fun text(input: String): FlutterElement { val f = _text(input) f.setParent(driver) f.setFileDetector(fileDetector) return f } } ================================================ FILE: finder/kotlin/src/main/kotlin/pro/truongsinh/appium_flutter/finder/FlutterElement.kt ================================================ package pro.truongsinh.appium_flutter.finder import org.openqa.selenium.remote.RemoteWebElement public class FlutterElement(m: Map) : RemoteWebElement() { private var _rawMap: Map = m init { id = serialize(m) } fun getRawMap(): Map { return _rawMap } override fun toString(): String { return String.format("[FlutterElement]") } } ================================================ FILE: finder/kotlin/src/main/kotlin/pro/truongsinh/appium_flutter/finder/ancestor.kt ================================================ @file:JvmName("_FinderRawMethods") @file:JvmMultifileClass package pro.truongsinh.appium_flutter.finder fun ancestor(of: FlutterElement, matching: FlutterElement, matchRoot: Boolean = false, firstMatchOnly: Boolean = false): FlutterElement { val m = mutableMapOf( "finderType" to "Ancestor", "matchRoot" to matchRoot.toString(), "firstMatchOnly" to firstMatchOnly.toString() ) m["of"] = of.getRawMap() m["matching"] = matching.getRawMap() return FlutterElement(m) } ================================================ FILE: finder/kotlin/src/main/kotlin/pro/truongsinh/appium_flutter/finder/bySemanticsLabel.kt ================================================ @file:JvmName("_FinderRawMethods") @file:JvmMultifileClass package pro.truongsinh.appium_flutter.finder import java.util.regex.Pattern; fun bySemanticsLabel(label: String): FlutterElement { return FlutterElement(mapOf( "finderType" to "BySemanticsLabel", "isRegExp" to false, "label" to label )) } fun bySemanticsLabel(label: Pattern): FlutterElement { return FlutterElement(mapOf( "finderType" to "BySemanticsLabel", "isRegExp" to true, "label" to label.toString() )) } ================================================ FILE: finder/kotlin/src/main/kotlin/pro/truongsinh/appium_flutter/finder/byTooltip.kt ================================================ @file:JvmName("_FinderRawMethods") @file:JvmMultifileClass package pro.truongsinh.appium_flutter.finder fun byTooltip(input: String): FlutterElement { return FlutterElement(mapOf( "finderType" to "ByTooltipMessage", "text" to input )) } ================================================ FILE: finder/kotlin/src/main/kotlin/pro/truongsinh/appium_flutter/finder/byType.kt ================================================ @file:JvmName("_FinderRawMethods") @file:JvmMultifileClass package pro.truongsinh.appium_flutter.finder fun byType(input: String): FlutterElement { return FlutterElement(mapOf( "finderType" to "ByType", "type" to input )) } ================================================ FILE: finder/kotlin/src/main/kotlin/pro/truongsinh/appium_flutter/finder/byValueKey.kt ================================================ @file:JvmName("_FinderRawMethods") @file:JvmMultifileClass package pro.truongsinh.appium_flutter.finder fun byValueKey(input: String): FlutterElement { return FlutterElement(mapOf( "finderType" to "ByValueKey", "keyValueType" to "String", "keyValueString" to input )) } fun byValueKey(input: Int): FlutterElement { return FlutterElement(mapOf( "finderType" to "ByValueKey", "keyValueType" to "int", "keyValueString" to input )) } ================================================ FILE: finder/kotlin/src/main/kotlin/pro/truongsinh/appium_flutter/finder/descendant.kt ================================================ @file:JvmName("_FinderRawMethods") @file:JvmMultifileClass package pro.truongsinh.appium_flutter.finder fun descendant(of: FlutterElement, matching: FlutterElement, matchRoot: Boolean = false, firstMatchOnly: Boolean = false): FlutterElement { val m = mutableMapOf( "finderType" to "Descendant", "matchRoot" to matchRoot.toString(), "firstMatchOnly" to firstMatchOnly.toString() ) m["of"] = of.getRawMap() m["matching"] = matching.getRawMap() return FlutterElement(m) } ================================================ FILE: finder/kotlin/src/main/kotlin/pro/truongsinh/appium_flutter/finder/pageback.kt ================================================ @file:JvmName("_FinderRawMethods") @file:JvmMultifileClass package pro.truongsinh.appium_flutter.finder fun pageBack(): FlutterElement { return FlutterElement(mapOf("finderType" to "PageBack")) } ================================================ FILE: finder/kotlin/src/main/kotlin/pro/truongsinh/appium_flutter/finder/serializer.kt ================================================ @file:JvmName("_FinderRawMethods") @file:JvmMultifileClass package pro.truongsinh.appium_flutter.finder import java.util.Base64 import kotlinx.serialization.* import kotlinx.serialization.json.* val json = Json(JsonConfiguration.Stable) val base64encoder = Base64.getUrlEncoder().withoutPadding() val base64decoder = Base64.getUrlDecoder() @UseExperimental(ImplicitReflectionSerializer::class) fun serialize(o: Map): String { val jsonStringified = json.stringify(jsonObjectFrom(o)) val base64Encoded = base64encoder.encodeToString(jsonStringified.toByteArray()) return base64Encoded } @UseExperimental(ImplicitReflectionSerializer::class) fun jsonObjectFrom(o: Map): Map { return o.map { val jsonO = when (val value = it.value) { is String -> JsonLiteral(value) is Number -> JsonLiteral(value) is Boolean -> JsonLiteral(value) is Map<*, *> -> JsonLiteral(json.stringify(jsonObjectFrom(value as Map))) is JsonElement -> value else -> JsonNull } Pair(it.key, jsonO) }.toMap() } fun deserialize(base64Encoded: String): Map { val base64Decoded = String(base64decoder.decode(base64Encoded)) val jsonObject = json.parseJson(base64Decoded) as JsonObject return jsonObject.toMap() } ================================================ FILE: finder/kotlin/src/main/kotlin/pro/truongsinh/appium_flutter/finder/text.kt ================================================ @file:JvmName("_FinderRawMethods") @file:JvmMultifileClass package pro.truongsinh.appium_flutter.finder fun text(input: String): FlutterElement { return FlutterElement(mapOf( "finderType" to "ByText", "text" to input )) } ================================================ FILE: finder/kotlin/src/test/kotlin/pro/truongsinh/appium_flutter/finder/FinderTest.kt ================================================ package pro.truongsinh.appium_flutter.finder import java.util.regex.Pattern; import org.junit.Assert.assertEquals import org.junit.Test class FinderTest { @Test fun TestAncestor() { val expected = "eyJmaW5kZXJUeXBlIjoiQW5jZXN0b3IiLCJtYXRjaFJvb3QiOiJmYWxzZSIsImZpcnN0TWF0Y2hPbmx5IjoiZmFsc2UiLCJvZiI6IntcImZpbmRlclR5cGVcIjpcIkFuY2VzdG9yXCIsXCJtYXRjaFJvb3RcIjpcImZhbHNlXCIsXCJmaXJzdE1hdGNoT25seVwiOlwiZmFsc2VcIixcIm9mXCI6XCJ7XFxcImZpbmRlclR5cGVcXFwiOlxcXCJQYWdlQmFja1xcXCJ9XCIsXCJtYXRjaGluZ1wiOlwie1xcXCJmaW5kZXJUeXBlXFxcIjpcXFwiUGFnZUJhY2tcXFwifVwifSIsIm1hdGNoaW5nIjoie1wiZmluZGVyVHlwZVwiOlwiQW5jZXN0b3JcIixcIm1hdGNoUm9vdFwiOlwiZmFsc2VcIixcImZpcnN0TWF0Y2hPbmx5XCI6XCJmYWxzZVwiLFwib2ZcIjpcIntcXFwiZmluZGVyVHlwZVxcXCI6XFxcIlBhZ2VCYWNrXFxcIn1cIixcIm1hdGNoaW5nXCI6XCJ7XFxcImZpbmRlclR5cGVcXFwiOlxcXCJQYWdlQmFja1xcXCJ9XCJ9In0" val observed = ancestor( of = ancestor( of = pageBack(), matching = pageBack() ), matching = ancestor( of = pageBack(), matching = pageBack() ) ).id assertEquals(expected, observed) } @Test fun TestBySemanticsLabelString() { assertEquals("eyJmaW5kZXJUeXBlIjoiQnlTZW1hbnRpY3NMYWJlbCIsImlzUmVnRXhwIjpmYWxzZSwibGFiZWwiOiJzaW1wbGUifQ", bySemanticsLabel("simple").id) } @Test fun TestBySemanticsLabelRegex() { assertEquals("eyJmaW5kZXJUeXBlIjoiQnlTZW1hbnRpY3NMYWJlbCIsImlzUmVnRXhwIjp0cnVlLCJsYWJlbCI6ImNvbXBsaWNhdGVkIn0", bySemanticsLabel(Pattern.compile("complicated")).id) } @Test fun TestByTooltip() { assertEquals("eyJmaW5kZXJUeXBlIjoiQnlUb29sdGlwTWVzc2FnZSIsInRleHQiOiJteVRleHQifQ", byTooltip("myText").id) } @Test fun TestByType() { assertEquals("eyJmaW5kZXJUeXBlIjoiQnlUeXBlIiwidHlwZSI6Im15VGV4dCJ9", byType("myText").id) } @Test fun testByValueKeyString() { val expectedJsonElement = deserialize("eyJmaW5kZXJUeXBlIjoiQnlWYWx1ZUtleSIsImtleVZhbHVlU3RyaW5nIjoiNDIiLCJrZXlWYWx1ZVR5cGUiOiJTdHJpbmcifQ") val obserbedJsonElement = deserialize(byValueKey("42").id) assertEquals(true, expectedJsonElement.equals(obserbedJsonElement)) } @Test fun testByValueKeyInt() { val expectedJsonElement = deserialize("eyJmaW5kZXJUeXBlIjoiQnlWYWx1ZUtleSIsImtleVZhbHVlU3RyaW5nIjo0Miwia2V5VmFsdWVUeXBlIjoiaW50In0") val obserbedJsonElement = deserialize(byValueKey(42).id) assertEquals(true, expectedJsonElement.equals(obserbedJsonElement)) } @Test fun testDescendant() { val expected = "eyJmaW5kZXJUeXBlIjoiRGVzY2VuZGFudCIsIm1hdGNoUm9vdCI6ImZhbHNlIiwiZmlyc3RNYXRjaE9ubHkiOiJmYWxzZSIsIm9mIjoie1wiZmluZGVyVHlwZVwiOlwiRGVzY2VuZGFudFwiLFwibWF0Y2hSb290XCI6XCJmYWxzZVwiLFwiZmlyc3RNYXRjaE9ubHlcIjpcImZhbHNlXCIsXCJvZlwiOlwie1xcXCJmaW5kZXJUeXBlXFxcIjpcXFwiUGFnZUJhY2tcXFwifVwiLFwibWF0Y2hpbmdcIjpcIntcXFwiZmluZGVyVHlwZVxcXCI6XFxcIlBhZ2VCYWNrXFxcIn1cIn0iLCJtYXRjaGluZyI6IntcImZpbmRlclR5cGVcIjpcIkRlc2NlbmRhbnRcIixcIm1hdGNoUm9vdFwiOlwiZmFsc2VcIixcImZpcnN0TWF0Y2hPbmx5XCI6XCJmYWxzZVwiLFwib2ZcIjpcIntcXFwiZmluZGVyVHlwZVxcXCI6XFxcIlBhZ2VCYWNrXFxcIn1cIixcIm1hdGNoaW5nXCI6XCJ7XFxcImZpbmRlclR5cGVcXFwiOlxcXCJQYWdlQmFja1xcXCJ9XCJ9In0" val observed = descendant( of = descendant( of = pageBack(), matching = pageBack() ), matching = descendant( of = pageBack(), matching = pageBack() ) ).id assertEquals(expected, observed) } @Test fun testPageback() { assertEquals("eyJmaW5kZXJUeXBlIjoiUGFnZUJhY2sifQ", pageBack().id) } @Test fun testText() { assertEquals("eyJmaW5kZXJUeXBlIjoiQnlUZXh0IiwidGV4dCI6IlRoaXMgaXMgMm5kIHJvdXRlIn0", text("This is 2nd route").id) } } ================================================ FILE: finder/nodejs/LICENSE ================================================ MIT License ----------- Copyright (c) 2019 TruongSinh Tran-Nguyen Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: finder/nodejs/README.md ================================================ # Appium Flutter Finder Companion `finder` for [Appium Flutter Driver](https://www.npmjs.com/package/appium-flutter-driver), that mimics the API of Flutter Driver's [CommonFinders class](https://api.flutter.dev/flutter/flutter_driver/CommonFinders-class.html). All documentation and examples are available in [Appium Flutter Driver package](https://www.npmjs.com/package/appium-flutter-driver). # Release ``` $ cd finder/nodejs $ npm version $ git commit -am 'chore: bump version' $ git tag js-finder- # e.g. git tag js-finder-0.0.23 $ git push origin js-finder-0.0.23 $ npm publish ``` ## Changelog - 0.2.0 - Fix type of `matchRoot` and `firstMatchOnly` in `ancestor` and `descendant` - 0.1.0 - Add `firstMatchOnly` in `ancestor` and `descendant` - 0.0.23 - Fix `ancestor` and `descendant` ================================================ FILE: finder/nodejs/lib/base64url.ts ================================================ const W3C_ELEMENT: string = `element-6066-11e4-a52e-4f735466cecf`; const MJSON_ELEMENT: string = `ELEMENT`; export const encode = (input: string) => Buffer.from(input) .toString(`base64`) .replace(/=/g, ``) .replace(/\+/g, `-`) .replace(/\//g, `_`); export const decode = (input: string | {[key: string]: string}) => { let base64String: string = ``; if (typeof input === `string`) { base64String = input; } else if (typeof input === `object` && W3C_ELEMENT in input) { base64String = input[W3C_ELEMENT]; } else if (typeof input === `object` && MJSON_ELEMENT in input) { base64String = input[MJSON_ELEMENT]; } else { throw new Error(`input is invalid ${JSON.stringify(input)}`); } return Buffer.from(base64String, `base64`).toString(); }; ================================================ FILE: finder/nodejs/lib/base64url_test.ts ================================================ import expect from 'expect'; import { decode, encode } from './base64url'; describe(`base64url`, () => { it(`decode multiple occurrences of +/=`, () => { expect(decode(`1L3Xst+9zp/Gncqt1rXTkde92onGrN6ozq/dpdyX3ZnEu9+TyIhhYQ==`)).toBe(`Խײ߽ΟƝʭֵӑ׽ډƬިίݥܗݙĻߓȈaa`); expect(decode(`1L3Xst-9zp_Gncqt1rXTkde92onGrN6ozq_dpdyX3ZnEu9-TyIhhYQ`)).toBe(`Խײ߽ΟƝʭֵӑ׽ډƬިίݥܗݙĻߓȈaa`); }); it(`encode multiple occurrences of +/=`, () => { expect(encode(`Խײ߽ΟƝʭֵӑ׽ډƬިίݥܗݙĻߓȈaa`)).toBe(`1L3Xst-9zp_Gncqt1rXTkde92onGrN6ozq_dpdyX3ZnEu9-TyIhhYQ`); }); describe(`decode`, () => { it(`decode MJSONWP element object`, () => { expect(decode({ ELEMENT: `1L3Xst+9zp/Gncqt1rXTkde92onGrN6ozq/dpdyX3ZnEu9+TyIhhYQ==` })) .toBe(`Խײ߽ΟƝʭֵӑ׽ډƬިίݥܗݙĻߓȈaa`); }); it(`decode W3C element object`, () => { expect(decode({ 'element-6066-11e4-a52e-4f735466cecf': `1L3Xst+9zp/Gncqt1rXTkde92onGrN6ozq/dpdyX3ZnEu9+TyIhhYQ==` })) .toBe(`Խײ߽ΟƝʭֵӑ׽ډƬިίݥܗݙĻߓȈaa`); }); it(`throws Error for strang object`, () => { expect(() => decode({ foo: `bar` })).toThrow(); }); }); }); ================================================ FILE: finder/nodejs/lib/deserializer.ts ================================================ import { decode } from './base64url'; // @todo consider using protobuf export const deserialize = (base64String: string) => JSON.parse(decode(base64String)); ================================================ FILE: finder/nodejs/lib/serializer.ts ================================================ import { encode } from './base64url'; import { deserialize } from './deserializer'; // @todo consider using protobuf function serialize(obj: object) { return encode(JSON.stringify(obj)); } export type SerializableFinder = string; export type Pattern = string | RegExp; export const ancestor = (args: { of: SerializableFinder; matching: SerializableFinder; matchRoot?: boolean; firstMatchOnly?: boolean; }) => { const { of, matching, matchRoot = false, firstMatchOnly = false} = args; const a: any = { finderType: `Ancestor`, firstMatchOnly: `${firstMatchOnly}`, matchRoot: `${matchRoot}`, }; const ofParam: any = {}; Object.entries(deserialize(of)).forEach( ([key, value]) => (ofParam[key] = value), ); a[`of`] = JSON.stringify(ofParam); const matchingPara: any = {}; Object.entries(deserialize(matching)).forEach( ([key, value]) => (matchingPara[key] = value), ); a[`matching`] = JSON.stringify(matchingPara); return serialize(a); }; export const bySemanticsLabel = (label: Pattern) => serialize({ finderType: `BySemanticsLabel`, isRegExp: label instanceof RegExp ? true : false, label: label instanceof RegExp ? label.toString().slice(1, -1) : label, }); export const byTooltip = (text: string) => serialize({ finderType: `ByTooltipMessage`, text, }); export const byType = (type: string) => serialize({ finderType: `ByType`, type, }); export const byValueKey = (key: string | number) => serialize({ finderType: `ByValueKey`, keyValueString: key, keyValueType: typeof key === `string` ? `String` : `int`, }); export const descendant = (args: { of: SerializableFinder; matching: SerializableFinder; matchRoot?: boolean; firstMatchOnly?: boolean; }) => { const { of, matching, matchRoot = false , firstMatchOnly = false} = args; const a: any = { finderType: `Descendant`, firstMatchOnly: `${firstMatchOnly}`, matchRoot: `${matchRoot}`, }; const ofParam: any = {}; Object.entries(deserialize(of)).forEach( ([key, value]) => (ofParam[key] = value), ); a[`of`] = JSON.stringify(ofParam); const matchingParam: any = {}; Object.entries(deserialize(matching)).forEach( ([key, value]) => (matchingParam[key] = value), ); a[`matching`] = JSON.stringify(matchingParam); return serialize(a); }; export const pageBack = () => serialize({ finderType: `PageBack`, }); export const byText = (text: string) => serialize({ finderType: `ByText`, text, }); ================================================ FILE: finder/nodejs/lib/serializer_test.ts ================================================ // tslint:disable:object-literal-sort-keys import expect from 'expect'; import * as find from './serializer'; describe(`serializer`, () => { it(`ancestor`, () => { const expected = `eyJmaW5kZXJUeXBlIjoiQW5jZXN0b3IiLCJmaXJzdE1hdGNoT25seSI6InRydWUiLCJtYXRjaFJvb3QiOiJmYWxzZSIsIm9mIjoie1wiZmluZGVyVHlwZVwiOlwiQW5jZXN0b3JcIixcImZpcnN0TWF0Y2hPbmx5XCI6XCJmYWxzZVwiLFwibWF0Y2hSb290XCI6XCJmYWxzZVwiLFwib2ZcIjpcIntcXFwiZmluZGVyVHlwZVxcXCI6XFxcIlBhZ2VCYWNrXFxcIn1cIixcIm1hdGNoaW5nXCI6XCJ7XFxcImZpbmRlclR5cGVcXFwiOlxcXCJQYWdlQmFja1xcXCJ9XCJ9IiwibWF0Y2hpbmciOiJ7XCJmaW5kZXJUeXBlXCI6XCJBbmNlc3RvclwiLFwiZmlyc3RNYXRjaE9ubHlcIjpcImZhbHNlXCIsXCJtYXRjaFJvb3RcIjpcImZhbHNlXCIsXCJvZlwiOlwie1xcXCJmaW5kZXJUeXBlXFxcIjpcXFwiUGFnZUJhY2tcXFwifVwiLFwibWF0Y2hpbmdcIjpcIntcXFwiZmluZGVyVHlwZVxcXCI6XFxcIlBhZ2VCYWNrXFxcIn1cIn0ifQ`; const observed = find.ancestor({ of: find.ancestor({ of: find.pageBack(), matching: find.pageBack(), }), matching: find.ancestor({ of: find.pageBack(), matching: find.pageBack(), }), firstMatchOnly: true, }); expect(observed).toBe(expected); }); it(`descendant`, () => { const expected = `eyJmaW5kZXJUeXBlIjoiRGVzY2VuZGFudCIsImZpcnN0TWF0Y2hPbmx5IjoiZmFsc2UiLCJtYXRjaFJvb3QiOiJmYWxzZSIsIm9mIjoie1wiZmluZGVyVHlwZVwiOlwiRGVzY2VuZGFudFwiLFwiZmlyc3RNYXRjaE9ubHlcIjpcImZhbHNlXCIsXCJtYXRjaFJvb3RcIjpcImZhbHNlXCIsXCJvZlwiOlwie1xcXCJmaW5kZXJUeXBlXFxcIjpcXFwiUGFnZUJhY2tcXFwifVwiLFwibWF0Y2hpbmdcIjpcIntcXFwiZmluZGVyVHlwZVxcXCI6XFxcIlBhZ2VCYWNrXFxcIn1cIn0iLCJtYXRjaGluZyI6IntcImZpbmRlclR5cGVcIjpcIkRlc2NlbmRhbnRcIixcImZpcnN0TWF0Y2hPbmx5XCI6XCJmYWxzZVwiLFwibWF0Y2hSb290XCI6XCJmYWxzZVwiLFwib2ZcIjpcIntcXFwiZmluZGVyVHlwZVxcXCI6XFxcIlBhZ2VCYWNrXFxcIn1cIixcIm1hdGNoaW5nXCI6XCJ7XFxcImZpbmRlclR5cGVcXFwiOlxcXCJQYWdlQmFja1xcXCJ9XCJ9In0`; const observed = find.descendant({ of: find.descendant({ of: find.pageBack(), matching: find.pageBack(), }), matching: find.descendant({ of: find.pageBack(), matching: find.pageBack(), }), }); expect(observed).toBe(expected); }); it(`text`, () => { const expected = find.byText(`This is 2nd route`); expect(expected).toBe( `eyJmaW5kZXJUeXBlIjoiQnlUZXh0IiwidGV4dCI6IlRoaXMgaXMgMm5kIHJvdXRlIn0`, ); }); it(`pageBack`, () => { const expected = find.pageBack(); expect(expected).toBe(`eyJmaW5kZXJUeXBlIjoiUGFnZUJhY2sifQ`); }); it(`bySemanticsLabel String`, () => { const expected = find.bySemanticsLabel(`simple`); expect(expected).toBe( `eyJmaW5kZXJUeXBlIjoiQnlTZW1hbnRpY3NMYWJlbCIsImlzUmVnRXhwIjpmYWxzZSwibGFiZWwiOiJzaW1wbGUifQ`, ); }); it(`bySemanticsLabel RegEx`, () => { const expected = find.bySemanticsLabel(/complicated/); expect(expected).toBe( `eyJmaW5kZXJUeXBlIjoiQnlTZW1hbnRpY3NMYWJlbCIsImlzUmVnRXhwIjp0cnVlLCJsYWJlbCI6ImNvbXBsaWNhdGVkIn0`, ); }); it(`byValueKey String`, () => { const expected = find.byValueKey(`42`); expect(expected).toBe( `eyJmaW5kZXJUeXBlIjoiQnlWYWx1ZUtleSIsImtleVZhbHVlU3RyaW5nIjoiNDIiLCJrZXlWYWx1ZVR5cGUiOiJTdHJpbmcifQ`, ); }); it(`byValueKey Int`, () => { const expected = find.byValueKey(42); expect(expected).toBe( `eyJmaW5kZXJUeXBlIjoiQnlWYWx1ZUtleSIsImtleVZhbHVlU3RyaW5nIjo0Miwia2V5VmFsdWVUeXBlIjoiaW50In0`, ); }); it(`byTooltip`, () => { const expected = find.byTooltip(`myText`); expect(expected).toBe( `eyJmaW5kZXJUeXBlIjoiQnlUb29sdGlwTWVzc2FnZSIsInRleHQiOiJteVRleHQifQ`, ); }); it(`byType`, () => { const expected = find.byType(`myText`); expect(expected).toBe( `eyJmaW5kZXJUeXBlIjoiQnlUeXBlIiwidHlwZSI6Im15VGV4dCJ9`, ); }); }); ================================================ FILE: finder/nodejs/package.json ================================================ { "name": "appium-flutter-finder", "description": "Finder for Appium Flutter driver", "keywords": [ "appium", "flutter" ], "version": "0.2.0", "author": "TruongSinh Tran-Nguyen ", "license": "MIT", "repository": { "type": "git", "url": "git+https://github.com/truongsinh/appium-flutter-driver.git" }, "main": "./build/serializer.js", "bin": {}, "directories": { "lib": "lib" }, "files": [ "build" ], "scripts": { "test": "mocha --require ts-node/register lib/**/*_test.ts", "prepublishOnly": "cp ../../LICENSE ./", "prepare": "npm run clean && npm run compile", "clean": "rm -rf build", "compile": "tsc", "lint": "tslint 'lib/**/*.ts'" }, "devDependencies": { "@appium/eslint-config-appium-ts": "^3.0.0", "@appium/tsconfig": "^1.0.0", "@types/expect": "^24.3.0", "@types/mocha": "10.0.10", "@types/node": "^25.0.2", "expect": "^30.0.0", "mocha": "^11.0.1", "ts-node": "^10.9.2", "tslint": "^6.1.3", "typescript": "^6.0.3" } } ================================================ FILE: finder/nodejs/tsconfig.json ================================================ { "$schema": "https://json.schemastore.org/tsconfig", "extends": "@appium/tsconfig/tsconfig.json", "compilerOptions": { "esModuleInterop": true, "rootDir": ".", "outDir": "build", "types": ["node", "mocha"], "checkJs": true }, "include": ["lib"] } ================================================ FILE: finder/nodejs/tslint.json ================================================ { "defaultSeverity": "error", "extends": [ "tslint:recommended" ], "jsRules": {}, "rules": { "quotemark": [true, "backtick"] }, "rulesDirectory": [] } ================================================ FILE: finder/python/.pylintrc ================================================ [MASTER] # A comma-separated list of package or module names from where C extensions may # be loaded. Extensions are loading into the active Python interpreter and may # run arbitrary code extension-pkg-whitelist= # Add files or directories to the blacklist. They should be base names, not # paths. ignore=CVS # Add files or directories matching the regex patterns to the blacklist. The # regex matches against base names, not paths. ignore-patterns= # Python code to execute, usually for sys.path manipulation such as # pygtk.require(). #init-hook= # Use multiple processes to speed up Pylint. jobs=1 # List of plugins (as comma separated values of python modules names) to load, # usually to register additional checkers. load-plugins= # Pickle collected data for later comparisons. persistent=yes # Specify a configuration file. #rcfile= # When enabled, pylint would attempt to guess common misconfiguration and emit # user-friendly hints instead of false-positive error messages suggestion-mode=yes # Allow loading of arbitrary C extensions. Extensions are imported into the # active Python interpreter and may run arbitrary code. unsafe-load-any-extension=no [MESSAGES CONTROL] # Only show warnings with the listed confidence levels. Leave empty to show # all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED confidence= # Disable the message, report, category or checker with the given id(s). You # can either give multiple identifiers separated by comma (,) or put this # option multiple times (only on the command line, not in the configuration # file where it should appear only once).You can also use "--disable=all" to # disable everything first and then reenable specific checks. For example, if # you want to run only the similarities checker, you can use "--disable=all # --enable=similarities". If you want to run only the classes checker, but have # no Warning level messages displayed, use"--disable=all --enable=classes # --disable=W" disable=raw-checker-failed, bad-inline-option, locally-disabled, file-ignored, suppressed-message, useless-suppression, deprecated-pragma, empty-docstring, missing-docstring, too-few-public-methods, invalid-name, duplicate-code, too-many-ancestors, broad-except, line-too-long, super-with-arguments, # TODO: remove when it drops python 2.7 useless-object-inheritance # TODO: remove when it drops python 2.7 # Enable the message, report, category or checker with the given id(s). You can # either give multiple identifier separated by comma (,) or put this option # multiple time (only on the command line, not in the configuration file where # it should appear only once). See also the "--disable" option for examples. enable=c-extension-no-member [REPORTS] # Python expression which should return a note less than 10 (10 is the highest # note). You have access to the variables errors warning, statement which # respectively contain the number of errors / warnings messages and the total # number of statements analyzed. This is used by the global evaluation report # (RP0004). evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) # Template used to display messages. This is a python new-style format string # used to format the message information. See doc for all details #msg-template= # Set the output format. Available formats are text, parseable, colorized, json # and msvs (visual studio).You can also give a reporter class, eg # mypackage.mymodule.MyReporterClass. output-format=text # Tells whether to display a full report or only the messages reports=no # Activate the evaluation score. score=yes [REFACTORING] # Maximum number of nested blocks for function / method body max-nested-blocks=5 # Complete name of functions that never returns. When checking for # inconsistent-return-statements if a never returning function is called then # it will be considered as an explicit return statement and no message will be # printed. never-returning-functions=optparse.Values,sys.exit [LOGGING] # Logging modules to check that the string format arguments are in logging # function parameter format logging-modules=logging [SPELLING] # Limits count of emitted suggestions for spelling mistakes max-spelling-suggestions=4 # Spelling dictionary name. Available dictionaries: none. To make it working # install python-enchant package. spelling-dict= # List of comma separated words that should not be checked. spelling-ignore-words= # A path to a file that contains private dictionary; one word per line. spelling-private-dict-file= # Tells whether to store unknown words to indicated private dictionary in # --spelling-private-dict-file option instead of raising a message. spelling-store-unknown-words=no [MISCELLANEOUS] # List of note tags to take in consideration, separated by a comma. notes=FIXME, XXX, TODO [SIMILARITIES] # Ignore comments when computing similarities. ignore-comments=yes # Ignore docstrings when computing similarities. ignore-docstrings=yes # Ignore imports when computing similarities. ignore-imports=no # Minimum lines number of a similarity. min-similarity-lines=4 [TYPECHECK] # List of decorators that produce context managers, such as # contextlib.contextmanager. Add to this list to register other decorators that # produce valid context managers. contextmanager-decorators=contextlib.contextmanager # List of members which are set dynamically and missed by pylint inference # system, and so shouldn't trigger E1101 when accessed. Python regular # expressions are accepted. generated-members= # Tells whether missing members accessed in mixin class should be ignored. A # mixin class is detected if its name ends with "mixin" (case insensitive). ignore-mixin-members=yes # This flag controls whether pylint should warn about no-member and similar # checks whenever an opaque object is returned when inferring. The inference # can return multiple potential results while evaluating a Python object, but # some branches might not be evaluated, which results in partial inference. In # that case, it might be useful to still emit no-member and other checks for # the rest of the inferred objects. ignore-on-opaque-inference=yes # List of class names for which member attributes should not be checked (useful # for classes with dynamically set attributes). This supports the use of # qualified names. ignored-classes=optparse.Values,thread._local,_thread._local # List of module names for which member attributes should not be checked # (useful for modules/projects where namespaces are manipulated during runtime # and thus existing member attributes cannot be deduced by static analysis. It # supports qualified module names, as well as Unix pattern matching. ignored-modules= # Show a hint with possible names when a member name was not found. The aspect # of finding the hint is based on edit distance. missing-member-hint=yes # The minimum edit distance a name should have in order to be considered a # similar match for a missing member name. missing-member-hint-distance=1 # The total number of similar names that should be taken in consideration when # showing a hint for a missing member. missing-member-max-choices=1 [VARIABLES] # List of additional names supposed to be defined in builtins. Remember that # you should avoid to define new builtins when possible. additional-builtins= # Tells whether unused global variables should be treated as a violation. allow-global-unused-variables=yes # List of strings which can identify a callback function by name. A callback # name must start or end with one of those strings. callbacks=cb_, _cb # A regular expression matching the name of dummy variables (i.e. expectedly # not used). dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_ # Argument names that match this expression will be ignored. Default to name # with leading underscore ignored-argument-names=_.*|^ignored_|^unused_ # Tells whether we should check for unused import in __init__ files. init-import=no # List of qualified module names which can have objects that can redefine # builtins. redefining-builtins-modules=six.moves,past.builtins,future.builtins,io,builtins [FORMAT] # Expected format of line ending, e.g. empty (any line ending), LF or CRLF. expected-line-ending-format= # Regexp for a line that is allowed to be longer than the limit. ignore-long-lines=^\s*(# )??$ # Number of spaces of indent required inside a hanging or continued line. indent-after-paren=4 # String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 # tab). indent-string=' ' # Maximum number of characters on a single line. max-line-length=128 # Maximum number of lines in a module max-module-lines=1000 # Allow the body of a class to be on the same line as the declaration if body # contains single statement. single-line-class-stmt=no # Allow the body of an if to be on the same line as the test if there is no # else. single-line-if-stmt=no [BASIC] # Naming style matching correct argument names argument-naming-style=snake_case # Regular expression matching correct argument names. Overrides argument- # naming-style #argument-rgx= # Naming style matching correct attribute names attr-naming-style=snake_case # Regular expression matching correct attribute names. Overrides attr-naming- # style #attr-rgx= # Bad variable names which should always be refused, separated by a comma bad-names=foo, bar, baz, toto, tutu, tata # Naming style matching correct class attribute names class-attribute-naming-style=any # Regular expression matching correct class attribute names. Overrides class- # attribute-naming-style #class-attribute-rgx= # Naming style matching correct class names class-naming-style=PascalCase # Regular expression matching correct class names. Overrides class-naming-style #class-rgx= # Naming style matching correct constant names const-naming-style=UPPER_CASE # Regular expression matching correct constant names. Overrides const-naming- # style #const-rgx= # Minimum line length for functions/classes that require docstrings, shorter # ones are exempt. docstring-min-length=-1 # Naming style matching correct function names function-naming-style=snake_case # Regular expression matching correct function names. Overrides function- # naming-style #function-rgx= # Good variable names which should always be accepted, separated by a comma good-names=i, j, k, ex, Run, _ # Include a hint for the correct naming format with invalid-name include-naming-hint=no # Naming style matching correct inline iteration names inlinevar-naming-style=any # Regular expression matching correct inline iteration names. Overrides # inlinevar-naming-style #inlinevar-rgx= # Naming style matching correct method names method-naming-style=snake_case # Regular expression matching correct method names. Overrides method-naming- # style #method-rgx= # Naming style matching correct module names module-naming-style=snake_case # Regular expression matching correct module names. Overrides module-naming- # style #module-rgx= # Colon-delimited sets of names that determine each other's naming style when # the name regexes allow several styles. name-group= # Regular expression which should only match function or class names that do # not require a docstring. no-docstring-rgx=^_ # List of decorators that produce properties, such as abc.abstractproperty. Add # to this list to register other decorators that produce valid properties. property-classes=abc.abstractproperty # Naming style matching correct variable names variable-naming-style=snake_case # Regular expression matching correct variable names. Overrides variable- # naming-style #variable-rgx= [DESIGN] # Maximum number of arguments for function / method max-args=6 # Maximum number of attributes for a class (see R0902). max-attributes=7 # Maximum number of boolean expressions in a if statement max-bool-expr=5 # Maximum number of branch for function / method body max-branches=12 # Maximum number of locals for function / method body max-locals=15 # Maximum number of parents for a class (see R0901). max-parents=7 # Maximum number of public methods for a class (see R0904). max-public-methods=20 # Maximum number of return / yield for function / method body max-returns=6 # Maximum number of statements in function / method body max-statements=50 # Minimum number of public methods for a class (see R0903). min-public-methods=2 [CLASSES] # List of method names used to declare (i.e. assign) instance attributes. defining-attr-methods=__init__, __new__, setUp # List of member names, which should be excluded from the protected access # warning. exclude-protected=_asdict, _fields, _replace, _source, _make # List of valid names for the first argument in a class method. valid-classmethod-first-arg=cls # List of valid names for the first argument in a metaclass class method. valid-metaclass-classmethod-first-arg=mcs [IMPORTS] # Allow wildcard imports from modules that define __all__. allow-wildcard-with-all=no # Analyse import fallback blocks. This can be used to support both Python 2 and # 3 compatible code, which means that the block might have code that exists # only in one or another interpreter, leading to false positives when analysed. analyse-fallback-blocks=yes # Deprecated modules which should not be used, separated by a comma deprecated-modules=regsub, TERMIOS, Bastion, rexec # Create a graph of external dependencies in the given file (report RP0402 must # not be disabled) ext-import-graph= # Create a graph of every (i.e. internal and external) dependencies in the # given file (report RP0402 must not be disabled) import-graph= # Create a graph of internal dependencies in the given file (report RP0402 must # not be disabled) int-import-graph= # Force import order to recognize a module as part of the standard # compatibility libraries. known-standard-library= # Force import order to recognize a module as part of a third party library. known-third-party=enchant [EXCEPTIONS] # Exceptions that will emit a warning when being caught. Defaults to # "Exception" overgeneral-exceptions=builtins.Exception ================================================ FILE: finder/python/README.md ================================================ # Getting the Appium Flutter Finder There are three ways to install and use the Appium Flutter Finder. Supported Python version follows appium python client. 1. Install from [PyPi](https://pypi.org), as ['Appium-Flutter-Finder'](https://pypi.org/project/Appium-Flutter-Finder/). ```shell pip install Appium-Flutter-Finder ``` 2. Install from source, via [PyPi](https://pypi.org). From ['Appium-Flutter-Finder'](https://pypi.org/project/Appium-Flutter-Finder/), download and unarchive the source tarball (Appium-Flutter-Finder-X.X.tar.gz). ```shell tar -xvf Appium-Flutter-Finder-X.X.tar.gz cd Appium-Flutter-Finder-X.X python setup.py install ``` 3. Install from source via [GitHub](https://github.com/appium/python-client). ```shell git clone git@github.com:appium/python-client.git cd python-client python setup.py install ``` # How to use Examples can be found out [here](../../example/python/example.py). # Release ``` pip install twine ``` ``` python setup.py sdist twine upload dist/Appium-Flutter-Finder-X.X.tar.gz ``` # Changelog - 0.8.0 - Update the limit of python appium client version - 0.7.0 - Update the limit of python appium client version - 0.6.1 - Fix package - 0.6.0 - Fix type of `match_root` and `first_match_only` in `by_ancestor` and `by_descendant - 0.5.0 - Allow Appium-Python-Client to be v3 - 0.4.0 - Bump base Appium-Python-Client to v2 - 0.3.1 - Use Appium-Python-Client 1.x - 0.3.0 - Add `first_match_only` option in `by_ancestor` and `by_descendant` - 0.2.0 - Support over Python 3.6 - 0.1.5 - Fix `by_ancestor` and `by_descendant` - https://github.com/truongsinh/appium-flutter-driver/pull/165#issuecomment-877928553 - 0.1.4 - Remove whitespaces from the decoded JSON - Fix `by_ancestor` and `by_descendant` - 0.1.3 - Allow `from appium_flutter_finder import FlutterElement, FlutterFinder` - 0.1.2 - Fix b64encode error in Python 3 - 0.1.1 - Initial release ================================================ FILE: finder/python/appium_flutter_finder/__init__.py ================================================ from .flutter_finder import FlutterElement, FlutterFinder ================================================ FILE: finder/python/appium_flutter_finder/flutter_finder.py ================================================ import base64 import json from appium.webdriver.webelement import WebElement class FlutterElement(WebElement): pass class FlutterFinder: def by_ancestor(self, serialized_finder, matching, match_root=False, first_match_only=False): return self._by_ancestor_or_descendant( type_='Ancestor', serialized_finder=serialized_finder, matching=matching, match_root=match_root, first_match_only=first_match_only ) def by_descendant(self, serialized_finder, matching, match_root=False, first_match_only=False): return self._by_ancestor_or_descendant( type_='Descendant', serialized_finder=serialized_finder, matching=matching, match_root=match_root, first_match_only=first_match_only ) def by_semantics_label(self, label, isRegExp=False): return self._serialize({ 'finderType': 'BySemanticsLabel', 'isRegExp': isRegExp, 'label': label }) def by_tooltip(self, text): return self._serialize({ 'finderType': 'ByTooltipMessage', 'text': text }) def by_text(self, text): return self._serialize({ 'finderType': 'ByText', 'text': text }) def by_type(self, type_): return self._serialize({ 'finderType': 'ByType', 'type': type_ }) def by_value_key(self, key): return self._serialize({ 'finderType': 'ByValueKey', 'keyValueString': key, 'keyValueType': 'String' if isinstance(key, str) else 'int' }) def page_back(self): return self._serialize({ 'finderType': 'PageBack' }) def _serialize(self, finder_dict): # type: (dict) -> str return base64.b64encode( bytes(json.dumps(finder_dict, separators=(',', ':')), 'UTF-8')).decode('UTF-8') def _by_ancestor_or_descendant(self, type_, serialized_finder, matching, match_root=False, first_match_only=False): # pylint: disable=too-many-positional-arguments param = {'finderType': type_, 'matchRoot': str(match_root).lower(), 'firstMatchOnly': str(first_match_only).lower()} try: finder = json.loads(base64.b64decode( serialized_finder).decode('utf-8')) except Exception: finder = {} param.setdefault('of', {}) for finder_key, finder_value in finder.items(): param['of'].setdefault(finder_key, finder_value) param['of'] = json.dumps(param['of'], separators=(',', ':')) try: matching = json.loads(base64.b64decode(matching).decode('utf-8')) except Exception: matching = {} param.setdefault('matching', {}) for matching_key, matching_value in matching.items(): param['matching'].setdefault(matching_key, matching_value) param['matching'] = json.dumps(param['matching'], separators=(',', ':')) return self._serialize(param) ================================================ FILE: finder/python/setup.py ================================================ #!/usr/bin/env python import io import os from setuptools import find_packages, setup setup( name='Appium-Flutter-Finder', version='0.8.0', description='An extension of finder for Appium flutter', long_description=io.open(os.path.join(os.path.dirname('__file__'), 'README.md'), encoding='utf-8').read(), long_description_content_type='text/markdown', keywords=[ 'appium', 'flutter', 'python client', 'mobile automation' ], author='Kazuaki Matsuo', author_email='fly.49.89.over@gmail.com', url='https://github.com/appium/appium-flutter-driver', packages=find_packages(include=['appium_flutter_finder*']), license='MIT', classifiers=[ 'Development Status :: 5 - Production/Stable', 'Programming Language :: Python', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', 'Environment :: Console', 'Environment :: MacOS X', 'Environment :: Win32 (MS Windows)', 'Intended Audience :: Developers', 'Intended Audience :: Other Audience', 'License :: OSI Approved :: MIT License', 'Operating System :: OS Independent', 'Topic :: Software Development :: Quality Assurance', 'Topic :: Software Development :: Testing' ], install_requires=['Appium-Python-Client >= 2.0.0, < 6'] ) ================================================ FILE: finder/python/tests/__init__.py ================================================ ================================================ FILE: finder/python/tests/flutter_finder_tests.py ================================================ import unittest import appium_flutter_finder.flutter_finder as finder class FlutterFinderTest(unittest.TestCase): def test_by_ancestor(self): assert finder.FlutterFinder().by_ancestor( finder.FlutterFinder().by_ancestor( finder.FlutterFinder().page_back(), finder.FlutterFinder().page_back() ), finder.FlutterFinder().by_ancestor( finder.FlutterFinder().page_back(), finder.FlutterFinder().page_back() ), first_match_only=True ) == ( 'eyJmaW5kZXJUeXBlIjoiQW5jZXN0b3IiLCJtYXRjaFJvb3QiOiJmYWxzZSIsImZpcnN0TWF0Y2hPbmx5IjoidHJ1ZSIsIm9mIjoie1wiZmluZGVyVHlwZVwiOlwiQW5jZXN0b3JcIixcIm1hdGNoUm9vdFwiOlwiZmFsc2VcIixcImZpcnN0TWF0Y2hPbmx5XCI6XCJmYWxzZVwiLFwib2ZcIjpcIntcXFwiZmluZGVyVHlwZVxcXCI6XFxcIlBhZ2VCYWNrXFxcIn1cIixcIm1hdGNoaW5nXCI6XCJ7XFxcImZpbmRlclR5cGVcXFwiOlxcXCJQYWdlQmFja1xcXCJ9XCJ9IiwibWF0Y2hpbmciOiJ7XCJmaW5kZXJUeXBlXCI6XCJBbmNlc3RvclwiLFwibWF0Y2hSb290XCI6XCJmYWxzZVwiLFwiZmlyc3RNYXRjaE9ubHlcIjpcImZhbHNlXCIsXCJvZlwiOlwie1xcXCJmaW5kZXJUeXBlXFxcIjpcXFwiUGFnZUJhY2tcXFwifVwiLFwibWF0Y2hpbmdcIjpcIntcXFwiZmluZGVyVHlwZVxcXCI6XFxcIlBhZ2VCYWNrXFxcIn1cIn0ifQ==' ) def test_by_descendant(self): assert finder.FlutterFinder().by_descendant( finder.FlutterFinder().by_descendant( finder.FlutterFinder().page_back(), finder.FlutterFinder().page_back() ), finder.FlutterFinder().by_descendant( finder.FlutterFinder().page_back(), finder.FlutterFinder().page_back() ) ) == ( 'eyJmaW5kZXJUeXBlIjoiRGVzY2VuZGFudCIsIm1hdGNoUm9vdCI6ImZhbHNlIiwiZmlyc3RNYXRjaE9ubHkiOiJmYWxzZSIsIm9mIjoie1wiZmluZGVyVHlwZVwiOlwiRGVzY2VuZGFudFwiLFwibWF0Y2hSb290XCI6XCJmYWxzZVwiLFwiZmlyc3RNYXRjaE9ubHlcIjpcImZhbHNlXCIsXCJvZlwiOlwie1xcXCJmaW5kZXJUeXBlXFxcIjpcXFwiUGFnZUJhY2tcXFwifVwiLFwibWF0Y2hpbmdcIjpcIntcXFwiZmluZGVyVHlwZVxcXCI6XFxcIlBhZ2VCYWNrXFxcIn1cIn0iLCJtYXRjaGluZyI6IntcImZpbmRlclR5cGVcIjpcIkRlc2NlbmRhbnRcIixcIm1hdGNoUm9vdFwiOlwiZmFsc2VcIixcImZpcnN0TWF0Y2hPbmx5XCI6XCJmYWxzZVwiLFwib2ZcIjpcIntcXFwiZmluZGVyVHlwZVxcXCI6XFxcIlBhZ2VCYWNrXFxcIn1cIixcIm1hdGNoaW5nXCI6XCJ7XFxcImZpbmRlclR5cGVcXFwiOlxcXCJQYWdlQmFja1xcXCJ9XCJ9In0=' ) def test_by_semantics_label(self): assert finder.FlutterFinder().by_semantics_label('simple') == \ 'eyJmaW5kZXJUeXBlIjoiQnlTZW1hbnRpY3NMYWJlbCIsImlzUmVnRXhwIjpmYWxzZSwibGFiZWwiOiJzaW1wbGUifQ==' def test_by_semantics_label_regex(self): assert finder.FlutterFinder().by_semantics_label(r'complicated', isRegExp=True) == \ 'eyJmaW5kZXJUeXBlIjoiQnlTZW1hbnRpY3NMYWJlbCIsImlzUmVnRXhwIjp0cnVlLCJsYWJlbCI6ImNvbXBsaWNhdGVkIn0=' def test_by_tooltip(self): assert finder.FlutterFinder().by_tooltip('myText') == \ 'eyJmaW5kZXJUeXBlIjoiQnlUb29sdGlwTWVzc2FnZSIsInRleHQiOiJteVRleHQifQ==' def test_by_type(self): assert finder.FlutterFinder().by_type('myText') == \ 'eyJmaW5kZXJUeXBlIjoiQnlUeXBlIiwidHlwZSI6Im15VGV4dCJ9' def test_by_key_value_int(self): assert finder.FlutterFinder().by_value_key(42) == \ 'eyJmaW5kZXJUeXBlIjoiQnlWYWx1ZUtleSIsImtleVZhbHVlU3RyaW5nIjo0Miwia2V5VmFsdWVUeXBlIjoiaW50In0=' def test_by_key_value_string(self): assert finder.FlutterFinder().by_value_key('42') == \ 'eyJmaW5kZXJUeXBlIjoiQnlWYWx1ZUtleSIsImtleVZhbHVlU3RyaW5nIjoiNDIiLCJrZXlWYWx1ZVR5cGUiOiJTdHJpbmcifQ==' def test_page_back(self): assert finder.FlutterFinder().page_back() == \ 'eyJmaW5kZXJUeXBlIjoiUGFnZUJhY2sifQ==' def test_by_text(self): assert finder.FlutterFinder().by_text('This is 2nd route') == \ 'eyJmaW5kZXJUeXBlIjoiQnlUZXh0IiwidGV4dCI6IlRoaXMgaXMgMm5kIHJvdXRlIn0=' ================================================ FILE: finder/ruby/Gemfile ================================================ source 'https://rubygems.org' gemspec gem 'minitest', '~> 5.0' gem 'rake', '~> 13.0' ================================================ FILE: finder/ruby/README.md ================================================ # AppiumFlutterFinder Ruby finder elements for https://github.com/appium/appium-flutter-driver ## Installation Add this line to your application's Gemfile: ```ruby gem 'appium_flutter_finder' ``` And then execute: $ bundle Or install it yourself as: $ gem install appium_flutter_finder ## Usage ```ruby include Appium::Flutter::Finder @driver = ::Appium::Core.for(caps).start_driver # Send a request to an element element = Appium::Flutter::Element.new( @driver, finder: by_text('You have pushed the button this many times:') ) assert element.text == 'You have pushed the button this many times:' # Get render tree by Flutter @driver.execute_script 'flutter:getRenderTree', {} ``` ## Development After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org). ## Changelog - 0.8.0 - Bump the supported Ruby version to 3.1+ by following core - 0.7.1 - Update the upper limit of ruby_lib_core - 0.7.0 - Update the upper limit of ruby_lib_core - 0.6.0 - Fix type of `match_root` and `first_match_only` in `by_ancestor` and `by_descendant` - 0.5.0 - Support appium_lib_core version to v7 as well. The appium_lib_core requires Ruby v3. - 0.4.2 - Relax the dependency version restriction - 0.4.1 - Add `attr_reader` for `Appium::Flutter::Element#id` - 0.4.0 - Bump appium_lib_core version to v5+ - 0.3, 0.3.1 - Add `first_match_only` option in `by_ancestor` and `by_descendant` - 0.2.1 - Fix `by_ancestor` and `by_descendant` - https://github.com/truongsinh/appium-flutter-driver/pull/165#issuecomment-877928553 - 0.2.0 - Bump ruby_lib_core version to 4+ ## Contributing Bug reports and pull requests are welcome on GitHub at https://github.com/truongsinh/appium-flutter-driver/tree/main/finder/ruby . ================================================ FILE: finder/ruby/Rakefile ================================================ require 'bundler/gem_tasks' require 'rake/testtask' Rake::TestTask.new(:test) do |t| t.libs << 'test' t.libs << 'lib' t.test_files = FileList['test/**/*_test.rb'] end task default: :test ================================================ FILE: finder/ruby/appium_flutter_finder.gemspec ================================================ lib = File.expand_path('lib', __dir__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'appium_flutter_finder/version' Gem::Specification.new do |spec| spec.required_ruby_version = Gem::Requirement.new('>= 3.1') spec.name = 'appium_flutter_finder' spec.version = Appium::Flutter::Finder::VERSION spec.authors = ['Kazuaki Matsuo'] spec.email = ['fly.49.89.over@gmail.com'] spec.summary = 'Finder for appium-flutter-driver' spec.description = 'Finder for appium-flutter-driver' spec.homepage = 'https://github.com/truongsinh/appium-flutter-driver' # Specify which files should be added to the gem when it is released. # The `git ls-files -z` loads the files in the RubyGem that have been added into git. spec.files = Dir.chdir(File.expand_path(__dir__)) do `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } end spec.bindir = 'exe' spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } spec.require_paths = ['lib'] spec.add_dependency 'appium_lib_core', '>= 5' end ================================================ FILE: finder/ruby/lib/appium_flutter_finder/version.rb ================================================ module Appium module Flutter module Finder VERSION = '0.8.0'.freeze end end end ================================================ FILE: finder/ruby/lib/appium_flutter_finder.rb ================================================ require 'json' require 'base64' require 'appium_lib_core' require 'appium_flutter_finder/version' module Appium module Flutter # Handles flutter elements as Appium Elements class Element < ::Selenium::WebDriver::Element attr_reader :id def initialize(driver, finder:) @bridge = driver.bridge @id = finder end end # Get find element context for flutter driver module Finder def by_ancestor(serialized_finder:, matching:, match_root: false, first_match_only: false) by_ancestor_or_descendant( type: 'Ancestor', serialized_finder: serialized_finder, matching: matching, match_root: match_root, first_match_only: first_match_only ) end def by_descendant(serialized_finder:, matching:, match_root: false, first_match_only: false) by_ancestor_or_descendant( type: 'Descendant', serialized_finder: serialized_finder, matching: matching, match_root: match_root, first_match_only: first_match_only ) end def by_semantics_label(label) serialize( finderType: 'BySemanticsLabel', isRegExp: label.is_a?(Regexp), # Should be '/a/' as String in regex case label: label.is_a?(Regexp) ? label.source : label ) end def by_tooltip(text) serialize( finderType: 'ByTooltipMessage', text: text ) end def by_type(type) serialize( finderType: 'ByType', type: type ) end def by_value_key(key) serialize( finderType: 'ByValueKey', keyValueString: key, keyValueType: key.is_a?(String) ? 'String' : 'int' ) end def page_back serialize( finderType: 'PageBack' ) end def by_text(text) serialize( finderType: 'ByText', text: text ) end private def serialize(hash) Base64.strict_encode64(hash.to_json) end def by_ancestor_or_descendant(type:, serialized_finder:, matching:, match_root: false, first_match_only: false) param = { finderType: type, matchRoot: match_root.to_s, firstMatchOnly: first_match_only.to_s} finder = begin JSON.parse(Base64.decode64(serialized_finder)) rescue JSONError {} end of_param = {} finder.each_key do |key| of_param[key] = finder[key] end param['of'] = of_param.to_json matching = begin JSON.parse(Base64.decode64(matching)) rescue JSONError {} end matching_param = {} matching.each_key do |key| matching_param[key] = matching[key] end param['matching'] = matching_param.to_json serialize param end end end end ================================================ FILE: finder/ruby/test/appium_flutter_finder_test.rb ================================================ require 'test_helper' require_relative '../lib/appium_flutter_finder' class AppiumFlutterFinderTest < Minitest::Test include Appium::Flutter::Finder def test_by_ancestor assert_equal( 'eyJmaW5kZXJUeXBlIjoiQW5jZXN0b3IiLCJtYXRjaFJvb3QiOiJmYWxzZSIsImZpcnN0TWF0Y2hPbmx5IjoidHJ1ZSIsIm9mIjoie1wiZmluZGVyVHlwZVwiOlwiQW5jZXN0b3JcIixcIm1hdGNoUm9vdFwiOlwiZmFsc2VcIixcImZpcnN0TWF0Y2hPbmx5XCI6XCJmYWxzZVwiLFwib2ZcIjpcIntcXFwiZmluZGVyVHlwZVxcXCI6XFxcIlBhZ2VCYWNrXFxcIn1cIixcIm1hdGNoaW5nXCI6XCJ7XFxcImZpbmRlclR5cGVcXFwiOlxcXCJQYWdlQmFja1xcXCJ9XCJ9IiwibWF0Y2hpbmciOiJ7XCJmaW5kZXJUeXBlXCI6XCJBbmNlc3RvclwiLFwibWF0Y2hSb290XCI6XCJmYWxzZVwiLFwiZmlyc3RNYXRjaE9ubHlcIjpcImZhbHNlXCIsXCJvZlwiOlwie1xcXCJmaW5kZXJUeXBlXFxcIjpcXFwiUGFnZUJhY2tcXFwifVwiLFwibWF0Y2hpbmdcIjpcIntcXFwiZmluZGVyVHlwZVxcXCI6XFxcIlBhZ2VCYWNrXFxcIn1cIn0ifQ==', by_ancestor( serialized_finder: by_ancestor( serialized_finder: page_back, matching: page_back ), matching: by_ancestor( serialized_finder: page_back, matching: page_back ), first_match_only: true ) ) end def test_by_descendant assert_equal( 'eyJmaW5kZXJUeXBlIjoiRGVzY2VuZGFudCIsIm1hdGNoUm9vdCI6ImZhbHNlIiwiZmlyc3RNYXRjaE9ubHkiOiJmYWxzZSIsIm9mIjoie1wiZmluZGVyVHlwZVwiOlwiRGVzY2VuZGFudFwiLFwibWF0Y2hSb290XCI6XCJmYWxzZVwiLFwiZmlyc3RNYXRjaE9ubHlcIjpcImZhbHNlXCIsXCJvZlwiOlwie1xcXCJmaW5kZXJUeXBlXFxcIjpcXFwiUGFnZUJhY2tcXFwifVwiLFwibWF0Y2hpbmdcIjpcIntcXFwiZmluZGVyVHlwZVxcXCI6XFxcIlBhZ2VCYWNrXFxcIn1cIn0iLCJtYXRjaGluZyI6IntcImZpbmRlclR5cGVcIjpcIkRlc2NlbmRhbnRcIixcIm1hdGNoUm9vdFwiOlwiZmFsc2VcIixcImZpcnN0TWF0Y2hPbmx5XCI6XCJmYWxzZVwiLFwib2ZcIjpcIntcXFwiZmluZGVyVHlwZVxcXCI6XFxcIlBhZ2VCYWNrXFxcIn1cIixcIm1hdGNoaW5nXCI6XCJ7XFxcImZpbmRlclR5cGVcXFwiOlxcXCJQYWdlQmFja1xcXCJ9XCJ9In0=', by_descendant( serialized_finder: by_descendant( serialized_finder: page_back, matching: page_back ), matching: by_descendant( serialized_finder: page_back, matching: page_back ) ) ) end def test_by_semantics_label assert_equal( 'eyJmaW5kZXJUeXBlIjoiQnlTZW1hbnRpY3NMYWJlbCIsImlzUmVnRXhwIjpmYWxzZSwibGFiZWwiOiJzaW1wbGUifQ==', by_semantics_label('simple') ) end def test_by_semantics_label_regex assert_equal( 'eyJmaW5kZXJUeXBlIjoiQnlTZW1hbnRpY3NMYWJlbCIsImlzUmVnRXhwIjp0cnVlLCJsYWJlbCI6ImNvbXBsaWNhdGVkIn0=', by_semantics_label(/complicated/) ) end def test_by_tooltip assert_equal( 'eyJmaW5kZXJUeXBlIjoiQnlUb29sdGlwTWVzc2FnZSIsInRleHQiOiJteVRleHQifQ==', by_tooltip('myText') ) end def test_by_type assert_equal( 'eyJmaW5kZXJUeXBlIjoiQnlUeXBlIiwidHlwZSI6Im15VGV4dCJ9', by_type('myText') ) end def test_by_key_value_int assert_equal( 'eyJmaW5kZXJUeXBlIjoiQnlWYWx1ZUtleSIsImtleVZhbHVlU3RyaW5nIjo0Miwia2V5VmFsdWVUeXBlIjoiaW50In0=', by_value_key(42) ) end def test_by_key_value_string assert_equal( 'eyJmaW5kZXJUeXBlIjoiQnlWYWx1ZUtleSIsImtleVZhbHVlU3RyaW5nIjoiNDIiLCJrZXlWYWx1ZVR5cGUiOiJTdHJpbmcifQ==', by_value_key('42') ) end def test_page_back assert_equal 'eyJmaW5kZXJUeXBlIjoiUGFnZUJhY2sifQ==', page_back end def test_by_text assert_equal( 'eyJmaW5kZXJUeXBlIjoiQnlUZXh0IiwidGV4dCI6IlRoaXMgaXMgMm5kIHJvdXRlIn0=', by_text('This is 2nd route') ) end end ================================================ FILE: finder/ruby/test/test_helper.rb ================================================ $LOAD_PATH.unshift File.expand_path('../lib', __dir__) require 'appium_flutter_finder' require 'minitest/autorun' ================================================ FILE: finder/spec.json ================================================ { "ancestor": "eyJmaW5kZXJUeXBlIjoiQW5jZXN0b3IiLCJtYXRjaFJvb3QiOmZhbHNlLCJvZl9maW5kZXJUeXBlIjoiQnlTZW1hbnRpY3NMYWJlbCIsIm9mX2lzUmVnRXhwIjp0cnVlLCJvZl9sYWJlbCI6ImNvdW50ZXJfc2VtYW50aWMiLCJtYXRjaGluZ19maW5kZXJUeXBlIjoiQnlUeXBlIiwibWF0Y2hpbmdfdHlwZSI6IlRvb2x0aXAifQ" } ================================================ FILE: jitpack.yml ================================================ jdk: - openjdk11 install: - cd finder/kotlin - ./gradlew publishToMavenLocal