diff --git a/.browserslistrc b/.browserslistrc index 0066735a..093c144b 100644 --- a/.browserslistrc +++ b/.browserslistrc @@ -1,15 +1,18 @@ # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. + # For additional information regarding the format and rule options, please see: + # https://github.com/browserslist/browserslist#queries # For the full list of supported browsers by the Angular framework, please see: + # https://angular.io/guide/browser-support # You can see what browsers were selected by your queries by running: -# npx browserslist -> 0.5% -last 2 versions -Firefox ESR +# npx browserslist + +last 2 ChromeAndroid versions +last 2 iOS versions +last 2 Samsung versions not dead -not IE 9-11 # For IE 9-11 support, remove 'not'. \ No newline at end of file diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 1c24f127..00000000 --- a/.eslintignore +++ /dev/null @@ -1,4 +0,0 @@ -node_modules -dist -.angular -src/zone-flags.ts \ No newline at end of file diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index 91b976e0..00000000 --- a/.eslintrc +++ /dev/null @@ -1,29 +0,0 @@ -{ - "root": true, - "parser": "@typescript-eslint/parser", - "parserOptions": { - "project": "./tsconfig.json" - }, - "plugins": [ - "@typescript-eslint" - ], - "extends": [ - "eslint:recommended", - "plugin:@typescript-eslint/eslint-recommended", - "plugin:@typescript-eslint/recommended" - ], - "rules": { - "@typescript-eslint/await-thenable": "error", - "require-await": "off", - "@typescript-eslint/require-await": "error", - "@typescript-eslint/no-misused-promises": [ - "error", - { - "checksVoidReturn": false - } - ], - "no-shadow": "off", - "@typescript-eslint/no-shadow": "error" - // "@typescript-eslint/no-floating-promises": "error" - } -} diff --git a/.github/assets/android.png b/.github/assets/android.png new file mode 100644 index 00000000..9e3ad085 Binary files /dev/null and b/.github/assets/android.png differ diff --git a/.github/assets/ios.png b/.github/assets/ios.png new file mode 100644 index 00000000..25e8db4b Binary files /dev/null and b/.github/assets/ios.png differ diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index a956c340..3533509b 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -14,9 +14,8 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node-version: [16.x] + node-version: [22.x] steps: - - name: Check out code uses: actions/checkout@v3 @@ -24,15 +23,45 @@ jobs: uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} - - - name: Dependency install + cache: 'npm' # Enables automatic npm caching + + - name: Restore npm Cache + uses: actions/cache@v3 + with: + path: ~/.npm + key: npm-${{ runner.os }}-${{ hashFiles('package-lock.json') }} + restore-keys: | + npm-${{ runner.os }}- + + - name: Install Dependencies run: | - npm install @ionic/cli@6.20.4 native-run@1.3.0 - npm install - + npm ci + npm install @ionic/cli@6.20.4 native-run@1.3.0 + + - name: Cache Build Artifacts (optional) + uses: actions/cache@v3 + with: + path: | + storage-mirror/node_modules + node_modules + key: build-${{ runner.os }}-${{ hashFiles('package-lock.json') }} + restore-keys: | + build-${{ runner.os }}- + + - name: Build Storage Mirror + run: | + cd storage-mirror + npm ci + npm run build + + - name: Copy environment.ts to environment.prod.ts + run: | + cp src/environments/environment.ts src/environments/environment.prod.ts + - name: Build run: | - ./node_modules/@ionic/cli/bin/ionic build --prod --release - - #- name: Test - # run: ./node_modules/@angular/cli/bin/ng test + npx ionic build --prod --release + + - name: Run Vitest + run: | + npx vitest --coverage --run diff --git a/.github/workflows/lint-format.yml b/.github/workflows/lint-format.yml index 2354d478..cc8f0e04 100644 --- a/.github/workflows/lint-format.yml +++ b/.github/workflows/lint-format.yml @@ -13,15 +13,28 @@ jobs: name: lint-format runs-on: ubuntu-latest steps: - - name: Checkout Repository - uses: actions/checkout@v3 - - name: Setup Node Environment - uses: actions/setup-node@v3 - with: - node-version: 16 - - name: Install Dependencies - run: npm ci - - name: Check File Format - run: npm run prettier-check - - name: Lint Files - run: npm run lint \ No newline at end of file + - name: Checkout Repository + uses: actions/checkout@v3 + + - name: Setup Node Environment + uses: actions/setup-node@v3 + with: + node-version: 22 + cache: 'npm' # Enables caching for npm dependencies + + - name: Restore npm Cache + uses: actions/cache@v3 + with: + path: ~/.npm + key: npm-${{ runner.os }}-${{ hashFiles('package-lock.json') }} + restore-keys: | + npm-${{ runner.os }}- + + - name: Install Dependencies + run: npm ci + + - name: Check File Format + run: npm run prettier-check + + - name: Lint Files + run: npm run lint diff --git a/.gitignore b/.gitignore index 92f09c2c..4be897ad 100644 --- a/.gitignore +++ b/.gitignore @@ -13,11 +13,14 @@ Thumbs.db UserInterfaceState.xcuserstate $RECYCLE.BIN/ .angular +.env +bundle*.zip *.log log.txt npm-debug.log* +/tmp /.idea /.ionic /.sass-cache @@ -30,10 +33,15 @@ npm-debug.log* /platforms /plugins /www +/www-sourcemap /android/app/src/prod/google-services.json /android/app/src/beta/google-services.json /ios/App/GoogleService-Info.plist /appassets +/local_env/server.* /android/.idea android/.idea/jarRepositories.xml android/.idea/misc.xml +/src/environments/environment.prod.ts +ios/GoogleService-Info.plist +test/user-auth/auth.js diff --git a/.npmrc b/.npmrc new file mode 100644 index 00000000..98237db5 --- /dev/null +++ b/.npmrc @@ -0,0 +1,2 @@ +# @analogjs/platform and nx require vite 5 but we use vite 6 +legacy-peer-deps=true \ No newline at end of file diff --git a/README.md b/README.md index 8b005fbe..21876a84 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,12 @@ ![[beaconchain Dashboard](https://beaconcha.in/mobile)](.github/banner.png) -[![Build](https://github.com/gobitfly/eth2-beaconchain-explorer-app/actions/workflows/build.yaml/badge.svg)](https://github.com/gobitfly/eth2-beaconchain-explorer-app/actions/workflows/build.yaml) +[![Build](https://github.com/gobitfly/eth2-beaconchain-explorer-app/actions/workflows/build.yaml/badge.svg)](https://github.com/gobitfly/eth2-beaconchain-explorer-app/actions/workflows/build.yaml) # Beaconchain Dashboard App -Beaconchain Dashboard is an open source ethereum and gnosis validator performance tracker app for Android and iOS. It utilizes the beaconcha.in API. +Beaconchain Dashboard is an open source ethereum and gnosis validator performance tracker app for Android and iOS. It utilizes the beaconcha.in API. - -[![Get it on Google Play](https://beaconcha.in/img/android.png)](https://play.google.com/store/apps/details?id=in.beaconcha.mobile) -[![Get it App Store](https://beaconcha.in/img/ios.png)](https://apps.apple.com/app/beaconchain-dashboard/id1541822121) +[![Get it on Google Play](.github/assets/android.png)](https://play.google.com/store/apps/details?id=in.beaconcha.mobile) +[![Get it App Store](.github/assets/ios.png)](https://apps.apple.com/app/beaconchain-dashboard/id1541822121) ## About @@ -16,19 +15,19 @@ Beaconchain Dashboard is an Angular app written in Typescript, HTML & CSS. It ut ## Features - Ethereum and Gnosis supported -- Keep track on your validators online status, balances, returns and more -- Various notification alerts for your validators +- Keep track on your validators online status, balances, returns and more +- Various notification alerts for your validators - Execution block rewards overview - Machine monitoring (CPU usage, network usage and more) -- Rocketpool support +- Rocket Pool support - Customize stake share if you only partially own a validator -- Combined dashboard view -- Support for up to 280 validators -- Ethereum client update notifications -- Network warnings -- Support for multiple currencies -- Mainnet & Testnet support -- Light Theme & Dark Theme +- Combined dashboard view +- Support for up to 280 validators +- Ethereum client update notifications +- Network warnings +- Support for multiple currencies +- Mainnet & Testnet support +- Light Theme & Dark Theme ## Device support @@ -36,30 +35,46 @@ Beaconchain Dashboard is an Angular app written in Typescript, HTML & CSS. It ut - iOS 13 or newer ## Development + +### Prerequisites + +You will need the following installed on your system for local development: + +1. **Docker** (for Docker Compose) +2. **OpenSSL** (to generate SSL certificates for local testing) +3. **NodeJS 22** + ### Getting started 1. Clone repo 2. Install dependencies + ``` npm install -g @ionic/cli native-run cordova-res +cd storage-mirror +npm i +cd .. npm i +npm run generate-cert ``` - -NOTE: You need to provide your own google-services.json for Android and GoogleService-Info.plist for iOS. + +NOTE: You need to provide your own google-services.json for Android and GoogleService-Info.plist for iOS. ### Browser + To run the app in your browser, simply use -`npm run-script serve` +`npm run dev` to start a local webserver with livereload enabled. ### Android **Prerequisites** -* NodeJS 16 -* Install [Android Studio](https://developer.android.com/studio#downloads]) (2022.2.1 or newer) -* Use Android Studio to install the Android SDK: https://capacitorjs.com/docs/android + +- NodeJS 22 +- Install [Android Studio](https://developer.android.com/studio#downloads]) (2022.2.1 or newer) +- Use Android Studio to install the Android SDK: https://capacitorjs.com/docs/android For Linux Users: Open capacitor.config.json (in the root of the project) and adapt the paths for the _linuxAndroidStudioPath_ variable to reflect your local setup. @@ -73,23 +88,25 @@ Make sure port 8100 is accessible on your computer and use the following command `ionic cap run android --livereload --external --host=192.168.1.64 --disableHostCheck --configuration=development` -Adapt the --host param to match your computers IP. +Adapt the --host param to match your computers IP. #### Build for production -`npm run-script build-android-for-production` +`npm run build-android` #### Install via Android Studio + To install the app on a real device, follow this guide: https://developer.android.com/studio/run/device Or to run it in an emulator, follow up here: https://developer.android.com/studio/run/emulator - ### iOS + **Prerequisites** -* NodeJS 16 -* macOS with macOS Monterey 12.5 newer -* Xcode 14.1 or newer + +- NodeJS 22 +- macOS with macOS Monterey 12.5 newer +- Xcode 14.1 or newer Build the the app at least once before proceeding: @@ -101,17 +118,17 @@ Make sure port 8100 is accessible on your mac and use the following command to r `ionic cap run ios --livereload --external --host=192.168.1.64 --disableHostCheck --configuration=development` -Adapt the --host param to match your macs IP. +Adapt the --host param to match your macs IP. #### Build for production -`npm run-script build-ios-for-production` +`npm run build-ios` ### Best Practices -* Use components when we need it for multiple pages. -* Use pipes for currency conversion or interpreting a value -* Keep in mind that the app can be used in light and dark theme, use css vars when styling. Global theme attributes can be found in src/app/theme/variables.scss and src/app/global.scss. +- Use components when we need it for multiple pages. +- Use pipes for currency conversion or interpreting a value +- Keep in mind that the app can be used in light and dark theme, use css vars when styling. Global theme attributes can be found in src/app/theme/variables.scss and src/app/global.scss. ## License diff --git a/android/app/build.gradle b/android/app/build.gradle index 90da432b..c168fa7b 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -8,8 +8,8 @@ android { namespace "in.beaconcha.mobile" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 114 - versionName "4.5.12" + versionCode 123 + versionName "5.0.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } diff --git a/android/app/capacitor.build.gradle b/android/app/capacitor.build.gradle index d06eadd6..4dfd444c 100644 --- a/android/app/capacitor.build.gradle +++ b/android/app/capacitor.build.gradle @@ -22,8 +22,11 @@ dependencies { implementation project(':capacitor-splash-screen') implementation project(':capacitor-status-bar') implementation project(':capacitor-toast') + implementation project(':capawesome-capacitor-app-update') + implementation project(':capgo-capacitor-updater') implementation project(':capacitor-navigationbarnx') - implementation "com.android.billingclient:billing:7.0.0" + implementation project(':storage-mirror') + implementation "com.android.billingclient:billing:7.1.1" } diff --git a/android/app/src/androidTest/java/com/getcapacitor/myapp/ExampleInstrumentedTest.java b/android/app/src/androidTest/java/com/getcapacitor/myapp/ExampleInstrumentedTest.java index 4425dde9..80946a66 100644 --- a/android/app/src/androidTest/java/com/getcapacitor/myapp/ExampleInstrumentedTest.java +++ b/android/app/src/androidTest/java/com/getcapacitor/myapp/ExampleInstrumentedTest.java @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // diff --git a/android/app/src/main/assets/capacitor.config.json b/android/app/src/main/assets/capacitor.config.json index 1e41f78b..66a44193 100644 --- a/android/app/src/main/assets/capacitor.config.json +++ b/android/app/src/main/assets/capacitor.config.json @@ -9,8 +9,14 @@ "launchAutoHide": false, "androidScaleType": "CENTER_CROP" }, + "CapacitorCookies": { + "enabled": true + }, "CapacitorHttp": { "enabled": true + }, + "CapacitorUpdater": { + "autoUpdate": false } }, "android": { diff --git a/android/app/src/main/assets/capacitor.plugins.json b/android/app/src/main/assets/capacitor.plugins.json index da1ad267..c2f8f825 100644 --- a/android/app/src/main/assets/capacitor.plugins.json +++ b/android/app/src/main/assets/capacitor.plugins.json @@ -51,8 +51,20 @@ "pkg": "@capacitor/toast", "classpath": "com.capacitorjs.plugins.toast.ToastPlugin" }, + { + "pkg": "@capawesome/capacitor-app-update", + "classpath": "io.capawesome.capacitorjs.plugins.appupdate.AppUpdatePlugin" + }, + { + "pkg": "@capgo/capacitor-updater", + "classpath": "ee.forgr.capacitor_updater.CapacitorUpdaterPlugin" + }, { "pkg": "capacitor-navigationbarnx", "classpath": "com.nikosdouvlis.navigationbar.NavigationBar" + }, + { + "pkg": "storage-mirror", + "classpath": "at.bitfly.storagemirror.StorageMirrorPlugin" } ] diff --git a/android/app/src/main/java/in/beaconcha/mobile/MainActivity.java b/android/app/src/main/java/in/beaconcha/mobile/MainActivity.java index c4062a1f..69840667 100644 --- a/android/app/src/main/java/in/beaconcha/mobile/MainActivity.java +++ b/android/app/src/main/java/in/beaconcha/mobile/MainActivity.java @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -19,8 +18,27 @@ */ package in.beaconcha.mobile; +import android.app.Activity; +import android.webkit.WebView; + import com.getcapacitor.BridgeActivity; +import java.io.File; + public class MainActivity extends BridgeActivity { + @Override + public void onStart() { + // reset bundle to locally shipped + /*var prefs = this.getApplicationContext().getSharedPreferences(com.getcapacitor.plugin.WebView.WEBVIEW_PREFS_NAME, Activity.MODE_PRIVATE); + var editor = prefs.edit(); + editor.putString(com.getcapacitor.plugin.WebView.CAP_SERVER_PATH, new File("public").getPath()); + + editor.commit();*/ + + super.onStart(); + // Disable the rubber-band over-scroll effect that causes the app UI to get stretched. + WebView v = getBridge().getWebView(); + v.setOverScrollMode(v.OVER_SCROLL_NEVER); + } } diff --git a/android/app/src/main/java/in/beaconcha/mobile/widget b/android/app/src/main/java/in/beaconcha/mobile/widget index 51c4441b..b5694659 160000 --- a/android/app/src/main/java/in/beaconcha/mobile/widget +++ b/android/app/src/main/java/in/beaconcha/mobile/widget @@ -1 +1 @@ -Subproject commit 51c4441b12bbb82fe26feb3ad93feb36f23f6751 +Subproject commit b569465933893eb4ac4947a207a37163660e5f10 diff --git a/android/app/src/main/res/layout/widget_long.xml b/android/app/src/main/res/layout/widget_long.xml index f503a0f9..e2da3e60 100644 --- a/android/app/src/main/res/layout/widget_long.xml +++ b/android/app/src/main/res/layout/widget_long.xml @@ -72,7 +72,7 @@ android:id="@+id/txt_description" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:text="Today" + android:text="Last 24h" android:textColor="?attr/descriptionTextColor" android:textSize="13sp" android:textStyle="normal" /> @@ -99,7 +99,7 @@ android:id="@+id/txt_description3" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:text="Effectiveness" + android:text="Efficiency" android:textColor="?attr/descriptionTextColor" android:textSize="13sp" android:textStyle="normal" /> diff --git a/android/app/src/main/res/layout/widget_long_rpl.xml b/android/app/src/main/res/layout/widget_long_rpl.xml index 934280bf..6856638c 100644 --- a/android/app/src/main/res/layout/widget_long_rpl.xml +++ b/android/app/src/main/res/layout/widget_long_rpl.xml @@ -9,7 +9,6 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center" - android:adjustViewBounds="true" android:background="@drawable/widget_bg_long" android:orientation="horizontal" @@ -22,7 +21,6 @@ android:orientation="horizontal"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - + + + + + + + + - - - - - - + + + + + + + + - - + + + + + + + + - - - - - - + + + + + + + + - - + + + + + + + + - - - - - + android:layout_columnWeight="1" + android:layout_margin="5dp" + android:gravity="center" + android:orientation="vertical"> + + + + + + + + + diff --git a/android/app/src/main/res/layout/widget_square.xml b/android/app/src/main/res/layout/widget_square.xml index bef6592f..caa775c0 100644 --- a/android/app/src/main/res/layout/widget_square.xml +++ b/android/app/src/main/res/layout/widget_square.xml @@ -82,7 +82,7 @@ android:id="@+id/txt_description" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:text="Today" + android:text="Last 24h" android:textColor="?attr/descriptionTextColor" android:textSize="13sp" android:textStyle="normal" /> diff --git a/android/app/src/test/java/com/getcapacitor/myapp/ExampleUnitTest.java b/android/app/src/test/java/com/getcapacitor/myapp/ExampleUnitTest.java index 5486a19c..526ecf1e 100644 --- a/android/app/src/test/java/com/getcapacitor/myapp/ExampleUnitTest.java +++ b/android/app/src/test/java/com/getcapacitor/myapp/ExampleUnitTest.java @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // diff --git a/android/capacitor.settings.gradle b/android/capacitor.settings.gradle index 1a9f0c6c..86cdedbf 100644 --- a/android/capacitor.settings.gradle +++ b/android/capacitor.settings.gradle @@ -41,5 +41,14 @@ project(':capacitor-status-bar').projectDir = new File('../node_modules/@capacit include ':capacitor-toast' project(':capacitor-toast').projectDir = new File('../node_modules/@capacitor/toast/android') +include ':capawesome-capacitor-app-update' +project(':capawesome-capacitor-app-update').projectDir = new File('../node_modules/@capawesome/capacitor-app-update/android') + +include ':capgo-capacitor-updater' +project(':capgo-capacitor-updater').projectDir = new File('../node_modules/@capgo/capacitor-updater/android') + include ':capacitor-navigationbarnx' project(':capacitor-navigationbarnx').projectDir = new File('../node_modules/capacitor-navigationbarnx/android') + +include ':storage-mirror' +project(':storage-mirror').projectDir = new File('../storage-mirror/android') diff --git a/angular.json b/angular.json index 4832ba80..6adf3d41 100644 --- a/angular.json +++ b/angular.json @@ -12,18 +12,16 @@ "schematics": {}, "architect": { "build": { - "builder": "@angular-devkit/build-angular:browser", + "builder": "@angular-devkit/build-angular:application", "options": { - "outputPath": "www", + "outputPath": { + "base": "www", + "browser": "" + }, "index": "src/index.html", - "main": "src/main.ts", - "polyfills": "src/polyfills.ts", + "polyfills": ["zone.js"], "tsConfig": "tsconfig.app.json", - "allowedCommonJsDependencies": [ - "highcharts", - "ethereum-blockies", - "magic-snowflakes" - ], + "allowedCommonJsDependencies": ["highcharts", "ethereum-blockies", "cordova-plugin-purchase"], "assets": [ { "glob": "**/*", @@ -44,7 +42,8 @@ "input": "src/global.scss" } ], - "scripts": [] + "scripts": [], + "browser": "src/main.ts" }, "configurations": { "production": { @@ -56,21 +55,22 @@ ], "optimization": true, "outputHashing": "none", - "sourceMap": true, + "sourceMap": { + "scripts": true, + "styles": false, + "hidden": true, + "vendor": false + }, "namedChunks": false, "aot": true, "extractLicenses": true, - "vendorChunk": false, - "buildOptimizer": true, "budgets": [] }, "ci": { "progress": false }, "development": { - "buildOptimizer": true, "optimization": false, - "vendorChunk": true, "extractLicenses": false, "sourceMap": true, "namedChunks": true @@ -80,48 +80,25 @@ "serve": { "builder": "@angular-devkit/build-angular:dev-server", "options": { - "browserTarget": "app:build" + "buildTarget": "app:build" }, "configurations": { "production": { - "browserTarget": "app:build:production" + "buildTarget": "app:build:production" }, "ci": { "progress": false }, "development": { - "browserTarget": "app:build:development" + "buildTarget": "app:build:development" } }, - "defaultConfiguration": "production" + "defaultConfiguration": "production" }, "test": { - "builder": "@angular-devkit/build-angular:karma", + "builder": "@analogjs/vitest-angular:test", "options": { - "main": "src/test.ts", - "polyfills": "src/polyfills.ts", - "tsConfig": "tsconfig.spec.json", - "karmaConfig": "karma.conf.js", - "styles": [], - "scripts": [], - "assets": [ - { - "glob": "favicon.ico", - "input": "src/", - "output": "/" - }, - { - "glob": "**/*", - "input": "src/assets", - "output": "/assets" - } - ] - }, - "configurations": { - "ci": { - "progress": false, - "watch": false - } + "viteConfigPath": "vite.config.mts" } }, "lint": { @@ -174,7 +151,10 @@ } }, "cli": { - "defaultCollection": "@ionic/angular-toolkit" + "defaultCollection": "@ionic/angular-toolkit", + "cache": { + "enabled": false + } }, "schematics": { "@ionic/angular-toolkit:component": { diff --git a/capacitor.config.json b/capacitor.config.json index 1e41f78b..7e4ac517 100644 --- a/capacitor.config.json +++ b/capacitor.config.json @@ -1,22 +1,28 @@ { - "appId": "in.beaconcha.mobile", - "appName": "Beaconchain Dashboard", - "bundledWebRuntime": false, - "npmClient": "npm", - "webDir": "www", - "plugins": { + "appId": "in.beaconcha.mobile", + "appName": "Beaconchain Dashboard", + "bundledWebRuntime": false, + "npmClient": "npm", + "webDir": "www", + "plugins": { "SplashScreen": { "launchAutoHide": false, "androidScaleType": "CENTER_CROP" }, + "CapacitorCookies": { + "enabled": true + }, "CapacitorHttp": { "enabled": true + }, + "CapacitorUpdater": { + "autoUpdate": false } }, - "android": { - "flavor": "prod" - }, - "server": { - "androidScheme": "http" - } + "android": { + "flavor": "prod" + }, + "server": { + "androidScheme": "http" + } } diff --git a/e2e/protractor.conf.js b/e2e/protractor.conf.js deleted file mode 100644 index 3d505a9a..00000000 --- a/e2e/protractor.conf.js +++ /dev/null @@ -1,46 +0,0 @@ -/* - * This is the default license template. - * - * File: protractor.conf.js - * Author: bob - * Copyright (c) 2021 bob - * - * To edit this license information: Press Ctrl+Shift+P and press 'Create new License Template...'. - */ - -// @ts-check -// Protractor configuration file, see link for more information -// https://github.com/angular/protractor/blob/master/lib/config.ts - -const { SpecReporter, StacktraceOption } = require('jasmine-spec-reporter'); - -/** - * @type { import("protractor").Config } - */ -exports.config = { - allScriptsTimeout: 11000, - specs: [ - './src/**/*.e2e-spec.ts' - ], - capabilities: { - browserName: 'chrome' - }, - directConnect: true, - baseUrl: 'http://localhost:4200/', - framework: 'jasmine', - jasmineNodeOpts: { - showColors: true, - defaultTimeoutInterval: 30000, - print: function() {} - }, - onPrepare() { - require('ts-node').register({ - project: require('path').join(__dirname, './tsconfig.json') - }); - jasmine.getEnv().addReporter(new SpecReporter({ - spec: { - displayStacktrace: StacktraceOption.PRETTY - } - })); - } -}; diff --git a/e2e/src/app.e2e-spec.ts b/e2e/src/app.e2e-spec.ts deleted file mode 100644 index 2b5bbb12..00000000 --- a/e2e/src/app.e2e-spec.ts +++ /dev/null @@ -1,34 +0,0 @@ -/* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) - * // - * // This file is part of Beaconchain Dashboard. - * // - * // Beaconchain Dashboard is free software: you can redistribute it and/or modify - * // it under the terms of the GNU General Public License as published by - * // the Free Software Foundation, either version 3 of the License, or - * // (at your option) any later version. - * // - * // Beaconchain Dashboard is distributed in the hope that it will be useful, - * // but WITHOUT ANY WARRANTY; without even the implied warranty of - * // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * // GNU General Public License for more details. - * // - * // You should have received a copy of the GNU General Public License - * // along with Beaconchain Dashboard. If not, see . - */ - -import { AppPage } from './app.po'; - -describe('new App', () => { - let page: AppPage; - - beforeEach(() => { - page = new AppPage(); - }); - - it('should display welcome message', () => { - page.navigateTo(); - expect(page.getPageTitle()).toContain('Tab 1'); - }); -}); diff --git a/e2e/src/app.po.ts b/e2e/src/app.po.ts deleted file mode 100644 index 08b305d4..00000000 --- a/e2e/src/app.po.ts +++ /dev/null @@ -1,31 +0,0 @@ -/* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) - * // - * // This file is part of Beaconchain Dashboard. - * // - * // Beaconchain Dashboard is free software: you can redistribute it and/or modify - * // it under the terms of the GNU General Public License as published by - * // the Free Software Foundation, either version 3 of the License, or - * // (at your option) any later version. - * // - * // Beaconchain Dashboard is distributed in the hope that it will be useful, - * // but WITHOUT ANY WARRANTY; without even the implied warranty of - * // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * // GNU General Public License for more details. - * // - * // You should have received a copy of the GNU General Public License - * // along with Beaconchain Dashboard. If not, see . - */ - -import { browser, by, element } from 'protractor'; - -export class AppPage { - navigateTo() { - return browser.get('/'); - } - - getPageTitle() { - return element(by.css('ion-title')).getText(); - } -} diff --git a/e2e/tsconfig.json b/e2e/tsconfig.json deleted file mode 100644 index 7789780b..00000000 --- a/e2e/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "extends": "../tsconfig.json", - "compilerOptions": { - "outDir": "../out-tsc/app", - "module": "commonjs", - "target": "es2017", - "types": [ - "jasmine", - "jasminewd2", - "node" - ] - } -} diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 00000000..f125ee1e --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,53 @@ +import tseslint from "@typescript-eslint/eslint-plugin"; +import tsparser from "@typescript-eslint/parser"; +export default [ + { + ignores: [ + "node_modules", + "dist", + ".angular", + "src/zone-flags.ts", + "increment-build.js", + "seal-bundle.js", + "android/app/**", // Ignore Android build folder + "ios/App/App/public/**", // Ignore iOS assets + "storage-mirror/**", + "e2e/**", + ], + }, + { + files: ["**/*.ts", "**/*.tsx"], + languageOptions: { + parser: await import("@typescript-eslint/parser"), + parserOptions: { + project: "./tsconfig.json", + }, + }, + plugins: { + "@typescript-eslint": await import("@typescript-eslint/eslint-plugin"), + }, + rules: { + "@typescript-eslint/await-thenable": "error", + "require-await": "off", + "@typescript-eslint/require-await": "error", + "@typescript-eslint/no-misused-promises": [ + "error", + { "checksVoidReturn": false }, + ], + "no-shadow": "off", + "@typescript-eslint/no-shadow": "error", + "@typescript-eslint/no-unused-vars": [ + "error", + { + "args": "all", + "argsIgnorePattern": "^_", + "caughtErrors": "all", + "caughtErrorsIgnorePattern": "^_", + "destructuredArrayIgnorePattern": "^_", + "varsIgnorePattern": "^_", + "ignoreRestSiblings": true, + }, + ], + }, + }, +]; diff --git a/increment-build.js b/increment-build.js new file mode 100644 index 00000000..f4964063 --- /dev/null +++ b/increment-build.js @@ -0,0 +1,62 @@ +const fs = require('fs'); +const path = require('path'); +const readline = require('readline'); + +// Path to the version.json file +const filePath = path.join("./src/", 'version.json'); + +// Create an interface to read input from the user +const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout +}); + +// Read and parse the version file +fs.readFile(filePath, 'utf8', (err, data) => { + if (err) { + console.error('Error reading version file:', err); + process.exit(1); + } + + const versionInfo = JSON.parse(data); + + // Increment the build number + versionInfo.buildNumber += 1; + + // Ask the user for the formatted version + rl.question('What is the new version called (semantic versioning): ', (formattedVersionInput) => { + versionInfo.formattedVersion = formattedVersionInput; + + // Write the updated version info back to the file + fs.writeFile(filePath, JSON.stringify(versionInfo, null, 2), 'utf8', (err) => { + if (err) { + console.error('Error writing version file:', err); + process.exit(1); + } + + console.log(`Build number updated to: ${versionInfo.buildNumber}`); + console.log(`Formatted version updated to: ${versionInfo.formattedVersion}`); + + // Close the input stream + rl.close(); + }); + + // // Create a git tag using the formatted version + // const gitTagCommand = `git tag -a ${versionInfo.formattedVersion} -m "Version ${versionInfo.formattedVersion}"`; + + // exec(gitTagCommand, (error, stdout, stderr) => { + // if (error) { + // console.error(`Error creating git tag: ${error.message}`); + // process.exit(1); + // } + // if (stderr) { + // console.error(`Git error: ${stderr}`); + // } + + // console.log(`Git tag ${versionInfo.formattedVersion} created successfully.`); + + // // Close the readline interface + // rl.close(); + // }); + }); +}); diff --git a/ionic.config.json b/ionic.config.json index 59b76393..c09fdd3c 100644 --- a/ionic.config.json +++ b/ionic.config.json @@ -1,7 +1,7 @@ { - "name": "validator-app", - "integrations": { - "capacitor": {} - }, - "type": "angular" + "name": "validator-app", + "integrations": { + "capacitor": {} + }, + "type": "angular" } diff --git a/ios/App/App.xcodeproj/project.pbxproj b/ios/App/App.xcodeproj/project.pbxproj index 6b1570c6..e6217a19 100644 --- a/ios/App/App.xcodeproj/project.pbxproj +++ b/ios/App/App.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 2799A3DBF6024D568580B288 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 9AD28401CDFC4DFC99D4171C /* PrivacyInfo.xcprivacy */; }; 2FAD9763203C412B000D30F8 /* config.xml in Resources */ = {isa = PBXBuildFile; fileRef = 2FAD9762203C412B000D30F8 /* config.xml */; }; 50379B232058CBB4000EE86E /* capacitor.config.json in Resources */ = {isa = PBXBuildFile; fileRef = 50379B222058CBB4000EE86E /* capacitor.config.json */; }; 504EC3081FED79650016851F /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 504EC3071FED79650016851F /* AppDelegate.swift */; }; @@ -26,8 +27,6 @@ C76F886C263021BF0066804A /* Beaconchain WidgetExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = C76F885C263021BC0066804A /* Beaconchain WidgetExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; C790154F257E70EA0077FB87 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = C790154E257E70EA0077FB87 /* GoogleService-Info.plist */; }; C7A11E3D26AF015F00BCBA28 /* public in Resources */ = {isa = PBXBuildFile; fileRef = C7A11E3C26AF015F00BCBA28 /* public */; }; - C7AAA53A26398A5A00CCFC42 /* StorageMirror.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7AAA53926398A5A00CCFC42 /* StorageMirror.swift */; }; - C7AAA54226398DD600CCFC42 /* StorageMirror.m in Sources */ = {isa = PBXBuildFile; fileRef = C7AAA54126398DD600CCFC42 /* StorageMirror.m */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -64,6 +63,7 @@ 504EC3111FED79650016851F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 504EC3131FED79650016851F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 64322C5426BBEFF60080504C /* Beaconchain WidgetExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "Beaconchain WidgetExtension.entitlements"; sourceTree = ""; }; + 9AD28401CDFC4DFC99D4171C /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; path = PrivacyInfo.xcprivacy; sourceTree = ""; }; AF277DCFFFF123FFC6DF26C7 /* Pods_App.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_App.framework; sourceTree = BUILT_PRODUCTS_DIR; }; AF51FD2D460BCFE21FA515B2 /* Pods-App.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App.release.xcconfig"; path = "Pods/Target Support Files/Pods-App/Pods-App.release.xcconfig"; sourceTree = ""; }; C7065CAD2632EEE800DF9149 /* WebAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebAPI.swift; sourceTree = ""; }; @@ -80,9 +80,7 @@ C790154E257E70EA0077FB87 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "../../GoogleService-Info.plist"; sourceTree = ""; }; C7901566257FC9CD0077FB87 /* App.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = App.entitlements; sourceTree = ""; }; C7A11E3C26AF015F00BCBA28 /* public */ = {isa = PBXFileReference; lastKnownFileType = folder; path = public; sourceTree = ""; }; - C7AAA53926398A5A00CCFC42 /* StorageMirror.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StorageMirror.swift; sourceTree = ""; }; C7AAA54026398DD600CCFC42 /* App-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "App-Bridging-Header.h"; sourceTree = ""; }; - C7AAA54126398DD600CCFC42 /* StorageMirror.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = StorageMirror.m; sourceTree = ""; }; FC68EB0AF532CFC21C3344DD /* Pods-App.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App.debug.xcconfig"; path = "Pods/Target Support Files/Pods-App/Pods-App.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -126,6 +124,7 @@ 504EC3051FED79650016851F /* Products */, 7F8756D8B27F46E3366F6CEA /* Pods */, 27E2DDA53C4D2A4D1A88CE4A /* Frameworks */, + 9AD28401CDFC4DFC99D4171C /* PrivacyInfo.xcprivacy */, ); sourceTree = ""; }; @@ -152,8 +151,6 @@ 504EC3101FED79650016851F /* LaunchScreen.storyboard */, 504EC3131FED79650016851F /* Info.plist */, 2FAD9762203C412B000D30F8 /* config.xml */, - C7AAA53926398A5A00CCFC42 /* StorageMirror.swift */, - C7AAA54126398DD600CCFC42 /* StorageMirror.m */, C7AAA54026398DD600CCFC42 /* App-Bridging-Header.h */, ); path = App; @@ -275,6 +272,7 @@ 2FAD9763203C412B000D30F8 /* config.xml in Resources */, C790154F257E70EA0077FB87 /* GoogleService-Info.plist in Resources */, C7A11E3D26AF015F00BCBA28 /* public in Resources */, + 2799A3DBF6024D568580B288 /* PrivacyInfo.xcprivacy in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -330,8 +328,6 @@ buildActionMask = 2147483647; files = ( C76F8869263021BF0066804A /* Beaconchain_Widget.intentdefinition in Sources */, - C7AAA53A26398A5A00CCFC42 /* StorageMirror.swift in Sources */, - C7AAA54226398DD600CCFC42 /* StorageMirror.m in Sources */, 504EC3081FED79650016851F /* AppDelegate.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -504,15 +500,15 @@ CODE_SIGN_ENTITLEMENTS = App/App.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 110; - DEVELOPMENT_TEAM = 3HYX3N9WTV; + CURRENT_PROJECT_VERSION = 120; + DEVELOPMENT_TEAM = M6RLJ8D785; INFOPLIST_FILE = App/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 4.5.5; + MARKETING_VERSION = 5.0.0; OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\""; PRODUCT_BUNDLE_IDENTIFIER = in.beaconcha.mobile; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -535,15 +531,15 @@ CODE_SIGN_ENTITLEMENTS = App/AppRelease.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 110; - DEVELOPMENT_TEAM = 3HYX3N9WTV; + CURRENT_PROJECT_VERSION = 120; + DEVELOPMENT_TEAM = M6RLJ8D785; INFOPLIST_FILE = App/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 4.5.5; + MARKETING_VERSION = 5.0.0; PRODUCT_BUNDLE_IDENTIFIER = in.beaconcha.mobile; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -566,8 +562,8 @@ CODE_SIGN_ENTITLEMENTS = "Beaconchain WidgetExtension.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 110; - DEVELOPMENT_TEAM = 3HYX3N9WTV; + CURRENT_PROJECT_VERSION = 120; + DEVELOPMENT_TEAM = M6RLJ8D785; INFOPLIST_FILE = "Beaconchain Widget/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 14.0; LD_RUNPATH_SEARCH_PATHS = ( @@ -575,10 +571,10 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 4.5.5; + MARKETING_VERSION = 5.0.0; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = "in.beaconcha.mobile.Beaconchain-Widget"; + PRODUCT_BUNDLE_IDENTIFIER = "in.beaconcha.mobile.Beaconchain-Widget2"; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; SWIFT_VERSION = 5.0; @@ -598,8 +594,8 @@ CODE_SIGN_ENTITLEMENTS = "Beaconchain WidgetExtension.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 110; - DEVELOPMENT_TEAM = 3HYX3N9WTV; + CURRENT_PROJECT_VERSION = 120; + DEVELOPMENT_TEAM = M6RLJ8D785; INFOPLIST_FILE = "Beaconchain Widget/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 14.0; LD_RUNPATH_SEARCH_PATHS = ( @@ -607,9 +603,9 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 4.5.5; + MARKETING_VERSION = 5.0.0; MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = "in.beaconcha.mobile.Beaconchain-Widget"; + PRODUCT_BUNDLE_IDENTIFIER = "in.beaconcha.mobile.Beaconchain-Widget2"; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; SWIFT_VERSION = 5.0; diff --git a/ios/App/App.xcodeproj/xcshareddata/xcschemes/Beaconchain WidgetExtension.xcscheme b/ios/App/App.xcodeproj/xcshareddata/xcschemes/Beaconchain WidgetExtension.xcscheme new file mode 100644 index 00000000..4f76b3d8 --- /dev/null +++ b/ios/App/App.xcodeproj/xcshareddata/xcschemes/Beaconchain WidgetExtension.xcscheme @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/App/App/App.entitlements b/ios/App/App/App.entitlements index ed1ddb74..3243bfd4 100644 --- a/ios/App/App/App.entitlements +++ b/ios/App/App/App.entitlements @@ -6,7 +6,7 @@ development com.apple.security.application-groups - group.in.beaconcha.mobile + group.in.beaconcha.mobile2 diff --git a/ios/App/App/AppDelegate.swift b/ios/App/App/AppDelegate.swift index 254a92a9..dc24ce5b 100644 --- a/ios/App/App/AppDelegate.swift +++ b/ios/App/App/AppDelegate.swift @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // diff --git a/ios/App/App/AppRelease.entitlements b/ios/App/App/AppRelease.entitlements index ed1ddb74..3243bfd4 100644 --- a/ios/App/App/AppRelease.entitlements +++ b/ios/App/App/AppRelease.entitlements @@ -6,7 +6,7 @@ development com.apple.security.application-groups - group.in.beaconcha.mobile + group.in.beaconcha.mobile2 diff --git a/ios/App/App/StorageMirror.m b/ios/App/App/StorageMirror.m deleted file mode 100644 index 3da5f03c..00000000 --- a/ios/App/App/StorageMirror.m +++ /dev/null @@ -1,12 +0,0 @@ -// -// StorageMirror.m -// App -// -// Created by Kai Pflaume on 28.04.21. -// - -#import - -CAP_PLUGIN(StorageMirror, "StorageMirror", - CAP_PLUGIN_METHOD(reflect, CAPPluginReturnNone); -) diff --git a/ios/App/App/StorageMirror.swift b/ios/App/App/StorageMirror.swift deleted file mode 100644 index b54369c2..00000000 --- a/ios/App/App/StorageMirror.swift +++ /dev/null @@ -1,24 +0,0 @@ -// -// StorageMirror.swift -// App -// -// Created by Kai Pflaume on 28.04.21. -// - -import Foundation -import Capacitor - -@objc(StorageMirror) -public class StorageMirror: CAPPlugin { - - let defaults = UserDefaults.standard - let shared = UserDefaults(suiteName: "group.in.beaconcha.mobile") - - @objc func reflect(_ call: CAPPluginCall) { - let keysToReflect = call.getArray("keys", String.self) ?? [] - keysToReflect.forEach { key in - let value = defaults.string(forKey: key) ?? "" - shared?.set(value, forKey: key) - } - } -} diff --git a/ios/App/App/capacitor.config.json b/ios/App/App/capacitor.config.json index 72994f80..ffc00ec0 100644 --- a/ios/App/App/capacitor.config.json +++ b/ios/App/App/capacitor.config.json @@ -9,16 +9,22 @@ "launchAutoHide": false, "androidScaleType": "CENTER_CROP" }, + "CapacitorCookies": { + "enabled": true + }, "CapacitorHttp": { "enabled": true + }, + "CapacitorUpdater": { + "autoUpdate": false } }, - "server": { - "androidScheme": "http" - }, "android": { "flavor": "prod" }, + "server": { + "androidScheme": "http" + }, "packageClassList": [ "OAuth2ClientPlugin", "AppPlugin", @@ -33,7 +39,10 @@ "SplashScreenPlugin", "StatusBarPlugin", "ToastPlugin", + "AppUpdatePlugin", + "CapacitorUpdaterPlugin", "NavigationBar", + "StorageMirrorPlugin", "CDVPlugin" ] } diff --git a/ios/App/Beaconchain Widget b/ios/App/Beaconchain Widget new file mode 160000 index 00000000..493654b7 --- /dev/null +++ b/ios/App/Beaconchain Widget @@ -0,0 +1 @@ +Subproject commit 493654b740a1c2caa0d6642764c0478891d3fb46 diff --git a/ios/App/Beaconchain WidgetExtension.entitlements b/ios/App/Beaconchain WidgetExtension.entitlements index 2f18fea8..5fadb512 100644 --- a/ios/App/Beaconchain WidgetExtension.entitlements +++ b/ios/App/Beaconchain WidgetExtension.entitlements @@ -4,7 +4,7 @@ com.apple.security.application-groups - group.in.beaconcha.mobile + group.in.beaconcha.mobile2 diff --git a/ios/App/Podfile b/ios/App/Podfile index 55aed951..6db4f689 100644 --- a/ios/App/Podfile +++ b/ios/App/Podfile @@ -24,7 +24,10 @@ def capacitor_pods pod 'CapacitorSplashScreen', :path => '../../node_modules/@capacitor/splash-screen' pod 'CapacitorStatusBar', :path => '../../node_modules/@capacitor/status-bar' pod 'CapacitorToast', :path => '../../node_modules/@capacitor/toast' + pod 'CapawesomeCapacitorAppUpdate', :path => '../../node_modules/@capawesome/capacitor-app-update' + pod 'CapgoCapacitorUpdater', :path => '../../node_modules/@capgo/capacitor-updater' pod 'CapacitorNavigationbarnx', :path => '../../node_modules/capacitor-navigationbarnx' + pod 'StorageMirror', :path => '../../storage-mirror' pod 'CordovaPlugins', :path => '../capacitor-cordova-ios-plugins' end diff --git a/ios/App/Podfile.lock b/ios/App/Podfile.lock index 4a86b7bf..0d9512ee 100644 --- a/ios/App/Podfile.lock +++ b/ios/App/Podfile.lock @@ -1,37 +1,46 @@ PODS: + - Alamofire (5.9.1) - ByteowlsCapacitorOauth2 (5.0.0): - Capacitor - OAuthSwift (= 2.2.0) - - Capacitor (5.4.2): + - Capacitor (6.1.2): - CapacitorCordova - - CapacitorApp (5.0.6): + - CapacitorApp (6.0.1): - Capacitor - - CapacitorBrowser (5.1.0): + - CapacitorBrowser (6.0.2): - Capacitor - - CapacitorClipboard (5.0.6): + - CapacitorClipboard (6.0.1): - Capacitor - - CapacitorCordova (5.4.2) - - CapacitorDevice (5.0.6): + - CapacitorCordova (6.1.2) + - CapacitorDevice (6.0.1): - Capacitor - - CapacitorHaptics (5.0.6): + - CapacitorHaptics (6.0.1): - Capacitor - - CapacitorKeyboard (5.0.6): + - CapacitorKeyboard (6.0.2): - Capacitor - - CapacitorLocalNotifications (5.0.6): + - CapacitorLocalNotifications (6.1.0): - Capacitor - CapacitorNavigationbarnx (0.0.2): - Capacitor - - CapacitorPreferences (5.0.6): + - CapacitorPreferences (6.0.2): - Capacitor - - CapacitorPushNotifications (5.1.0): + - CapacitorPushNotifications (6.0.2): - Capacitor - - CapacitorSplashScreen (5.0.6): + - CapacitorSplashScreen (6.0.2): - Capacitor - - CapacitorStatusBar (5.0.6): + - CapacitorStatusBar (6.0.1): - Capacitor - - CapacitorToast (5.0.6): + - CapacitorToast (6.0.2): - Capacitor - - CordovaPlugins (5.4.2): + - CapawesomeCapacitorAppUpdate (6.0.0): + - Capacitor + - CapgoCapacitorUpdater (6.1.32): + - Alamofire + - Capacitor + - SSZipArchive + - SwiftyRSA + - Version + - CordovaPlugins (6.1.2): - CapacitorCordova - Firebase/CoreOnly (9.2.0): - FirebaseCore (= 9.2.0) @@ -92,6 +101,13 @@ PODS: - nanopb/encode (2.30909.0) - OAuthSwift (2.2.0) - PromisesObjC (2.1.1) + - SSZipArchive (2.4.3) + - StorageMirror (0.0.1): + - Capacitor + - SwiftyRSA (1.7.0): + - SwiftyRSA/ObjC (= 1.7.0) + - SwiftyRSA/ObjC (1.7.0) + - Version (0.8.0) DEPENDENCIES: - "ByteowlsCapacitorOauth2 (from `../../node_modules/@byteowls/capacitor-oauth2`)" @@ -110,12 +126,16 @@ DEPENDENCIES: - "CapacitorSplashScreen (from `../../node_modules/@capacitor/splash-screen`)" - "CapacitorStatusBar (from `../../node_modules/@capacitor/status-bar`)" - "CapacitorToast (from `../../node_modules/@capacitor/toast`)" + - "CapawesomeCapacitorAppUpdate (from `../../node_modules/@capawesome/capacitor-app-update`)" + - "CapgoCapacitorUpdater (from `../../node_modules/@capgo/capacitor-updater`)" - CordovaPlugins (from `../capacitor-cordova-ios-plugins`) - Firebase/Messaging - FirebaseCore + - StorageMirror (from `../../storage-mirror`) SPEC REPOS: trunk: + - Alamofire - Firebase - FirebaseCore - FirebaseCoreDiagnostics @@ -127,6 +147,9 @@ SPEC REPOS: - nanopb - OAuthSwift - PromisesObjC + - SSZipArchive + - SwiftyRSA + - Version EXTERNAL SOURCES: ByteowlsCapacitorOauth2: @@ -161,27 +184,36 @@ EXTERNAL SOURCES: :path: "../../node_modules/@capacitor/status-bar" CapacitorToast: :path: "../../node_modules/@capacitor/toast" + CapawesomeCapacitorAppUpdate: + :path: "../../node_modules/@capawesome/capacitor-app-update" + CapgoCapacitorUpdater: + :path: "../../node_modules/@capgo/capacitor-updater" CordovaPlugins: :path: "../capacitor-cordova-ios-plugins" + StorageMirror: + :path: "../../storage-mirror" SPEC CHECKSUMS: + Alamofire: f36a35757af4587d8e4f4bfa223ad10be2422b8c ByteowlsCapacitorOauth2: dde6b8fdf2995bc7872434c407ee2492ce562638 - Capacitor: 8a9db42d105f55843cd8ed2a3cb54e2b78e7f102 - CapacitorApp: 963d90cb449803d58efc33bb515c81151e69159d - CapacitorBrowser: 31371ef981e378cb592be8cc203a9a4cbf43c486 - CapacitorClipboard: ae6864d6b4ff2243fc7ce19124df307d8d1bb78d - CapacitorCordova: cfcc06b698481da655415985eeb2b8da363f8451 - CapacitorDevice: 9233ba5f0c8f601bf4992006f5d2b2a86b7abc2e - CapacitorHaptics: 186982679c5f4005d1e6d2c719b8251c0d3a6df8 - CapacitorKeyboard: 2f3296af2bc929a5069f02ed264fdce58ed62028 - CapacitorLocalNotifications: 7ed607db672dc2834f22a25422b86e74129a032a + Capacitor: 679f9673fdf30597493a6362a5d5bf233d46abc2 + CapacitorApp: 0bc633b4eae40a1f32cd2834788fad3bc42da6a1 + CapacitorBrowser: 83ec661a9ccd56c28a6851e4dd1ac33b181227ec + CapacitorClipboard: 756cd7e83e8d5d19b0c74f40b57517c287bd5fe2 + CapacitorCordova: f48c89f96c319101cd2f0ce8a2b7449b5fb8b3dd + CapacitorDevice: 7097a1deb4224b77fd13a6e60a355d0062a5d772 + CapacitorHaptics: fe689ade56ef20ec9b041a753c6da70c5d8ec9a9 + CapacitorKeyboard: 2700f9b18687be021e28b5a09b59eb151a46d5e0 + CapacitorLocalNotifications: 6bac9e948b2b8852506c6d74abb2cde140250f86 CapacitorNavigationbarnx: a22badd7d90d9715ecc08f3ae3824a57a37724b0 - CapacitorPreferences: 8053abfef3bd11e3e83834792a97e5a6387bf591 - CapacitorPushNotifications: 14425a66891d4134e73b6abe1932eeff37e4389d - CapacitorSplashScreen: f3c7de5468a52893e90f49d033772984270241b4 - CapacitorStatusBar: a73a9ae0dd2ca30ee429782d5d3ae82dcfa80207 - CapacitorToast: 61a9bec819ad3aeccc1ebe3fcbff565c22969c71 - CordovaPlugins: 13d1f5b0b81c2eba67b8f70432c3edb07483877c + CapacitorPreferences: e8284bf740cf8c6d3f25409af3c01df87dfeb5a1 + CapacitorPushNotifications: ccd797926c030acad3d5498ef452c735c90a2c89 + CapacitorSplashScreen: 250df9ef8014fac5c7c1fd231f0f8b1d8f0b5624 + CapacitorStatusBar: b81d4fb5d4e0064c712018071b3ab4b810b39a63 + CapacitorToast: cfd82cd5afdc3f027ad4a8859f909ae4a327f3c3 + CapawesomeCapacitorAppUpdate: 3c05b5c8e42f9c6a88d666093406e9336d9bfdb1 + CapgoCapacitorUpdater: f286378946eae7e06e54bd135815f3c5d939dfcc + CordovaPlugins: 584b5df0e1bde7be088e132f0efb476ab8f8bcfa Firebase: 4ba896cb8e5105d4b9e247e1c1b6222b548df55a FirebaseCore: 0e27f2a15d8f7b7ef11e7d93e23b1cbab55d748c FirebaseCoreDiagnostics: ad3f6c68b7c5b63b7cf15b0785d7137f05f32268 @@ -193,7 +225,11 @@ SPEC CHECKSUMS: nanopb: b552cce312b6c8484180ef47159bc0f65a1f0431 OAuthSwift: 75efbb5bd9a4b2b71a37bd7e986bf3f55ddd54c6 PromisesObjC: ab77feca74fa2823e7af4249b8326368e61014cb + SSZipArchive: fe6a26b2a54d5a0890f2567b5cc6de5caa600aef + StorageMirror: 29856c6eceb244679e713a6517dbfaa0ba12bffe + SwiftyRSA: 8c6dd1ea7db1b8dc4fb517a202f88bb1354bc2c6 + Version: de5907f2c5d0f3cf21708db7801d1d5401139486 -PODFILE CHECKSUM: 0abccb83d0d503da1628c7d1ca5579739161bb33 +PODFILE CHECKSUM: a7181fdf0c40eae25759aa2b27c893186f8a69dd -COCOAPODS: 1.14.2 +COCOAPODS: 1.15.2 diff --git a/ios/App/PrivacyInfo.xcprivacy b/ios/App/PrivacyInfo.xcprivacy new file mode 100644 index 00000000..b67558db --- /dev/null +++ b/ios/App/PrivacyInfo.xcprivacy @@ -0,0 +1,22 @@ + + + + + NSPrivacyTracking + + NSPrivacyAccessedAPITypes + + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryUserDefaults + NSPrivacyAccessedAPITypeReasons + + CA92.1 + + + + NSPrivacyCollectedDataTypes + + + \ No newline at end of file diff --git a/karma.conf.js b/karma.conf.js deleted file mode 100644 index ca6a34a0..00000000 --- a/karma.conf.js +++ /dev/null @@ -1,59 +0,0 @@ -/* - * This is the default license template. - * - * File: karma.conf.js - * Author: bob - * Copyright (c) 2021 bob - * - * To edit this license information: Press Ctrl+Shift+P and press 'Create new License Template...'. - */ - -// Karma configuration file, see link for more information -// https://karma-runner.github.io/1.0/config/configuration-file.html -process.env.CHROME_BIN = require('puppeteer').executablePath() - -module.exports = function (config) { - config.set({ - basePath: '', - frameworks: ['jasmine', '@angular-devkit/build-angular'], - plugins: [ - require('karma-jasmine'), - require('karma-chrome-launcher'), - require('karma-phantomjs-launcher'), - require('karma-jasmine-html-reporter'), - require('karma-coverage-istanbul-reporter'), - require('@angular-devkit/build-angular/plugins/karma') - ], - client: { - clearContext: false, // leave Jasmine Spec Runner output visible in browser - jasmine: { - random: false, - } - }, - capabilities: { - 'browserName': 'chrome', - chromeOptions: { - binary: process.env.CHROME_BIN, - args: ['--headless', '--disable-gpu', '--window-size=800,600', '--no-sandbox'] - } - }, - coverageIstanbulReporter: { - dir: require('path').join(__dirname, '../coverage'), - reports: ['html', 'lcovonly', 'text-summary'], - fixWebpackSourcePaths: true - }, - reporters: ['progress', 'kjhtml'], - port: 9876, - colors: true, - logLevel: config.LOG_INFO, - autoWatch: true, - browsers: ['ChromeHeadlessNoSandbox'], - customLaunchers: { - ChromeHeadlessNoSandbox: { - base: 'ChromeHeadless', - flags: ['--no-sandbox'] - } - }, - singleRun: false - }); -}; diff --git a/local_bundle_serve.sh b/local_bundle_serve.sh new file mode 100755 index 00000000..779ba353 --- /dev/null +++ b/local_bundle_serve.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +python3 -m http.server 8181 diff --git a/local_env/docker-compose.yml b/local_env/docker-compose.yml new file mode 100644 index 00000000..e4c21bdd --- /dev/null +++ b/local_env/docker-compose.yml @@ -0,0 +1,13 @@ +version: '3' + +services: + nginx-proxy: + image: nginx:alpine + container_name: app-local-proxy + network_mode: host + volumes: + - ./nginx.conf:/etc/nginx/nginx.conf + - ./https-serve.conf:/etc/nginx/conf.d/https-serve.conf +# - ./cookie-manipulator-proxy.conf:/etc/nginx/conf.d/cookie-manipulator-proxy.conf + - ./server.crt:/etc/nginx/certificates/server.crt + - ./server.key:/etc/nginx/certificates/server.key diff --git a/local_env/generate-cert.js b/local_env/generate-cert.js new file mode 100644 index 00000000..7fa3807f --- /dev/null +++ b/local_env/generate-cert.js @@ -0,0 +1,30 @@ +const { execSync } = require('child_process'); +const fs = require('fs'); +const path = require('path'); + +const certPath = path.join(__dirname, './server.crt'); +const keyPath = path.join(__dirname, './server.key'); + +// Ensure the directory exists +const localEnvDir = path.join(__dirname, 'local_env'); +if (!fs.existsSync(localEnvDir)) { + fs.mkdirSync(localEnvDir, { recursive: true }); +} + +if (!fs.existsSync(certPath) || !fs.existsSync(keyPath)) { + console.log('Generating self-signed certificate and key...'); + + try { + const opensslCommand = ` +openssl req -x509 -newkey rsa:2048 -nodes -keyout "${keyPath}" -out "${certPath}" -days 3650 -subj "/CN=localhost" + `; + execSync(opensslCommand, { stdio: 'inherit' }); + + console.log('Certificate and key generated successfully.'); + } catch (error) { + console.error('Error generating certificate and key:', error); + process.exit(1); + } +} else { + console.log('Certificate and key already exist.'); +} diff --git a/local_env/https-serve.conf b/local_env/https-serve.conf new file mode 100644 index 00000000..c08898dd --- /dev/null +++ b/local_env/https-serve.conf @@ -0,0 +1,33 @@ +server { + listen 8103 ssl; + server_name app-dev.beaconcha.in; # New subdomain + + ssl_certificate /etc/nginx/certificates/server.crt; + ssl_certificate_key /etc/nginx/certificates/server.key; + + location / { + proxy_pass http://localhost:8100; # Proxying to your existing HTTP server on port 8100 + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + # Optional: Disable SSL verification for local proxying + proxy_ssl_verify off; + } + + # WebSocket proxying for both ws:// and wss:// protocols + location /ng-cli-ws { + proxy_pass http://localhost:8100; # Adjust this to point to your backend WebSocket server if needed + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + # Optional: Disable SSL verification for local proxying + proxy_ssl_verify off; + } +} diff --git a/local_env/nginx.conf b/local_env/nginx.conf new file mode 100644 index 00000000..6790c822 --- /dev/null +++ b/local_env/nginx.conf @@ -0,0 +1,7 @@ +events { + worker_connections 1024; # Set the maximum number of simultaneous connections +} + +http { + include /etc/nginx/conf.d/*.conf; +} diff --git a/local_env/run.js b/local_env/run.js new file mode 100644 index 00000000..ffebb74f --- /dev/null +++ b/local_env/run.js @@ -0,0 +1,138 @@ +const puppeteer = require('puppeteer'); +const { exec } = require('child_process'); + +(async () => { + // Function to run docker-compose up + const runDockerCompose = () => { + return new Promise((resolve, reject) => { + exec('docker compose up -d', { cwd: __dirname }, (error, stdout, stderr) => { + if (error) { + console.error(`Error running docker-compose: ${error.message}`); + return reject(error); + } + if (stderr) { + console.warn(`Docker-compose warnings: ${stderr}`); + } + console.log(`Docker-compose output: ${stdout}`); + resolve(); + }); + }); + }; + + try { + console.log('Starting Docker Compose...'); + await runDockerCompose(); // Run docker compose up -d nginx-proxy + console.log('Docker Compose started successfully.'); + + const browser = await puppeteer.launch({ + headless: false, // Set to true for headless mode + devtools: true, // Open browser with DevTools enabled + args: [ + '--disable-web-security', // Disable web security to bypass CORS + '--disable-features=SameSiteByDefaultCookies,CookiesWithoutSameSiteMustBeSecure,IsolateOrigins,site-per-process', // Additional security disablement + '--disable-strict-mixed-content-checking', // Allow mixed content + '--no-sandbox', // Disable sandbox (if needed for Linux) + '--disable-setuid-sandbox', + '--ignore-certificate-errors', // Ignore SSL certificate errors (for self-signed certs) + '--user-data-dir=./tmp', + '--disable-third-party-cookie-blocking' + // '--proxy-server=http://localhost:8088' + ] + }); + + const page = await browser.newPage(); + + // Enable request interception + await page.setRequestInterception(true); + + page.on('request', request => { + const headers = request.headers(); + + // Check for any *.beaconcha.in domain + const url = request.url(); + if (url.endsWith('.beaconcha.in') || url.includes('.beaconcha.in/')) { + let cookieHeader = headers['cookie'] || ''; + let xCookieHeader = headers['x-cookie'] || ''; + + // Parse cookies into key-value pairs + const parseCookies = (cookieString) => { + return cookieString.split(';').reduce((acc, pair) => { + const [key, value] = pair.split('=').map(item => item.trim()); + if (key && value) acc[key] = value; + return acc; + }, {}); + }; + + const cookieObject = parseCookies(cookieHeader); + const xCookieObject = parseCookies(xCookieHeader); + + // Merge X-Cookie values, overriding existing Cookie values + const mergedCookies = { ...cookieObject, ...xCookieObject }; + + // Convert merged cookies back to a header string + const mergedCookieHeader = Object.entries(mergedCookies) + .map(([key, value]) => `${key}=${value}`) + .join('; '); + + // Set the new Cookie header + headers['cookie'] = mergedCookieHeader; + + // Remove the X-Cookie header + delete headers['x-cookie']; + } + + // Allow the request to proceed with modified headers + request.continue({ headers }); + }); + + // Emulate a mobile device + // const iPhone = puppeteer.devices['iPhone 15 Pro']; + // await page.emulate(iPhone); + + // Open your local app + await page.goto('https://localhost:8103/tabs/dashboard', { + waitUntil: 'networkidle0' + }); + + console.log('Page loaded with mobile emulation and DevTools enabled.'); + + // Optional: Log responses for debugging + page.on('response', async (response) => { + const cookies = response.headers()['set-cookie']; + + if (cookies) { + // Ensure cookies is an array (split if it's a string) + const cookieArray = Array.isArray(cookies) ? cookies : [cookies]; + + cookieArray.forEach(cookie => { + // console.log('Found cookie:', cookie); + + // Extract the cookie value (before the ';' separator) + const cookieParts = cookie.split(';')[0].split('='); + const cookieName = cookieParts[0]; + const cookieValue = cookieParts[1]; + + const domain = response.url().split('/')[2]; // Extract the domain from the response URL + + // Set the cookie for that domain + page.setCookie({ + name: cookieName, + value: cookieValue, + domain: domain, // Set cookie for the specific domain + path: '/', + secure: true, + httpOnly: cookie.includes('HttpOnly'), + sameSite: cookie.includes('SameSite=None') ? 'None' : 'Strict', // Use None if specified, otherwise Strict + }); + + // console.log(`Set cookie: ${cookieName} for domain: ${domain}`); + }); + } + }); + + // Keep the browser open for testing or close it after your actions + // await browser.close(); + } catch (error) { + console.error('An error occurred:', error); + } +})(); diff --git a/package-lock.json b/package-lock.json index 4f4f6e6f..f43ed494 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,17452 +1,37513 @@ { - "name": "beaconchain-dashboard", - "version": "2.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "beaconchain-dashboard", - "version": "2.0.0", - "dependencies": { - "@angular/animations": "^16.2.5", - "@angular/cdk": "^16.2.7", - "@angular/common": "~16.2.5", - "@angular/core": "~16.2.5", - "@angular/forms": "~16.2.5", - "@angular/platform-browser": "~16.2.5", - "@angular/platform-browser-dynamic": "~16.2.5", - "@angular/router": "~16.2.5", - "@awesome-cordova-plugins/core": "^6.4.0", - "@awesome-cordova-plugins/splash-screen": "^6.4.0", - "@awesome-cordova-plugins/status-bar": "^6.4.0", - "@byteowls/capacitor-oauth2": "^5.0.0", - "@capacitor/android": "^6.0.0", - "@capacitor/app": "^6.0.0", - "@capacitor/browser": "^6.0.0", - "@capacitor/clipboard": "^6.0.0", - "@capacitor/core": "^6.0.0", - "@capacitor/device": "^6.0.0", - "@capacitor/haptics": "^6.0.0", - "@capacitor/ios": "^6.0.0", - "@capacitor/keyboard": "^6.0.0", - "@capacitor/local-notifications": "^6.0.0", - "@capacitor/preferences": "^6.0.0", - "@capacitor/push-notifications": "^6.0.0", - "@capacitor/splash-screen": "^6.0.0", - "@capacitor/status-bar": "^6.0.0", - "@capacitor/toast": "^6.0.0", - "@ionic/angular": "^7.4.3", - "async-mutex": "^0.2.6", - "bignumber.js": "^9.1.2", - "canvas-confetti": "^1.3.3", - "capacitor-navigationbarnx": "0.1.6", - "cordova-plugin-purchase": "^13.11.1", - "cordova-res": "^0.15.2", - "ethereum-blockies": "^0.1.1", - "hammerjs": "^2.0.8", - "highcharts": "^11.1.0", - "intl": "^1.2.5", - "jetifier": "^1.6.6", - "magic-snowflakes": "^4.1.6", - "ng2-tooltip-directive-major-angular-updates": "^2.11.0", - "ngx-timeago": "^3.0.0", - "rxjs": "~7.8.1", - "tslib": "^2.6.2", - "zone.js": "~0.13.0" - }, - "devDependencies": { - "@angular-devkit/build-angular": "^16.2.5", - "@angular/cli": "~16.2.5", - "@angular/compiler": "~16.2.8", - "@angular/compiler-cli": "~16.2.5", - "@angular/language-service": "~16.2.5", - "@capacitor/cli": "^6.0.0", - "@ionic/angular-toolkit": "^10.0.0", - "@types/jasmine": "~5.1.0", - "@types/jasminewd2": "~2.0.11", - "@typescript-eslint/eslint-plugin": "^6.7.5", - "@typescript-eslint/parser": "^6.7.5", - "ajv": "^8.12.0", - "codelyzer": "^6.0.0", - "eslint": "^8.51.0", - "jasmine-core": "~5.1.1", - "jasmine-spec-reporter": "~7.0.0", - "karma": "~6.4.2", - "karma-chrome-launcher": "~3.2.0", - "karma-coverage-istanbul-reporter": "~3.0.3", - "karma-jasmine": "~5.1.0", - "karma-jasmine-html-reporter": "^2.1.0", - "karma-phantomjs-launcher": "^1.0.4", - "prettier": "2.8.0", - "protractor": "~7.0.0", - "ts-node": "~8.3.0", - "tslint": "~6.1.3", - "typescript": "~5.1.6" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", - "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@angular-devkit/architect": { - "version": "0.1602.14", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1602.14.tgz", - "integrity": "sha512-eSdONEV5dbtLNiOMBy9Ue9DdJ1ct6dH9RdZfYiedq6VZn0lejePAjY36MYVXgq2jTE+v/uIiaNy7caea5pt55A==", - "dev": true, - "dependencies": { - "@angular-devkit/core": "16.2.14", - "rxjs": "7.8.1" - }, - "engines": { - "node": "^16.14.0 || >=18.10.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "node_modules/@angular-devkit/build-angular": { - "version": "16.2.14", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-16.2.14.tgz", - "integrity": "sha512-bXQ6i7QPhwmYHuh+DSNkBhjTIHQF0C6fqZEg2ApJA3NmnzE98oQnmJ9AnGnAkdf1Mjn3xi2gxoZWPDDxGEINMw==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "2.2.1", - "@angular-devkit/architect": "0.1602.14", - "@angular-devkit/build-webpack": "0.1602.14", - "@angular-devkit/core": "16.2.14", - "@babel/core": "7.22.9", - "@babel/generator": "7.22.9", - "@babel/helper-annotate-as-pure": "7.22.5", - "@babel/helper-split-export-declaration": "7.22.6", - "@babel/plugin-proposal-async-generator-functions": "7.20.7", - "@babel/plugin-transform-async-to-generator": "7.22.5", - "@babel/plugin-transform-runtime": "7.22.9", - "@babel/preset-env": "7.22.9", - "@babel/runtime": "7.22.6", - "@babel/template": "7.22.5", - "@discoveryjs/json-ext": "0.5.7", - "@ngtools/webpack": "16.2.14", - "@vitejs/plugin-basic-ssl": "1.0.1", - "ansi-colors": "4.1.3", - "autoprefixer": "10.4.14", - "babel-loader": "9.1.3", - "babel-plugin-istanbul": "6.1.1", - "browserslist": "^4.21.5", - "chokidar": "3.5.3", - "copy-webpack-plugin": "11.0.0", - "critters": "0.0.20", - "css-loader": "6.8.1", - "esbuild-wasm": "0.18.17", - "fast-glob": "3.3.1", - "guess-parser": "0.4.22", - "https-proxy-agent": "5.0.1", - "inquirer": "8.2.4", - "jsonc-parser": "3.2.0", - "karma-source-map-support": "1.4.0", - "less": "4.1.3", - "less-loader": "11.1.0", - "license-webpack-plugin": "4.0.2", - "loader-utils": "3.2.1", - "magic-string": "0.30.1", - "mini-css-extract-plugin": "2.7.6", - "mrmime": "1.0.1", - "open": "8.4.2", - "ora": "5.4.1", - "parse5-html-rewriting-stream": "7.0.0", - "picomatch": "2.3.1", - "piscina": "4.0.0", - "postcss": "8.4.31", - "postcss-loader": "7.3.3", - "resolve-url-loader": "5.0.0", - "rxjs": "7.8.1", - "sass": "1.64.1", - "sass-loader": "13.3.2", - "semver": "7.5.4", - "source-map-loader": "4.0.1", - "source-map-support": "0.5.21", - "terser": "5.19.2", - "text-table": "0.2.0", - "tree-kill": "1.2.2", - "tslib": "2.6.1", - "vite": "4.5.3", - "webpack": "5.88.2", - "webpack-dev-middleware": "6.1.2", - "webpack-dev-server": "4.15.1", - "webpack-merge": "5.9.0", - "webpack-subresource-integrity": "5.1.0" - }, - "engines": { - "node": "^16.14.0 || >=18.10.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "optionalDependencies": { - "esbuild": "0.18.17" - }, - "peerDependencies": { - "@angular/compiler-cli": "^16.0.0", - "@angular/localize": "^16.0.0", - "@angular/platform-server": "^16.0.0", - "@angular/service-worker": "^16.0.0", - "jest": "^29.5.0", - "jest-environment-jsdom": "^29.5.0", - "karma": "^6.3.0", - "ng-packagr": "^16.0.0", - "protractor": "^7.0.0", - "tailwindcss": "^2.0.0 || ^3.0.0", - "typescript": ">=4.9.3 <5.2" - }, - "peerDependenciesMeta": { - "@angular/localize": { - "optional": true - }, - "@angular/platform-server": { - "optional": true - }, - "@angular/service-worker": { - "optional": true - }, - "jest": { - "optional": true - }, - "jest-environment-jsdom": { - "optional": true - }, - "karma": { - "optional": true - }, - "ng-packagr": { - "optional": true - }, - "protractor": { - "optional": true - }, - "tailwindcss": { - "optional": true - } - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/tslib": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz", - "integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==", - "dev": true - }, - "node_modules/@angular-devkit/build-webpack": { - "version": "0.1602.14", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1602.14.tgz", - "integrity": "sha512-f+ZTCjOoA1SCQEaX3L/63ubqr/vlHkwDXAtKjBsQgyz6srnETcjy96Us5k/LoK7/hPc85zFneqLinfqOMVWHJQ==", - "dev": true, - "dependencies": { - "@angular-devkit/architect": "0.1602.14", - "rxjs": "7.8.1" - }, - "engines": { - "node": "^16.14.0 || >=18.10.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "webpack": "^5.30.0", - "webpack-dev-server": "^4.0.0" - } - }, - "node_modules/@angular-devkit/core": { - "version": "16.2.14", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-16.2.14.tgz", - "integrity": "sha512-Ui14/d2+p7lnmXlK/AX2ieQEGInBV75lonNtPQgwrYgskF8ufCuN0DyVZQUy9fJDkC+xQxbJyYrby/BS0R0e7w==", - "dev": true, - "dependencies": { - "ajv": "8.12.0", - "ajv-formats": "2.1.1", - "jsonc-parser": "3.2.0", - "picomatch": "2.3.1", - "rxjs": "7.8.1", - "source-map": "0.7.4" - }, - "engines": { - "node": "^16.14.0 || >=18.10.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "chokidar": "^3.5.2" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } - } - }, - "node_modules/@angular-devkit/core/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@angular-devkit/schematics": { - "version": "16.2.14", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-16.2.14.tgz", - "integrity": "sha512-B6LQKInCT8w5zx5Pbroext5eFFRTCJdTwHN8GhcVS8IeKCnkeqVTQLjB4lBUg7LEm8Y7UHXwzrVxmk+f+MBXhw==", - "dev": true, - "dependencies": { - "@angular-devkit/core": "16.2.14", - "jsonc-parser": "3.2.0", - "magic-string": "0.30.1", - "ora": "5.4.1", - "rxjs": "7.8.1" - }, - "engines": { - "node": "^16.14.0 || >=18.10.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "node_modules/@angular/animations": { - "version": "16.2.12", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-16.2.12.tgz", - "integrity": "sha512-MD0ElviEfAJY8qMOd6/jjSSvtqER2RDAi0lxe6EtUacC1DHCYkaPrKW4vLqY+tmZBg1yf+6n+uS77pXcHHcA3w==", - "dependencies": { - "tslib": "^2.3.0" - }, - "engines": { - "node": "^16.14.0 || >=18.10.0" - }, - "peerDependencies": { - "@angular/core": "16.2.12" - } - }, - "node_modules/@angular/cdk": { - "version": "16.2.14", - "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-16.2.14.tgz", - "integrity": "sha512-n6PrGdiVeSTEmM/HEiwIyg6YQUUymZrb5afaNLGFRM5YL0Y8OBqd+XhCjb0OfD/AfgCUtedVEPwNqrfW8KzgGw==", - "dependencies": { - "tslib": "^2.3.0" - }, - "optionalDependencies": { - "parse5": "^7.1.2" - }, - "peerDependencies": { - "@angular/common": "^16.0.0 || ^17.0.0", - "@angular/core": "^16.0.0 || ^17.0.0", - "rxjs": "^6.5.3 || ^7.4.0" - } - }, - "node_modules/@angular/cli": { - "version": "16.2.14", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-16.2.14.tgz", - "integrity": "sha512-0y71jtitigVolm4Rim1b8xPQ+B22cGp4Spef2Wunpqj67UowN6tsZaVuWBEQh4u5xauX8LAHKqsvy37ZPWCc4A==", - "dev": true, - "dependencies": { - "@angular-devkit/architect": "0.1602.14", - "@angular-devkit/core": "16.2.14", - "@angular-devkit/schematics": "16.2.14", - "@schematics/angular": "16.2.14", - "@yarnpkg/lockfile": "1.1.0", - "ansi-colors": "4.1.3", - "ini": "4.1.1", - "inquirer": "8.2.4", - "jsonc-parser": "3.2.0", - "npm-package-arg": "10.1.0", - "npm-pick-manifest": "8.0.1", - "open": "8.4.2", - "ora": "5.4.1", - "pacote": "15.2.0", - "resolve": "1.22.2", - "semver": "7.5.4", - "symbol-observable": "4.0.0", - "yargs": "17.7.2" - }, - "bin": { - "ng": "bin/ng.js" - }, - "engines": { - "node": "^16.14.0 || >=18.10.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "node_modules/@angular/common": { - "version": "16.2.12", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-16.2.12.tgz", - "integrity": "sha512-B+WY/cT2VgEaz9HfJitBmgdk4I333XG/ybC98CMC4Wz8E49T8yzivmmxXB3OD6qvjcOB6ftuicl6WBqLbZNg2w==", - "dependencies": { - "tslib": "^2.3.0" - }, - "engines": { - "node": "^16.14.0 || >=18.10.0" - }, - "peerDependencies": { - "@angular/core": "16.2.12", - "rxjs": "^6.5.3 || ^7.4.0" - } - }, - "node_modules/@angular/compiler": { - "version": "16.2.12", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-16.2.12.tgz", - "integrity": "sha512-6SMXUgSVekGM7R6l1Z9rCtUGtlg58GFmgbpMCsGf+VXxP468Njw8rjT2YZkf5aEPxEuRpSHhDYjqz7n14cwCXQ==", - "dependencies": { - "tslib": "^2.3.0" - }, - "engines": { - "node": "^16.14.0 || >=18.10.0" - }, - "peerDependencies": { - "@angular/core": "16.2.12" - }, - "peerDependenciesMeta": { - "@angular/core": { - "optional": true - } - } - }, - "node_modules/@angular/compiler-cli": { - "version": "16.2.12", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-16.2.12.tgz", - "integrity": "sha512-pWSrr152562ujh6lsFZR8NfNc5Ljj+zSTQO44DsuB0tZjwEpnRcjJEgzuhGXr+CoiBf+jTSPZKemtSktDk5aaA==", - "dev": true, - "dependencies": { - "@babel/core": "7.23.2", - "@jridgewell/sourcemap-codec": "^1.4.14", - "chokidar": "^3.0.0", - "convert-source-map": "^1.5.1", - "reflect-metadata": "^0.1.2", - "semver": "^7.0.0", - "tslib": "^2.3.0", - "yargs": "^17.2.1" - }, - "bin": { - "ng-xi18n": "bundles/src/bin/ng_xi18n.js", - "ngc": "bundles/src/bin/ngc.js", - "ngcc": "bundles/ngcc/index.js" - }, - "engines": { - "node": "^16.14.0 || >=18.10.0" - }, - "peerDependencies": { - "@angular/compiler": "16.2.12", - "typescript": ">=4.9.3 <5.2" - } - }, - "node_modules/@angular/compiler-cli/node_modules/@babel/core": { - "version": "7.23.2", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.2.tgz", - "integrity": "sha512-n7s51eWdaWZ3vGT2tD4T7J6eJs3QoBXydv7vkUM06Bf1cbVD2Kc2UrkzhiQwobfV7NwOnQXYL7UBJ5VPU+RGoQ==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.22.13", - "@babel/generator": "^7.23.0", - "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-module-transforms": "^7.23.0", - "@babel/helpers": "^7.23.2", - "@babel/parser": "^7.23.0", - "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.2", - "@babel/types": "^7.23.0", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@angular/compiler-cli/node_modules/@babel/core/node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true - }, - "node_modules/@angular/compiler-cli/node_modules/@babel/core/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@angular/compiler-cli/node_modules/@babel/generator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", - "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.7", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@angular/compiler-cli/node_modules/@babel/template": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", - "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@angular/core": { - "version": "16.2.12", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-16.2.12.tgz", - "integrity": "sha512-GLLlDeke/NjroaLYOks0uyzFVo6HyLl7VOm0K1QpLXnYvW63W9Ql/T3yguRZa7tRkOAeFZ3jw+1wnBD4O8MoUA==", - "dependencies": { - "tslib": "^2.3.0" - }, - "engines": { - "node": "^16.14.0 || >=18.10.0" - }, - "peerDependencies": { - "rxjs": "^6.5.3 || ^7.4.0", - "zone.js": "~0.13.0" - } - }, - "node_modules/@angular/forms": { - "version": "16.2.12", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-16.2.12.tgz", - "integrity": "sha512-1Eao89hlBgLR3v8tU91vccn21BBKL06WWxl7zLpQmG6Hun+2jrThgOE4Pf3os4fkkbH4Apj0tWL2fNIWe/blbw==", - "dependencies": { - "tslib": "^2.3.0" - }, - "engines": { - "node": "^16.14.0 || >=18.10.0" - }, - "peerDependencies": { - "@angular/common": "16.2.12", - "@angular/core": "16.2.12", - "@angular/platform-browser": "16.2.12", - "rxjs": "^6.5.3 || ^7.4.0" - } - }, - "node_modules/@angular/language-service": { - "version": "16.2.12", - "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-16.2.12.tgz", - "integrity": "sha512-sZwB+ZEjChx9EYcqPaS4OnhC/q5RcedZjIdM9mCxuU/MtseURRYRI/8Hnm1RHo9qyc5PmsQpg7p9Vp/5hXLUjw==", - "dev": true, - "engines": { - "node": "^16.14.0 || >=18.10.0" - } - }, - "node_modules/@angular/platform-browser": { - "version": "16.2.12", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-16.2.12.tgz", - "integrity": "sha512-NnH7ju1iirmVEsUq432DTm0nZBGQsBrU40M3ZeVHMQ2subnGiyUs3QyzDz8+VWLL/T5xTxWLt9BkDn65vgzlIQ==", - "dependencies": { - "tslib": "^2.3.0" - }, - "engines": { - "node": "^16.14.0 || >=18.10.0" - }, - "peerDependencies": { - "@angular/animations": "16.2.12", - "@angular/common": "16.2.12", - "@angular/core": "16.2.12" - }, - "peerDependenciesMeta": { - "@angular/animations": { - "optional": true - } - } - }, - "node_modules/@angular/platform-browser-dynamic": { - "version": "16.2.12", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-16.2.12.tgz", - "integrity": "sha512-ya54jerNgreCVAR278wZavwjrUWImMr2F8yM5n9HBvsMBbFaAQ83anwbOEiHEF2BlR+gJiEBLfpuPRMw20pHqw==", - "dependencies": { - "tslib": "^2.3.0" - }, - "engines": { - "node": "^16.14.0 || >=18.10.0" - }, - "peerDependencies": { - "@angular/common": "16.2.12", - "@angular/compiler": "16.2.12", - "@angular/core": "16.2.12", - "@angular/platform-browser": "16.2.12" - } - }, - "node_modules/@angular/router": { - "version": "16.2.12", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-16.2.12.tgz", - "integrity": "sha512-aU6QnYSza005V9P3W6PpkieL56O0IHps96DjqI1RS8yOJUl3THmokqYN4Fm5+HXy4f390FN9i6ftadYQDKeWmA==", - "dependencies": { - "tslib": "^2.3.0" - }, - "engines": { - "node": "^16.14.0 || >=18.10.0" - }, - "peerDependencies": { - "@angular/common": "16.2.12", - "@angular/core": "16.2.12", - "@angular/platform-browser": "16.2.12", - "rxjs": "^6.5.3 || ^7.4.0" - } - }, - "node_modules/@assemblyscript/loader": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/@assemblyscript/loader/-/loader-0.10.1.tgz", - "integrity": "sha512-H71nDOOL8Y7kWRLqf6Sums+01Q5msqBW2KhDUTemh1tvY04eSkSXrK0uj/4mmY0Xr16/3zyZmsrxN7CKuRbNRg==", - "dev": true - }, - "node_modules/@awesome-cordova-plugins/core": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/@awesome-cordova-plugins/core/-/core-6.8.0.tgz", - "integrity": "sha512-++catmWWdZQ8/oTCt4yBrpdtJqZ3D7xFRrjQozLcEmtSb7FMaYoBGkn6FmZa+LYsNuzTaW84gdir5I+cllS+xA==", - "dependencies": { - "@types/cordova": "latest" - }, - "peerDependencies": { - "rxjs": "^5.5.0 || ^6.5.0 || ^7.3.0" - } - }, - "node_modules/@awesome-cordova-plugins/splash-screen": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/@awesome-cordova-plugins/splash-screen/-/splash-screen-6.8.0.tgz", - "integrity": "sha512-V494+xvWba1t5/bQs1EM8pqwGIHsnrG6DR6ON39Yl8L+PewC0tHd29kBsulHbY4HBsWqeSoU5BkdfzPYpr0Ykw==", - "dependencies": { - "@types/cordova": "latest" - }, - "peerDependencies": { - "@awesome-cordova-plugins/core": "^6.0.1", - "rxjs": "^5.5.0 || ^6.5.0 || ^7.3.0" - } - }, - "node_modules/@awesome-cordova-plugins/status-bar": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/@awesome-cordova-plugins/status-bar/-/status-bar-6.8.0.tgz", - "integrity": "sha512-SEoghsYWxNIhj07Fns9iqg4QlNOcHRRmg4EYNX2KY+7UOPeRYgSaphbo0u0ivAKRR4ibDd9Kl7uIOfn4j4HHcQ==", - "dependencies": { - "@types/cordova": "latest" - }, - "peerDependencies": { - "@awesome-cordova-plugins/core": "^6.0.1", - "rxjs": "^5.5.0 || ^6.5.0 || ^7.3.0" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.24.7", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz", - "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.9.tgz", - "integrity": "sha512-G2EgeufBcYw27U4hhoIwFcgc1XU7TlXJ3mv04oOv1WCuo900U/anZSPzEqNjwdjgffkk2Gs0AN0dW1CKVLcG7w==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.22.5", - "@babel/generator": "^7.22.9", - "@babel/helper-compilation-targets": "^7.22.9", - "@babel/helper-module-transforms": "^7.22.9", - "@babel/helpers": "^7.22.6", - "@babel/parser": "^7.22.7", - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.8", - "@babel/types": "^7.22.5", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.2", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/generator": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.9.tgz", - "integrity": "sha512-KtLMbmicyuK2Ak/FTCJVbDnkN1SlT8/kceFTiuDiiRUUSMnHMidxSCdG4ndkTOHHpoomWe/4xkvHkEOncwjYIw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.5", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", - "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.24.7.tgz", - "integrity": "sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA==", - "dev": true, - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz", - "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.24.7", - "@babel/helper-validator-option": "^7.24.7", - "browserslist": "^4.22.2", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.7.tgz", - "integrity": "sha512-kTkaDl7c9vO80zeX1rJxnuRpEsD5tA81yh11X1gQo+PhSti3JS+7qeZo9U4RHobKRiFPKaGK3svUAeb8D0Q7eg==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-member-expression-to-functions": "^7.24.7", - "@babel/helper-optimise-call-expression": "^7.24.7", - "@babel/helper-replace-supers": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-create-class-features-plugin/node_modules/@babel/helper-annotate-as-pure": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", - "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-create-class-features-plugin/node_modules/@babel/helper-split-export-declaration": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", - "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.24.7.tgz", - "integrity": "sha512-03TCmXy2FtXJEZfbXDTSqq1fRJArk7lX9DOFC/47VthYcxyIOx+eXQmdo6DOQvrbpIix+KfXwvuXdFDZHxt+rA==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "regexpu-core": "^5.3.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/@babel/helper-annotate-as-pure": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", - "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz", - "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", - "dev": true, - "dependencies": { - "@babel/helper-compilation-targets": "^7.22.6", - "@babel/helper-plugin-utils": "^7.22.5", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", - "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", - "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", - "dev": true, - "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name/node_modules/@babel/template": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", - "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", - "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.7.tgz", - "integrity": "sha512-LGeMaf5JN4hAT471eJdBs/GK1DoYIJ5GCtZN/EsL6KUiiDZOvO/eKE11AMZJa2zP4zk4qe9V2O/hxAmkRc8p6w==", - "dev": true, - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", - "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", - "dev": true, - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz", - "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==", - "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-simple-access": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-module-transforms/node_modules/@babel/helper-split-export-declaration": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", - "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz", - "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", - "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.24.7.tgz", - "integrity": "sha512-9pKLcTlZ92hNZMQfGCHImUpDOlAgkkpqalWEeftW5FBya75k8Li2ilerxkM/uBEj01iBZXcCIB/bwvDYgWyibA==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-wrap-function": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-remap-async-to-generator/node_modules/@babel/helper-annotate-as-pure": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", - "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.7.tgz", - "integrity": "sha512-qTAxxBM81VEyoAY0TtLrx1oAEJc09ZK67Q9ljQToqCnA+55eNwCORaxlKyu+rNfX86o8OXRUSNUnrtsAZXM9sg==", - "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-member-expression-to-functions": "^7.24.7", - "@babel/helper-optimise-call-expression": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", - "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", - "dev": true, - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz", - "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==", - "dev": true, - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", - "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz", - "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-wrap-function": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.24.7.tgz", - "integrity": "sha512-N9JIYk3TD+1vq/wn77YnJOqMtfWhNewNE+DJV4puD2X7Ew9J4JvrzrFDfTfyv5EgEXVy9/Wt8QiOErzEmv5Ifw==", - "dev": true, - "dependencies": { - "@babel/helper-function-name": "^7.24.7", - "@babel/template": "^7.24.7", - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-wrap-function/node_modules/@babel/template": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", - "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz", - "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==", - "dev": true, - "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers/node_modules/@babel/template": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", - "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.24.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", - "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", - "dev": true, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.24.7.tgz", - "integrity": "sha512-unaQgZ/iRu/By6tsjMZzpeBZjChYfLYry6HrEXPoz3KmfF0sVBQ1l8zKMQ4xRGLWVsjuvB8nQfjNP/DcfEOCsg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.7.tgz", - "integrity": "sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/plugin-transform-optional-chaining": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.13.0" - } - }, - "node_modules/@babel/plugin-proposal-async-generator-functions": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.7.tgz", - "integrity": "sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA==", - "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-async-generator-functions instead.", - "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-remap-async-to-generator": "^7.18.9", - "@babel/plugin-syntax-async-generators": "^7.8.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.21.0-placeholder-for-preset-env.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", - "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", - "dev": true, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-unicode-property-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", - "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", - "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-unicode-property-regex instead.", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.7.tgz", - "integrity": "sha512-Ec3NRUMoi8gskrkBe3fNmEQfxDvY8bgfQpz6jlk/41kX9eUjvpyqWU7PBP/pLAvMaSQjbMNKJmvX57jP+M6bPg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.7.tgz", - "integrity": "sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-unicode-sets-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", - "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.7.tgz", - "integrity": "sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.24.7.tgz", - "integrity": "sha512-o+iF77e3u7ZS4AoAuJvapz9Fm001PuD2V3Lp6OSE4FYQke+cSewYtnek+THqGRWyQloRCyvWL1OkyfNEl9vr/g==", - "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-remap-async-to-generator": "^7.24.7", - "@babel/plugin-syntax-async-generators": "^7.8.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.22.5.tgz", - "integrity": "sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ==", - "dev": true, - "dependencies": { - "@babel/helper-module-imports": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-remap-async-to-generator": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.7.tgz", - "integrity": "sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.7.tgz", - "integrity": "sha512-Nd5CvgMbWc+oWzBsuaMcbwjJWAcp5qzrbg69SZdHSP7AMY0AbWFqFO0WTFCA1jxhMCwodRwvRec8k0QUbZk7RQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-class-properties": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.7.tgz", - "integrity": "sha512-vKbfawVYayKcSeSR5YYzzyXvsDFWU2mD8U5TFeXtbCPLFUqe7GyCgvO6XDHzje862ODrOwy6WCPmKeWHbCFJ4w==", - "dev": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.7.tgz", - "integrity": "sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ==", - "dev": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-class-static-block": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0" - } - }, - "node_modules/@babel/plugin-transform-classes": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.7.tgz", - "integrity": "sha512-CFbbBigp8ln4FU6Bpy6g7sE8B/WmCmzvivzUC6xDAdWVsjYTXijpuuGJmYkAaoWAzcItGKT3IOAbxRItZ5HTjw==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-replace-supers": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-classes/node_modules/@babel/helper-annotate-as-pure": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", - "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/plugin-transform-classes/node_modules/@babel/helper-split-export-declaration": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", - "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.7.tgz", - "integrity": "sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/template": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-computed-properties/node_modules/@babel/template": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", - "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.7.tgz", - "integrity": "sha512-19eJO/8kdCQ9zISOf+SEUJM/bAUIsvY3YDnXZTupUCQ8LgrWnsG/gFB9dvXqdXnRXMAM8fvt7b0CBKQHNGy1mw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.7.tgz", - "integrity": "sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.7.tgz", - "integrity": "sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-dynamic-import": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.7.tgz", - "integrity": "sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.7.tgz", - "integrity": "sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ==", - "dev": true, - "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.7.tgz", - "integrity": "sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-for-of": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.7.tgz", - "integrity": "sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-function-name": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.7.tgz", - "integrity": "sha512-U9FcnA821YoILngSmYkW6FjyQe2TyZD5pHt4EVIhmcTkrJw/3KqcrRSxuOo5tFZJi7TE19iDyI1u+weTI7bn2w==", - "dev": true, - "dependencies": { - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.7.tgz", - "integrity": "sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-json-strings": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-literals": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.7.tgz", - "integrity": "sha512-vcwCbb4HDH+hWi8Pqenwnjy+UiklO4Kt1vfspcQYFhJdpthSnW8XvWGyDZWKNVrVbVViI/S7K9PDJZiUmP2fYQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.7.tgz", - "integrity": "sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.7.tgz", - "integrity": "sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.7.tgz", - "integrity": "sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg==", - "dev": true, - "dependencies": { - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.7.tgz", - "integrity": "sha512-iFI8GDxtevHJ/Z22J5xQpVqFLlMNstcLXh994xifFwxxGslr2ZXXLWgtBeLctOD63UFDArdvN6Tg8RFw+aEmjQ==", - "dev": true, - "dependencies": { - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-simple-access": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.7.tgz", - "integrity": "sha512-GYQE0tW7YoaN13qFh3O1NCY4MPkUiAH3fiF7UcV/I3ajmDKEdG3l+UOcbAm4zUE3gnvUU+Eni7XrVKo9eO9auw==", - "dev": true, - "dependencies": { - "@babel/helper-hoist-variables": "^7.24.7", - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.7.tgz", - "integrity": "sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A==", - "dev": true, - "dependencies": { - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.24.7.tgz", - "integrity": "sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-new-target": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.7.tgz", - "integrity": "sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.7.tgz", - "integrity": "sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.7.tgz", - "integrity": "sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.7.tgz", - "integrity": "sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q==", - "dev": true, - "dependencies": { - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-object-super": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.7.tgz", - "integrity": "sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-replace-supers": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.7.tgz", - "integrity": "sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.7.tgz", - "integrity": "sha512-tK+0N9yd4j+x/4hxF3F0e0fu/VdcxU18y5SevtyM/PCFlQvXbR0Zmlo2eBrKtVipGNFzpq56o8WsIIKcJFUCRQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-parameters": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.7.tgz", - "integrity": "sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-private-methods": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.7.tgz", - "integrity": "sha512-COTCOkG2hn4JKGEKBADkA8WNb35TGkkRbI5iT845dB+NyqgO8Hn+ajPbSnIQznneJTa3d30scb6iz/DhH8GsJQ==", - "dev": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.7.tgz", - "integrity": "sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-private-property-in-object/node_modules/@babel/helper-annotate-as-pure": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", - "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.7.tgz", - "integrity": "sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.7.tgz", - "integrity": "sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "regenerator-transform": "^0.15.2" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.7.tgz", - "integrity": "sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-runtime": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.22.9.tgz", - "integrity": "sha512-9KjBH61AGJetCPYp/IEyLEp47SyybZb0nDRpBvmtEkm+rUIwxdlKpyNHI1TmsGkeuLclJdleQHRZ8XLBnnh8CQ==", - "dev": true, - "dependencies": { - "@babel/helper-module-imports": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5", - "babel-plugin-polyfill-corejs2": "^0.4.4", - "babel-plugin-polyfill-corejs3": "^0.8.2", - "babel-plugin-polyfill-regenerator": "^0.5.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.7.tgz", - "integrity": "sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-spread": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.7.tgz", - "integrity": "sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.7.tgz", - "integrity": "sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.7.tgz", - "integrity": "sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.7.tgz", - "integrity": "sha512-VtR8hDy7YLB7+Pet9IarXjg/zgCMSF+1mNS/EQEiEaUPoFXCVsHG64SIxcaaI2zJgRiv+YmgaQESUfWAdbjzgg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.7.tgz", - "integrity": "sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-property-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.7.tgz", - "integrity": "sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.7.tgz", - "integrity": "sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-sets-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.7.tgz", - "integrity": "sha512-2G8aAvF4wy1w/AGZkemprdGMRg5o6zPNhbHVImRz3lss55TYCBd6xStN19rt8XJHq20sqV0JbyWjOWwQRwV/wg==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/preset-env": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.22.9.tgz", - "integrity": "sha512-wNi5H/Emkhll/bqPjsjQorSykrlfY5OWakd6AulLvMEytpKasMVUpVy8RL4qBIBs5Ac6/5i0/Rv0b/Fg6Eag/g==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.22.9", - "@babel/helper-compilation-targets": "^7.22.9", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-option": "^7.22.5", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.22.5", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.22.5", - "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.22.5", - "@babel/plugin-syntax-import-attributes": "^7.22.5", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.22.5", - "@babel/plugin-transform-async-generator-functions": "^7.22.7", - "@babel/plugin-transform-async-to-generator": "^7.22.5", - "@babel/plugin-transform-block-scoped-functions": "^7.22.5", - "@babel/plugin-transform-block-scoping": "^7.22.5", - "@babel/plugin-transform-class-properties": "^7.22.5", - "@babel/plugin-transform-class-static-block": "^7.22.5", - "@babel/plugin-transform-classes": "^7.22.6", - "@babel/plugin-transform-computed-properties": "^7.22.5", - "@babel/plugin-transform-destructuring": "^7.22.5", - "@babel/plugin-transform-dotall-regex": "^7.22.5", - "@babel/plugin-transform-duplicate-keys": "^7.22.5", - "@babel/plugin-transform-dynamic-import": "^7.22.5", - "@babel/plugin-transform-exponentiation-operator": "^7.22.5", - "@babel/plugin-transform-export-namespace-from": "^7.22.5", - "@babel/plugin-transform-for-of": "^7.22.5", - "@babel/plugin-transform-function-name": "^7.22.5", - "@babel/plugin-transform-json-strings": "^7.22.5", - "@babel/plugin-transform-literals": "^7.22.5", - "@babel/plugin-transform-logical-assignment-operators": "^7.22.5", - "@babel/plugin-transform-member-expression-literals": "^7.22.5", - "@babel/plugin-transform-modules-amd": "^7.22.5", - "@babel/plugin-transform-modules-commonjs": "^7.22.5", - "@babel/plugin-transform-modules-systemjs": "^7.22.5", - "@babel/plugin-transform-modules-umd": "^7.22.5", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", - "@babel/plugin-transform-new-target": "^7.22.5", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.22.5", - "@babel/plugin-transform-numeric-separator": "^7.22.5", - "@babel/plugin-transform-object-rest-spread": "^7.22.5", - "@babel/plugin-transform-object-super": "^7.22.5", - "@babel/plugin-transform-optional-catch-binding": "^7.22.5", - "@babel/plugin-transform-optional-chaining": "^7.22.6", - "@babel/plugin-transform-parameters": "^7.22.5", - "@babel/plugin-transform-private-methods": "^7.22.5", - "@babel/plugin-transform-private-property-in-object": "^7.22.5", - "@babel/plugin-transform-property-literals": "^7.22.5", - "@babel/plugin-transform-regenerator": "^7.22.5", - "@babel/plugin-transform-reserved-words": "^7.22.5", - "@babel/plugin-transform-shorthand-properties": "^7.22.5", - "@babel/plugin-transform-spread": "^7.22.5", - "@babel/plugin-transform-sticky-regex": "^7.22.5", - "@babel/plugin-transform-template-literals": "^7.22.5", - "@babel/plugin-transform-typeof-symbol": "^7.22.5", - "@babel/plugin-transform-unicode-escapes": "^7.22.5", - "@babel/plugin-transform-unicode-property-regex": "^7.22.5", - "@babel/plugin-transform-unicode-regex": "^7.22.5", - "@babel/plugin-transform-unicode-sets-regex": "^7.22.5", - "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.22.5", - "babel-plugin-polyfill-corejs2": "^0.4.4", - "babel-plugin-polyfill-corejs3": "^0.8.2", - "babel-plugin-polyfill-regenerator": "^0.5.1", - "core-js-compat": "^3.31.0", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/preset-env/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/preset-modules": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6.tgz", - "integrity": "sha512-ID2yj6K/4lKfhuU3+EX4UvNbIt7eACFbHmNUjzA+ep+B5971CknnA/9DEWKbRokfbbtblxxxXFJJrH47UEAMVg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", - "@babel/plugin-transform-dotall-regex": "^7.4.4", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/@babel/regjsgen": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", - "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==", - "dev": true - }, - "node_modules/@babel/runtime": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.6.tgz", - "integrity": "sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==", - "dev": true, - "dependencies": { - "regenerator-runtime": "^0.13.11" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/template": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", - "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.22.5", - "@babel/parser": "^7.22.5", - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz", - "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-hoist-variables": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7", - "debug": "^4.3.1", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse/node_modules/@babel/generator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", - "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.7", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse/node_modules/@babel/helper-split-export-declaration": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", - "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/types": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", - "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", - "dev": true, - "dependencies": { - "@babel/helper-string-parser": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7", - "to-fast-properties": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@byteowls/capacitor-oauth2": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@byteowls/capacitor-oauth2/-/capacitor-oauth2-5.0.0.tgz", - "integrity": "sha512-yW50GypmyPJcH/95NwR2jJcgT78vBN3FYKL2w6A3vrT04bRLQyw2K0fLqfj8Zws6DJy43Ck1wPs0Bcdvbsub7A==", - "peerDependencies": { - "@capacitor/core": ">=5" - } - }, - "node_modules/@capacitor/android": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@capacitor/android/-/android-6.1.0.tgz", - "integrity": "sha512-S4PW4N5xtKHTrICjG7bkBhI70jdXbb+8nbm1pJpuXChCD0gkCcofJhPaw4bCoO0egcugBN1U7DkegNw5jWpHcw==", - "peerDependencies": { - "@capacitor/core": "^6.1.0" - } - }, - "node_modules/@capacitor/app": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@capacitor/app/-/app-6.0.0.tgz", - "integrity": "sha512-X5UGd90Jh5p9rmoPyMqFyFWqOypdJgVJhYcM5X1YyDVJJGzmJ5MuYv1+ajj5DW9Qyh+5a3th9WYptdGby8jidA==", - "peerDependencies": { - "@capacitor/core": "^6.0.0" - } - }, - "node_modules/@capacitor/browser": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@capacitor/browser/-/browser-6.0.1.tgz", - "integrity": "sha512-KBK0PKfmUj0if+gYWEh0+LG70l1gcLGbDCWJt2Ig3naXHGlrLoWBqVArCgbwBzwJZL+VlwW7iEhAzGOWpg2jhw==", - "peerDependencies": { - "@capacitor/core": "^6.0.0" - } - }, - "node_modules/@capacitor/cli": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@capacitor/cli/-/cli-6.1.0.tgz", - "integrity": "sha512-HEKDh3+FuNZKFHmSDZ7nAnaX3bzhtznYk9GsZBMac1y4CTAxIykPX9wzZ3DzLeM/EbMBGFClUbefkIkimAyfYg==", - "dev": true, - "dependencies": { - "@ionic/cli-framework-output": "^2.2.5", - "@ionic/utils-fs": "^3.1.6", - "@ionic/utils-process": "^2.1.11", - "@ionic/utils-subprocess": "2.1.11", - "@ionic/utils-terminal": "^2.3.3", - "commander": "^9.3.0", - "debug": "^4.3.4", - "env-paths": "^2.2.0", - "kleur": "^4.1.4", - "native-run": "^2.0.0", - "open": "^8.4.0", - "plist": "^3.0.5", - "prompts": "^2.4.2", - "rimraf": "^4.4.1", - "semver": "^7.3.7", - "tar": "^6.1.11", - "tslib": "^2.4.0", - "xml2js": "^0.5.0" - }, - "bin": { - "cap": "bin/capacitor", - "capacitor": "bin/capacitor" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@capacitor/clipboard": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@capacitor/clipboard/-/clipboard-6.0.0.tgz", - "integrity": "sha512-NjcGr2jncSZy9NM9grePo8zz0hhBYYBYZV71xXjLvJhVY4PSdZD/Sj+4jm0pvlOKSK8vAXYyF6VcWT4/Kh/xmw==", - "peerDependencies": { - "@capacitor/core": "^6.0.0" - } - }, - "node_modules/@capacitor/core": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@capacitor/core/-/core-6.1.0.tgz", - "integrity": "sha512-Kt4ONm0X9xxJXn9Q73oBaKdzep5B/VJw3VjXa2eGul4cD2k37mJwgjpXSMRnLH0Aju5bCiRL8J/hMAfTlokO6A==", - "dependencies": { - "tslib": "^2.1.0" - } - }, - "node_modules/@capacitor/device": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@capacitor/device/-/device-6.0.0.tgz", - "integrity": "sha512-3cV4XcH9pTWcstecyr8rNBQvFCsxYugJdPetk898airCbV1bqZSGF2YLSoPQj4BiDITSlNgwABNwNYMCNzs/gw==", - "peerDependencies": { - "@capacitor/core": "^6.0.0" - } - }, - "node_modules/@capacitor/haptics": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@capacitor/haptics/-/haptics-6.0.0.tgz", - "integrity": "sha512-z2TmB+pTbd98Il2I1xpZGClCFwORxxP2m9f1a0rh70c2ubj2atVyZctgxrx1fuoExZTNGSxHaylWfrmjmtelVg==", - "peerDependencies": { - "@capacitor/core": "^6.0.0" - } - }, - "node_modules/@capacitor/ios": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@capacitor/ios/-/ios-6.1.0.tgz", - "integrity": "sha512-ex2q0LAyDDgfJj4fKDQuSNUYSpic3939/8A/sIIIxslwuRBF5i5fuhAngu6BhCt/pQSfEETcHtg2j2vD+YEZ2w==", - "peerDependencies": { - "@capacitor/core": "^6.1.0" - } - }, - "node_modules/@capacitor/keyboard": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@capacitor/keyboard/-/keyboard-6.0.1.tgz", - "integrity": "sha512-fBjqQaMc5uhFj6ycLnLa2hzQsR77pj/iuLLATkWihMUze3dD+IkwqFnEyOLsyk+52uoOYM7WkziSpNTquU1sZA==", - "peerDependencies": { - "@capacitor/core": "^6.0.0" - } - }, - "node_modules/@capacitor/local-notifications": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@capacitor/local-notifications/-/local-notifications-6.0.0.tgz", - "integrity": "sha512-a/g/ZlPgaBXue374oNzGvvNZWNpnclfcLzfE/P/PjhHxdHsM7J3OK0IfmjrEsRiON4AEIga+dkHi5yBjNAHCFw==", - "peerDependencies": { - "@capacitor/core": "^6.0.0" - } - }, - "node_modules/@capacitor/preferences": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@capacitor/preferences/-/preferences-6.0.1.tgz", - "integrity": "sha512-5UvSK3O/tgPcQ1QyX0zYjb0uujFw+PQgYUSt6i2evf609jAIo7QG1IUZzGb6swEPCpk621wEc6R7Yq/Ywa3GPA==", - "peerDependencies": { - "@capacitor/core": "^6.0.0" - } - }, - "node_modules/@capacitor/push-notifications": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@capacitor/push-notifications/-/push-notifications-6.0.1.tgz", - "integrity": "sha512-NFVAnmBsyuTFScTMUrgOr3EKnCl9etGeXignC2Y5QsOoqjT+fhVhIUco9BR7Bi48JGdvK/evqzwt36LMF82bBw==", - "peerDependencies": { - "@capacitor/core": "^6.0.0" - } - }, - "node_modules/@capacitor/splash-screen": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@capacitor/splash-screen/-/splash-screen-6.0.1.tgz", - "integrity": "sha512-ndsqq335Mb6NxDrcXsT0PVwomo/UrDN4ykqpu8wY8F3HT4vbr8Hojh5PLqtlTy6TCIIIen58fkEgIoyGPsPSaw==", - "peerDependencies": { - "@capacitor/core": "^6.0.0" - } - }, - "node_modules/@capacitor/status-bar": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@capacitor/status-bar/-/status-bar-6.0.0.tgz", - "integrity": "sha512-Wo0ILugYlmENegKDgTzVCPjbvP8h1ObgHslLdgeVG643ViMS/diausHIq8e104WIKCXtKIELmQeYVp9mX7932g==", - "peerDependencies": { - "@capacitor/core": "^6.0.0" - } - }, - "node_modules/@capacitor/toast": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@capacitor/toast/-/toast-6.0.1.tgz", - "integrity": "sha512-f3tpRcX60PhJoEDDokZc1+/aLWCNUvvlm9PjqJLEP2OYVYOay8NOBFsxut7j49YD6z6oN6NRd87sb7TI+CREvA==", - "peerDependencies": { - "@capacitor/core": "^6.0.0" - } - }, - "node_modules/@colors/colors": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", - "dev": true, - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/@discoveryjs/json-ext": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", - "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", - "dev": true, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.17.tgz", - "integrity": "sha512-wHsmJG/dnL3OkpAcwbgoBTTMHVi4Uyou3F5mf58ZtmUyIKfcdA7TROav/6tCzET4A3QW2Q2FC+eFneMU+iyOxg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.17.tgz", - "integrity": "sha512-9np+YYdNDed5+Jgr1TdWBsozZ85U1Oa3xW0c7TWqH0y2aGghXtZsuT8nYRbzOMcl0bXZXjOGbksoTtVOlWrRZg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.17.tgz", - "integrity": "sha512-O+FeWB/+xya0aLg23hHEM2E3hbfwZzjqumKMSIqcHbNvDa+dza2D0yLuymRBQQnC34CWrsJUXyH2MG5VnLd6uw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.17.tgz", - "integrity": "sha512-M9uJ9VSB1oli2BE/dJs3zVr9kcCBBsE883prage1NWz6pBS++1oNn/7soPNS3+1DGj0FrkSvnED4Bmlu1VAE9g==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.17.tgz", - "integrity": "sha512-XDre+J5YeIJDMfp3n0279DFNrGCXlxOuGsWIkRb1NThMZ0BsrWXoTg23Jer7fEXQ9Ye5QjrvXpxnhzl3bHtk0g==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.17.tgz", - "integrity": "sha512-cjTzGa3QlNfERa0+ptykyxs5A6FEUQQF0MuilYXYBGdBxD3vxJcKnzDlhDCa1VAJCmAxed6mYhA2KaJIbtiNuQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.17.tgz", - "integrity": "sha512-sOxEvR8d7V7Kw8QqzxWc7bFfnWnGdaFBut1dRUYtu+EIRXefBc/eIsiUiShnW0hM3FmQ5Zf27suDuHsKgZ5QrA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.17.tgz", - "integrity": "sha512-2d3Lw6wkwgSLC2fIvXKoMNGVaeY8qdN0IC3rfuVxJp89CRfA3e3VqWifGDfuakPmp90+ZirmTfye1n4ncjv2lg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.17.tgz", - "integrity": "sha512-c9w3tE7qA3CYWjT+M3BMbwMt+0JYOp3vCMKgVBrCl1nwjAlOMYzEo+gG7QaZ9AtqZFj5MbUc885wuBBmu6aADQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.17.tgz", - "integrity": "sha512-1DS9F966pn5pPnqXYz16dQqWIB0dmDfAQZd6jSSpiT9eX1NzKh07J6VKR3AoXXXEk6CqZMojiVDSZi1SlmKVdg==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.17.tgz", - "integrity": "sha512-EvLsxCk6ZF0fpCB6w6eOI2Fc8KW5N6sHlIovNe8uOFObL2O+Mr0bflPHyHwLT6rwMg9r77WOAWb2FqCQrVnwFg==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.17.tgz", - "integrity": "sha512-e0bIdHA5p6l+lwqTE36NAW5hHtw2tNRmHlGBygZC14QObsA3bD4C6sXLJjvnDIjSKhW1/0S3eDy+QmX/uZWEYQ==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.17.tgz", - "integrity": "sha512-BAAilJ0M5O2uMxHYGjFKn4nJKF6fNCdP1E0o5t5fvMYYzeIqy2JdAP88Az5LHt9qBoUa4tDaRpfWt21ep5/WqQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.17.tgz", - "integrity": "sha512-Wh/HW2MPnC3b8BqRSIme/9Zhab36PPH+3zam5pqGRH4pE+4xTrVLx2+XdGp6fVS3L2x+DrsIcsbMleex8fbE6g==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.17.tgz", - "integrity": "sha512-j/34jAl3ul3PNcK3pfI0NSlBANduT2UO5kZ7FCaK33XFv3chDhICLY8wJJWIhiQ+YNdQ9dxqQctRg2bvrMlYgg==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.17.tgz", - "integrity": "sha512-QM50vJ/y+8I60qEmFxMoxIx4de03pGo2HwxdBeFd4nMh364X6TIBZ6VQ5UQmPbQWUVWHWws5MmJXlHAXvJEmpQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.17.tgz", - "integrity": "sha512-/jGlhWR7Sj9JPZHzXyyMZ1RFMkNPjC6QIAan0sDOtIo2TYk3tZn5UDrkE0XgsTQCxWTTOcMPf9p6Rh2hXtl5TQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.17.tgz", - "integrity": "sha512-rSEeYaGgyGGf4qZM2NonMhMOP/5EHp4u9ehFiBrg7stH6BYEEjlkVREuDEcQ0LfIl53OXLxNbfuIj7mr5m29TA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.17.tgz", - "integrity": "sha512-Y7ZBbkLqlSgn4+zot4KUNYst0bFoO68tRgI6mY2FIM+b7ZbyNVtNbDP5y8qlu4/knZZ73fgJDlXID+ohY5zt5g==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.17.tgz", - "integrity": "sha512-bwPmTJsEQcbZk26oYpc4c/8PvTY3J5/QK8jM19DVlEsAB41M39aWovWoHtNm78sd6ip6prilxeHosPADXtEJFw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.17.tgz", - "integrity": "sha512-H/XaPtPKli2MhW+3CQueo6Ni3Avggi6hP/YvgkEe1aSaxw+AeO8MFjq8DlgfTd9Iz4Yih3QCZI6YLMoyccnPRg==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.17.tgz", - "integrity": "sha512-fGEb8f2BSA3CW7riJVurug65ACLuQAzKq0SSqkY2b2yHHH0MzDfbLyKIGzHwOI/gkHcxM/leuSW6D5w/LMNitA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", - "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", - "dev": true, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@eslint/eslintrc/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==", - "dev": true - }, - "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@eslint/eslintrc/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/@eslint/eslintrc/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/@eslint/eslintrc/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@gar/promisify": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", - "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", - "dev": true - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", - "deprecated": "Use @eslint/config-array instead", - "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead", - "dev": true - }, - "node_modules/@ionic/angular": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@ionic/angular/-/angular-7.8.6.tgz", - "integrity": "sha512-3Qe53hXpyjtx6fFcxt/NTAlauIawsGmCZJPauV5sAnSKVuX8C82C1zMAZTeJt6m2dnd71wythc98BXUXsx/UxQ==", - "dependencies": { - "@ionic/core": "7.8.6", - "ionicons": "^7.0.0", - "jsonc-parser": "^3.0.0", - "tslib": "^2.3.0" - }, - "peerDependencies": { - "@angular/core": ">=14.0.0", - "@angular/forms": ">=14.0.0", - "@angular/router": ">=14.0.0", - "rxjs": ">=7.5.0", - "zone.js": ">=0.11.0" - } - }, - "node_modules/@ionic/angular-toolkit": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/@ionic/angular-toolkit/-/angular-toolkit-10.1.1.tgz", - "integrity": "sha512-idLaBUY14M7JQmvxAGeDZvk7WcamWEHo1OHGRuLRAn+7uWrKeGxfWbnbZJhvRCLQndr8j7q3WV3Z+0APkPuKaQ==", - "dev": true, - "dependencies": { - "@angular-devkit/core": "^16.0.0", - "@angular-devkit/schematics": "^16.0.0", - "@schematics/angular": "^16.0.0" - } - }, - "node_modules/@ionic/cli-framework-output": { - "version": "2.2.8", - "resolved": "https://registry.npmjs.org/@ionic/cli-framework-output/-/cli-framework-output-2.2.8.tgz", - "integrity": "sha512-TshtaFQsovB4NWRBydbNFawql6yul7d5bMiW1WYYf17hd99V6xdDdk3vtF51bw6sLkxON3bDQpWsnUc9/hVo3g==", - "dev": true, - "dependencies": { - "@ionic/utils-terminal": "2.3.5", - "debug": "^4.0.0", - "tslib": "^2.0.1" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@ionic/core": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.8.6.tgz", - "integrity": "sha512-HAYZdEmeJgOdo2kDlZkcCGHb+zs/vjU6iv4skbVBL7y+OnSv/oC2u83Yee8S3/aY0YAxkyBgu7hLTYH13Zc2Aw==", - "dependencies": { - "@stencil/core": "^4.12.2", - "ionicons": "^7.2.2", - "tslib": "^2.1.0" - } - }, - "node_modules/@ionic/utils-array": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@ionic/utils-array/-/utils-array-2.1.5.tgz", - "integrity": "sha512-HD72a71IQVBmQckDwmA8RxNVMTbxnaLbgFOl+dO5tbvW9CkkSFCv41h6fUuNsSEVgngfkn0i98HDuZC8mk+lTA==", - "dependencies": { - "debug": "^4.0.0", - "tslib": "^2.0.1" - }, - "engines": { - "node": ">=10.3.0" - } - }, - "node_modules/@ionic/utils-fs": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/@ionic/utils-fs/-/utils-fs-3.1.7.tgz", - "integrity": "sha512-2EknRvMVfhnyhL1VhFkSLa5gOcycK91VnjfrTB0kbqkTFCOXyXgVLI5whzq7SLrgD9t1aqos3lMMQyVzaQ5gVA==", - "dependencies": { - "@types/fs-extra": "^8.0.0", - "debug": "^4.0.0", - "fs-extra": "^9.0.0", - "tslib": "^2.0.1" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@ionic/utils-object": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/@ionic/utils-object/-/utils-object-2.1.6.tgz", - "integrity": "sha512-vCl7sl6JjBHFw99CuAqHljYJpcE88YaH2ZW4ELiC/Zwxl5tiwn4kbdP/gxi2OT3MQb1vOtgAmSNRtusvgxI8ww==", - "dev": true, - "dependencies": { - "debug": "^4.0.0", - "tslib": "^2.0.1" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@ionic/utils-process": { - "version": "2.1.12", - "resolved": "https://registry.npmjs.org/@ionic/utils-process/-/utils-process-2.1.12.tgz", - "integrity": "sha512-Jqkgyq7zBs/v/J3YvKtQQiIcxfJyplPgECMWgdO0E1fKrrH8EF0QGHNJ9mJCn6PYe2UtHNS8JJf5G21e09DfYg==", - "dev": true, - "dependencies": { - "@ionic/utils-object": "2.1.6", - "@ionic/utils-terminal": "2.3.5", - "debug": "^4.0.0", - "signal-exit": "^3.0.3", - "tree-kill": "^1.2.2", - "tslib": "^2.0.1" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@ionic/utils-stream": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/@ionic/utils-stream/-/utils-stream-3.1.5.tgz", - "integrity": "sha512-hkm46uHvEC05X/8PHgdJi4l4zv9VQDELZTM+Kz69odtO9zZYfnt8DkfXHJqJ+PxmtiE5mk/ehJWLnn/XAczTUw==", - "dev": true, - "dependencies": { - "debug": "^4.0.0", - "tslib": "^2.0.1" - }, - "engines": { - "node": ">=10.3.0" - } - }, - "node_modules/@ionic/utils-subprocess": { - "version": "2.1.11", - "resolved": "https://registry.npmjs.org/@ionic/utils-subprocess/-/utils-subprocess-2.1.11.tgz", - "integrity": "sha512-6zCDixNmZCbMCy5np8klSxOZF85kuDyzZSTTQKQP90ZtYNCcPYmuFSzaqDwApJT4r5L3MY3JrqK1gLkc6xiUPw==", - "dev": true, - "dependencies": { - "@ionic/utils-array": "2.1.5", - "@ionic/utils-fs": "3.1.6", - "@ionic/utils-process": "2.1.10", - "@ionic/utils-stream": "3.1.5", - "@ionic/utils-terminal": "2.3.3", - "cross-spawn": "^7.0.3", - "debug": "^4.0.0", - "tslib": "^2.0.1" - }, - "engines": { - "node": ">=10.3.0" - } - }, - "node_modules/@ionic/utils-subprocess/node_modules/@ionic/utils-fs": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/@ionic/utils-fs/-/utils-fs-3.1.6.tgz", - "integrity": "sha512-eikrNkK89CfGPmexjTfSWl4EYqsPSBh0Ka7by4F0PLc1hJZYtJxUZV3X4r5ecA8ikjicUmcbU7zJmAjmqutG/w==", - "dev": true, - "dependencies": { - "@types/fs-extra": "^8.0.0", - "debug": "^4.0.0", - "fs-extra": "^9.0.0", - "tslib": "^2.0.1" - }, - "engines": { - "node": ">=10.3.0" - } - }, - "node_modules/@ionic/utils-subprocess/node_modules/@ionic/utils-object": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@ionic/utils-object/-/utils-object-2.1.5.tgz", - "integrity": "sha512-XnYNSwfewUqxq+yjER1hxTKggftpNjFLJH0s37jcrNDwbzmbpFTQTVAp4ikNK4rd9DOebX/jbeZb8jfD86IYxw==", - "dev": true, - "dependencies": { - "debug": "^4.0.0", - "tslib": "^2.0.1" - }, - "engines": { - "node": ">=10.3.0" - } - }, - "node_modules/@ionic/utils-subprocess/node_modules/@ionic/utils-process": { - "version": "2.1.10", - "resolved": "https://registry.npmjs.org/@ionic/utils-process/-/utils-process-2.1.10.tgz", - "integrity": "sha512-mZ7JEowcuGQK+SKsJXi0liYTcXd2bNMR3nE0CyTROpMECUpJeAvvaBaPGZf5ERQUPeWBVuwqAqjUmIdxhz5bxw==", - "dev": true, - "dependencies": { - "@ionic/utils-object": "2.1.5", - "@ionic/utils-terminal": "2.3.3", - "debug": "^4.0.0", - "signal-exit": "^3.0.3", - "tree-kill": "^1.2.2", - "tslib": "^2.0.1" - }, - "engines": { - "node": ">=10.3.0" - } - }, - "node_modules/@ionic/utils-subprocess/node_modules/@ionic/utils-terminal": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/@ionic/utils-terminal/-/utils-terminal-2.3.3.tgz", - "integrity": "sha512-RnuSfNZ5fLEyX3R5mtcMY97cGD1A0NVBbarsSQ6yMMfRJ5YHU7hHVyUfvZeClbqkBC/pAqI/rYJuXKCT9YeMCQ==", - "dev": true, - "dependencies": { - "@types/slice-ansi": "^4.0.0", - "debug": "^4.0.0", - "signal-exit": "^3.0.3", - "slice-ansi": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "tslib": "^2.0.1", - "untildify": "^4.0.0", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=10.3.0" - } - }, - "node_modules/@ionic/utils-terminal": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@ionic/utils-terminal/-/utils-terminal-2.3.5.tgz", - "integrity": "sha512-3cKScz9Jx2/Pr9ijj1OzGlBDfcmx7OMVBt4+P1uRR0SSW4cm1/y3Mo4OY3lfkuaYifMNBW8Wz6lQHbs1bihr7A==", - "dev": true, - "dependencies": { - "@types/slice-ansi": "^4.0.0", - "debug": "^4.0.0", - "signal-exit": "^3.0.3", - "slice-ansi": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "tslib": "^2.0.1", - "untildify": "^4.0.0", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "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==", - "dev": true, - "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-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, - "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==", - "dev": true - }, - "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==", - "dev": true, - "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.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "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==", - "dev": true, - "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/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", - "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "dev": true - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@leichtgewicht/ip-codec": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", - "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", - "dev": true - }, - "node_modules/@ngtools/webpack": { - "version": "16.2.14", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-16.2.14.tgz", - "integrity": "sha512-3+zPP3Wir46qrZ3FEiTz5/emSoVHYUCH+WgBmJ57mZCx1qBOYh2VgllnPr/Yusl1sc/jUZjdwq/es/9ZNw+zDQ==", - "dev": true, - "engines": { - "node": "^16.14.0 || >=18.10.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "@angular/compiler-cli": "^16.0.0", - "typescript": ">=4.9.3 <5.2", - "webpack": "^5.54.0" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@npmcli/fs": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.1.tgz", - "integrity": "sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==", - "dev": true, - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@npmcli/git": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-4.1.0.tgz", - "integrity": "sha512-9hwoB3gStVfa0N31ymBmrX+GuDGdVA/QWShZVqE0HK2Af+7QGGrCTbZia/SW0ImUTjTne7SP91qxDmtXvDHRPQ==", - "dev": true, - "dependencies": { - "@npmcli/promise-spawn": "^6.0.0", - "lru-cache": "^7.4.4", - "npm-pick-manifest": "^8.0.0", - "proc-log": "^3.0.0", - "promise-inflight": "^1.0.1", - "promise-retry": "^2.0.1", - "semver": "^7.3.5", - "which": "^3.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@npmcli/git/node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/@npmcli/git/node_modules/which": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz", - "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/which.js" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@npmcli/installed-package-contents": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-2.1.0.tgz", - "integrity": "sha512-c8UuGLeZpm69BryRykLuKRyKFZYJsZSCT4aVY5ds4omyZqJ172ApzgfKJ5eV/r3HgLdUYgFVe54KSFVjKoe27w==", - "dev": true, - "dependencies": { - "npm-bundled": "^3.0.0", - "npm-normalize-package-bin": "^3.0.0" - }, - "bin": { - "installed-package-contents": "bin/index.js" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@npmcli/move-file": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-2.0.1.tgz", - "integrity": "sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==", - "deprecated": "This functionality has been moved to @npmcli/fs", - "dev": true, - "dependencies": { - "mkdirp": "^1.0.4", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/@npmcli/move-file/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@npmcli/move-file/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@npmcli/node-gyp": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-3.0.0.tgz", - "integrity": "sha512-gp8pRXC2oOxu0DUE1/M3bYtb1b3/DbJ5aM113+XJBgfXdussRAsX0YOrOhdd8WvnAR6auDBvJomGAkLKA5ydxA==", - "dev": true, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@npmcli/promise-spawn": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-6.0.2.tgz", - "integrity": "sha512-gGq0NJkIGSwdbUt4yhdF8ZrmkGKVz9vAdVzpOfnom+V8PLSmSOVhZwbNvZZS1EYcJN5hzzKBxmmVVAInM6HQLg==", - "dev": true, - "dependencies": { - "which": "^3.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@npmcli/promise-spawn/node_modules/which": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz", - "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/which.js" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@npmcli/run-script": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-6.0.2.tgz", - "integrity": "sha512-NCcr1uQo1k5U+SYlnIrbAh3cxy+OQT1VtqiAbxdymSlptbzBb62AjH2xXgjNCoP073hoa1CfCAcwoZ8k96C4nA==", - "dev": true, - "dependencies": { - "@npmcli/node-gyp": "^3.0.0", - "@npmcli/promise-spawn": "^6.0.0", - "node-gyp": "^9.0.0", - "read-package-json-fast": "^3.0.0", - "which": "^3.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@npmcli/run-script/node_modules/which": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz", - "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/which.js" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "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==", - "dev": true, - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/@schematics/angular": { - "version": "16.2.14", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-16.2.14.tgz", - "integrity": "sha512-YqIv727l9Qze8/OL6H9mBHc2jVXzAGRNBYnxYWqWhLbfvuVbbldo6NNIIjgv6lrl2LJSdPAAMNOD5m/f6210ug==", - "dev": true, - "dependencies": { - "@angular-devkit/core": "16.2.14", - "@angular-devkit/schematics": "16.2.14", - "jsonc-parser": "3.2.0" - }, - "engines": { - "node": "^16.14.0 || >=18.10.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "node_modules/@sigstore/bundle": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-1.1.0.tgz", - "integrity": "sha512-PFutXEy0SmQxYI4texPw3dd2KewuNqv7OuK1ZFtY2fM754yhvG2KdgwIhRnoEE2uHdtdGNQ8s0lb94dW9sELog==", - "dev": true, - "dependencies": { - "@sigstore/protobuf-specs": "^0.2.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@sigstore/protobuf-specs": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.2.1.tgz", - "integrity": "sha512-XTWVxnWJu+c1oCshMLwnKvz8ZQJJDVOlciMfgpJBQbThVjKTCG8dwyhgLngBD2KN0ap9F/gOV8rFDEx8uh7R2A==", - "dev": true, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@sigstore/sign": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-1.0.0.tgz", - "integrity": "sha512-INxFVNQteLtcfGmcoldzV6Je0sbbfh9I16DM4yJPw3j5+TFP8X6uIiA18mvpEa9yyeycAKgPmOA3X9hVdVTPUA==", - "dev": true, - "dependencies": { - "@sigstore/bundle": "^1.1.0", - "@sigstore/protobuf-specs": "^0.2.0", - "make-fetch-happen": "^11.0.1" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@sigstore/sign/node_modules/@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", - "dev": true, - "engines": { - "node": ">= 10" - } - }, - "node_modules/@sigstore/sign/node_modules/http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", - "dev": true, - "dependencies": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/@sigstore/sign/node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/@sigstore/sign/node_modules/make-fetch-happen": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz", - "integrity": "sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==", - "dev": true, - "dependencies": { - "agentkeepalive": "^4.2.1", - "cacache": "^17.0.0", - "http-cache-semantics": "^4.1.1", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", - "is-lambda": "^1.0.1", - "lru-cache": "^7.7.1", - "minipass": "^5.0.0", - "minipass-fetch": "^3.0.0", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "promise-retry": "^2.0.1", - "socks-proxy-agent": "^7.0.0", - "ssri": "^10.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@sigstore/sign/node_modules/minipass-fetch": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.5.tgz", - "integrity": "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==", - "dev": true, - "dependencies": { - "minipass": "^7.0.3", - "minipass-sized": "^1.0.3", - "minizlib": "^2.1.2" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - }, - "optionalDependencies": { - "encoding": "^0.1.13" - } - }, - "node_modules/@sigstore/sign/node_modules/minipass-fetch/node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/@sigstore/tuf": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-1.0.3.tgz", - "integrity": "sha512-2bRovzs0nJZFlCN3rXirE4gwxCn97JNjMmwpecqlbgV9WcxX7WRuIrgzx/X7Ib7MYRbyUTpBYE0s2x6AmZXnlg==", - "dev": true, - "dependencies": { - "@sigstore/protobuf-specs": "^0.2.0", - "tuf-js": "^1.1.7" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@socket.io/component-emitter": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", - "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==", - "dev": true - }, - "node_modules/@stencil/core": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.19.2.tgz", - "integrity": "sha512-ZdnbHmHEl8E5vN0GWDtONe5w6j3CrSqqxZM4hNLBPkV/aouWKug7D5/Mi6RazfYO5U4fmHQYLwMz60rHcx0G4g==", - "bin": { - "stencil": "bin/stencil" - }, - "engines": { - "node": ">=16.0.0", - "npm": ">=7.10.0" - } - }, - "node_modules/@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/@tufjs/canonical-json": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-1.0.0.tgz", - "integrity": "sha512-QTnf++uxunWvG2z3UFNzAoQPHxnSXOwtaI3iJ+AohhV+5vONuArPjJE7aPXPVXfXJsqrVbZBu9b81AJoSd09IQ==", - "dev": true, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@tufjs/models": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-1.0.4.tgz", - "integrity": "sha512-qaGV9ltJP0EO25YfFUPhxRVK0evXFIAGicsVXuRim4Ed9cjPxYhNnNJ49SFmbeLgtxpslIkX317IgpfcHPVj/A==", - "dev": true, - "dependencies": { - "@tufjs/canonical-json": "1.0.0", - "minimatch": "^9.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@types/body-parser": { - "version": "1.19.5", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", - "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", - "dev": true, - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "node_modules/@types/bonjour": { - "version": "3.5.13", - "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", - "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/connect": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/connect-history-api-fallback": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", - "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", - "dev": true, - "dependencies": { - "@types/express-serve-static-core": "*", - "@types/node": "*" - } - }, - "node_modules/@types/cookie": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", - "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==", - "dev": true - }, - "node_modules/@types/cordova": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/@types/cordova/-/cordova-11.0.3.tgz", - "integrity": "sha512-kyuRQ40/NWQVhqGIHq78Ehu2Bf9Mlg0LhmSmis6ZFJK7z933FRfYi8tHe/k/0fB+PGfCf95rJC6TO7dopaFvAg==" - }, - "node_modules/@types/cors": { - "version": "2.8.17", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz", - "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/eslint": { - "version": "8.56.10", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", - "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==", - "dev": true, - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "node_modules/@types/eslint-scope": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", - "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", - "dev": true, - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true - }, - "node_modules/@types/express": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", - "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", - "dev": true, - "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "node_modules/@types/express-serve-static-core": { - "version": "4.19.5", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.5.tgz", - "integrity": "sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==", - "dev": true, - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, - "node_modules/@types/fs-extra": { - "version": "8.1.5", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.5.tgz", - "integrity": "sha512-0dzKcwO+S8s2kuF5Z9oUWatQJj5Uq/iqphEtE3GQJVRRYm/tD1LglU2UnXi2A8jLq5umkGouOXOR9y0n613ZwQ==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/http-errors": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", - "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", - "dev": true - }, - "node_modules/@types/http-proxy": { - "version": "1.17.14", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.14.tgz", - "integrity": "sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/jasmine": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-5.1.4.tgz", - "integrity": "sha512-px7OMFO/ncXxixDe1zR13V1iycqWae0MxTaw62RpFlksUi5QuNWgQJFkTQjIOvrmutJbI7Fp2Y2N1F6D2R4G6w==", - "dev": true - }, - "node_modules/@types/jasminewd2": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/@types/jasminewd2/-/jasminewd2-2.0.13.tgz", - "integrity": "sha512-aJ3wj8tXMpBrzQ5ghIaqMisD8C3FIrcO6sDKHqFbuqAsI7yOxj0fA7MrRCPLZHIVUjERIwsMmGn/vB0UQ9u0Hg==", - "dev": true, - "dependencies": { - "@types/jasmine": "*" - } - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true - }, - "node_modules/@types/mime": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", - "dev": true - }, - "node_modules/@types/node": { - "version": "20.14.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.10.tgz", - "integrity": "sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@types/node-forge": { - "version": "1.3.11", - "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", - "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/q": { - "version": "0.0.32", - "resolved": "https://registry.npmjs.org/@types/q/-/q-0.0.32.tgz", - "integrity": "sha512-qYi3YV9inU/REEfxwVcGZzbS3KG/Xs90lv0Pr+lDtuVjBPGd1A+eciXzVSaRvLify132BfcvhvEjeVahrUl0Ug==", - "dev": true - }, - "node_modules/@types/qs": { - "version": "6.9.15", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", - "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==", - "dev": true - }, - "node_modules/@types/range-parser": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", - "dev": true - }, - "node_modules/@types/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", - "dev": true - }, - "node_modules/@types/selenium-webdriver": { - "version": "3.0.26", - "resolved": "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-3.0.26.tgz", - "integrity": "sha512-dyIGFKXfUFiwkMfNGn1+F6b80ZjR3uSYv1j6xVJSDlft5waZ2cwkHW4e7zNzvq7hiEackcgvBpmnXZrI1GltPg==", - "dev": true - }, - "node_modules/@types/semver": { - "version": "7.5.8", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", - "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", - "dev": true - }, - "node_modules/@types/send": { - "version": "0.17.4", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", - "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", - "dev": true, - "dependencies": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "node_modules/@types/serve-index": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", - "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", - "dev": true, - "dependencies": { - "@types/express": "*" - } - }, - "node_modules/@types/serve-static": { - "version": "1.15.7", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", - "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", - "dev": true, - "dependencies": { - "@types/http-errors": "*", - "@types/node": "*", - "@types/send": "*" - } - }, - "node_modules/@types/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-+OpjSaq85gvlZAYINyzKpLeiFkSC4EsC6IIiT6v6TLSU5k5U83fHGj9Lel8oKEXM0HqgrMVCjXPDPVICtxF7EQ==", - "dev": true - }, - "node_modules/@types/sockjs": { - "version": "0.3.36", - "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", - "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/ws": { - "version": "8.5.10", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", - "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz", - "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==", - "dev": true, - "dependencies": { - "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/type-utils": "6.21.0", - "@typescript-eslint/utils": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", - "debug": "^4.3.4", - "graphemer": "^1.4.0", - "ignore": "^5.2.4", - "natural-compare": "^1.4.0", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", - "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/typescript-estree": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", - "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz", - "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==", - "dev": true, - "dependencies": { - "@typescript-eslint/typescript-estree": "6.21.0", - "@typescript-eslint/utils": "6.21.0", - "debug": "^4.3.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", - "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", - "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", - "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/typescript-estree": "6.21.0", - "semver": "^7.5.4" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", - "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true - }, - "node_modules/@vitejs/plugin-basic-ssl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-1.0.1.tgz", - "integrity": "sha512-pcub+YbFtFhaGRTo1832FQHQSHvMrlb43974e2eS8EKleR3p1cDdkJFPci1UhwkEf1J9Bz+wKBSzqpKp7nNj2A==", - "dev": true, - "engines": { - "node": ">=14.6.0" - }, - "peerDependencies": { - "vite": "^3.0.0 || ^4.0.0" - } - }, - "node_modules/@webassemblyjs/ast": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", - "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", - "dev": true, - "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" - } - }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", - "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", - "dev": true, - "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", - "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.12.1" - } - }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", - "dev": true, - "dependencies": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", - "dev": true, - "dependencies": { - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", - "dev": true - }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", - "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-opt": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1", - "@webassemblyjs/wast-printer": "1.12.1" - } - }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", - "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", - "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1" - } - }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", - "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", - "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@wessberg/ts-evaluator": { - "version": "0.0.27", - "resolved": "https://registry.npmjs.org/@wessberg/ts-evaluator/-/ts-evaluator-0.0.27.tgz", - "integrity": "sha512-7gOpVm3yYojUp/Yn7F4ZybJRxyqfMNf0LXK5KJiawbPfL0XTsJV+0mgrEDjOIR6Bi0OYk2Cyg4tjFu1r8MCZaA==", - "deprecated": "this package has been renamed to ts-evaluator. Please install ts-evaluator instead", - "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "jsdom": "^16.4.0", - "object-path": "^0.11.5", - "tslib": "^2.0.3" - }, - "engines": { - "node": ">=10.1.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/wessberg/ts-evaluator?sponsor=1" - }, - "peerDependencies": { - "typescript": ">=3.2.x || >= 4.x" - } - }, - "node_modules/@wessberg/ts-evaluator/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==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@wessberg/ts-evaluator/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "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/@wessberg/ts-evaluator/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==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@wessberg/ts-evaluator/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==", - "dev": true - }, - "node_modules/@wessberg/ts-evaluator/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==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@wessberg/ts-evaluator/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==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@xmldom/xmldom": { - "version": "0.8.10", - "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", - "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==", - "dev": true, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "node_modules/@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true - }, - "node_modules/@yarnpkg/lockfile": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", - "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", - "dev": true - }, - "node_modules/abab": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", - "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", - "deprecated": "Use your platform's native atob() and btoa() methods instead", - "dev": true - }, - "node_modules/abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dev": true, - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-globals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", - "dev": true, - "dependencies": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" - } - }, - "node_modules/acorn-globals/node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-import-assertions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", - "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", - "dev": true, - "peerDependencies": { - "acorn": "^8" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/adjust-sourcemap-loader": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz", - "integrity": "sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==", - "dev": true, - "dependencies": { - "loader-utils": "^2.0.0", - "regex-parser": "^2.2.11" - }, - "engines": { - "node": ">=8.9" - } - }, - "node_modules/adjust-sourcemap-loader/node_modules/loader-utils": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", - "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", - "dev": true, - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" - } - }, - "node_modules/adm-zip": { - "version": "0.5.14", - "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.14.tgz", - "integrity": "sha512-DnyqqifT4Jrcvb8USYjp6FHtBpEIz1mnXu6pTRHZ0RL69LbQYiO+0lDFg5+OKA7U29oWSs3a/i8fhn8ZcceIWg==", - "dev": true, - "engines": { - "node": ">=12.0" - } - }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/agentkeepalive": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz", - "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==", - "dev": true, - "dependencies": { - "humanize-ms": "^1.2.1" - }, - "engines": { - "node": ">= 8.0.0" - } - }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ajv": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", - "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.3", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dev": true, - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/ansi-colors": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-html-community": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", - "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", - "dev": true, - "engines": [ - "node >= 0.8.0" - ], - "bin": { - "ansi-html": "bin/ansi-html" - } - }, - "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==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/app-root-path": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.1.0.tgz", - "integrity": "sha512-biN3PwB2gUtjaYy/isrU3aNWI5w+fAfvHkSvCKeQGxhmYpwKFUxudR3Yya+KqVRHBmEDYh+/lTozYCFbmzX4nA==", - "dev": true, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/aproba": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", - "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", - "dev": true - }, - "node_modules/are-we-there-yet": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", - "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", - "deprecated": "This package is no longer supported.", - "dev": true, - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/argparse/node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true - }, - "node_modules/aria-query": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-3.0.0.tgz", - "integrity": "sha512-majUxHgLehQTeSA+hClx+DY09OVUqG3GtezWkF1krgLGNdlDu9l9V8DaqNMWbq4Eddc8wsyDA0hpDUtnYxQEXw==", - "dev": true, - "dependencies": { - "ast-types-flow": "0.0.7", - "commander": "^2.11.0" - } - }, - "node_modules/aria-query/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "dev": true - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "dev": true, - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/ast-types-flow": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", - "integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==", - "dev": true - }, - "node_modules/astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/async-mutex": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.2.6.tgz", - "integrity": "sha512-Hs4R+4SPgamu6rSGW8C7cV9gaWUKEHykfzCCvIRuaVv636Ju10ZdeUbvb4TBEW0INuq2DHZqXbK4Nd3yG4RaRw==", - "dependencies": { - "tslib": "^2.0.0" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true - }, - "node_modules/at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/autoprefixer": { - "version": "10.4.14", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.14.tgz", - "integrity": "sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/autoprefixer" - } - ], - "dependencies": { - "browserslist": "^4.21.5", - "caniuse-lite": "^1.0.30001464", - "fraction.js": "^4.2.0", - "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", - "postcss-value-parser": "^4.2.0" - }, - "bin": { - "autoprefixer": "bin/autoprefixer" - }, - "engines": { - "node": "^10 || ^12 || >=14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/aws4": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.0.tgz", - "integrity": "sha512-3AungXC4I8kKsS9PuS4JH2nc+0bVY/mjgrephHTIi8fpEeGsTHBUJeosp0Wc1myYMElmD0B3Oc4XL/HVJ4PV2g==", - "dev": true - }, - "node_modules/axobject-query": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.0.2.tgz", - "integrity": "sha512-MCeek8ZH7hKyO1rWUbKNQBbl4l2eY0ntk7OGi+q0RlafrCnfPxC06WZA+uebCfmYp4mNU9jRBP1AhGyf8+W3ww==", - "dev": true, - "dependencies": { - "ast-types-flow": "0.0.7" - } - }, - "node_modules/babel-loader": { - "version": "9.1.3", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.3.tgz", - "integrity": "sha512-xG3ST4DglodGf8qSwv0MdeWLhrDsw/32QMdTO5T1ZIp9gQur0HkCyFs7Awskr10JKXFXwpAhiCuYX5oGXnRGbw==", - "dev": true, - "dependencies": { - "find-cache-dir": "^4.0.0", - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 14.15.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0", - "webpack": ">=5" - } - }, - "node_modules/babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.11", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", - "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.6.2", - "semver": "^6.3.1" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.8.7", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.7.tgz", - "integrity": "sha512-KyDvZYxAzkC0Aj2dAPyDzi2Ym15e5JKZSK+maI7NAwSqofvuFglbSsxE7wUOvTg9oFVnHMzVzBKcqEb4PJgtOA==", - "dev": true, - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.4.4", - "core-js-compat": "^3.33.1" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-corejs3/node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.4.tgz", - "integrity": "sha512-QcJMILQCu2jm5TFPGA3lCpJJTeEP+mqeXooG/NZbg/h5FTFi6V0+99ahlRsW8/kRLyb24LZVCCiclDedhLKcBA==", - "dev": true, - "dependencies": { - "@babel/helper-compilation-targets": "^7.22.6", - "@babel/helper-plugin-utils": "^7.22.5", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.5.tgz", - "integrity": "sha512-OJGYZlhLqBh2DDHeqAxWB1XIvr49CxiJ2gIt61/PU55CQK4Z58OzMqjDe1zwQdQk+rBYsRc+1rJmdajM3gimHg==", - "dev": true, - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.5.0" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-regenerator/node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.5.0.tgz", - "integrity": "sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q==", - "dev": true, - "dependencies": { - "@babel/helper-compilation-targets": "^7.22.6", - "@babel/helper-plugin-utils": "^7.22.5", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "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==", - "dev": true - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/base64id": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", - "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", - "dev": true, - "engines": { - "node": "^4.5.0 || >= 5.9" - } - }, - "node_modules/batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", - "dev": true - }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", - "dev": true, - "dependencies": { - "tweetnacl": "^0.14.3" - } - }, - "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==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/bignumber.js": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", - "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", - "engines": { - "node": "*" - } - }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/blocking-proxy": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/blocking-proxy/-/blocking-proxy-1.0.1.tgz", - "integrity": "sha512-KE8NFMZr3mN2E0HcvCgRtX7DjhiIQrwle+nSVJVC/yqFb9+xznHl2ZcoBp2L9qzkI4t4cBFJ1efXF8Dwi132RA==", - "dev": true, - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "blocking-proxy": "built/lib/bin.js" - }, - "engines": { - "node": ">=6.9.x" - } - }, - "node_modules/body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", - "dev": true, - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/bonjour-service": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", - "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.3", - "multicast-dns": "^7.2.5" - } - }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "dev": true - }, - "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==", - "dev": true, - "dependencies": { - "big-integer": "1.6.x" - }, - "engines": { - "node": ">= 5.10.0" - } - }, - "node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", - "dev": true - }, - "node_modules/browserslist": { - "version": "4.23.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.2.tgz", - "integrity": "sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "caniuse-lite": "^1.0.30001640", - "electron-to-chromium": "^1.4.820", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.1.0" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/browserstack": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/browserstack/-/browserstack-1.6.1.tgz", - "integrity": "sha512-GxtFjpIaKdbAyzHfFDKixKO8IBT7wR3NjbzrGc78nNs/Ciys9wU3/nBtsqsWv5nDSrdI5tz0peKuzCPuNXNUiw==", - "dev": true, - "dependencies": { - "https-proxy-agent": "^2.2.1" - } - }, - "node_modules/browserstack/node_modules/agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "dev": true, - "dependencies": { - "es6-promisify": "^5.0.0" - }, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/browserstack/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/browserstack/node_modules/https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "dev": true, - "dependencies": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - }, - "engines": { - "node": ">= 4.5.0" - } - }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "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==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "node_modules/builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha512-wxXCdllwGhI2kCC0MnvTGYTMvnVZTvqgypkiTI8Pa5tcz2i6VqsqwYGgqwXji+4RgCzms6EajE4IxiUH6HH8nQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/cacache": { - "version": "17.1.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-17.1.4.tgz", - "integrity": "sha512-/aJwG2l3ZMJ1xNAnqbMpA40of9dj/pIH3QfiuQSqjfPJF747VR0J/bHn+/KdNnHKc6XQcWt/AfRSBft82W1d2A==", - "dev": true, - "dependencies": { - "@npmcli/fs": "^3.1.0", - "fs-minipass": "^3.0.0", - "glob": "^10.2.2", - "lru-cache": "^7.7.1", - "minipass": "^7.0.3", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "p-map": "^4.0.0", - "ssri": "^10.0.0", - "tar": "^6.1.11", - "unique-filename": "^3.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/cacache/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "dev": true, - "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/cacache/node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/cacache/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/cacache/node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "dev": true, - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001641", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001641.tgz", - "integrity": "sha512-Phv5thgl67bHYo1TtMY/MurjkHhV4EDaCosezRXgZ8jzA/Ub+wjxAvbGvjoFENStinwi5kCyOYV3mi5tOGykwA==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ] - }, - "node_modules/canvas-confetti": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/canvas-confetti/-/canvas-confetti-1.9.3.tgz", - "integrity": "sha512-rFfTURMvmVEX1gyXFgn5QMn81bYk70qa0HLzcIOSVEyl57n6o9ItHeBtUSWdvKAPY0xlvBHno4/v3QPrT83q9g==", - "funding": { - "type": "donate", - "url": "https://www.paypal.me/kirilvatev" - } - }, - "node_modules/capacitor-navigationbarnx": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/capacitor-navigationbarnx/-/capacitor-navigationbarnx-0.1.6.tgz", - "integrity": "sha512-Z/1636u53k0Zw4BGTEMSvwV9yxVc4Fny0pSowlfHNViJxxz9r281D7Hhuo1OFlVpF3BAzWGeaHQ1iB4lf1WuXQ==", - "dependencies": { - "@capacitor/core": "^5.0.0" - } - }, - "node_modules/capacitor-navigationbarnx/node_modules/@capacitor/core": { - "version": "5.7.6", - "resolved": "https://registry.npmjs.org/@capacitor/core/-/core-5.7.6.tgz", - "integrity": "sha512-YVCNegFg04Pm6Rfc6KbZT2wnxAUzhcyi3b+MWFj+FwUOOFNmnGkzxCFo4tQakXFblfOK6pU0Va5XuiNs1+Fnow==", - "dependencies": { - "tslib": "^2.1.0" - } - }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", - "dev": true - }, - "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true - }, - "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/chrome-trace-event": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", - "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", - "dev": true, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "dependencies": { - "restore-cursor": "^3.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-spinners": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", - "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", - "dev": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cli-width": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", - "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", - "dev": true, - "engines": { - "node": ">= 10" - } - }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/codelyzer": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/codelyzer/-/codelyzer-6.0.2.tgz", - "integrity": "sha512-v3+E0Ucu2xWJMOJ2fA/q9pDT/hlxHftHGPUay1/1cTgyPV5JTHFdO9hqo837Sx2s9vKBMTt5gO+lhF95PO6J+g==", - "dev": true, - "dependencies": { - "@angular/compiler": "9.0.0", - "@angular/core": "9.0.0", - "app-root-path": "^3.0.0", - "aria-query": "^3.0.0", - "axobject-query": "2.0.2", - "css-selector-tokenizer": "^0.7.1", - "cssauron": "^1.4.0", - "damerau-levenshtein": "^1.0.4", - "rxjs": "^6.5.3", - "semver-dsl": "^1.0.1", - "source-map": "^0.5.7", - "sprintf-js": "^1.1.2", - "tslib": "^1.10.0", - "zone.js": "~0.10.3" - }, - "peerDependencies": { - "@angular/compiler": ">=2.3.1 <13.0.0 || ^12.0.0-next || ^12.1.0-next || ^12.2.0-next", - "@angular/core": ">=2.3.1 <13.0.0 || ^12.0.0-next || ^12.1.0-next || ^12.2.0-next", - "tslint": "^5.0.0 || ^6.0.0" - } - }, - "node_modules/codelyzer/node_modules/@angular/compiler": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-9.0.0.tgz", - "integrity": "sha512-ctjwuntPfZZT2mNj2NDIVu51t9cvbhl/16epc5xEwyzyDt76pX9UgwvY+MbXrf/C/FWwdtmNtfP698BKI+9leQ==", - "dev": true, - "peerDependencies": { - "tslib": "^1.10.0" - } - }, - "node_modules/codelyzer/node_modules/@angular/core": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-9.0.0.tgz", - "integrity": "sha512-6Pxgsrf0qF9iFFqmIcWmjJGkkCaCm6V5QNnxMy2KloO3SDq6QuMVRbN9RtC8Urmo25LP+eZ6ZgYqFYpdD8Hd9w==", - "dev": true, - "peerDependencies": { - "rxjs": "^6.5.3", - "tslib": "^1.10.0", - "zone.js": "~0.10.2" - } - }, - "node_modules/codelyzer/node_modules/rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "dev": true, - "dependencies": { - "tslib": "^1.9.0" - }, - "engines": { - "npm": ">=2.0.0" - } - }, - "node_modules/codelyzer/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/codelyzer/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "node_modules/codelyzer/node_modules/zone.js": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.10.3.tgz", - "integrity": "sha512-LXVLVEq0NNOqK/fLJo3d0kfzd4sxwn2/h67/02pjCjfKDxgx1i9QqpvtHD8CrBnSSwMw5+dy11O7FRX5mkO7Cg==", - "dev": true - }, - "node_modules/color": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", - "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", - "dependencies": { - "color-convert": "^2.0.1", - "color-string": "^1.9.0" - }, - "engines": { - "node": ">=12.5.0" - } - }, - "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - }, - "node_modules/color-string": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", - "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", - "dependencies": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, - "node_modules/color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "dev": true, - "bin": { - "color-support": "bin.js" - } - }, - "node_modules/color/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==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color/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==" - }, - "node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "dev": true - }, - "node_modules/colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true, - "engines": { - "node": ">=0.1.90" - } - }, - "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==", - "dev": true, - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/commander": { - "version": "9.5.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", - "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", - "dev": true, - "engines": { - "node": "^12.20.0 || >=14" - } - }, - "node_modules/common-path-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", - "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", - "dev": true - }, - "node_modules/compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "dev": true, - "dependencies": { - "mime-db": ">= 1.43.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", - "dev": true, - "dependencies": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/compression/node_modules/bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/compression/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/compression/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/compression/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==", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "node_modules/concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "engines": [ - "node >= 0.8" - ], - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/concat-stream/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==", - "dev": 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/concat-stream/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==", - "dev": true - }, - "node_modules/concat-stream/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==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/connect": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", - "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", - "dev": true, - "dependencies": { - "debug": "2.6.9", - "finalhandler": "1.1.2", - "parseurl": "~1.3.3", - "utils-merge": "1.0.1" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/connect-history-api-fallback": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", - "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/connect/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/connect/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "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==", - "dev": true - }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dev": true, - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true - }, - "node_modules/cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", - "dev": true - }, - "node_modules/copy-anything": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz", - "integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==", - "dev": true, - "dependencies": { - "is-what": "^3.14.1" - }, - "funding": { - "url": "https://github.com/sponsors/mesqueeb" - } - }, - "node_modules/copy-webpack-plugin": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz", - "integrity": "sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==", - "dev": true, - "dependencies": { - "fast-glob": "^3.2.11", - "glob-parent": "^6.0.1", - "globby": "^13.1.1", - "normalize-path": "^3.0.0", - "schema-utils": "^4.0.0", - "serialize-javascript": "^6.0.0" - }, - "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - } - }, - "node_modules/copy-webpack-plugin/node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/copy-webpack-plugin/node_modules/globby": { - "version": "13.2.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", - "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", - "dev": true, - "dependencies": { - "dir-glob": "^3.0.1", - "fast-glob": "^3.3.0", - "ignore": "^5.2.4", - "merge2": "^1.4.1", - "slash": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/copy-webpack-plugin/node_modules/slash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", - "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cordova-plugin-purchase": { - "version": "13.11.1", - "resolved": "https://registry.npmjs.org/cordova-plugin-purchase/-/cordova-plugin-purchase-13.11.1.tgz", - "integrity": "sha512-24KpOIgRaNFFH2F8TWE8lYhY6T3mYereqGNGGXJPi5j60MKx/CHqOuyvbCuMdAfLG+7XiGhcEi7XSXbOrFrEzw==" - }, - "node_modules/cordova-res": { - "version": "0.15.4", - "resolved": "https://registry.npmjs.org/cordova-res/-/cordova-res-0.15.4.tgz", - "integrity": "sha512-TjFZhjUtK8qq4DVrgR+KI7tKcUL704cnkTPRhHbKlCPzefHoz1tBOX93wc76dOMmOWKTsbJz83DIm6mqdp5Pmg==", - "dependencies": { - "@ionic/utils-array": "^2.1.5", - "@ionic/utils-fs": "^3.1.5", - "debug": "^4.2.0", - "elementtree": "^0.1.7", - "sharp": "^0.29.2", - "tslib": "^2.0.3" - }, - "bin": { - "cordova-res": "bin/cordova-res" - }, - "engines": { - "node": ">=10.3.0" - } - }, - "node_modules/core-js-compat": { - "version": "3.37.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz", - "integrity": "sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==", - "dev": true, - "dependencies": { - "browserslist": "^4.23.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", - "dev": true - }, - "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "dev": true, - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/cosmiconfig": { - "version": "8.3.6", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", - "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", - "dev": true, - "dependencies": { - "import-fresh": "^3.3.0", - "js-yaml": "^4.1.0", - "parse-json": "^5.2.0", - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/d-fischer" - }, - "peerDependencies": { - "typescript": ">=4.9.5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/cosmiconfig/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==", - "dev": true - }, - "node_modules/cosmiconfig/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/critters": { - "version": "0.0.20", - "resolved": "https://registry.npmjs.org/critters/-/critters-0.0.20.tgz", - "integrity": "sha512-CImNRorKOl5d8TWcnAz5n5izQ6HFsvz29k327/ELy6UFcmbiZNOsinaKvzv16WZR0P6etfSWYzE47C4/56B3Uw==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "css-select": "^5.1.0", - "dom-serializer": "^2.0.0", - "domhandler": "^5.0.2", - "htmlparser2": "^8.0.2", - "postcss": "^8.4.23", - "pretty-bytes": "^5.3.0" - } - }, - "node_modules/critters/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==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/critters/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "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/critters/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==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/critters/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==", - "dev": true - }, - "node_modules/critters/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==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/critters/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==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/css-loader": { - "version": "6.8.1", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.8.1.tgz", - "integrity": "sha512-xDAXtEVGlD0gJ07iclwWVkLoZOpEvAWaSyf6W18S2pOC//K8+qUDIx8IIT3D+HjnmkJPQeesOPv5aiUaJsCM2g==", - "dev": true, - "dependencies": { - "icss-utils": "^5.1.0", - "postcss": "^8.4.21", - "postcss-modules-extract-imports": "^3.0.0", - "postcss-modules-local-by-default": "^4.0.3", - "postcss-modules-scope": "^3.0.0", - "postcss-modules-values": "^4.0.0", - "postcss-value-parser": "^4.2.0", - "semver": "^7.3.8" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - } - }, - "node_modules/css-select": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", - "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", - "dev": true, - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.1.0", - "domhandler": "^5.0.2", - "domutils": "^3.0.1", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/css-selector-tokenizer": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.3.tgz", - "integrity": "sha512-jWQv3oCEL5kMErj4wRnK/OPoBi0D+P1FR2cDCKYPaMeD2eW3/mttav8HT4hT1CKopiJI/psEULjkClhvJo4Lvg==", - "dev": true, - "dependencies": { - "cssesc": "^3.0.0", - "fastparse": "^1.1.2" - } - }, - "node_modules/css-what": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", - "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", - "dev": true, - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/cssauron": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/cssauron/-/cssauron-1.4.0.tgz", - "integrity": "sha512-Ht70DcFBh+/ekjVrYS2PlDMdSQEl3OFNmjK6lcn49HptBgilXf/Zwg4uFh9Xn0pX3Q8YOkSjIFOfK2osvdqpBw==", - "dev": true, - "dependencies": { - "through": "X.X.X" - } - }, - "node_modules/cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "dev": true, - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cssom": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", - "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", - "dev": true - }, - "node_modules/cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", - "dev": true, - "dependencies": { - "cssom": "~0.3.6" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cssstyle/node_modules/cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", - "dev": true - }, - "node_modules/custom-event": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", - "integrity": "sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg==", - "dev": true - }, - "node_modules/damerau-levenshtein": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", - "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", - "dev": true - }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", - "dev": true, - "dependencies": { - "abab": "^2.0.3", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/date-format": { - "version": "4.0.14", - "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", - "integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/decimal.js": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", - "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", - "dev": true - }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "node_modules/default-gateway": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", - "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", - "dev": true, - "dependencies": { - "execa": "^5.0.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/defaults": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", - "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", - "dev": true, - "dependencies": { - "clone": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dev": true, - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-lazy-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/del": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", - "integrity": "sha512-Z4fzpbIRjOu7lO5jCETSWoqUDVe0IPOlfugBsF6suen2LKDlVb4QZpKEM9P+buNJ4KI1eN7I083w/pbKUpsrWQ==", - "dev": true, - "dependencies": { - "globby": "^5.0.0", - "is-path-cwd": "^1.0.0", - "is-path-in-cwd": "^1.0.0", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "rimraf": "^2.2.8" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/del/node_modules/array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", - "dev": true, - "dependencies": { - "array-uniq": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/del/node_modules/globby": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", - "integrity": "sha512-HJRTIH2EeH44ka+LWig+EqT2ONSYpVlNfx6pyd592/VF1TbfljJ7elwie7oSwcViLGqOdWocSdu2txwBF9bjmQ==", - "dev": true, - "dependencies": { - "array-union": "^1.0.1", - "arrify": "^1.0.0", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/del/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", - "dev": true - }, - "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==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "dev": true, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", - "bin": { - "detect-libc": "bin/detect-libc.js" - }, - "engines": { - "node": ">=0.10" - } - }, - "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==", - "dev": true - }, - "node_modules/di": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", - "integrity": "sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA==", - "dev": true - }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/dns-packet": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", - "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", - "dev": true, - "dependencies": { - "@leichtgewicht/ip-codec": "^2.0.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/dom-serialize": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", - "integrity": "sha512-Yra4DbvoW7/Z6LBN560ZwXMjoNOSAN2wRsKFGc4iBeso+mpIA6qj1vfdf9HpMaKAqG6wXTy+1SYEzmNpKXOSsQ==", - "dev": true, - "dependencies": { - "custom-event": "~1.0.0", - "ent": "~2.2.0", - "extend": "^3.0.0", - "void-elements": "^2.0.0" - } - }, - "node_modules/dom-serializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", - "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", - "dev": true, - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "entities": "^4.2.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ] - }, - "node_modules/domexception": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", - "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", - "deprecated": "Use your platform's native DOMException instead", - "dev": true, - "dependencies": { - "webidl-conversions": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/domexception/node_modules/webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/domhandler": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", - "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", - "dev": true, - "dependencies": { - "domelementtype": "^2.3.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/domutils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", - "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", - "dev": true, - "dependencies": { - "dom-serializer": "^2.0.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true - }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", - "dev": true, - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "node_modules/ecc-jsbn/node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", - "dev": true - }, - "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==", - "dev": true - }, - "node_modules/electron-to-chromium": { - "version": "1.4.825", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.825.tgz", - "integrity": "sha512-OCcF+LwdgFGcsYPYC5keEEFC2XT0gBhrYbeGzHCx7i9qRFbzO/AqTmc/C/1xNhJj+JA7rzlN7mpBuStshh96Cg==", - "dev": true - }, - "node_modules/elementtree": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/elementtree/-/elementtree-0.1.7.tgz", - "integrity": "sha512-wkgGT6kugeQk/P6VZ/f4T+4HB41BVgNBq5CDIZVbQ02nvTVqAiVTbskxxu3eA/X96lMlfYOwnLQpN2v5E1zDEg==", - "dependencies": { - "sax": "1.1.4" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "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==", - "dev": true - }, - "node_modules/emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/encoding": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", - "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", - "dev": true, - "optional": true, - "dependencies": { - "iconv-lite": "^0.6.2" - } - }, - "node_modules/encoding/node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dev": true, - "optional": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/engine.io": { - "version": "6.5.5", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.5.tgz", - "integrity": "sha512-C5Pn8Wk+1vKBoHghJODM63yk8MvrO9EWZUfkAt5HAqIgPE4/8FF0PEGHXtEd40l223+cE5ABWuPzm38PHFXfMA==", - "dev": true, - "dependencies": { - "@types/cookie": "^0.4.1", - "@types/cors": "^2.8.12", - "@types/node": ">=10.0.0", - "accepts": "~1.3.4", - "base64id": "2.0.0", - "cookie": "~0.4.1", - "cors": "~2.8.5", - "debug": "~4.3.1", - "engine.io-parser": "~5.2.1", - "ws": "~8.17.1" - }, - "engines": { - "node": ">=10.2.0" - } - }, - "node_modules/engine.io-parser": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.2.tgz", - "integrity": "sha512-RcyUFKA93/CXH20l4SoVvzZfrSDMOTUS3bWVpTt2FuFP+XYrL8i8oonHP7WInRyVHXh0n/ORtoeiE1os+8qkSw==", - "dev": true, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/engine.io/node_modules/ws": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", - "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", - "dev": true, - "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/enhanced-resolve": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.0.tgz", - "integrity": "sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/ent": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.1.tgz", - "integrity": "sha512-QHuXVeZx9d+tIQAz/XztU0ZwZf2Agg9CcXcgE1rurqvdBeDBrpSwjl8/6XUqMg7tw2Y7uAdKb2sRv+bSEFqQ5A==", - "dev": true, - "dependencies": { - "punycode": "^1.4.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "devOptional": true, - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/err-code": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", - "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", - "dev": true - }, - "node_modules/errno": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", - "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", - "dev": true, - "optional": true, - "dependencies": { - "prr": "~1.0.1" - }, - "bin": { - "errno": "cli.js" - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.2.4" - }, - "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==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-module-lexer": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", - "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", - "dev": true - }, - "node_modules/es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", - "dev": true - }, - "node_modules/es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==", - "dev": true, - "dependencies": { - "es6-promise": "^4.0.3" - } - }, - "node_modules/esbuild": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.17.tgz", - "integrity": "sha512-1GJtYnUxsJreHYA0Y+iQz2UEykonY66HNWOb0yXYZi9/kNrORUEHVg87eQsCtqh59PEJ5YVZJO98JHznMJSWjg==", - "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/android-arm": "0.18.17", - "@esbuild/android-arm64": "0.18.17", - "@esbuild/android-x64": "0.18.17", - "@esbuild/darwin-arm64": "0.18.17", - "@esbuild/darwin-x64": "0.18.17", - "@esbuild/freebsd-arm64": "0.18.17", - "@esbuild/freebsd-x64": "0.18.17", - "@esbuild/linux-arm": "0.18.17", - "@esbuild/linux-arm64": "0.18.17", - "@esbuild/linux-ia32": "0.18.17", - "@esbuild/linux-loong64": "0.18.17", - "@esbuild/linux-mips64el": "0.18.17", - "@esbuild/linux-ppc64": "0.18.17", - "@esbuild/linux-riscv64": "0.18.17", - "@esbuild/linux-s390x": "0.18.17", - "@esbuild/linux-x64": "0.18.17", - "@esbuild/netbsd-x64": "0.18.17", - "@esbuild/openbsd-x64": "0.18.17", - "@esbuild/sunos-x64": "0.18.17", - "@esbuild/win32-arm64": "0.18.17", - "@esbuild/win32-ia32": "0.18.17", - "@esbuild/win32-x64": "0.18.17" - } - }, - "node_modules/esbuild-wasm": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.18.17.tgz", - "integrity": "sha512-9OHGcuRzy+I8ziF9FzjfKLWAPbvi0e/metACVg9k6bK+SI4FFxeV6PcZsz8RIVaMD4YNehw+qj6UMR3+qj/EuQ==", - "dev": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "dev": true - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/escodegen": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", - "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", - "dev": true, - "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=6.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" - } - }, - "node_modules/escodegen/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/eslint/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==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/eslint/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==", - "dev": true - }, - "node_modules/eslint/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/eslint/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "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/eslint/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==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/eslint/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==", - "dev": true - }, - "node_modules/eslint/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/eslint/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/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==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/eslint/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/eslint/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/eslint/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/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==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/ethereum-blockies": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ethereum-blockies/-/ethereum-blockies-0.1.1.tgz", - "integrity": "sha512-ED+noMZ6z7RrzzhvrQna1L30C27MX+ZsdB5c/d5vygXtHjEyAQjQS2TgCYhPxs+z3U+u2YQsL9PiRkNl1f+ugg==" - }, - "node_modules/eventemitter-asyncresource": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/eventemitter-asyncresource/-/eventemitter-asyncresource-1.0.0.tgz", - "integrity": "sha512-39F7TBIV0G7gTelxwbEqnwhp90eqCPON1k0NwNfwhgKn4Co4ybUbj2pECcXT0B3ztRKZ7Pw1JujUUgmQJHcVAQ==", - "dev": true - }, - "node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "dev": true - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true, - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/execa/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==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/expand-template": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/exponential-backoff": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz", - "integrity": "sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==", - "dev": true - }, - "node_modules/express": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", - "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", - "dev": true, - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.2", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.6.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/express/node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/express/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/express/node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "dev": true, - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/express/node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "node_modules/external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dev": true, - "dependencies": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/extract-zip": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz", - "integrity": "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==", - "dev": true, - "dependencies": { - "concat-stream": "^1.6.2", - "debug": "^2.6.9", - "mkdirp": "^0.5.4", - "yauzl": "^2.10.0" - }, - "bin": { - "extract-zip": "cli.js" - } - }, - "node_modules/extract-zip/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/extract-zip/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", - "dev": true, - "engines": [ - "node >=0.6.0" - ] - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/fast-glob": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", - "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "node_modules/fastparse": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz", - "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==", - "dev": true - }, - "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/faye-websocket": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", - "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", - "dev": true, - "dependencies": { - "websocket-driver": ">=0.5.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", - "dev": true, - "dependencies": { - "pend": "~1.2.0" - } - }, - "node_modules/figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^1.0.5" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "dev": true, - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/finalhandler/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==", - "dev": true, - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/find-cache-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", - "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", - "dev": true, - "dependencies": { - "common-path-prefix": "^3.0.0", - "pkg-dir": "^7.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dev": true, - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flat-cache/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true - }, - "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/foreground-child": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz", - "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.0", - "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==", - "dev": true, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fraction.js": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", - "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", - "dev": true, - "engines": { - "node": "*" - }, - "funding": { - "type": "patreon", - "url": "https://github.com/sponsors/rawify" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" - }, - "node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/fs-minipass": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", - "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", - "dev": true, - "dependencies": { - "minipass": "^7.0.3" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/fs-minipass/node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/fs-monkey": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.6.tgz", - "integrity": "sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg==", - "dev": true - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "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==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gauge": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", - "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", - "deprecated": "This package is no longer supported.", - "dev": true, - "dependencies": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.3", - "console-control-strings": "^1.1.0", - "has-unicode": "^2.0.1", - "signal-exit": "^3.0.7", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.5" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "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==", - "dev": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "dev": true, - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0" - } - }, - "node_modules/github-from-package": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true - }, - "node_modules/glob/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/glob/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "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==" - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true - }, - "node_modules/guess-parser": { - "version": "0.4.22", - "resolved": "https://registry.npmjs.org/guess-parser/-/guess-parser-0.4.22.tgz", - "integrity": "sha512-KcUWZ5ACGaBM69SbqwVIuWGoSAgD+9iJnchR9j/IarVI1jHVeXv+bUXBIMeqVMSKt3zrn0Dgf9UpcOEpPBLbSg==", - "dev": true, - "dependencies": { - "@wessberg/ts-evaluator": "0.0.27" - }, - "peerDependencies": { - "typescript": ">=3.7.5" - } - }, - "node_modules/hammerjs": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/hammerjs/-/hammerjs-2.0.8.tgz", - "integrity": "sha512-tSQXBXS/MWQOn/RKckawJ61vvsDpCom87JgxiYdGwHdOa0ht0vzUWDlfioofFCRU0L+6NGDt6XzbgoJvZkMeRQ==", - "engines": { - "node": ">=0.8.0" - } - }, - "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==", - "dev": true - }, - "node_modules/har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "deprecated": "this library is no longer supported", - "dev": true, - "dependencies": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/har-validator/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/har-validator/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", - "dev": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-ansi/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dev": true, - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", - "dev": true - }, - "node_modules/hasha": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-2.2.0.tgz", - "integrity": "sha512-jZ38TU/EBiGKrmyTNNZgnvCZHNowiRI4+w/I9noMlekHTZH3KyGgvJLmhSgykeAQ9j2SYPDosM0Bg3wHfzibAQ==", - "dev": true, - "dependencies": { - "is-stream": "^1.0.1", - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/hdr-histogram-js": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/hdr-histogram-js/-/hdr-histogram-js-2.0.3.tgz", - "integrity": "sha512-Hkn78wwzWHNCp2uarhzQ2SGFLU3JY8SBDDd3TAABK4fc30wm+MuPOrg5QVFVfkKOQd6Bfz3ukJEI+q9sXEkK1g==", - "dev": true, - "dependencies": { - "@assemblyscript/loader": "^0.10.1", - "base64-js": "^1.2.0", - "pako": "^1.0.3" - } - }, - "node_modules/hdr-histogram-percentiles-obj": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hdr-histogram-percentiles-obj/-/hdr-histogram-percentiles-obj-3.0.0.tgz", - "integrity": "sha512-7kIufnBqdsBGcSZLPJwqHT3yhk1QTsSlFsVD3kx5ixH/AlgBs9yM1q6DPhXZ8f8gtdqgh7N7/5btRLpQsS2gHw==", - "dev": true - }, - "node_modules/highcharts": { - "version": "11.4.6", - "resolved": "https://registry.npmjs.org/highcharts/-/highcharts-11.4.6.tgz", - "integrity": "sha512-ntFZ053giEEquAxza+HlOWiLQyCLOjQ3M3EV4r6LoSNKS/fz2S0EKGl8G7Jls9EaYmdAHecB/vL4hGI2J1Ud9g==" - }, - "node_modules/hosted-git-info": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.1.tgz", - "integrity": "sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==", - "dev": true, - "dependencies": { - "lru-cache": "^7.5.1" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/hosted-git-info/node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "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==", - "dev": 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==", - "dev": 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/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==", - "dev": true - }, - "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==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/html-encoding-sniffer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", - "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", - "dev": true, - "dependencies": { - "whatwg-encoding": "^1.0.5" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/html-entities": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", - "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/mdevils" - }, - { - "type": "patreon", - "url": "https://patreon.com/mdevils" - } - ] - }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, - "node_modules/htmlparser2": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", - "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", - "dev": true, - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "entities": "^4.4.0" - } - }, - "node_modules/http-cache-semantics": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", - "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", - "dev": true - }, - "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==", - "dev": true - }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dev": true, - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/http-errors/node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/http-parser-js": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", - "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", - "dev": true - }, - "node_modules/http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", - "dev": true, - "dependencies": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "dev": true, - "dependencies": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/http-proxy-middleware": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", - "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", - "dev": true, - "dependencies": { - "@types/http-proxy": "^1.17.8", - "http-proxy": "^1.18.1", - "is-glob": "^4.0.1", - "is-plain-obj": "^3.0.0", - "micromatch": "^4.0.2" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "@types/express": "^4.17.13" - }, - "peerDependenciesMeta": { - "@types/express": { - "optional": true - } - } - }, - "node_modules/http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - }, - "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" - } - }, - "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dev": true, - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true, - "engines": { - "node": ">=10.17.0" - } - }, - "node_modules/humanize-ms": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", - "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", - "dev": true, - "dependencies": { - "ms": "^2.0.0" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/icss-utils": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", - "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", - "dev": true, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "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" - } - ] - }, - "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/ignore-walk": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-6.0.5.tgz", - "integrity": "sha512-VuuG0wCnjhnylG1ABXT3dAuIpTNDs/G8jlpmwXY03fXoXy/8ZK8/T+hMzt8L4WnrLCJgdybqgPagnF/f97cg3A==", - "dev": true, - "dependencies": { - "minimatch": "^9.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/image-size": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", - "integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==", - "dev": true, - "optional": true, - "bin": { - "image-size": "bin/image-size.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/immediate": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", - "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", - "dev": true - }, - "node_modules/immutable": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.6.tgz", - "integrity": "sha512-Ju0+lEMyzMVZarkTn/gqRpdqd5dOPaz1mCZ0SH3JV6iFw81PldE/PEB1hWVEA288HPt4WXW8O7AWxB10M+03QQ==", - "dev": true - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-fresh/node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/ini": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz", - "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==", - "dev": true, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/inquirer": { - "version": "8.2.4", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.4.tgz", - "integrity": "sha512-nn4F01dxU8VeKfq192IjLsxu0/OmMZ4Lg3xKAns148rCaXP6ntAoEkVYZThWjwON8AlzdZZi6oqnhNbxUG9hVg==", - "dev": true, - "dependencies": { - "ansi-escapes": "^4.2.1", - "chalk": "^4.1.1", - "cli-cursor": "^3.1.0", - "cli-width": "^3.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.21", - "mute-stream": "0.0.8", - "ora": "^5.4.1", - "run-async": "^2.4.0", - "rxjs": "^7.5.5", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/inquirer/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==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/inquirer/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "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/inquirer/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==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/inquirer/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==", - "dev": true - }, - "node_modules/inquirer/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==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/inquirer/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==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/intl": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/intl/-/intl-1.2.5.tgz", - "integrity": "sha512-rK0KcPHeBFBcqsErKSpvZnrOmWOj+EmDkyJ57e90YWaQNqbcivcqmKDlHEeNprDWOsKzPsh1BfSpPQdDvclHVw==" - }, - "node_modules/ionicons": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/ionicons/-/ionicons-7.4.0.tgz", - "integrity": "sha512-ZK94MMqgzMCPPMhmk8Ouu6goyVHFIlw/ACP6oe3FrikcI0N7CX0xcwVaEbUc0G/v3W0shI93vo+9ve/KpvcNhQ==", - "dependencies": { - "@stencil/core": "^4.0.3" - } - }, - "node_modules/ip-address": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", - "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", - "dev": true, - "dependencies": { - "jsbn": "1.1.0", - "sprintf-js": "^1.1.3" - }, - "engines": { - "node": ">= 12" - } - }, - "node_modules/ipaddr.js": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", - "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", - "dev": true, - "engines": { - "node": ">= 10" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-core-module": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.14.0.tgz", - "integrity": "sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==", - "dev": true, - "dependencies": { - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true, - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-interactive": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", - "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-lambda": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", - "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", - "dev": true - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-path-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", - "integrity": "sha512-cnS56eR9SPAscL77ik76ATVqoPARTqPIVkMDVxRaWH06zT+6+CzIroYRJ0VVvm0Z1zfAvxvz9i/D3Ppjaqt5Nw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-path-in-cwd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", - "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", - "dev": true, - "dependencies": { - "is-path-inside": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-path-in-cwd/node_modules/is-path-inside": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", - "integrity": "sha512-qhsCR/Esx4U4hg/9I19OVUAJkGWtjRYHMRgUMZE2TDdj+Ag+kttZanLupfddNyglzz50cUlmWzUaI37GDfNx/g==", - "dev": true, - "dependencies": { - "path-is-inside": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-obj": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", - "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "dev": true - }, - "node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true - }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-what": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz", - "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==", - "dev": true - }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "node_modules/isbinaryfile": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", - "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", - "dev": true, - "engines": { - "node": ">= 8.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/gjtorikian/" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", - "dev": true - }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", - "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", - "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", - "dev": true, - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/istanbul-lib-report": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", - "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", - "dev": true, - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-report/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==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report/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==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-source-maps": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", - "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^2.0.5", - "make-dir": "^2.1.0", - "rimraf": "^2.6.3", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/istanbul-lib-source-maps/node_modules/istanbul-lib-coverage": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", - "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/istanbul-lib-source-maps/node_modules/make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "dependencies": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/istanbul-lib-source-maps/node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/istanbul-lib-source-maps/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/istanbul-lib-source-maps/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/istanbul-lib-source-maps/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/istanbul-reports": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", - "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", - "dev": true, - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "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==", - "dev": true, - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, - "node_modules/jasmine": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-2.8.0.tgz", - "integrity": "sha512-KbdGQTf5jbZgltoHs31XGiChAPumMSY64OZMWLNYnEnMfG5uwGBhffePwuskexjT+/Jea/gU3qAU8344hNohSw==", - "dev": true, - "dependencies": { - "exit": "^0.1.2", - "glob": "^7.0.6", - "jasmine-core": "~2.8.0" - }, - "bin": { - "jasmine": "bin/jasmine.js" - } - }, - "node_modules/jasmine-core": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-5.1.2.tgz", - "integrity": "sha512-2oIUMGn00FdUiqz6epiiJr7xcFyNYj3rDcfmnzfkBnHyBQ3cBQUs4mmyGsOb7TTLb9kxk7dBcmEmqhDKkBoDyA==", - "dev": true - }, - "node_modules/jasmine-spec-reporter": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/jasmine-spec-reporter/-/jasmine-spec-reporter-7.0.0.tgz", - "integrity": "sha512-OtC7JRasiTcjsaCBPtMO0Tl8glCejM4J4/dNuOJdA8lBjz4PmWjYQ6pzb0uzpBNAWJMDudYuj9OdXJWqM2QTJg==", - "dev": true, - "dependencies": { - "colors": "1.4.0" - } - }, - "node_modules/jasmine/node_modules/jasmine-core": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.8.0.tgz", - "integrity": "sha512-SNkOkS+/jMZvLhuSx1fjhcNWUC/KG6oVyFUGkSBEr9n1axSNduWU8GlI7suaHXr4yxjet6KjrUZxUTE5WzzWwQ==", - "dev": true - }, - "node_modules/jasminewd2": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/jasminewd2/-/jasminewd2-2.2.0.tgz", - "integrity": "sha512-Rn0nZe4rfDhzA63Al3ZGh0E+JTmM6ESZYXJGKuqKGZObsAB9fwXPD03GjtIEvJBDOhN94T5MzbwZSqzFHSQPzg==", - "dev": true, - "engines": { - "node": ">= 6.9.x" - } - }, - "node_modules/jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "dev": true, - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/jest-worker/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==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/jetifier": { - "version": "1.6.8", - "resolved": "https://registry.npmjs.org/jetifier/-/jetifier-1.6.8.tgz", - "integrity": "sha512-3Zi16h6L5tXDRQJTb221cnRoVG9/9OvreLdLU2/ZjRv/GILL+2Cemt0IKvkowwkDpvouAU1DQPOJ7qaiHeIdrw==", - "bin": { - "jetifier": "bin/jetify", - "jetifier-standalone": "bin/jetifier-standalone", - "jetify": "bin/jetify" - } - }, - "node_modules/jiti": { - "version": "1.21.6", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", - "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", - "dev": true, - "bin": { - "jiti": "bin/jiti.js" - } - }, - "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==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsbn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", - "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", - "dev": true - }, - "node_modules/jsdom": { - "version": "16.7.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", - "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", - "dev": true, - "dependencies": { - "abab": "^2.0.5", - "acorn": "^8.2.4", - "acorn-globals": "^6.0.0", - "cssom": "^0.4.4", - "cssstyle": "^2.3.0", - "data-urls": "^2.0.0", - "decimal.js": "^10.2.1", - "domexception": "^2.0.1", - "escodegen": "^2.0.0", - "form-data": "^3.0.0", - "html-encoding-sniffer": "^2.0.1", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.0", - "parse5": "6.0.1", - "saxes": "^5.0.1", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.0.0", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^2.0.0", - "webidl-conversions": "^6.1.0", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.5.0", - "ws": "^7.4.6", - "xml-name-validator": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "canvas": "^2.5.0" - }, - "peerDependenciesMeta": { - "canvas": { - "optional": true - } - } - }, - "node_modules/jsdom/node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "dev": true - }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "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==", - "dev": true - }, - "node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonc-parser": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", - "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==" - }, - "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/jsonparse": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", - "dev": true, - "engines": [ - "node >= 0.2.0" - ] - }, - "node_modules/jsprim": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", - "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", - "dev": true, - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/jszip": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", - "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", - "dev": true, - "dependencies": { - "lie": "~3.3.0", - "pako": "~1.0.2", - "readable-stream": "~2.3.6", - "setimmediate": "^1.0.5" - } - }, - "node_modules/jszip/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==", - "dev": 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/jszip/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==", - "dev": true - }, - "node_modules/jszip/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==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/karma": { - "version": "6.4.3", - "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.3.tgz", - "integrity": "sha512-LuucC/RE92tJ8mlCwqEoRWXP38UMAqpnq98vktmS9SznSoUPPUJQbc91dHcxcunROvfQjdORVA/YFviH+Xci9Q==", - "dev": true, - "dependencies": { - "@colors/colors": "1.5.0", - "body-parser": "^1.19.0", - "braces": "^3.0.2", - "chokidar": "^3.5.1", - "connect": "^3.7.0", - "di": "^0.0.1", - "dom-serialize": "^2.2.1", - "glob": "^7.1.7", - "graceful-fs": "^4.2.6", - "http-proxy": "^1.18.1", - "isbinaryfile": "^4.0.8", - "lodash": "^4.17.21", - "log4js": "^6.4.1", - "mime": "^2.5.2", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.5", - "qjobs": "^1.2.0", - "range-parser": "^1.2.1", - "rimraf": "^3.0.2", - "socket.io": "^4.7.2", - "source-map": "^0.6.1", - "tmp": "^0.2.1", - "ua-parser-js": "^0.7.30", - "yargs": "^16.1.1" - }, - "bin": { - "karma": "bin/karma" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/karma-chrome-launcher": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.2.0.tgz", - "integrity": "sha512-rE9RkUPI7I9mAxByQWkGJFXfFD6lE4gC5nPuZdobf/QdTEJI6EU4yIay/cfU/xV4ZxlM5JiTv7zWYgA64NpS5Q==", - "dev": true, - "dependencies": { - "which": "^1.2.1" - } - }, - "node_modules/karma-chrome-launcher/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/karma-coverage-istanbul-reporter": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/karma-coverage-istanbul-reporter/-/karma-coverage-istanbul-reporter-3.0.3.tgz", - "integrity": "sha512-wE4VFhG/QZv2Y4CdAYWDbMmcAHeS926ZIji4z+FkB2aF/EposRb6DP6G5ncT/wXhqUfAb/d7kZrNKPonbvsATw==", - "dev": true, - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^3.0.6", - "istanbul-reports": "^3.0.2", - "minimatch": "^3.0.4" - }, - "funding": { - "url": "https://github.com/sponsors/mattlewis92" - } - }, - "node_modules/karma-coverage-istanbul-reporter/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/karma-coverage-istanbul-reporter/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/karma-jasmine": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-5.1.0.tgz", - "integrity": "sha512-i/zQLFrfEpRyQoJF9fsCdTMOF5c2dK7C7OmsuKg2D0YSsuZSfQDiLuaiktbuio6F2wiCsZSnSnieIQ0ant/uzQ==", - "dev": true, - "dependencies": { - "jasmine-core": "^4.1.0" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "karma": "^6.0.0" - } - }, - "node_modules/karma-jasmine-html-reporter": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-2.1.0.tgz", - "integrity": "sha512-sPQE1+nlsn6Hwb5t+HHwyy0A1FNCVKuL1192b+XNauMYWThz2kweiBVW1DqloRpVvZIJkIoHVB7XRpK78n1xbQ==", - "dev": true, - "peerDependencies": { - "jasmine-core": "^4.0.0 || ^5.0.0", - "karma": "^6.0.0", - "karma-jasmine": "^5.0.0" - } - }, - "node_modules/karma-jasmine/node_modules/jasmine-core": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-4.6.1.tgz", - "integrity": "sha512-VYz/BjjmC3klLJlLwA4Kw8ytk0zDSmbbDLNs794VnWmkcCB7I9aAL/D48VNQtmITyPvea2C3jdUMfc3kAoy0PQ==", - "dev": true - }, - "node_modules/karma-phantomjs-launcher": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/karma-phantomjs-launcher/-/karma-phantomjs-launcher-1.0.4.tgz", - "integrity": "sha512-tf4P3plsE7wb5Pqh8GJ6RnElxfI/UM4MtVnjbSIZFpdFJlKnjRzfIx8MLCcSYJBwZ1+qSKFz4uBe3XNoq2t3KA==", - "deprecated": "PhantomJS development have stopped, use puppeteer or similar", - "dev": true, - "dependencies": { - "lodash": "^4.0.1", - "phantomjs-prebuilt": "^2.1.7" - }, - "peerDependencies": { - "karma": ">=0.9" - } - }, - "node_modules/karma-source-map-support": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/karma-source-map-support/-/karma-source-map-support-1.4.0.tgz", - "integrity": "sha512-RsBECncGO17KAoJCYXjv+ckIz+Ii9NCi+9enk+rq6XC81ezYkb4/RHE6CTXdA7IOJqoF3wcaLfVG0CPmE5ca6A==", - "dev": true, - "dependencies": { - "source-map-support": "^0.5.5" - } - }, - "node_modules/karma/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/karma/node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/karma/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/karma/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/karma/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/karma/node_modules/tmp": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", - "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", - "dev": true, - "engines": { - "node": ">=14.14" - } - }, - "node_modules/karma/node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/karma/node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/kew": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/kew/-/kew-0.7.0.tgz", - "integrity": "sha512-IG6nm0+QtAMdXt9KvbgbGdvY50RSrw+U4sGZg+KlrSKPJEwVE5JVoI3d7RWfSMdBQneRheeAOj3lIjX5VL/9RQ==", - "dev": true - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/klaw": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", - "integrity": "sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==", - "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.9" - } - }, - "node_modules/kleur": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", - "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/klona": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz", - "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/launch-editor": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.8.0.tgz", - "integrity": "sha512-vJranOAJrI/llyWGRQqiDM+adrw+k83fvmmx3+nV47g3+36xM15jE+zyZ6Ffel02+xSvuM0b2GDRosXZkbb6wA==", - "dev": true, - "dependencies": { - "picocolors": "^1.0.0", - "shell-quote": "^1.8.1" - } - }, - "node_modules/less": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/less/-/less-4.1.3.tgz", - "integrity": "sha512-w16Xk/Ta9Hhyei0Gpz9m7VS8F28nieJaL/VyShID7cYvP6IL5oHeL6p4TXSDJqZE/lNv0oJ2pGVjJsRkfwm5FA==", - "dev": true, - "dependencies": { - "copy-anything": "^2.0.1", - "parse-node-version": "^1.0.1", - "tslib": "^2.3.0" - }, - "bin": { - "lessc": "bin/lessc" - }, - "engines": { - "node": ">=6" - }, - "optionalDependencies": { - "errno": "^0.1.1", - "graceful-fs": "^4.1.2", - "image-size": "~0.5.0", - "make-dir": "^2.1.0", - "mime": "^1.4.1", - "needle": "^3.1.0", - "source-map": "~0.6.0" - } - }, - "node_modules/less-loader": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-11.1.0.tgz", - "integrity": "sha512-C+uDBV7kS7W5fJlUjq5mPBeBVhYpTIm5gB09APT9o3n/ILeaXVsiSFTbZpTJCJwQ/Crczfn3DmfQFwxYusWFug==", - "dev": true, - "dependencies": { - "klona": "^2.0.4" - }, - "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "less": "^3.5.0 || ^4.0.0", - "webpack": "^5.0.0" - } - }, - "node_modules/less/node_modules/make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "optional": true, - "dependencies": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/less/node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true, - "optional": true, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/less/node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, - "optional": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/less/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "optional": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/less/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/license-webpack-plugin": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-4.0.2.tgz", - "integrity": "sha512-771TFWFD70G1wLTC4oU2Cw4qvtmNrIw+wRvBtn+okgHl7slJVi7zfNcdmqDL72BojM30VNJ2UHylr1o77U37Jw==", - "dev": true, - "dependencies": { - "webpack-sources": "^3.0.0" - }, - "peerDependenciesMeta": { - "webpack": { - "optional": true - }, - "webpack-sources": { - "optional": true - } - } - }, - "node_modules/lie": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", - "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", - "dev": true, - "dependencies": { - "immediate": "~3.0.5" - } - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true - }, - "node_modules/loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", - "dev": true, - "engines": { - "node": ">=6.11.5" - } - }, - "node_modules/loader-utils": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", - "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==", - "dev": true, - "engines": { - "node": ">= 12.13.0" - } - }, - "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "node_modules/lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", - "dev": true - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-symbols/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==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/log-symbols/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "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/log-symbols/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==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/log-symbols/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==", - "dev": true - }, - "node_modules/log-symbols/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==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/log-symbols/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==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/log4js": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.9.1.tgz", - "integrity": "sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g==", - "dev": true, - "dependencies": { - "date-format": "^4.0.14", - "debug": "^4.3.4", - "flatted": "^3.2.7", - "rfdc": "^1.3.0", - "streamroller": "^3.1.5" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/magic-snowflakes": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/magic-snowflakes/-/magic-snowflakes-4.2.0.tgz", - "integrity": "sha512-b3iU6ShpD8N3H4HCOw8HXzClONJ/0oKf+2VXBUD4munnBoSqV9nQLbYOx2DWbhbSygDVFnGWAp086BCGPJfSDg==", - "engines": { - "node": ">=12" - } - }, - "node_modules/magic-string": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.1.tgz", - "integrity": "sha512-mbVKXPmS0z0G4XqFDCTllmDQ6coZzn94aMlb0o/A4HEHJCKcanlDZwYJgwnkmgD3jyWhUgj9VsPrfd972yPffA==", - "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/make-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", - "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", - "dev": true, - "dependencies": { - "semver": "^7.5.3" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "node_modules/make-fetch-happen": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz", - "integrity": "sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==", - "dev": true, - "dependencies": { - "agentkeepalive": "^4.2.1", - "cacache": "^16.1.0", - "http-cache-semantics": "^4.1.0", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", - "is-lambda": "^1.0.1", - "lru-cache": "^7.7.1", - "minipass": "^3.1.6", - "minipass-collect": "^1.0.2", - "minipass-fetch": "^2.0.3", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "promise-retry": "^2.0.1", - "socks-proxy-agent": "^7.0.0", - "ssri": "^9.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/make-fetch-happen/node_modules/@npmcli/fs": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.2.tgz", - "integrity": "sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==", - "dev": true, - "dependencies": { - "@gar/promisify": "^1.1.3", - "semver": "^7.3.5" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/make-fetch-happen/node_modules/@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", - "dev": true, - "engines": { - "node": ">= 10" - } - }, - "node_modules/make-fetch-happen/node_modules/cacache": { - "version": "16.1.3", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.1.3.tgz", - "integrity": "sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==", - "dev": true, - "dependencies": { - "@npmcli/fs": "^2.1.0", - "@npmcli/move-file": "^2.0.0", - "chownr": "^2.0.0", - "fs-minipass": "^2.1.0", - "glob": "^8.0.1", - "infer-owner": "^1.0.4", - "lru-cache": "^7.7.1", - "minipass": "^3.1.6", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "mkdirp": "^1.0.4", - "p-map": "^4.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^3.0.2", - "ssri": "^9.0.0", - "tar": "^6.1.11", - "unique-filename": "^2.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/make-fetch-happen/node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dev": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/make-fetch-happen/node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/make-fetch-happen/node_modules/http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", - "dev": true, - "dependencies": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/make-fetch-happen/node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/make-fetch-happen/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/make-fetch-happen/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/make-fetch-happen/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/make-fetch-happen/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/make-fetch-happen/node_modules/rimraf/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/make-fetch-happen/node_modules/rimraf/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/make-fetch-happen/node_modules/rimraf/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/make-fetch-happen/node_modules/ssri": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-9.0.1.tgz", - "integrity": "sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==", - "dev": true, - "dependencies": { - "minipass": "^3.1.1" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/make-fetch-happen/node_modules/unique-filename": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-2.0.1.tgz", - "integrity": "sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==", - "dev": true, - "dependencies": { - "unique-slug": "^3.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/make-fetch-happen/node_modules/unique-slug": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-3.0.0.tgz", - "integrity": "sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==", - "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/make-fetch-happen/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/memfs": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", - "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", - "dev": true, - "dependencies": { - "fs-monkey": "^1.0.4" - }, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", - "dev": true - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", - "dev": true, - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", - "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", - "dev": true, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "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==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mini-css-extract-plugin": { - "version": "2.7.6", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.6.tgz", - "integrity": "sha512-Qk7HcgaPkGG6eD77mLvZS1nmxlao3j+9PkrT9Uc7HAE1id3F41+DdBRYRYkbyfNRGzm8/YWtzhw7nVPmwhqTQw==", - "dev": true, - "dependencies": { - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - } - }, - "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==", - "dev": true - }, - "node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minipass": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-collect": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", - "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", - "dev": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minipass-collect/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-collect/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/minipass-fetch": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.2.tgz", - "integrity": "sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==", - "dev": true, - "dependencies": { - "minipass": "^3.1.6", - "minipass-sized": "^1.0.3", - "minizlib": "^2.1.2" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - }, - "optionalDependencies": { - "encoding": "^0.1.13" - } - }, - "node_modules/minipass-fetch/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-fetch/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/minipass-flush": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", - "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", - "dev": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minipass-flush/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-flush/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/minipass-json-stream": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minipass-json-stream/-/minipass-json-stream-1.0.1.tgz", - "integrity": "sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg==", - "dev": true, - "dependencies": { - "jsonparse": "^1.3.1", - "minipass": "^3.0.0" - } - }, - "node_modules/minipass-json-stream/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-json-stream/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/minipass-pipeline": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", - "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", - "dev": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-pipeline/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-pipeline/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/minipass-sized": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", - "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", - "dev": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-sized/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-sized/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dev": true, - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minizlib/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minizlib/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" - }, - "node_modules/mrmime": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.1.tgz", - "integrity": "sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/multicast-dns": { - "version": "7.2.5", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", - "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", - "dev": true, - "dependencies": { - "dns-packet": "^5.2.2", - "thunky": "^1.0.2" - }, - "bin": { - "multicast-dns": "cli.js" - } - }, - "node_modules/mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true - }, - "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/napi-build-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", - "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" - }, - "node_modules/native-run": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/native-run/-/native-run-2.0.1.tgz", - "integrity": "sha512-XfG1FBZLM50J10xH9361whJRC9SHZ0Bub4iNRhhI61C8Jv0e1ud19muex6sNKB51ibQNUJNuYn25MuYET/rE6w==", - "dev": true, - "dependencies": { - "@ionic/utils-fs": "^3.1.7", - "@ionic/utils-terminal": "^2.3.4", - "bplist-parser": "^0.3.2", - "debug": "^4.3.4", - "elementtree": "^0.1.7", - "ini": "^4.1.1", - "plist": "^3.1.0", - "split2": "^4.2.0", - "through2": "^4.0.2", - "tslib": "^2.6.2", - "yauzl": "^2.10.0" - }, - "bin": { - "native-run": "bin/native-run" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "node_modules/needle": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/needle/-/needle-3.3.1.tgz", - "integrity": "sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==", - "dev": true, - "optional": true, - "dependencies": { - "iconv-lite": "^0.6.3", - "sax": "^1.2.4" - }, - "bin": { - "needle": "bin/needle" - }, - "engines": { - "node": ">= 4.4.x" - } - }, - "node_modules/needle/node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dev": true, - "optional": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/needle/node_modules/sax": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", - "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", - "dev": true, - "optional": true - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "node_modules/ng2-tooltip-directive-major-angular-updates": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/ng2-tooltip-directive-major-angular-updates/-/ng2-tooltip-directive-major-angular-updates-2.12.1.tgz", - "integrity": "sha512-jVn577OvvFEkUV9bIxMywbXYKoPpKISIblRflb8bjf1KSeUhLHCYZRscSith+/I2X7yLJME8Sg82UpA9F4hIyA==", - "dependencies": { - "tslib": "^2.4.1" - }, - "peerDependencies": { - "@angular/common": ">=15.0.4", - "@angular/core": ">=15.0.4" - } - }, - "node_modules/ngx-timeago": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ngx-timeago/-/ngx-timeago-3.0.0.tgz", - "integrity": "sha512-oz+X8qbPJD6uFHXVWUTE+scjLPskOKbrAVlUG0pUwrn8wru7woryGdK/xdjvS74n187tbo5+e8AXgLCqEvUSjw==", - "dependencies": { - "tslib": "^2.3.0" - }, - "peerDependencies": { - "@angular/core": ">=16.0.0", - "rxjs": ">=7.0.0" - } - }, - "node_modules/nice-napi": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/nice-napi/-/nice-napi-1.0.2.tgz", - "integrity": "sha512-px/KnJAJZf5RuBGcfD+Sp2pAKq0ytz8j+1NehvgIGFkvtvFrDM3T8E4x/JJODXK9WZow8RRGrbA9QQ3hs+pDhA==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "!win32" - ], - "dependencies": { - "node-addon-api": "^3.0.0", - "node-gyp-build": "^4.2.2" - } - }, - "node_modules/node-abi": { - "version": "3.65.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.65.0.tgz", - "integrity": "sha512-ThjYBfoDNr08AWx6hGaRbfPwxKV9kVzAzOzlLKbk2CuqXE2xnCh+cbAGnwM3t8Lq4v9rUB7VfondlkBckcJrVA==", - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/node-addon-api": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", - "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==", - "dev": true, - "optional": true - }, - "node_modules/node-forge": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", - "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", - "dev": true, - "engines": { - "node": ">= 6.13.0" - } - }, - "node_modules/node-gyp": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.4.1.tgz", - "integrity": "sha512-OQkWKbjQKbGkMf/xqI1jjy3oCTgMKJac58G2+bjZb3fza6gW2YrCSdMQYaoTb70crvE//Gngr4f0AgVHmqHvBQ==", - "dev": true, - "dependencies": { - "env-paths": "^2.2.0", - "exponential-backoff": "^3.1.1", - "glob": "^7.1.4", - "graceful-fs": "^4.2.6", - "make-fetch-happen": "^10.0.3", - "nopt": "^6.0.0", - "npmlog": "^6.0.0", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.2", - "which": "^2.0.2" - }, - "bin": { - "node-gyp": "bin/node-gyp.js" - }, - "engines": { - "node": "^12.13 || ^14.13 || >=16" - } - }, - "node_modules/node-gyp-build": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.1.tgz", - "integrity": "sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw==", - "dev": true, - "optional": true, - "bin": { - "node-gyp-build": "bin.js", - "node-gyp-build-optional": "optional.js", - "node-gyp-build-test": "build-test.js" - } - }, - "node_modules/node-gyp/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", - "dev": true - }, - "node_modules/nopt": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz", - "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==", - "dev": true, - "dependencies": { - "abbrev": "^1.0.0" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/normalize-package-data": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-5.0.0.tgz", - "integrity": "sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q==", - "dev": true, - "dependencies": { - "hosted-git-info": "^6.0.0", - "is-core-module": "^2.8.1", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.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==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm-bundled": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-3.0.1.tgz", - "integrity": "sha512-+AvaheE/ww1JEwRHOrn4WHNzOxGtVp+adrg2AeZS/7KuxGUYFuBta98wYpfHBbJp6Tg6j1NKSEVHNcfZzJHQwQ==", - "dev": true, - "dependencies": { - "npm-normalize-package-bin": "^3.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm-install-checks": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-6.3.0.tgz", - "integrity": "sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw==", - "dev": true, - "dependencies": { - "semver": "^7.1.1" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm-normalize-package-bin": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz", - "integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==", - "dev": true, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm-package-arg": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-10.1.0.tgz", - "integrity": "sha512-uFyyCEmgBfZTtrKk/5xDfHp6+MdrqGotX/VoOyEEl3mBwiEE5FlBaePanazJSVMPT7vKepcjYBY2ztg9A3yPIA==", - "dev": true, - "dependencies": { - "hosted-git-info": "^6.0.0", - "proc-log": "^3.0.0", - "semver": "^7.3.5", - "validate-npm-package-name": "^5.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm-packlist": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-7.0.4.tgz", - "integrity": "sha512-d6RGEuRrNS5/N84iglPivjaJPxhDbZmlbTwTDX2IbcRHG5bZCdtysYMhwiPvcF4GisXHGn7xsxv+GQ7T/02M5Q==", - "dev": true, - "dependencies": { - "ignore-walk": "^6.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm-pick-manifest": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-8.0.1.tgz", - "integrity": "sha512-mRtvlBjTsJvfCCdmPtiu2bdlx8d/KXtF7yNXNWe7G0Z36qWA9Ny5zXsI2PfBZEv7SXgoxTmNaTzGSbbzDZChoA==", - "dev": true, - "dependencies": { - "npm-install-checks": "^6.0.0", - "npm-normalize-package-bin": "^3.0.0", - "npm-package-arg": "^10.0.0", - "semver": "^7.3.5" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm-registry-fetch": { - "version": "14.0.5", - "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-14.0.5.tgz", - "integrity": "sha512-kIDMIo4aBm6xg7jOttupWZamsZRkAqMqwqqbVXnUqstY5+tapvv6bkH/qMR76jdgV+YljEUCyWx3hRYMrJiAgA==", - "dev": true, - "dependencies": { - "make-fetch-happen": "^11.0.0", - "minipass": "^5.0.0", - "minipass-fetch": "^3.0.0", - "minipass-json-stream": "^1.0.1", - "minizlib": "^2.1.2", - "npm-package-arg": "^10.0.0", - "proc-log": "^3.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm-registry-fetch/node_modules/@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", - "dev": true, - "engines": { - "node": ">= 10" - } - }, - "node_modules/npm-registry-fetch/node_modules/http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", - "dev": true, - "dependencies": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/npm-registry-fetch/node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/npm-registry-fetch/node_modules/make-fetch-happen": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz", - "integrity": "sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==", - "dev": true, - "dependencies": { - "agentkeepalive": "^4.2.1", - "cacache": "^17.0.0", - "http-cache-semantics": "^4.1.1", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", - "is-lambda": "^1.0.1", - "lru-cache": "^7.7.1", - "minipass": "^5.0.0", - "minipass-fetch": "^3.0.0", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "promise-retry": "^2.0.1", - "socks-proxy-agent": "^7.0.0", - "ssri": "^10.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm-registry-fetch/node_modules/minipass-fetch": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.5.tgz", - "integrity": "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==", - "dev": true, - "dependencies": { - "minipass": "^7.0.3", - "minipass-sized": "^1.0.3", - "minizlib": "^2.1.2" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - }, - "optionalDependencies": { - "encoding": "^0.1.13" - } - }, - "node_modules/npm-registry-fetch/node_modules/minipass-fetch/node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npmlog": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", - "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", - "deprecated": "This package is no longer supported.", - "dev": true, - "dependencies": { - "are-we-there-yet": "^3.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^4.0.3", - "set-blocking": "^2.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "dev": true, - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, - "node_modules/nwsapi": { - "version": "2.2.12", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.12.tgz", - "integrity": "sha512-qXDmcVlZV4XRtKFzddidpfVP4oMSGhga+xdMc25mv8kaLUHtgzCDhUxkrN8exkGdTlLNaXj7CV3GtON7zuGZ+w==", - "dev": true - }, - "node_modules/oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-path": { - "version": "0.11.8", - "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.11.8.tgz", - "integrity": "sha512-YJjNZrlXJFM42wTBn6zgOJVar9KFJvzx6sTWDte8sWZF//cnjl0BxHNpfZx+ZffXX63A9q0b1zsFiBX4g4X5KA==", - "dev": true, - "engines": { - "node": ">= 10.12.0" - } - }, - "node_modules/obuf": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", - "dev": 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==", - "dev": true, - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "dev": true, - "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==", - "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==", - "dev": true, - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/open": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", - "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", - "dev": true, - "dependencies": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dev": true, - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/ora": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", - "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", - "dev": true, - "dependencies": { - "bl": "^4.1.0", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-spinners": "^2.5.0", - "is-interactive": "^1.0.0", - "is-unicode-supported": "^0.1.0", - "log-symbols": "^4.1.0", - "strip-ansi": "^6.0.0", - "wcwidth": "^1.0.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ora/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==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/ora/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "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/ora/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==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/ora/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==", - "dev": true - }, - "node_modules/ora/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==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ora/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==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-retry": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", - "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", - "dev": true, - "dependencies": { - "@types/retry": "0.12.0", - "retry": "^0.13.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-retry/node_modules/retry": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/package-json-from-dist": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", - "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", - "dev": true - }, - "node_modules/pacote": { - "version": "15.2.0", - "resolved": "https://registry.npmjs.org/pacote/-/pacote-15.2.0.tgz", - "integrity": "sha512-rJVZeIwHTUta23sIZgEIM62WYwbmGbThdbnkt81ravBplQv+HjyroqnLRNH2+sLJHcGZmLRmhPwACqhfTcOmnA==", - "dev": true, - "dependencies": { - "@npmcli/git": "^4.0.0", - "@npmcli/installed-package-contents": "^2.0.1", - "@npmcli/promise-spawn": "^6.0.1", - "@npmcli/run-script": "^6.0.0", - "cacache": "^17.0.0", - "fs-minipass": "^3.0.0", - "minipass": "^5.0.0", - "npm-package-arg": "^10.0.0", - "npm-packlist": "^7.0.0", - "npm-pick-manifest": "^8.0.0", - "npm-registry-fetch": "^14.0.0", - "proc-log": "^3.0.0", - "promise-retry": "^2.0.1", - "read-package-json": "^6.0.0", - "read-package-json-fast": "^3.0.0", - "sigstore": "^1.3.0", - "ssri": "^10.0.0", - "tar": "^6.1.11" - }, - "bin": { - "pacote": "lib/bin.js" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parse-node-version": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", - "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/parse5": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", - "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", - "devOptional": true, - "dependencies": { - "entities": "^4.4.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parse5-html-rewriting-stream": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse5-html-rewriting-stream/-/parse5-html-rewriting-stream-7.0.0.tgz", - "integrity": "sha512-mazCyGWkmCRWDI15Zp+UiCqMp/0dgEmkZRvhlsqqKYr4SsVm/TvnSpD9fCvqCA2zoWJcfRym846ejWBBHRiYEg==", - "dev": true, - "dependencies": { - "entities": "^4.3.0", - "parse5": "^7.0.0", - "parse5-sax-parser": "^7.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parse5-sax-parser": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse5-sax-parser/-/parse5-sax-parser-7.0.0.tgz", - "integrity": "sha512-5A+v2SNsq8T6/mG3ahcz8ZtQ0OUFTatxPbeidoMB7tkJSGDY3tdfl4MHovtLQHkEn5CGxijNWRQHhRQ6IRpXKg==", - "dev": true, - "dependencies": { - "parse5": "^7.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", - "dev": true - }, - "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==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "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==", - "dev": true, - "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/path-scurry/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==", - "dev": true - }, - "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", - "dev": true - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "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==", - "dev": true - }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", - "dev": true - }, - "node_modules/phantomjs-prebuilt": { - "version": "2.1.16", - "resolved": "https://registry.npmjs.org/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.16.tgz", - "integrity": "sha512-PIiRzBhW85xco2fuj41FmsyuYHKjKuXWmhjy3A/Y+CMpN/63TV+s9uzfVhsUwFe0G77xWtHBG8xmXf5BqEUEuQ==", - "deprecated": "this package is now deprecated", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "es6-promise": "^4.0.3", - "extract-zip": "^1.6.5", - "fs-extra": "^1.0.0", - "hasha": "^2.2.0", - "kew": "^0.7.0", - "progress": "^1.1.8", - "request": "^2.81.0", - "request-progress": "^2.0.1", - "which": "^1.2.10" - }, - "bin": { - "phantomjs": "bin/phantomjs" - } - }, - "node_modules/phantomjs-prebuilt/node_modules/fs-extra": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz", - "integrity": "sha512-VerQV6vEKuhDWD2HGOybV6v5I73syoc/cXAbKlgTC7M/oFVEtklWlp9QH2Ijw3IaWDOQcMkldSPa7zXy79Z/UQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0" - } - }, - "node_modules/phantomjs-prebuilt/node_modules/jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", - "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/phantomjs-prebuilt/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", - "dev": true - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", - "dev": true, - "dependencies": { - "pinkie": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/piscina": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/piscina/-/piscina-4.0.0.tgz", - "integrity": "sha512-641nAmJS4k4iqpNUqfggqUBUMmlw0ZoM5VZKdQkV2e970Inn3Tk9kroCc1wpsYLD07vCwpys5iY0d3xI/9WkTg==", - "dev": true, - "dependencies": { - "eventemitter-asyncresource": "^1.0.0", - "hdr-histogram-js": "^2.0.1", - "hdr-histogram-percentiles-obj": "^3.0.0" - }, - "optionalDependencies": { - "nice-napi": "^1.0.2" - } - }, - "node_modules/pkg-dir": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", - "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", - "dev": true, - "dependencies": { - "find-up": "^6.3.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", - "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", - "dev": true, - "dependencies": { - "locate-path": "^7.1.0", - "path-exists": "^5.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", - "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", - "dev": true, - "dependencies": { - "p-locate": "^6.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/p-limit": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", - "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^1.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", - "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", - "dev": true, - "dependencies": { - "p-limit": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/path-exists": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", - "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, - "node_modules/pkg-dir/node_modules/yocto-queue": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", - "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", - "dev": true, - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/plist": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz", - "integrity": "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==", - "dev": true, - "dependencies": { - "@xmldom/xmldom": "^0.8.8", - "base64-js": "^1.5.1", - "xmlbuilder": "^15.1.1" - }, - "engines": { - "node": ">=10.4.0" - } - }, - "node_modules/postcss": { - "version": "8.4.31", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", - "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "nanoid": "^3.3.6", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/postcss-loader": { - "version": "7.3.3", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.3.3.tgz", - "integrity": "sha512-YgO/yhtevGO/vJePCQmTxiaEwER94LABZN0ZMT4A0vsak9TpO+RvKRs7EmJ8peIlB9xfXCsS7M8LjqncsUZ5HA==", - "dev": true, - "dependencies": { - "cosmiconfig": "^8.2.0", - "jiti": "^1.18.2", - "semver": "^7.3.8" - }, - "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "postcss": "^7.0.0 || ^8.0.1", - "webpack": "^5.0.0" - } - }, - "node_modules/postcss-modules-extract-imports": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", - "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", - "dev": true, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-local-by-default": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz", - "integrity": "sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==", - "dev": true, - "dependencies": { - "icss-utils": "^5.0.0", - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.1.0" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-scope": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz", - "integrity": "sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==", - "dev": true, - "dependencies": { - "postcss-selector-parser": "^6.0.4" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-values": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", - "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", - "dev": true, - "dependencies": { - "icss-utils": "^5.0.0" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-selector-parser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.0.tgz", - "integrity": "sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==", - "dev": true, - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true - }, - "node_modules/prebuild-install": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.2.tgz", - "integrity": "sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==", - "dependencies": { - "detect-libc": "^2.0.0", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.3", - "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^1.0.1", - "node-abi": "^3.3.0", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^4.0.0", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0" - }, - "bin": { - "prebuild-install": "bin.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/prebuild-install/node_modules/detect-libc": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", - "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prettier": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.0.tgz", - "integrity": "sha512-9Lmg8hTFZKG0Asr/kW9Bp8tJjRVluO8EJQVfY2T7FMw9T5jy4I/Uvx0Rca/XWf50QQ1/SS48+6IJWnrb+2yemA==", - "dev": true, - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/pretty-bytes": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", - "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", - "dev": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/proc-log": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-3.0.0.tgz", - "integrity": "sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==", - "dev": true, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.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==", - "dev": true - }, - "node_modules/progress": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", - "integrity": "sha512-UdA8mJ4weIkUBO224tIarHzuHs4HuYiJvsuGT7j/SPQiUJVjYvNDBIPa0hAorduOfjGohB/qHWRa/lrrWX/mXw==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", - "dev": true - }, - "node_modules/promise-retry": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", - "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", - "dev": true, - "dependencies": { - "err-code": "^2.0.2", - "retry": "^0.12.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/prompts/node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/protractor": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/protractor/-/protractor-7.0.0.tgz", - "integrity": "sha512-UqkFjivi4GcvUQYzqGYNe0mLzfn5jiLmO8w9nMhQoJRLhy2grJonpga2IWhI6yJO30LibWXJJtA4MOIZD2GgZw==", - "deprecated": "We have news to share - Protractor is deprecated and will reach end-of-life by Summer 2023. To learn more and find out about other options please refer to this post on the Angular blog. Thank you for using and contributing to Protractor. https://goo.gle/state-of-e2e-in-angular", - "dev": true, - "dependencies": { - "@types/q": "^0.0.32", - "@types/selenium-webdriver": "^3.0.0", - "blocking-proxy": "^1.0.0", - "browserstack": "^1.5.1", - "chalk": "^1.1.3", - "glob": "^7.0.3", - "jasmine": "2.8.0", - "jasminewd2": "^2.1.0", - "q": "1.4.1", - "saucelabs": "^1.5.0", - "selenium-webdriver": "3.6.0", - "source-map-support": "~0.4.0", - "webdriver-js-extender": "2.1.0", - "webdriver-manager": "^12.1.7", - "yargs": "^15.3.1" - }, - "bin": { - "protractor": "bin/protractor", - "webdriver-manager": "bin/webdriver-manager" - }, - "engines": { - "node": ">=10.13.x" - } - }, - "node_modules/protractor/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/protractor/node_modules/ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/protractor/node_modules/chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", - "dev": true, - "dependencies": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/protractor/node_modules/cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "node_modules/protractor/node_modules/cliui/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==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/protractor/node_modules/cliui/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==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/protractor/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==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/protractor/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==", - "dev": true - }, - "node_modules/protractor/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/protractor/node_modules/source-map-support": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", - "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", - "dev": true, - "dependencies": { - "source-map": "^0.5.6" - } - }, - "node_modules/protractor/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", - "dev": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/protractor/node_modules/supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/protractor/node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/protractor/node_modules/wrap-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==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/protractor/node_modules/wrap-ansi/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==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/protractor/node_modules/wrap-ansi/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==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/protractor/node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true - }, - "node_modules/protractor/node_modules/yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "dev": true, - "dependencies": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/protractor/node_modules/yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "engines": { - "node": ">=6" - } - }, - "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==", - "dev": true, - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/proxy-addr/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==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", - "dev": true, - "optional": true - }, - "node_modules/psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "dev": true - }, - "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", - "dev": true - }, - "node_modules/q": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz", - "integrity": "sha512-/CdEdaw49VZVmyIDGUQKDDT53c7qBkO6g5CefWz91Ae+l4+cRtcDYwMTXh6me4O8TMldeGHG3N2Bl84V78Ywbg==", - "deprecated": "You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other.\n\n(For a CapTP with native promises, see @endo/eventual-send and @endo/captp)", - "dev": true, - "engines": { - "node": ">=0.6.0", - "teleport": ">=0.2.0" - } - }, - "node_modules/qjobs": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", - "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", - "dev": true, - "engines": { - "node": ">=0.9" - } - }, - "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dev": true, - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "dev": true - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "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==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "dev": true, - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/rc/node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" - }, - "node_modules/rc/node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/read-package-json": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-6.0.4.tgz", - "integrity": "sha512-AEtWXYfopBj2z5N5PbkAOeNHRPUg5q+Nen7QLxV8M2zJq1ym6/lCz3fYNTCXe19puu2d06jfHhrP7v/S2PtMMw==", - "deprecated": "This package is no longer supported. Please use @npmcli/package-json instead.", - "dev": true, - "dependencies": { - "glob": "^10.2.2", - "json-parse-even-better-errors": "^3.0.0", - "normalize-package-data": "^5.0.0", - "npm-normalize-package-bin": "^3.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/read-package-json-fast": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-3.0.2.tgz", - "integrity": "sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw==", - "dev": true, - "dependencies": { - "json-parse-even-better-errors": "^3.0.0", - "npm-normalize-package-bin": "^3.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/read-package-json-fast/node_modules/json-parse-even-better-errors": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz", - "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==", - "dev": true, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/read-package-json/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "dev": true, - "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/read-package-json/node_modules/json-parse-even-better-errors": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz", - "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==", - "dev": true, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/read-package-json/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/read-package-json/node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "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==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/reflect-metadata": { - "version": "0.1.14", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.14.tgz", - "integrity": "sha512-ZhYeb6nRaXCfhnndflDK8qI6ZQ/YcWZCISRAWICW9XYqMUwjZM9Z0DveWX/ABN01oxSHwVxKQmxeYZSsm0jh5A==", - "dev": true - }, - "node_modules/regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "dev": true - }, - "node_modules/regenerate-unicode-properties": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", - "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", - "dev": true, - "dependencies": { - "regenerate": "^1.4.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", - "dev": true - }, - "node_modules/regenerator-transform": { - "version": "0.15.2", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", - "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.8.4" - } - }, - "node_modules/regex-parser": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.3.0.tgz", - "integrity": "sha512-TVILVSz2jY5D47F4mA4MppkBrafEaiUWJO/TcZHEIuI13AqoZMkK1WMA4Om1YkYbTx+9Ki1/tSUXbceyr9saRg==", - "dev": true - }, - "node_modules/regexpu-core": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", - "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", - "dev": true, - "dependencies": { - "@babel/regjsgen": "^0.8.0", - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.1.0", - "regjsparser": "^0.9.1", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regjsparser": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", - "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", - "dev": true, - "dependencies": { - "jsesc": "~0.5.0" - }, - "bin": { - "regjsparser": "bin/parser" - } - }, - "node_modules/regjsparser/node_modules/jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - } - }, - "node_modules/request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", - "dev": true, - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/request-progress": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-2.0.1.tgz", - "integrity": "sha512-dxdraeZVUNEn9AvLrxkgB2k6buTlym71dJk1fk4v8j3Ou3RKNm07BcgbHdj2lLgYGfqX71F+awb1MR+tWPFJzA==", - "dev": true, - "dependencies": { - "throttleit": "^1.0.0" - } - }, - "node_modules/request/node_modules/form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/request/node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/request/node_modules/qs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/request/node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "node_modules/requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "dev": true - }, - "node_modules/resolve": { - "version": "1.22.2", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", - "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", - "dev": true, - "dependencies": { - "is-core-module": "^2.11.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-url-loader": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-5.0.0.tgz", - "integrity": "sha512-uZtduh8/8srhBoMx//5bwqjQ+rfYOUq8zC9NrMUGtjBiGTtFJM42s58/36+hTqeqINcnYe08Nj3LkK9lW4N8Xg==", - "dev": true, - "dependencies": { - "adjust-sourcemap-loader": "^4.0.0", - "convert-source-map": "^1.7.0", - "loader-utils": "^2.0.0", - "postcss": "^8.2.14", - "source-map": "0.6.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/resolve-url-loader/node_modules/loader-utils": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", - "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", - "dev": true, - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" - } - }, - "node_modules/resolve-url-loader/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rfdc": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", - "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", - "dev": true - }, - "node_modules/rimraf": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.4.1.tgz", - "integrity": "sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==", - "dev": true, - "dependencies": { - "glob": "^9.2.0" - }, - "bin": { - "rimraf": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/glob": { - "version": "9.3.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz", - "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "minimatch": "^8.0.2", - "minipass": "^4.2.4", - "path-scurry": "^1.6.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/minimatch": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz", - "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/minipass": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", - "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/rollup": { - "version": "3.29.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz", - "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==", - "dev": true, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=14.18.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/rxjs": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", - "dependencies": { - "tslib": "^2.1.0" - } - }, - "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" - } - ] - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "node_modules/sass": { - "version": "1.64.1", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.64.1.tgz", - "integrity": "sha512-16rRACSOFEE8VN7SCgBu1MpYCyN7urj9At898tyzdXFhC+a+yOX5dXwAR7L8/IdPJ1NB8OYoXmD55DM30B2kEQ==", - "dev": true, - "dependencies": { - "chokidar": ">=3.0.0 <4.0.0", - "immutable": "^4.0.0", - "source-map-js": ">=0.6.2 <2.0.0" - }, - "bin": { - "sass": "sass.js" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/sass-loader": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-13.3.2.tgz", - "integrity": "sha512-CQbKl57kdEv+KDLquhC+gE3pXt74LEAzm+tzywcA0/aHZuub8wTErbjAoNI57rPUWRYRNC5WUnNl8eGJNbDdwg==", - "dev": true, - "dependencies": { - "neo-async": "^2.6.2" - }, - "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "fibers": ">= 3.1.0", - "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0", - "sass": "^1.3.0", - "sass-embedded": "*", - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "fibers": { - "optional": true - }, - "node-sass": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - } - } - }, - "node_modules/saucelabs": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/saucelabs/-/saucelabs-1.5.0.tgz", - "integrity": "sha512-jlX3FGdWvYf4Q3LFfFWS1QvPg3IGCGWxIc8QBFdPTbpTJnt/v17FHXYVAn7C8sHf1yUXo2c7yIM0isDryfYtHQ==", - "dev": true, - "dependencies": { - "https-proxy-agent": "^2.2.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/saucelabs/node_modules/agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "dev": true, - "dependencies": { - "es6-promisify": "^5.0.0" - }, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/saucelabs/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/saucelabs/node_modules/https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "dev": true, - "dependencies": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - }, - "engines": { - "node": ">= 4.5.0" - } - }, - "node_modules/sax": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.1.4.tgz", - "integrity": "sha512-5f3k2PbGGp+YtKJjOItpg3P99IMD84E4HOvcfleTb5joCHNXYLsR9yWFPOYGgaeMPDubQILTCMdsFb2OMeOjtg==" - }, - "node_modules/saxes": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", - "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", - "dev": true, - "dependencies": { - "xmlchars": "^2.2.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/schema-utils": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", - "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "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==", - "dev": true - }, - "node_modules/selenium-webdriver": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-3.6.0.tgz", - "integrity": "sha512-WH7Aldse+2P5bbFBO4Gle/nuQOdVwpHMTL6raL3uuBj/vPG07k6uzt3aiahu352ONBr5xXh0hDlM3LhtXPOC4Q==", - "dev": true, - "dependencies": { - "jszip": "^3.1.3", - "rimraf": "^2.5.4", - "tmp": "0.0.30", - "xml2js": "^0.4.17" - }, - "engines": { - "node": ">= 6.9.0" - } - }, - "node_modules/selenium-webdriver/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/selenium-webdriver/node_modules/tmp": { - "version": "0.0.30", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.30.tgz", - "integrity": "sha512-HXdTB7lvMwcb55XFfrTM8CPr/IYREk4hVBFaQ4b/6nInrluSL86hfHm7vu0luYKCfyBZp2trCjpc8caC3vVM3w==", - "dev": true, - "dependencies": { - "os-tmpdir": "~1.0.1" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/selenium-webdriver/node_modules/xml2js": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", - "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", - "dev": true, - "dependencies": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/selenium-webdriver/node_modules/xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/selfsigned": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", - "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", - "dev": true, - "dependencies": { - "@types/node-forge": "^1.3.0", - "node-forge": "^1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver-dsl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/semver-dsl/-/semver-dsl-1.0.1.tgz", - "integrity": "sha512-e8BOaTo007E3dMuQQTnPdalbKTABKNS7UxoBIDnwOqRa+QwMrCPjynB8zAlPF6xlqUfdLPPLIJ13hJNmhtq8Ng==", - "dev": true, - "dependencies": { - "semver": "^5.3.0" - } - }, - "node_modules/semver-dsl/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/semver/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "dev": true, - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/send/node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "node_modules/send/node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/serialize-javascript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", - "dev": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", - "dev": true, - "dependencies": { - "accepts": "~1.3.4", - "batch": "0.6.1", - "debug": "2.6.9", - "escape-html": "~1.0.3", - "http-errors": "~1.6.2", - "mime-types": "~2.1.17", - "parseurl": "~1.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/serve-index/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/serve-index/node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-index/node_modules/http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", - "dev": true, - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-index/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", - "dev": true - }, - "node_modules/serve-index/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/serve-index/node_modules/setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "dev": true - }, - "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", - "dev": true, - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "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==", - "dev": true - }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dev": true, - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", - "dev": true - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "dev": true - }, - "node_modules/shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/sharp": { - "version": "0.29.3", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.29.3.tgz", - "integrity": "sha512-fKWUuOw77E4nhpyzCCJR1ayrttHoFHBT2U/kR/qEMRhvPEcluG4BKj324+SCO1e84+knXHwhJ1HHJGnUt4ElGA==", - "hasInstallScript": true, - "dependencies": { - "color": "^4.0.1", - "detect-libc": "^1.0.3", - "node-addon-api": "^4.2.0", - "prebuild-install": "^7.0.0", - "semver": "^7.3.5", - "simple-get": "^4.0.0", - "tar-fs": "^2.1.1", - "tunnel-agent": "^0.6.0" - }, - "engines": { - "node": ">=12.13.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/sharp/node_modules/node-addon-api": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", - "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==" - }, - "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==", - "dev": true, - "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==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/shell-quote": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", - "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.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==", - "dev": true - }, - "node_modules/sigstore": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-1.9.0.tgz", - "integrity": "sha512-0Zjz0oe37d08VeOtBIuB6cRriqXse2e8w+7yIy2XSXjshRKxbc2KkhXjL229jXSxEm7UbcjS76wcJDGQddVI9A==", - "dev": true, - "dependencies": { - "@sigstore/bundle": "^1.1.0", - "@sigstore/protobuf-specs": "^0.2.0", - "@sigstore/sign": "^1.0.0", - "@sigstore/tuf": "^1.0.3", - "make-fetch-happen": "^11.0.1" - }, - "bin": { - "sigstore": "bin/sigstore.js" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/sigstore/node_modules/@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", - "dev": true, - "engines": { - "node": ">= 10" - } - }, - "node_modules/sigstore/node_modules/http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", - "dev": true, - "dependencies": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/sigstore/node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/sigstore/node_modules/make-fetch-happen": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz", - "integrity": "sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==", - "dev": true, - "dependencies": { - "agentkeepalive": "^4.2.1", - "cacache": "^17.0.0", - "http-cache-semantics": "^4.1.1", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", - "is-lambda": "^1.0.1", - "lru-cache": "^7.7.1", - "minipass": "^5.0.0", - "minipass-fetch": "^3.0.0", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "promise-retry": "^2.0.1", - "socks-proxy-agent": "^7.0.0", - "ssri": "^10.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/sigstore/node_modules/minipass-fetch": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.5.tgz", - "integrity": "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==", - "dev": true, - "dependencies": { - "minipass": "^7.0.3", - "minipass-sized": "^1.0.3", - "minizlib": "^2.1.2" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - }, - "optionalDependencies": { - "encoding": "^0.1.13" - } - }, - "node_modules/sigstore/node_modules/minipass-fetch/node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/simple-get": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", - "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "decompress-response": "^6.0.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "node_modules/simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", - "dependencies": { - "is-arrayish": "^0.3.1" - } - }, - "node_modules/simple-swizzle/node_modules/is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/slice-ansi/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==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/slice-ansi/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==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/slice-ansi/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==", - "dev": true - }, - "node_modules/smart-buffer": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", - "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", - "dev": true, - "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/socket.io": { - "version": "4.7.5", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.5.tgz", - "integrity": "sha512-DmeAkF6cwM9jSfmp6Dr/5/mfMwb5Z5qRrSXLpo3Fq5SqyU8CMF15jIN4ZhfSwu35ksM1qmHZDQ/DK5XTccSTvA==", - "dev": true, - "dependencies": { - "accepts": "~1.3.4", - "base64id": "~2.0.0", - "cors": "~2.8.5", - "debug": "~4.3.2", - "engine.io": "~6.5.2", - "socket.io-adapter": "~2.5.2", - "socket.io-parser": "~4.2.4" - }, - "engines": { - "node": ">=10.2.0" - } - }, - "node_modules/socket.io-adapter": { - "version": "2.5.5", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz", - "integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==", - "dev": true, - "dependencies": { - "debug": "~4.3.4", - "ws": "~8.17.1" - } - }, - "node_modules/socket.io-adapter/node_modules/ws": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", - "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", - "dev": true, - "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/socket.io-parser": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", - "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", - "dev": true, - "dependencies": { - "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.3.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/sockjs": { - "version": "0.3.24", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", - "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", - "dev": true, - "dependencies": { - "faye-websocket": "^0.11.3", - "uuid": "^8.3.2", - "websocket-driver": "^0.7.4" - } - }, - "node_modules/sockjs/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==", - "dev": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/socks": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", - "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", - "dev": true, - "dependencies": { - "ip-address": "^9.0.5", - "smart-buffer": "^4.2.0" - }, - "engines": { - "node": ">= 10.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/socks-proxy-agent": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", - "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", - "dev": true, - "dependencies": { - "agent-base": "^6.0.2", - "debug": "^4.3.3", - "socks": "^2.6.2" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-loader": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-4.0.1.tgz", - "integrity": "sha512-oqXpzDIByKONVY8g1NUPOTQhe0UTU5bWUl32GSkqK2LjJj0HmwTMVKxcUip0RgAYhY1mqgOxjbQM48a0mmeNfA==", - "dev": true, - "dependencies": { - "abab": "^2.0.6", - "iconv-lite": "^0.6.3", - "source-map-js": "^1.0.2" - }, - "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.72.1" - } - }, - "node_modules/source-map-loader/node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dev": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "dev": true, - "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==", - "dev": true - }, - "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==", - "dev": true, - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.18", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.18.tgz", - "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==", - "dev": true - }, - "node_modules/spdy": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", - "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", - "dev": 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==", - "dev": 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/split2": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", - "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", - "dev": true, - "engines": { - "node": ">= 10.x" - } - }, - "node_modules/sprintf-js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", - "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", - "dev": true - }, - "node_modules/sshpk": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", - "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", - "dev": true, - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sshpk/node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", - "dev": true - }, - "node_modules/ssri": { - "version": "10.0.6", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", - "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", - "dev": true, - "dependencies": { - "minipass": "^7.0.3" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/ssri/node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/streamroller": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.5.tgz", - "integrity": "sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==", - "dev": true, - "dependencies": { - "date-format": "^4.0.14", - "debug": "^4.3.4", - "fs-extra": "^8.1.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/streamroller/node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/streamroller/node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/streamroller/node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "engines": { - "node": ">= 4.0.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==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "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==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "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==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/symbol-observable": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz", - "integrity": "sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==", - "dev": true, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "dev": true - }, - "node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/tar": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", - "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", - "dev": true, - "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^5.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/tar-fs": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", - "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", - "dependencies": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.1.4" - } - }, - "node_modules/tar-fs/node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" - }, - "node_modules/tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "dependencies": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tar/node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dev": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/tar/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/tar/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/terser": { - "version": "5.19.2", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.19.2.tgz", - "integrity": "sha512-qC5+dmecKJA4cpYxRa5aVkKehYsQKc+AHeKl0Oe62aYjBL8ZA33tTljktDHJSaxxMnbI5ZYw+o/S2DxxLu8OfA==", - "dev": true, - "dependencies": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/terser-webpack-plugin": { - "version": "5.3.10", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", - "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.20", - "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.1", - "terser": "^5.26.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "uglify-js": { - "optional": true - } - } - }, - "node_modules/terser-webpack-plugin/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/terser-webpack-plugin/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/terser-webpack-plugin/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/terser-webpack-plugin/node_modules/terser": { - "version": "5.31.2", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.2.tgz", - "integrity": "sha512-LGyRZVFm/QElZHy/CPr/O4eNZOZIzsrQ92y4v9UJe/pFJjypje2yI3C2FmPtvUEnhadlSbmG2nXtdcjHOjCfxw==", - "dev": true, - "dependencies": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/terser/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/test-exclude/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/test-exclude/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "node_modules/throttleit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.1.tgz", - "integrity": "sha512-vDZpf9Chs9mAdfY046mcPt8fg5QSZr37hEH4TXYBnDF+izxgrbRGUAAaBvIk/fJm9aOFCGFd1EsNg5AZCbnQCQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true - }, - "node_modules/through2": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", - "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", - "dev": true, - "dependencies": { - "readable-stream": "3" - } - }, - "node_modules/thunky": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", - "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", - "dev": true - }, - "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "dependencies": { - "os-tmpdir": "~1.0.2" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "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==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/tough-cookie": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", - "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", - "dev": true, - "dependencies": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.2.0", - "url-parse": "^1.5.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tough-cookie/node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/tough-cookie/node_modules/universalify": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/tr46": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", - "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", - "dev": true, - "dependencies": { - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/tr46/node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/tree-kill": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", - "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", - "dev": true, - "bin": { - "tree-kill": "cli.js" - } - }, - "node_modules/ts-api-utils": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", - "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", - "dev": true, - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "typescript": ">=4.2.0" - } - }, - "node_modules/ts-node": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.3.0.tgz", - "integrity": "sha512-dyNS/RqyVTDcmNM4NIBAeDMpsAdaQ+ojdf0GOLqE6nwJOgzEkdRNzJywhDfwnuvB10oa6NLVG1rUJQCpRN7qoQ==", - "dev": true, - "dependencies": { - "arg": "^4.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "source-map-support": "^0.5.6", - "yn": "^3.0.0" - }, - "bin": { - "ts-node": "dist/bin.js" - }, - "engines": { - "node": ">=4.2.0" - }, - "peerDependencies": { - "typescript": ">=2.0" - } - }, - "node_modules/tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - }, - "node_modules/tslint": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz", - "integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==", - "deprecated": "TSLint has been deprecated in favor of ESLint. Please see https://github.com/palantir/tslint/issues/4534 for more information.", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.3.0", - "commander": "^2.12.1", - "diff": "^4.0.1", - "glob": "^7.1.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.3", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.13.0", - "tsutils": "^2.29.0" - }, - "bin": { - "tslint": "bin/tslint" - }, - "engines": { - "node": ">=4.8.0" - }, - "peerDependencies": { - "typescript": ">=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev || >= 4.0.0-dev" - } - }, - "node_modules/tslint/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/tslint/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "node_modules/tslint/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/tslint/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/tslint/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "node_modules/tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "dependencies": { - "tslib": "^1.8.1" - }, - "peerDependencies": { - "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev" - } - }, - "node_modules/tsutils/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "node_modules/tuf-js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-1.1.7.tgz", - "integrity": "sha512-i3P9Kgw3ytjELUfpuKVDNBJvk4u5bXL6gskv572mcevPbSKCV3zt3djhmlEQ65yERjIbOSncy7U4cQJaB1CBCg==", - "dev": true, - "dependencies": { - "@tufjs/models": "1.0.4", - "debug": "^4.3.4", - "make-fetch-happen": "^11.1.1" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/tuf-js/node_modules/@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", - "dev": true, - "engines": { - "node": ">= 10" - } - }, - "node_modules/tuf-js/node_modules/http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", - "dev": true, - "dependencies": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/tuf-js/node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/tuf-js/node_modules/make-fetch-happen": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz", - "integrity": "sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==", - "dev": true, - "dependencies": { - "agentkeepalive": "^4.2.1", - "cacache": "^17.0.0", - "http-cache-semantics": "^4.1.1", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", - "is-lambda": "^1.0.1", - "lru-cache": "^7.7.1", - "minipass": "^5.0.0", - "minipass-fetch": "^3.0.0", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "promise-retry": "^2.0.1", - "socks-proxy-agent": "^7.0.0", - "ssri": "^10.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/tuf-js/node_modules/minipass-fetch": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.5.tgz", - "integrity": "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==", - "dev": true, - "dependencies": { - "minipass": "^7.0.3", - "minipass-sized": "^1.0.3", - "minizlib": "^2.1.2" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - }, - "optionalDependencies": { - "encoding": "^0.1.13" - } - }, - "node_modules/tuf-js/node_modules/minipass-fetch/node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "dev": true - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dev": true, - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/typed-assert": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/typed-assert/-/typed-assert-1.0.9.tgz", - "integrity": "sha512-KNNZtayBCtmnNmbo5mG47p1XsCyrx6iVqomjcZnec/1Y5GGARaxPs6r49RnSPeUP3YjNYiU9sQHAtY4BBvnZwg==", - "dev": true - }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "dev": true - }, - "node_modules/typescript": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", - "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/ua-parser-js": { - "version": "0.7.38", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.38.tgz", - "integrity": "sha512-fYmIy7fKTSFAhG3fuPlubeGaMoAd6r0rSnfEsO5nEY55i26KSLt9EH7PLQiiqPUhNqYIJvSkTy1oArIcXAbPbA==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/ua-parser-js" - }, - { - "type": "paypal", - "url": "https://paypal.me/faisalman" - }, - { - "type": "github", - "url": "https://github.com/sponsors/faisalman" - } - ], - "engines": { - "node": "*" - } - }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" - }, - "node_modules/unicode-canonical-property-names-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", - "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", - "dev": true, - "dependencies": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", - "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-property-aliases-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", - "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/unique-filename": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz", - "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==", - "dev": true, - "dependencies": { - "unique-slug": "^4.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/unique-slug": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz", - "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==", - "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "engines": { - "node": ">= 10.0.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==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/untildify": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", - "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", - "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/uri-js/node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/url-parse": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "dev": true, - "dependencies": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "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==" - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "dev": true, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "dev": true, - "bin": { - "uuid": "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==", - "dev": true, - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/validate-npm-package-name": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.1.tgz", - "integrity": "sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==", - "dev": true, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.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==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "node_modules/vite": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.3.tgz", - "integrity": "sha512-kQL23kMeX92v3ph7IauVkXkikdDRsYMGTVl5KY2E9OY4ONLvkHf04MDTbnfo6NKxZiDLWzVpP5oTa8hQD8U3dg==", - "dev": true, - "dependencies": { - "esbuild": "^0.18.10", - "postcss": "^8.4.27", - "rollup": "^3.27.1" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - }, - "peerDependencies": { - "@types/node": ">= 14", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } - } - }, - "node_modules/void-elements": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", - "integrity": "sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/w3c-hr-time": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", - "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", - "deprecated": "Use your platform's native performance.now() and performance.timeOrigin.", - "dev": true, - "dependencies": { - "browser-process-hrtime": "^1.0.0" - } - }, - "node_modules/w3c-xmlserializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", - "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", - "dev": true, - "dependencies": { - "xml-name-validator": "^3.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/watchpack": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", - "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", - "dev": true, - "dependencies": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/wbuf": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", - "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", - "dev": true, - "dependencies": { - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/wcwidth": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", - "dev": true, - "dependencies": { - "defaults": "^1.0.3" - } - }, - "node_modules/webdriver-js-extender": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/webdriver-js-extender/-/webdriver-js-extender-2.1.0.tgz", - "integrity": "sha512-lcUKrjbBfCK6MNsh7xaY2UAUmZwe+/ib03AjVOpFobX4O7+83BUveSrLfU0Qsyb1DaKJdQRbuU+kM9aZ6QUhiQ==", - "dev": true, - "dependencies": { - "@types/selenium-webdriver": "^3.0.0", - "selenium-webdriver": "^3.0.1" - }, - "engines": { - "node": ">=6.9.x" - } - }, - "node_modules/webdriver-manager": { - "version": "12.1.9", - "resolved": "https://registry.npmjs.org/webdriver-manager/-/webdriver-manager-12.1.9.tgz", - "integrity": "sha512-Yl113uKm8z4m/KMUVWHq1Sjtla2uxEBtx2Ue3AmIlnlPAKloDn/Lvmy6pqWCUersVISpdMeVpAaGbNnvMuT2LQ==", - "dev": true, - "dependencies": { - "adm-zip": "^0.5.2", - "chalk": "^1.1.1", - "del": "^2.2.0", - "glob": "^7.0.3", - "ini": "^1.3.4", - "minimist": "^1.2.0", - "q": "^1.4.1", - "request": "^2.87.0", - "rimraf": "^2.5.2", - "semver": "^5.3.0", - "xml2js": "^0.4.17" - }, - "bin": { - "webdriver-manager": "bin/webdriver-manager" - }, - "engines": { - "node": ">=6.9.x" - } - }, - "node_modules/webdriver-manager/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webdriver-manager/node_modules/ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webdriver-manager/node_modules/chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", - "dev": true, - "dependencies": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webdriver-manager/node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, - "node_modules/webdriver-manager/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/webdriver-manager/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/webdriver-manager/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", - "dev": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webdriver-manager/node_modules/supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/webdriver-manager/node_modules/xml2js": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", - "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", - "dev": true, - "dependencies": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/webdriver-manager/node_modules/xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/webidl-conversions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", - "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", - "dev": true, - "engines": { - "node": ">=10.4" - } - }, - "node_modules/webpack": { - "version": "5.88.2", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.2.tgz", - "integrity": "sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==", - "dev": true, - "dependencies": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^1.0.0", - "@webassemblyjs/ast": "^1.11.5", - "@webassemblyjs/wasm-edit": "^1.11.5", - "@webassemblyjs/wasm-parser": "^1.11.5", - "acorn": "^8.7.1", - "acorn-import-assertions": "^1.9.0", - "browserslist": "^4.14.5", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.15.0", - "es-module-lexer": "^1.2.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", - "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.2.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.7", - "watchpack": "^2.4.0", - "webpack-sources": "^3.2.3" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/webpack-dev-middleware": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-6.1.2.tgz", - "integrity": "sha512-Wu+EHmX326YPYUpQLKmKbTyZZJIB8/n6R09pTmB03kJmnMsVPTo9COzHZFr01txwaCAuZvfBJE4ZCHRcKs5JaQ==", - "dev": true, - "dependencies": { - "colorette": "^2.0.10", - "memfs": "^3.4.12", - "mime-types": "^2.1.31", - "range-parser": "^1.2.1", - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "webpack": { - "optional": true - } - } - }, - "node_modules/webpack-dev-server": { - "version": "4.15.1", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.1.tgz", - "integrity": "sha512-5hbAst3h3C3L8w6W4P96L5vaV0PxSmJhxZvWKYIdgxOQm8pNZ5dEOmmSLBVpP85ReeyRt6AS1QJNyo/oFFPeVA==", - "dev": true, - "dependencies": { - "@types/bonjour": "^3.5.9", - "@types/connect-history-api-fallback": "^1.3.5", - "@types/express": "^4.17.13", - "@types/serve-index": "^1.9.1", - "@types/serve-static": "^1.13.10", - "@types/sockjs": "^0.3.33", - "@types/ws": "^8.5.5", - "ansi-html-community": "^0.0.8", - "bonjour-service": "^1.0.11", - "chokidar": "^3.5.3", - "colorette": "^2.0.10", - "compression": "^1.7.4", - "connect-history-api-fallback": "^2.0.0", - "default-gateway": "^6.0.3", - "express": "^4.17.3", - "graceful-fs": "^4.2.6", - "html-entities": "^2.3.2", - "http-proxy-middleware": "^2.0.3", - "ipaddr.js": "^2.0.1", - "launch-editor": "^2.6.0", - "open": "^8.0.9", - "p-retry": "^4.5.0", - "rimraf": "^3.0.2", - "schema-utils": "^4.0.0", - "selfsigned": "^2.1.1", - "serve-index": "^1.9.1", - "sockjs": "^0.3.24", - "spdy": "^4.0.2", - "webpack-dev-middleware": "^5.3.1", - "ws": "^8.13.0" - }, - "bin": { - "webpack-dev-server": "bin/webpack-dev-server.js" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.37.0 || ^5.0.0" - }, - "peerDependenciesMeta": { - "webpack": { - "optional": true - }, - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/webpack-dev-server/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/webpack-dev-server/node_modules/webpack-dev-middleware": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz", - "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==", - "dev": true, - "dependencies": { - "colorette": "^2.0.10", - "memfs": "^3.4.3", - "mime-types": "^2.1.31", - "range-parser": "^1.2.1", - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "node_modules/webpack-dev-server/node_modules/ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", - "dev": true, - "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/webpack-merge": { - "version": "5.9.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.9.0.tgz", - "integrity": "sha512-6NbRQw4+Sy50vYNTw7EyOn41OZItPiXB8GNv3INSoe3PSFaHJEz3SHTrYVaRm2LilNGnFUzh0FAwqPEmU/CwDg==", - "dev": true, - "dependencies": { - "clone-deep": "^4.0.1", - "wildcard": "^2.0.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/webpack-sources": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", - "dev": true, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/webpack-subresource-integrity": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/webpack-subresource-integrity/-/webpack-subresource-integrity-5.1.0.tgz", - "integrity": "sha512-sacXoX+xd8r4WKsy9MvH/q/vBtEHr86cpImXwyg74pFIpERKt6FmB8cXpeuh0ZLgclOlHI4Wcll7+R5L02xk9Q==", - "dev": true, - "dependencies": { - "typed-assert": "^1.0.8" - }, - "engines": { - "node": ">= 12" - }, - "peerDependencies": { - "html-webpack-plugin": ">= 5.0.0-beta.1 < 6", - "webpack": "^5.12.0" - }, - "peerDependenciesMeta": { - "html-webpack-plugin": { - "optional": true - } - } - }, - "node_modules/webpack/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/webpack/node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/webpack/node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/webpack/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/webpack/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/webpack/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/websocket-driver": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", - "dev": true, - "dependencies": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", - "dev": true, - "dependencies": { - "iconv-lite": "0.4.24" - } - }, - "node_modules/whatwg-mimetype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", - "dev": true - }, - "node_modules/whatwg-url": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", - "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", - "dev": true, - "dependencies": { - "lodash": "^4.7.0", - "tr46": "^2.1.0", - "webidl-conversions": "^6.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-module": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", - "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", - "dev": true - }, - "node_modules/wide-align": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", - "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", - "dev": true, - "dependencies": { - "string-width": "^1.0.2 || 2 || 3 || 4" - } - }, - "node_modules/wildcard": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", - "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", - "dev": true - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/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==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs/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==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs/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==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/wrap-ansi-cjs/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==", - "dev": true - }, - "node_modules/wrap-ansi/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==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi/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==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/wrap-ansi/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==", - "dev": true - }, - "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==" - }, - "node_modules/ws": { - "version": "7.5.10", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", - "dev": true, - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xml-name-validator": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", - "dev": true - }, - "node_modules/xml2js": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", - "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", - "dev": true, - "dependencies": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/xml2js/node_modules/xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/xmlbuilder": { - "version": "15.1.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", - "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", - "dev": true, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dev": true, - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", - "dev": true, - "dependencies": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/zone.js": { - "version": "0.13.3", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.13.3.tgz", - "integrity": "sha512-MKPbmZie6fASC/ps4dkmIhaT5eonHkEt6eAy80K42tAm0G2W+AahLJjbfi6X9NPdciOE9GRFTTM8u2IiF6O3ww==", - "dependencies": { - "tslib": "^2.3.0" - } - } - } + "name": "beaconchain-dashboard", + "version": "2.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "beaconchain-dashboard", + "version": "2.0.0", + "dependencies": { + "@angular/animations": "^19.1.4", + "@angular/cdk": "^18.2.3", + "@angular/common": "~19.1.4", + "@angular/core": "~19.1.4", + "@angular/forms": "~19.1.4", + "@angular/platform-browser": "~19.1.4", + "@angular/platform-browser-dynamic": "~19.1.4", + "@angular/router": "~19.1.4", + "@awesome-cordova-plugins/core": "^6.8.0", + "@awesome-cordova-plugins/splash-screen": "^6.8.0", + "@awesome-cordova-plugins/status-bar": "^6.8.0", + "@byteowls/capacitor-oauth2": "^5.0.0", + "@capacitor/android": "^6.1.2", + "@capacitor/app": "^6.0.1", + "@capacitor/browser": "^6.0.2", + "@capacitor/clipboard": "^6.0.1", + "@capacitor/core": "^6.1.2", + "@capacitor/device": "^6.0.1", + "@capacitor/haptics": "^6.0.1", + "@capacitor/ios": "^6.1.2", + "@capacitor/keyboard": "^6.0.2", + "@capacitor/local-notifications": "^6.1.0", + "@capacitor/preferences": "^6.0.2", + "@capacitor/push-notifications": "^6.0.2", + "@capacitor/splash-screen": "^6.0.2", + "@capacitor/status-bar": "^6.0.1", + "@capacitor/toast": "^6.0.2", + "@capawesome/capacitor-app-update": "^6.0.0", + "@capgo/capacitor-updater": "^6.1.32", + "@ionic/angular": "^8.4.3", + "@ionic/angular-server": "^8.4.3", + "@ionic/core": "^8.4.3", + "async-mutex": "^0.2.6", + "bignumber.js": "^9.1.2", + "canvas-confetti": "^1.9.3", + "capacitor-navigationbarnx": "0.1.6", + "cordova-plugin-purchase": "^13.12.1", + "cordova-res": "^0.15.4", + "echarts": "^5.5.1", + "ethereum-blockies": "^0.1.1", + "highcharts": "^11.4.8", + "intl": "^1.2.5", + "jetifier": "^1.6.8", + "lodash-es": "^4.17.21", + "luxon": "^3.5.0", + "ng2-tooltip-directive-major-angular-updates": "^2.12.1", + "ngx-echarts": "^17.2.0", + "ngx-timeago": "^3.0.0", + "puppeteer": "^23.11.0", + "rxjs": "~7.8.1", + "storage-mirror": "file:storage-mirror", + "tslib": "^2.7.0", + "zone.js": "^0.15.0" + }, + "devDependencies": { + "@analogjs/platform": "^1.13.0", + "@analogjs/vite-plugin-angular": "^1.13.0", + "@analogjs/vitest-angular": "^1.13.0", + "@angular-devkit/build-angular": "^19.1.5", + "@angular/cli": "~19.1.5", + "@angular/compiler": "~19.1.4", + "@angular/compiler-cli": "~19.1.4", + "@angular/language-service": "~19.1.4", + "@capacitor/cli": "^6.1.2", + "@ionic/angular-toolkit": "^11.0.1", + "@nx/devkit": "^20.4.0", + "@nx/vite": "^20.0.0", + "@types/canvas-confetti": "^1.6.4", + "@types/ethereum-blockies": "^0.1.2", + "@types/jasmine": "~5.1.0", + "@types/lodash-es": "^4.17.12", + "@types/luxon": "^3.4.2", + "@typescript-eslint/eslint-plugin": "^8.22.0", + "@typescript-eslint/parser": "^8.22.0", + "@vitest/coverage-v8": "^3.0.5", + "@vitest/ui": "^3.0.5", + "@wdio/appium-service": "^9.11.0", + "@wdio/cli": "^9.11.0", + "@wdio/local-runner": "^9.11.0", + "@wdio/mocha-framework": "^9.11.0", + "@wdio/spec-reporter": "^9.11.0", + "ajv": "^8.12.0", + "appium": "^2.16.2", + "appium-uiautomator2-driver": "^4.1.1", + "codelyzer": "^6.0.2", + "eslint": "^9.16.0", + "eslint-plugin-import": "^2.29.1", + "eslint-plugin-jsdoc": "^48.2.1", + "eslint-plugin-prefer-arrow": "1.2.2", + "fs-extra": "^11.2.0", + "jasmine-core": "~5.1.0", + "jasmine-spec-reporter": "~5.0.0", + "jsdom": "^22.0.0", + "nx": "^20.4.0", + "prettier": "3.3.3", + "protractor": "~7.0.0", + "ts-node": "~8.3.0", + "tslint": "~6.1.3", + "typescript": "~5.5.4", + "vite": "^6.0.0", + "vite-tsconfig-paths": "^4.2.0", + "vitest": "^3.0.5", + "zip-a-folder": "^3.1.7" + } + }, + "../storage-mirror": { + "version": "0.0.1", + "extraneous": true, + "license": "GPLv3", + "devDependencies": { + "@capacitor/android": "^6.0.0", + "@capacitor/core": "^6.0.0", + "@capacitor/docgen": "^0.2.2", + "@capacitor/ios": "^6.0.0", + "@ionic/eslint-config": "^0.4.0", + "@ionic/prettier-config": "^1.0.1", + "@ionic/swiftlint-config": "^1.1.2", + "eslint": "^8.57.0", + "prettier": "~2.3.0", + "prettier-plugin-java": "~1.0.2", + "rimraf": "^3.0.2", + "rollup": "^2.32.0", + "swiftlint": "^1.0.1", + "typescript": "~4.1.5" + }, + "peerDependencies": { + "@capacitor/core": "^6.0.0" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@analogjs/platform": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@analogjs/platform/-/platform-1.13.0.tgz", + "integrity": "sha512-dgLigWA/1NVVrJJSk9jrxkZfNmAcnpvMiSwcHy3KL7r/51rAe96cT3UNv/Swtwrm0xgR3Mj1bd+MENmk30DTpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@analogjs/vite-plugin-angular": "^1.13.0", + "@analogjs/vite-plugin-nitro": "^1.13.0", + "nitropack": "^2.10.0", + "vitefu": "^0.2.5" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/brandonroberts" + }, + "peerDependencies": { + "@nx/angular": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0", + "@nx/devkit": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0", + "@nx/vite": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0", + "marked": ">=5.0.2", + "marked-gfm-heading-id": "^3.0.4", + "marked-highlight": "^2.0.1", + "marked-mangle": "^1.1.7", + "marked-shiki": "^1.1.0", + "shiki": "^1.6.1" + }, + "peerDependenciesMeta": { + "marked-highlight": { + "optional": true + }, + "marked-shiki": { + "optional": true + }, + "prismjs": { + "optional": true + }, + "shiki": { + "optional": true + } + } + }, + "node_modules/@analogjs/vite-plugin-angular": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@analogjs/vite-plugin-angular/-/vite-plugin-angular-1.13.0.tgz", + "integrity": "sha512-h9XTXtbOKXyjrjFdy5qy40wam3vTttujWCpnoqygnopWaKS9T86LVnBFAW1p2yaBa7Wzz/BKDs2MtBBPWht8Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "ts-morph": "^21.0.0", + "vfile": "^6.0.3" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/brandonroberts" + }, + "peerDependencies": { + "@angular-devkit/build-angular": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "@angular/build": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@angular-devkit/build-angular": { + "optional": true + }, + "@angular/build": { + "optional": true + } + } + }, + "node_modules/@analogjs/vite-plugin-nitro": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@analogjs/vite-plugin-nitro/-/vite-plugin-nitro-1.13.0.tgz", + "integrity": "sha512-C60hGQwmoEr2fWT/uc62fKCHJHUAB0F0hQMemdpborxq8XekHk+FT1jS4bRhkFuQk1ZV2BNwH3biHBBs/M+3fQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.20.1", + "nitropack": "^2.10.0", + "xmlbuilder2": "^3.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/brandonroberts" + } + }, + "node_modules/@analogjs/vite-plugin-nitro/node_modules/@esbuild/aix-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", + "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@analogjs/vite-plugin-nitro/node_modules/@esbuild/android-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", + "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@analogjs/vite-plugin-nitro/node_modules/@esbuild/android-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", + "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@analogjs/vite-plugin-nitro/node_modules/@esbuild/android-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", + "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@analogjs/vite-plugin-nitro/node_modules/@esbuild/darwin-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", + "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@analogjs/vite-plugin-nitro/node_modules/@esbuild/darwin-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", + "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@analogjs/vite-plugin-nitro/node_modules/@esbuild/freebsd-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", + "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@analogjs/vite-plugin-nitro/node_modules/@esbuild/freebsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", + "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@analogjs/vite-plugin-nitro/node_modules/@esbuild/linux-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", + "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@analogjs/vite-plugin-nitro/node_modules/@esbuild/linux-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", + "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@analogjs/vite-plugin-nitro/node_modules/@esbuild/linux-ia32": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", + "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@analogjs/vite-plugin-nitro/node_modules/@esbuild/linux-loong64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", + "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@analogjs/vite-plugin-nitro/node_modules/@esbuild/linux-mips64el": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", + "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@analogjs/vite-plugin-nitro/node_modules/@esbuild/linux-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", + "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@analogjs/vite-plugin-nitro/node_modules/@esbuild/linux-riscv64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", + "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@analogjs/vite-plugin-nitro/node_modules/@esbuild/linux-s390x": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", + "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@analogjs/vite-plugin-nitro/node_modules/@esbuild/linux-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", + "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@analogjs/vite-plugin-nitro/node_modules/@esbuild/netbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", + "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@analogjs/vite-plugin-nitro/node_modules/@esbuild/openbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", + "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@analogjs/vite-plugin-nitro/node_modules/@esbuild/sunos-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", + "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@analogjs/vite-plugin-nitro/node_modules/@esbuild/win32-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", + "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@analogjs/vite-plugin-nitro/node_modules/@esbuild/win32-ia32": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", + "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@analogjs/vite-plugin-nitro/node_modules/@esbuild/win32-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", + "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@analogjs/vite-plugin-nitro/node_modules/esbuild": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", + "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.20.2", + "@esbuild/android-arm": "0.20.2", + "@esbuild/android-arm64": "0.20.2", + "@esbuild/android-x64": "0.20.2", + "@esbuild/darwin-arm64": "0.20.2", + "@esbuild/darwin-x64": "0.20.2", + "@esbuild/freebsd-arm64": "0.20.2", + "@esbuild/freebsd-x64": "0.20.2", + "@esbuild/linux-arm": "0.20.2", + "@esbuild/linux-arm64": "0.20.2", + "@esbuild/linux-ia32": "0.20.2", + "@esbuild/linux-loong64": "0.20.2", + "@esbuild/linux-mips64el": "0.20.2", + "@esbuild/linux-ppc64": "0.20.2", + "@esbuild/linux-riscv64": "0.20.2", + "@esbuild/linux-s390x": "0.20.2", + "@esbuild/linux-x64": "0.20.2", + "@esbuild/netbsd-x64": "0.20.2", + "@esbuild/openbsd-x64": "0.20.2", + "@esbuild/sunos-x64": "0.20.2", + "@esbuild/win32-arm64": "0.20.2", + "@esbuild/win32-ia32": "0.20.2", + "@esbuild/win32-x64": "0.20.2" + } + }, + "node_modules/@analogjs/vitest-angular": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@analogjs/vitest-angular/-/vitest-angular-1.13.0.tgz", + "integrity": "sha512-V3jLxXhiKSvSam15UGe9hVIfiX/Kx/XHXzFIlfHKlq0jUj/ys+WDdMuqaG4LrlhsxCjjDtISPGmW9uM+OMfO/A==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/brandonroberts" + }, + "peerDependencies": { + "@analogjs/vite-plugin-angular": "*", + "@angular-devkit/architect": "^0.1500.0 || ^0.1600.0 || ^0.1700.0 || ^0.1800.0 || ^0.1900.0 || next", + "vitest": "^1.3.1 || ^2.0.0 || ^3.0.0" + } + }, + "node_modules/@angular-devkit/architect": { + "version": "0.1901.5", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1901.5.tgz", + "integrity": "sha512-zlRudZx34FkFZnSdaQCjxDleHwbQYNLdBFcLi+FBwt0UXqxmhbEIasK3l/3kCOC3QledrjUzVXgouji+OZ/WGQ==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "19.1.5", + "rxjs": "7.8.1" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular-devkit/architect/node_modules/@angular-devkit/core": { + "version": "19.1.5", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.1.5.tgz", + "integrity": "sha512-wGKV+i5mCM/Hd/3CsdrIYcVi5G2Wg/D5941bUDXivrbsqHfKVINxAkI3OI1eaD90VnAL8ICrQEoAhh6ni2Umkg==", + "dev": true, + "dependencies": { + "ajv": "8.17.1", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.2", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^4.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/build-angular": { + "version": "19.1.5", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-19.1.5.tgz", + "integrity": "sha512-ny7ktNOTxaEi6cS3V6XFP5bbJkgiMt3OUNUYLdfdbv4y6wolVlPVHKl+wb4xs6tgbnmx63+e6zGpoDMCRytgcg==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "2.3.0", + "@angular-devkit/architect": "0.1901.5", + "@angular-devkit/build-webpack": "0.1901.5", + "@angular-devkit/core": "19.1.5", + "@angular/build": "19.1.5", + "@babel/core": "7.26.0", + "@babel/generator": "7.26.3", + "@babel/helper-annotate-as-pure": "7.25.9", + "@babel/helper-split-export-declaration": "7.24.7", + "@babel/plugin-transform-async-generator-functions": "7.25.9", + "@babel/plugin-transform-async-to-generator": "7.25.9", + "@babel/plugin-transform-runtime": "7.25.9", + "@babel/preset-env": "7.26.0", + "@babel/runtime": "7.26.0", + "@discoveryjs/json-ext": "0.6.3", + "@ngtools/webpack": "19.1.5", + "@vitejs/plugin-basic-ssl": "1.2.0", + "ansi-colors": "4.1.3", + "autoprefixer": "10.4.20", + "babel-loader": "9.2.1", + "browserslist": "^4.21.5", + "copy-webpack-plugin": "12.0.2", + "css-loader": "7.1.2", + "esbuild-wasm": "0.24.2", + "fast-glob": "3.3.3", + "http-proxy-middleware": "3.0.3", + "istanbul-lib-instrument": "6.0.3", + "jsonc-parser": "3.3.1", + "karma-source-map-support": "1.4.0", + "less": "4.2.1", + "less-loader": "12.2.0", + "license-webpack-plugin": "4.0.2", + "loader-utils": "3.3.1", + "mini-css-extract-plugin": "2.9.2", + "open": "10.1.0", + "ora": "5.4.1", + "picomatch": "4.0.2", + "piscina": "4.8.0", + "postcss": "8.4.49", + "postcss-loader": "8.1.1", + "resolve-url-loader": "5.0.0", + "rxjs": "7.8.1", + "sass": "1.83.1", + "sass-loader": "16.0.4", + "semver": "7.6.3", + "source-map-loader": "5.0.0", + "source-map-support": "0.5.21", + "terser": "5.37.0", + "tree-kill": "1.2.2", + "tslib": "2.8.1", + "webpack": "5.97.1", + "webpack-dev-middleware": "7.4.2", + "webpack-dev-server": "5.2.0", + "webpack-merge": "6.0.1", + "webpack-subresource-integrity": "5.1.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "optionalDependencies": { + "esbuild": "0.24.2" + }, + "peerDependencies": { + "@angular/compiler-cli": "^19.0.0", + "@angular/localize": "^19.0.0", + "@angular/platform-server": "^19.0.0", + "@angular/service-worker": "^19.0.0", + "@angular/ssr": "^19.1.5", + "@web/test-runner": "^0.19.0", + "browser-sync": "^3.0.2", + "jest": "^29.5.0", + "jest-environment-jsdom": "^29.5.0", + "karma": "^6.3.0", + "ng-packagr": "^19.0.0", + "protractor": "^7.0.0", + "tailwindcss": "^2.0.0 || ^3.0.0 || ^4.0.0", + "typescript": ">=5.5 <5.8" + }, + "peerDependenciesMeta": { + "@angular/localize": { + "optional": true + }, + "@angular/platform-server": { + "optional": true + }, + "@angular/service-worker": { + "optional": true + }, + "@angular/ssr": { + "optional": true + }, + "@web/test-runner": { + "optional": true + }, + "browser-sync": { + "optional": true + }, + "jest": { + "optional": true + }, + "jest-environment-jsdom": { + "optional": true + }, + "karma": { + "optional": true + }, + "ng-packagr": { + "optional": true + }, + "protractor": { + "optional": true + }, + "tailwindcss": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@angular-devkit/core": { + "version": "19.1.5", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.1.5.tgz", + "integrity": "sha512-wGKV+i5mCM/Hd/3CsdrIYcVi5G2Wg/D5941bUDXivrbsqHfKVINxAkI3OI1eaD90VnAL8ICrQEoAhh6ni2Umkg==", + "dev": true, + "dependencies": { + "ajv": "8.17.1", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.2", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^4.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/build-webpack": { + "version": "0.1901.5", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1901.5.tgz", + "integrity": "sha512-UxEoF7F8L1GpH/N4me7VGe5ZPfxIiVHyhw5/ck3rcVbT6YD22/GYFGSJRGYP+D7LLTJ7OOQvfD6Bc/q62HhWvA==", + "dev": true, + "dependencies": { + "@angular-devkit/architect": "0.1901.5", + "rxjs": "7.8.1" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "webpack": "^5.30.0", + "webpack-dev-server": "^5.0.2" + } + }, + "node_modules/@angular-devkit/schematics": { + "version": "19.1.5", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-19.1.5.tgz", + "integrity": "sha512-8QjOlO2CktcTT0TWcaABea2xSePxoPKaZu96+6gc8oZzj/y8DbdGiO9mRvIac9+m4hiZI41Cqm1W+yMsCzYMkA==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "19.1.5", + "jsonc-parser": "3.3.1", + "magic-string": "0.30.17", + "ora": "5.4.1", + "rxjs": "7.8.1" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular-devkit/schematics/node_modules/@angular-devkit/core": { + "version": "19.1.5", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.1.5.tgz", + "integrity": "sha512-wGKV+i5mCM/Hd/3CsdrIYcVi5G2Wg/D5941bUDXivrbsqHfKVINxAkI3OI1eaD90VnAL8ICrQEoAhh6ni2Umkg==", + "dev": true, + "dependencies": { + "ajv": "8.17.1", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.2", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^4.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@angular/animations": { + "version": "19.1.4", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-19.1.4.tgz", + "integrity": "sha512-QGswsf/X+k7TijIgBzL6V8+KcArFAgebY6zM0L/Len8v5PNzPzdjJH99+P++5AOLiJctYKfISUwnlMbDb50NrA==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/core": "19.1.4" + } + }, + "node_modules/@angular/build": { + "version": "19.1.5", + "resolved": "https://registry.npmjs.org/@angular/build/-/build-19.1.5.tgz", + "integrity": "sha512-byoHcv0/s6WGWap59s43N/eC+4NsviuTnGoj+iR0ayubk8snn6jdkZLbFDfnTuQlTiu4ok8/XcksjzeMkgGyyw==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "2.3.0", + "@angular-devkit/architect": "0.1901.5", + "@angular-devkit/core": "19.1.5", + "@babel/core": "7.26.0", + "@babel/helper-annotate-as-pure": "7.25.9", + "@babel/helper-split-export-declaration": "7.24.7", + "@babel/plugin-syntax-import-attributes": "7.26.0", + "@inquirer/confirm": "5.1.1", + "@vitejs/plugin-basic-ssl": "1.2.0", + "beasties": "0.2.0", + "browserslist": "^4.23.0", + "esbuild": "0.24.2", + "fast-glob": "3.3.3", + "https-proxy-agent": "7.0.6", + "istanbul-lib-instrument": "6.0.3", + "listr2": "8.2.5", + "magic-string": "0.30.17", + "mrmime": "2.0.0", + "parse5-html-rewriting-stream": "7.0.0", + "picomatch": "4.0.2", + "piscina": "4.8.0", + "rollup": "4.30.1", + "sass": "1.83.1", + "semver": "7.6.3", + "vite": "6.0.11", + "watchpack": "2.4.2" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "optionalDependencies": { + "lmdb": "3.2.2" + }, + "peerDependencies": { + "@angular/compiler": "^19.0.0", + "@angular/compiler-cli": "^19.0.0", + "@angular/localize": "^19.0.0", + "@angular/platform-server": "^19.0.0", + "@angular/service-worker": "^19.0.0", + "@angular/ssr": "^19.1.5", + "less": "^4.2.0", + "ng-packagr": "^19.0.0", + "postcss": "^8.4.0", + "tailwindcss": "^2.0.0 || ^3.0.0 || ^4.0.0", + "typescript": ">=5.5 <5.8" + }, + "peerDependenciesMeta": { + "@angular/localize": { + "optional": true + }, + "@angular/platform-server": { + "optional": true + }, + "@angular/service-worker": { + "optional": true + }, + "@angular/ssr": { + "optional": true + }, + "less": { + "optional": true + }, + "ng-packagr": { + "optional": true + }, + "postcss": { + "optional": true + }, + "tailwindcss": { + "optional": true + } + } + }, + "node_modules/@angular/build/node_modules/@angular-devkit/core": { + "version": "19.1.5", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.1.5.tgz", + "integrity": "sha512-wGKV+i5mCM/Hd/3CsdrIYcVi5G2Wg/D5941bUDXivrbsqHfKVINxAkI3OI1eaD90VnAL8ICrQEoAhh6ni2Umkg==", + "dev": true, + "dependencies": { + "ajv": "8.17.1", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.2", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^4.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@angular/cdk": { + "version": "18.2.3", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-18.2.3.tgz", + "integrity": "sha512-lUcpYTxPZuntJ1FK7V2ugapCGMIhT6TUDjIGgXfS9AxGSSKgwr8HNs6Ze9pcjYC44UhP40sYAZuiaFwmE60A2A==", + "dependencies": { + "tslib": "^2.3.0" + }, + "optionalDependencies": { + "parse5": "^7.1.2" + }, + "peerDependencies": { + "@angular/common": "^18.0.0 || ^19.0.0", + "@angular/core": "^18.0.0 || ^19.0.0", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/cli": { + "version": "19.1.5", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-19.1.5.tgz", + "integrity": "sha512-bedjH3jUcrLgN3GOTTuvjbPcY3Lm0YcYBVY35S1ugI88UK6nbtttiRdgK++Qk2Q8wbg6zuaBAr4ACbfPMsnRaA==", + "dev": true, + "dependencies": { + "@angular-devkit/architect": "0.1901.5", + "@angular-devkit/core": "19.1.5", + "@angular-devkit/schematics": "19.1.5", + "@inquirer/prompts": "7.2.1", + "@listr2/prompt-adapter-inquirer": "2.0.18", + "@schematics/angular": "19.1.5", + "@yarnpkg/lockfile": "1.1.0", + "ini": "5.0.0", + "jsonc-parser": "3.3.1", + "listr2": "8.2.5", + "npm-package-arg": "12.0.1", + "npm-pick-manifest": "10.0.0", + "pacote": "20.0.0", + "resolve": "1.22.10", + "semver": "7.6.3", + "symbol-observable": "4.0.0", + "yargs": "17.7.2" + }, + "bin": { + "ng": "bin/ng.js" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular/cli/node_modules/@angular-devkit/core": { + "version": "19.1.5", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.1.5.tgz", + "integrity": "sha512-wGKV+i5mCM/Hd/3CsdrIYcVi5G2Wg/D5941bUDXivrbsqHfKVINxAkI3OI1eaD90VnAL8ICrQEoAhh6ni2Umkg==", + "dev": true, + "dependencies": { + "ajv": "8.17.1", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.2", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^4.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@angular/cli/node_modules/ini": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-5.0.0.tgz", + "integrity": "sha512-+N0ngpO3e7cRUWOJAS7qw0IZIVc6XPrW4MlFBdD066F2L4k1L6ker3hLqSq7iXxU5tgS4WGkIUElWn5vogAEnw==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@angular/common": { + "version": "19.1.4", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-19.1.4.tgz", + "integrity": "sha512-E4MCl13VIotOxmzKQ/UGciPeaRXQgH7ymesEjYVGcT8jmC+qz5dEcoN7L5Jvq9aUsmLBt9MFp/B5QqKCIXMqYA==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/core": "19.1.4", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/compiler": { + "version": "19.1.4", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-19.1.4.tgz", + "integrity": "sha512-9vGUZ+QhGWvf5dfeILybrh5rvZQtNqS8WumMeX2/vCb0JTA0N4DsL1Sy47HuWcgKBxbmHVUdF5/iufcFaqk2FA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/core": "19.1.4" + }, + "peerDependenciesMeta": { + "@angular/core": { + "optional": true + } + } + }, + "node_modules/@angular/compiler-cli": { + "version": "19.1.4", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-19.1.4.tgz", + "integrity": "sha512-ozJvTUzPOgFqlz69YnV14Ncod+iH0cXZvUKerjw8o+JsixLG2LmJpwQ79Gh4a/ZQmAkAxMAYYK5izCiio8MmTg==", + "dev": true, + "dependencies": { + "@babel/core": "7.26.0", + "@jridgewell/sourcemap-codec": "^1.4.14", + "chokidar": "^4.0.0", + "convert-source-map": "^1.5.1", + "reflect-metadata": "^0.2.0", + "semver": "^7.0.0", + "tslib": "^2.3.0", + "yargs": "^17.2.1" + }, + "bin": { + "ng-xi18n": "bundles/src/bin/ng_xi18n.js", + "ngc": "bundles/src/bin/ngc.js", + "ngcc": "bundles/ngcc/index.js" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/compiler": "19.1.4", + "typescript": ">=5.5 <5.8" + } + }, + "node_modules/@angular/compiler-cli/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular/compiler-cli/node_modules/readdirp": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.1.tgz", + "integrity": "sha512-h80JrZu/MHUZCyHu5ciuoI0+WxsCxzxJTILn6Fs8rxSnFPh+UVHYfeIxK1nVGugMqkfC4vJcBOYbkfkwYK0+gw==", + "dev": true, + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular/core": { + "version": "19.1.4", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-19.1.4.tgz", + "integrity": "sha512-r3T81lM9evmuW36HA3VAxIJ61M8kirGR8yHoln9fXSnYG8UeJ7JlWEbVRHmVHKOB48VK0bS/VxqN+w9TOq3bZg==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "rxjs": "^6.5.3 || ^7.4.0", + "zone.js": "~0.15.0" + } + }, + "node_modules/@angular/forms": { + "version": "19.1.4", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-19.1.4.tgz", + "integrity": "sha512-dcf4G+vXrfvy5NAP+C4A2rBeaZuwKs/TeWjZDpkRUPQMwTvDJcSNH+pqOeVsYUGNY2BkY1uPjzmgZh4F5NMQ9A==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/common": "19.1.4", + "@angular/core": "19.1.4", + "@angular/platform-browser": "19.1.4", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/language-service": { + "version": "19.1.4", + "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-19.1.4.tgz", + "integrity": "sha512-4W6dlBvukL3b7BnGiMM5cPGx3rAAVhBNicfNHX6hXCkz26AV0VFIbfrt/8GRSFmsDYZEOhXvhAy8dxHQCtyCqA==", + "dev": true, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + } + }, + "node_modules/@angular/platform-browser": { + "version": "19.1.4", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-19.1.4.tgz", + "integrity": "sha512-IoVIvemj7ni6GLDCvwtZhTgMQjPyG+xPW7rASN2RVl9T3uS1fJUpXrh5JzBcCikIj20O2KV9mqt7p4iIXy9jbQ==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/animations": "19.1.4", + "@angular/common": "19.1.4", + "@angular/core": "19.1.4" + }, + "peerDependenciesMeta": { + "@angular/animations": { + "optional": true + } + } + }, + "node_modules/@angular/platform-browser-dynamic": { + "version": "19.1.4", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-19.1.4.tgz", + "integrity": "sha512-r1AM8qkjl63cg46tgOHsVV4URHDctcVpt98DU/d/yN8JAugrx6GA1qOM/HMDspMjEIU4aYcSkUUY6h6uIkYmOQ==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/common": "19.1.4", + "@angular/compiler": "19.1.4", + "@angular/core": "19.1.4", + "@angular/platform-browser": "19.1.4" + } + }, + "node_modules/@angular/router": { + "version": "19.1.4", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-19.1.4.tgz", + "integrity": "sha512-0gEhGGqcCS7adKuv/XeQjRbhEqRXPhIH4ygjwfonV+uvmK+C1sf+bnAt4o01hxwf12w4FcnNPkgBKt+rJJ+LpA==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/common": "19.1.4", + "@angular/core": "19.1.4", + "@angular/platform-browser": "19.1.4", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@appium/base-driver": { + "version": "9.16.2", + "resolved": "https://registry.npmjs.org/@appium/base-driver/-/base-driver-9.16.2.tgz", + "integrity": "sha512-vuQf9XQKGAMl5d5pM63FOrnRJUSVjw6J5kPXApfnkTJovwyV9SViYptnCB/TcahjX2bHQ+fUka82MWzHKPzpHg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@appium/support": "^6.0.6", + "@appium/types": "^0.25.1", + "@colors/colors": "1.6.0", + "async-lock": "1.4.1", + "asyncbox": "3.0.0", + "axios": "1.7.9", + "bluebird": "3.7.2", + "body-parser": "1.20.3", + "express": "4.21.2", + "fastest-levenshtein": "1.0.16", + "http-status-codes": "2.3.0", + "lodash": "4.17.21", + "lru-cache": "10.4.3", + "method-override": "3.0.0", + "morgan": "1.10.0", + "path-to-regexp": "8.2.0", + "serve-favicon": "2.5.0", + "source-map-support": "0.5.21", + "type-fest": "4.35.0", + "validate.js": "0.13.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0", + "npm": ">=8" + }, + "optionalDependencies": { + "spdy": "4.0.2" + } + }, + "node_modules/@appium/base-driver/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==", + "dev": true, + "license": "ISC" + }, + "node_modules/@appium/base-driver/node_modules/path-to-regexp": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz", + "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + } + }, + "node_modules/@appium/base-driver/node_modules/type-fest": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.35.0.tgz", + "integrity": "sha512-2/AwEFQDFEy30iOLjrvHDIH7e4HEWH+f1Yl1bI5XMqzuoCUqwYCdxachgsgv0og/JdVZUhbfjcJAoHj5L1753A==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@appium/base-plugin": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/@appium/base-plugin/-/base-plugin-2.3.3.tgz", + "integrity": "sha512-wPGgTfG02O2HzCcUWbEuN4fjjs/zoA3Il/tcbaT6rnZYAbOAW2uC4B6l+eqisFRLepj1p8djf0XQyPAVyeIZzw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@appium/base-driver": "^9.16.2", + "@appium/support": "^6.0.6" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0", + "npm": ">=8" + } + }, + "node_modules/@appium/docutils": { + "version": "1.0.32", + "resolved": "https://registry.npmjs.org/@appium/docutils/-/docutils-1.0.32.tgz", + "integrity": "sha512-8kGYxaasCQYlYZrOD++hIPvKMgFuxjvtcATSL2bszRZvzWq6cXmVUS4guym/RzXtlAYq6NrTqshY8x5xKcSi3w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@appium/support": "^6.0.6", + "@appium/tsconfig": "^0.3.4", + "@sliphua/lilconfig-ts-loader": "3.2.2", + "chalk": "4.1.2", + "consola": "3.4.0", + "diff": "7.0.0", + "json5": "2.2.3", + "lilconfig": "3.1.3", + "lodash": "4.17.21", + "pkg-dir": "5.0.0", + "read-pkg": "5.2.0", + "semver": "7.7.1", + "source-map-support": "0.5.21", + "teen_process": "2.2.3", + "type-fest": "4.35.0", + "typescript": "5.7.3", + "yaml": "2.7.0", + "yargs": "17.7.2", + "yargs-parser": "21.1.1" + }, + "bin": { + "appium-docs": "bin/appium-docs.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0", + "npm": ">=8" + } + }, + "node_modules/@appium/docutils/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@appium/docutils/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": 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/@appium/docutils/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@appium/docutils/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/@appium/docutils/node_modules/diff": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz", + "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/@appium/docutils/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@appium/docutils/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true, + "license": "ISC" + }, + "node_modules/@appium/docutils/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/@appium/docutils/node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/@appium/docutils/node_modules/pkg-dir": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz", + "integrity": "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^5.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@appium/docutils/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@appium/docutils/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/@appium/docutils/node_modules/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@appium/docutils/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@appium/docutils/node_modules/type-fest": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.35.0.tgz", + "integrity": "sha512-2/AwEFQDFEy30iOLjrvHDIH7e4HEWH+f1Yl1bI5XMqzuoCUqwYCdxachgsgv0og/JdVZUhbfjcJAoHj5L1753A==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@appium/docutils/node_modules/typescript": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", + "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/@appium/logger": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@appium/logger/-/logger-1.6.1.tgz", + "integrity": "sha512-3TWpLR1qVQ0usLJ6R49iN4TV9Zs0nog1oL3hakCglwP0g4ZllwwEbp+2b1ovJfX6oOv1wXNREyokq2uxU5gB/Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "console-control-strings": "1.1.0", + "lodash": "4.17.21", + "lru-cache": "10.4.3", + "set-blocking": "2.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0", + "npm": ">=8" + } + }, + "node_modules/@appium/logger/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==", + "dev": true, + "license": "ISC" + }, + "node_modules/@appium/schema": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@appium/schema/-/schema-0.8.1.tgz", + "integrity": "sha512-3yzfQ/K7RMGnfYDgFG7JdCPsjjN3eS33n2SBeGJtd28mDtgO7EzcmtiUBQjbkxyu0Q7h8KOexiqndvgTCgHeGQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "json-schema": "0.4.0", + "source-map-support": "0.5.21" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0", + "npm": ">=8" + } + }, + "node_modules/@appium/support": { + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/@appium/support/-/support-6.0.6.tgz", + "integrity": "sha512-qgj1uxHF7Suqi8wdWFBrG12dhLMAthpX973L7JHutM2jneynoIUaKtSXdd6zg0ZG/9clfY0C/06pIQTQljj+Lg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@appium/logger": "^1.6.1", + "@appium/tsconfig": "^0.3.4", + "@appium/types": "^0.25.1", + "@colors/colors": "1.6.0", + "archiver": "7.0.1", + "axios": "1.7.9", + "base64-stream": "1.0.0", + "bluebird": "3.7.2", + "bplist-creator": "0.1.1", + "bplist-parser": "0.3.2", + "form-data": "4.0.2", + "get-stream": "6.0.1", + "glob": "10.4.5", + "jsftp": "2.1.3", + "klaw": "4.1.0", + "lockfile": "1.0.4", + "lodash": "4.17.21", + "log-symbols": "4.1.0", + "moment": "2.30.1", + "mv": "2.1.1", + "ncp": "2.0.0", + "pkg-dir": "5.0.0", + "plist": "3.1.0", + "pluralize": "8.0.0", + "read-pkg": "5.2.0", + "resolve-from": "5.0.0", + "sanitize-filename": "1.6.3", + "semver": "7.7.1", + "shell-quote": "1.8.2", + "source-map-support": "0.5.21", + "supports-color": "8.1.1", + "teen_process": "2.2.3", + "type-fest": "4.35.0", + "uuid": "11.1.0", + "which": "4.0.0", + "yauzl": "3.2.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0", + "npm": ">=8" + }, + "optionalDependencies": { + "sharp": "0.33.5" + } + }, + "node_modules/@appium/support/node_modules/form-data": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz", + "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@appium/support/node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@appium/support/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "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/support/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@appium/support/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true, + "license": "ISC" + }, + "node_modules/@appium/support/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/@appium/support/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/@appium/support/node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/@appium/support/node_modules/pkg-dir": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz", + "integrity": "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^5.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@appium/support/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@appium/support/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/@appium/support/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@appium/support/node_modules/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@appium/support/node_modules/sharp": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.5.tgz", + "integrity": "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.3", + "semver": "^7.6.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.33.5", + "@img/sharp-darwin-x64": "0.33.5", + "@img/sharp-libvips-darwin-arm64": "1.0.4", + "@img/sharp-libvips-darwin-x64": "1.0.4", + "@img/sharp-libvips-linux-arm": "1.0.5", + "@img/sharp-libvips-linux-arm64": "1.0.4", + "@img/sharp-libvips-linux-s390x": "1.0.4", + "@img/sharp-libvips-linux-x64": "1.0.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.0.4", + "@img/sharp-libvips-linuxmusl-x64": "1.0.4", + "@img/sharp-linux-arm": "0.33.5", + "@img/sharp-linux-arm64": "0.33.5", + "@img/sharp-linux-s390x": "0.33.5", + "@img/sharp-linux-x64": "0.33.5", + "@img/sharp-linuxmusl-arm64": "0.33.5", + "@img/sharp-linuxmusl-x64": "0.33.5", + "@img/sharp-wasm32": "0.33.5", + "@img/sharp-win32-ia32": "0.33.5", + "@img/sharp-win32-x64": "0.33.5" + } + }, + "node_modules/@appium/support/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/@appium/support/node_modules/type-fest": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.35.0.tgz", + "integrity": "sha512-2/AwEFQDFEy30iOLjrvHDIH7e4HEWH+f1Yl1bI5XMqzuoCUqwYCdxachgsgv0og/JdVZUhbfjcJAoHj5L1753A==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@appium/support/node_modules/uuid": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", + "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", + "dev": true, + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/esm/bin/uuid" + } + }, + "node_modules/@appium/support/node_modules/which": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, + "node_modules/@appium/support/node_modules/yauzl": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-3.2.0.tgz", + "integrity": "sha512-Ow9nuGZE+qp1u4JIPvg+uCiUr7xGQWdff7JQSk5VGYTAZMDe2q8lxJ10ygv10qmSj031Ty/6FNJpLO4o1Sgc+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-crc32": "~0.2.3", + "pend": "~1.2.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@appium/tsconfig": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@appium/tsconfig/-/tsconfig-0.3.4.tgz", + "integrity": "sha512-tX719/ekarAWmJb+AaG6//8+3qQITshTgTZor0EbdEwA2KG3bGPwMIoCp10np6/qFr+sMZC0CbuKJruHSCDhhw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@tsconfig/node14": "14.1.2" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0", + "npm": ">=8" + } + }, + "node_modules/@appium/tsconfig/node_modules/@tsconfig/node14": { + "version": "14.1.2", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-14.1.2.tgz", + "integrity": "sha512-1vncsbfCZ3TBLPxesRYz02Rn7SNJfbLoDVkcZ7F/ixOV6nwxwgdhD1mdPcc5YQ413qBJ8CvMxXMFfJ7oawjo7Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@appium/types": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@appium/types/-/types-0.25.1.tgz", + "integrity": "sha512-2Lu5qwFNQa+iPw98XdB5/7tXKO7dugZHXfAsF050wgJkJJ4kDemVFJ4yr1YqM7DYmgqZnt+k0EfzshLODCHXTA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@appium/logger": "^1.6.1", + "@appium/schema": "^0.8.1", + "@appium/tsconfig": "^0.3.4", + "type-fest": "4.35.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0", + "npm": ">=8" + } + }, + "node_modules/@appium/types/node_modules/type-fest": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.35.0.tgz", + "integrity": "sha512-2/AwEFQDFEy30iOLjrvHDIH7e4HEWH+f1Yl1bI5XMqzuoCUqwYCdxachgsgv0og/JdVZUhbfjcJAoHj5L1753A==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@awesome-cordova-plugins/core": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@awesome-cordova-plugins/core/-/core-6.8.0.tgz", + "integrity": "sha512-++catmWWdZQ8/oTCt4yBrpdtJqZ3D7xFRrjQozLcEmtSb7FMaYoBGkn6FmZa+LYsNuzTaW84gdir5I+cllS+xA==", + "dependencies": { + "@types/cordova": "latest" + }, + "peerDependencies": { + "rxjs": "^5.5.0 || ^6.5.0 || ^7.3.0" + } + }, + "node_modules/@awesome-cordova-plugins/splash-screen": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@awesome-cordova-plugins/splash-screen/-/splash-screen-6.8.0.tgz", + "integrity": "sha512-V494+xvWba1t5/bQs1EM8pqwGIHsnrG6DR6ON39Yl8L+PewC0tHd29kBsulHbY4HBsWqeSoU5BkdfzPYpr0Ykw==", + "dependencies": { + "@types/cordova": "latest" + }, + "peerDependencies": { + "@awesome-cordova-plugins/core": "^6.0.1", + "rxjs": "^5.5.0 || ^6.5.0 || ^7.3.0" + } + }, + "node_modules/@awesome-cordova-plugins/status-bar": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@awesome-cordova-plugins/status-bar/-/status-bar-6.8.0.tgz", + "integrity": "sha512-SEoghsYWxNIhj07Fns9iqg4QlNOcHRRmg4EYNX2KY+7UOPeRYgSaphbo0u0ivAKRR4ibDd9Kl7uIOfn4j4HHcQ==", + "dependencies": { + "@types/cordova": "latest" + }, + "peerDependencies": { + "@awesome-cordova-plugins/core": "^6.0.1", + "rxjs": "^5.5.0 || ^6.5.0 || ^7.3.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.5.tgz", + "integrity": "sha512-XvcZi1KWf88RVbF9wn8MN6tYFloU5qX8KjuF3E1PVBmJ9eypXfs4GRiJwLuTZL0iSnJUKn1BFPa5BPZZJyFzPg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", + "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.26.0", + "@babel/generator": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.0", + "@babel/parser": "^7.26.0", + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.26.0", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.3.tgz", + "integrity": "sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.26.3", + "@babel/types": "^7.26.3", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz", + "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.26.5.tgz", + "integrity": "sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.26.5", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz", + "integrity": "sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/traverse": "^7.25.9", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.26.3.tgz", + "integrity": "sha512-G7ZRb40uUgdKOQqPLjfD12ZmGA54PzqDFUv2BKImnC9QIfGhIHKvVML0oN8IUiDq4iRqpq74ABpvOaerfWdong==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "regexpu-core": "^6.2.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.3.tgz", + "integrity": "sha512-HK7Bi+Hj6H+VTHA3ZvBis7V/6hu9QuTrnMXNybfUf2iiuU/N97I8VjB+KbhFF8Rld/Lx5MzoCwPCpPjfK+n8Cg==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz", + "integrity": "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz", + "integrity": "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.26.5.tgz", + "integrity": "sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.9.tgz", + "integrity": "sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-wrap-function": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.26.5.tgz", + "integrity": "sha512-bJ6iIVdYX1YooY2X7w1q6VITt+LnUILtNk7zT78ykuwStx8BauCzxvFqFaHjOpW1bVnSUM1PN1f0p5P21wHxvg==", + "dev": true, + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/traverse": "^7.26.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz", + "integrity": "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.9.tgz", + "integrity": "sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g==", + "dev": true, + "dependencies": { + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.26.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.7.tgz", + "integrity": "sha512-8NHiL98vsi0mbPQmYAGWwfcFaOy4j2HY49fXJCfuDcdE7fMIsH9a7GdaeXpIBsbT7307WU8KCMp5pUVDNL4f9A==", + "dev": true, + "dependencies": { + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.26.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.7.tgz", + "integrity": "sha512-kEvgGGgEjRUutvdVvZhbn/BxVt+5VSpwXz1j3WYXQbXDo8KzFOPNG2GQbdAiNq8g6wn1yKk7C/qrke03a84V+w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.26.7" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz", + "integrity": "sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.9.tgz", + "integrity": "sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.9.tgz", + "integrity": "sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.9.tgz", + "integrity": "sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/plugin-transform-optional-chaining": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.9.tgz", + "integrity": "sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-decorators": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.25.9.tgz", + "integrity": "sha512-smkNLL/O1ezy9Nhy4CNosc4Va+1wo5w4gzSZeLe6y6dM4mmHfYOCPolXQPHQxonZCF+ZyebxN9vqOolkYrSn5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/plugin-syntax-decorators": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-decorators": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.25.9.tgz", + "integrity": "sha512-ryzI0McXUPJnRCvMo4lumIKZUzhYUO/ScI+Mz4YVaTLt04DHNSjEUjKVvbzQjZFLuod/cYEc07mJWhzl6v4DPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.26.0.tgz", + "integrity": "sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz", + "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.9.tgz", + "integrity": "sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.9.tgz", + "integrity": "sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.9.tgz", + "integrity": "sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.9.tgz", + "integrity": "sha512-RXV6QAzTBbhDMO9fWwOmwwTuYaiPbggWQ9INdZqAYeSHyG7FzQ+nOZaUUjNwKv9pV3aE4WFqFm1Hnbci5tBCAw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-remap-async-to-generator": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.9.tgz", + "integrity": "sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-remap-async-to-generator": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.26.5.tgz", + "integrity": "sha512-chuTSY+hq09+/f5lMj8ZSYgCFpppV2CbYrhNFJ1BFoXpiWPnnAb7R0MqrafCpN8E1+YRrtM1MXZHJdIx8B6rMQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.26.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.9.tgz", + "integrity": "sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.9.tgz", + "integrity": "sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.26.0.tgz", + "integrity": "sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.9.tgz", + "integrity": "sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9", + "@babel/traverse": "^7.25.9", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.9.tgz", + "integrity": "sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/template": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.9.tgz", + "integrity": "sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.9.tgz", + "integrity": "sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.9.tgz", + "integrity": "sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.9.tgz", + "integrity": "sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.9.tgz", + "integrity": "sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.26.3.tgz", + "integrity": "sha512-7CAHcQ58z2chuXPWblnn1K6rLDnDWieghSOEmqQsrBenH0P9InCUtOJYD89pvngljmZlJcz3fcmgYsXFNGa1ZQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.9.tgz", + "integrity": "sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.25.9.tgz", + "integrity": "sha512-LqHxduHoaGELJl2uhImHwRQudhCM50pT46rIBNvtT/Oql3nqiS3wOwP+5ten7NpYSXrrVLgtZU3DZmPtWZo16A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.9.tgz", + "integrity": "sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.9.tgz", + "integrity": "sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.9.tgz", + "integrity": "sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.9.tgz", + "integrity": "sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.9.tgz", + "integrity": "sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.9.tgz", + "integrity": "sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.26.3.tgz", + "integrity": "sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.9.tgz", + "integrity": "sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.9.tgz", + "integrity": "sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.9.tgz", + "integrity": "sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.9.tgz", + "integrity": "sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.26.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.26.6.tgz", + "integrity": "sha512-CKW8Vu+uUZneQCPtXmSBUC6NCAUdya26hWCElAWh5mVSlSRsmiCPUUDKb3Z0szng1hiAJa098Hkhg9o4SE35Qw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.26.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.9.tgz", + "integrity": "sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.9.tgz", + "integrity": "sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/plugin-transform-parameters": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.9.tgz", + "integrity": "sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.9.tgz", + "integrity": "sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.9.tgz", + "integrity": "sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.9.tgz", + "integrity": "sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.9.tgz", + "integrity": "sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.9.tgz", + "integrity": "sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.9.tgz", + "integrity": "sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.9.tgz", + "integrity": "sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "regenerator-transform": "^0.15.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regexp-modifiers": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.26.0.tgz", + "integrity": "sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.9.tgz", + "integrity": "sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.25.9.tgz", + "integrity": "sha512-nZp7GlEl+yULJrClz0SwHPqir3lc0zsPrDHQUcxGspSL7AKrexNSEfTbfqnDNJUO13bgKyfuOLMF8Xqtu8j3YQ==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.6", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.9.tgz", + "integrity": "sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.9.tgz", + "integrity": "sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.9.tgz", + "integrity": "sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.25.9.tgz", + "integrity": "sha512-o97AE4syN71M/lxrCtQByzphAdlYluKPDBzDVzMmfCobUjjhAryZV0AIpRPrxN0eAkxXO6ZLEScmt+PNhj2OTw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.26.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.26.7.tgz", + "integrity": "sha512-jfoTXXZTgGg36BmhqT3cAYK5qkmqvJpvNrPhaK/52Vgjhw4Rq29s9UqpWWV0D6yuRmgiFH/BUVlkl96zJWqnaw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.26.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.26.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.26.7.tgz", + "integrity": "sha512-5cJurntg+AT+cgelGP9Bt788DKiAw9gIMSMU2NJrLAilnj0m8WZWUNZPSLOmadYsujHutpgElO+50foX+ib/Wg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.26.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/plugin-syntax-typescript": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.9.tgz", + "integrity": "sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.9.tgz", + "integrity": "sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.9.tgz", + "integrity": "sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.9.tgz", + "integrity": "sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.0.tgz", + "integrity": "sha512-H84Fxq0CQJNdPFT2DrfnylZ3cf5K43rGfWK4LJGPpjKHiZlk0/RzwEus3PDDZZg+/Er7lCA03MVacueUuXdzfw==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.9", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.9", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.9", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.25.9", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.9", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-import-assertions": "^7.26.0", + "@babel/plugin-syntax-import-attributes": "^7.26.0", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.25.9", + "@babel/plugin-transform-async-generator-functions": "^7.25.9", + "@babel/plugin-transform-async-to-generator": "^7.25.9", + "@babel/plugin-transform-block-scoped-functions": "^7.25.9", + "@babel/plugin-transform-block-scoping": "^7.25.9", + "@babel/plugin-transform-class-properties": "^7.25.9", + "@babel/plugin-transform-class-static-block": "^7.26.0", + "@babel/plugin-transform-classes": "^7.25.9", + "@babel/plugin-transform-computed-properties": "^7.25.9", + "@babel/plugin-transform-destructuring": "^7.25.9", + "@babel/plugin-transform-dotall-regex": "^7.25.9", + "@babel/plugin-transform-duplicate-keys": "^7.25.9", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.9", + "@babel/plugin-transform-dynamic-import": "^7.25.9", + "@babel/plugin-transform-exponentiation-operator": "^7.25.9", + "@babel/plugin-transform-export-namespace-from": "^7.25.9", + "@babel/plugin-transform-for-of": "^7.25.9", + "@babel/plugin-transform-function-name": "^7.25.9", + "@babel/plugin-transform-json-strings": "^7.25.9", + "@babel/plugin-transform-literals": "^7.25.9", + "@babel/plugin-transform-logical-assignment-operators": "^7.25.9", + "@babel/plugin-transform-member-expression-literals": "^7.25.9", + "@babel/plugin-transform-modules-amd": "^7.25.9", + "@babel/plugin-transform-modules-commonjs": "^7.25.9", + "@babel/plugin-transform-modules-systemjs": "^7.25.9", + "@babel/plugin-transform-modules-umd": "^7.25.9", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.25.9", + "@babel/plugin-transform-new-target": "^7.25.9", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.25.9", + "@babel/plugin-transform-numeric-separator": "^7.25.9", + "@babel/plugin-transform-object-rest-spread": "^7.25.9", + "@babel/plugin-transform-object-super": "^7.25.9", + "@babel/plugin-transform-optional-catch-binding": "^7.25.9", + "@babel/plugin-transform-optional-chaining": "^7.25.9", + "@babel/plugin-transform-parameters": "^7.25.9", + "@babel/plugin-transform-private-methods": "^7.25.9", + "@babel/plugin-transform-private-property-in-object": "^7.25.9", + "@babel/plugin-transform-property-literals": "^7.25.9", + "@babel/plugin-transform-regenerator": "^7.25.9", + "@babel/plugin-transform-regexp-modifiers": "^7.26.0", + "@babel/plugin-transform-reserved-words": "^7.25.9", + "@babel/plugin-transform-shorthand-properties": "^7.25.9", + "@babel/plugin-transform-spread": "^7.25.9", + "@babel/plugin-transform-sticky-regex": "^7.25.9", + "@babel/plugin-transform-template-literals": "^7.25.9", + "@babel/plugin-transform-typeof-symbol": "^7.25.9", + "@babel/plugin-transform-unicode-escapes": "^7.25.9", + "@babel/plugin-transform-unicode-property-regex": "^7.25.9", + "@babel/plugin-transform-unicode-regex": "^7.25.9", + "@babel/plugin-transform-unicode-sets-regex": "^7.25.9", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.6", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "core-js-compat": "^3.38.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/preset-typescript": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.26.0.tgz", + "integrity": "sha512-NMk1IGZ5I/oHhoXEElcm+xUnL/szL6xflkFZmoEU9xj1qSJXpiS7rsspYo92B4DRCDvZn2erT5LdsCeXAKNCkg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "@babel/plugin-syntax-jsx": "^7.25.9", + "@babel/plugin-transform-modules-commonjs": "^7.25.9", + "@babel/plugin-transform-typescript": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", + "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", + "dev": true, + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/standalone": { + "version": "7.26.7", + "resolved": "https://registry.npmjs.org/@babel/standalone/-/standalone-7.26.7.tgz", + "integrity": "sha512-Fvdo9Dd20GDUAREzYMIR2EFMKAJ+ccxstgQdb39XV/yvygHL4UPcqgTkiChPyltAe/b+zgq+vUPXeukEZ6aUeA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", + "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.26.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.7.tgz", + "integrity": "sha512-1x1sgeyRLC3r5fQOM0/xtQKsYjyxmFjaOrLJNtZ81inNjyJHGIolTULPiSc/2qe1/qfpFLisLQYFnnZl7QoedA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.5", + "@babel/parser": "^7.26.7", + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.7", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/@babel/generator": { + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.5.tgz", + "integrity": "sha512-2caSP6fN9I7HOe6nqhtft7V4g7/V/gfDsC3Ag4W7kEzzvRGKqiv0pu0HogPiZ3KaVSoNDhUws6IJjDjpfmYIXw==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.26.5", + "@babel/types": "^7.26.5", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.26.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.7.tgz", + "integrity": "sha512-t8kDRGrKXyp6+tjUh7hw2RLyclsW4TRoRvRHtSyAX9Bb5ldlFh+90YAYY6awRXrlB4G5G2izNeGySpATlFzmOg==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz", + "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@byteowls/capacitor-oauth2": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@byteowls/capacitor-oauth2/-/capacitor-oauth2-5.0.0.tgz", + "integrity": "sha512-yW50GypmyPJcH/95NwR2jJcgT78vBN3FYKL2w6A3vrT04bRLQyw2K0fLqfj8Zws6DJy43Ck1wPs0Bcdvbsub7A==", + "peerDependencies": { + "@capacitor/core": ">=5" + } + }, + "node_modules/@capacitor/android": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@capacitor/android/-/android-6.1.2.tgz", + "integrity": "sha512-Yh0gQDY1bgRrL25J6ecIlvvs2kF8iNSwIPXjyw6Yz9mnwYxBazF5KZbjpKtGPnJgicJhFkYGsqOkEtxrve0EoQ==", + "peerDependencies": { + "@capacitor/core": "^6.1.0" + } + }, + "node_modules/@capacitor/app": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@capacitor/app/-/app-6.0.1.tgz", + "integrity": "sha512-0kXbOl7LPPMFVcAii3u/7Ps0DvXlr7dtHT97r9J1faDlgdQLQUvtGp48tjvFm48gqHI0aOPRJnTBr5JXW4ETYg==", + "peerDependencies": { + "@capacitor/core": "^6.0.0" + } + }, + "node_modules/@capacitor/browser": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@capacitor/browser/-/browser-6.0.2.tgz", + "integrity": "sha512-mJjdKbpdCAaaDVZD/vjzpJJxL1VvwsGTcEGn+4PpCQyPu3+yNQO7vgjwBV7ZYS6+mZIKeYn5swWq0BFuAcDqFg==", + "peerDependencies": { + "@capacitor/core": "^6.0.0" + } + }, + "node_modules/@capacitor/cli": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@capacitor/cli/-/cli-6.1.2.tgz", + "integrity": "sha512-HKCNGE0RP8U7aiEF2vg5wTivJROS8BVfu8a3yYJb1mRQvzv+czpmtHNsTWS/WukvwoxUjyjRmsNQSAACHfMTmQ==", + "dev": true, + "dependencies": { + "@ionic/cli-framework-output": "^2.2.5", + "@ionic/utils-fs": "^3.1.6", + "@ionic/utils-process": "^2.1.11", + "@ionic/utils-subprocess": "2.1.11", + "@ionic/utils-terminal": "^2.3.3", + "commander": "^9.3.0", + "debug": "^4.3.4", + "env-paths": "^2.2.0", + "kleur": "^4.1.4", + "native-run": "^2.0.0", + "open": "^8.4.0", + "plist": "^3.0.5", + "prompts": "^2.4.2", + "rimraf": "^4.4.1", + "semver": "^7.3.7", + "tar": "^6.1.11", + "tslib": "^2.4.0", + "xml2js": "^0.5.0" + }, + "bin": { + "cap": "bin/capacitor", + "capacitor": "bin/capacitor" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@capacitor/cli/node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@capacitor/cli/node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@capacitor/cli/node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@capacitor/cli/node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "dev": true, + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@capacitor/clipboard": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@capacitor/clipboard/-/clipboard-6.0.1.tgz", + "integrity": "sha512-aN6QsZD79Z605sK9YA8JtJLuD5vI/WrPzT/RCWUWBWPdFzhnRdT45dbsnQVvL2kzzm5aTsCAPepkdRqpvWwCGA==", + "peerDependencies": { + "@capacitor/core": "^6.0.0" + } + }, + "node_modules/@capacitor/core": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@capacitor/core/-/core-6.1.2.tgz", + "integrity": "sha512-xFy1/4qLFLp5WCIzIhtwUuVNNoz36+V7/BzHmLqgVJcvotc4MMjswW/TshnPQaLLujEOaLkA4h8ZJ0uoK3ImGg==", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@capacitor/device": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@capacitor/device/-/device-6.0.1.tgz", + "integrity": "sha512-Tlz67DAO5GKb5YAfupXiENZxDww6mHnG9iKI+8D5SVF82VLpEv5r9qwKtiounuQB2y2HWiHV8tlOk7DqnLVUqQ==", + "peerDependencies": { + "@capacitor/core": "^6.0.0" + } + }, + "node_modules/@capacitor/docgen": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@capacitor/docgen/-/docgen-0.2.2.tgz", + "integrity": "sha512-617jB5DlKjUljxfoANORWeqffsHqHekckH48oslKWFGzfCHYIAEPfJfMa5M4mVSzn2ifSvWB5C3st4augwhl5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "^14.18.0", + "colorette": "^2.0.16", + "github-slugger": "^1.4.0", + "minimist": "^1.2.5", + "typescript": "~4.2.4" + }, + "bin": { + "docgen": "bin/docgen" + }, + "engines": { + "node": ">=14.5.0" + } + }, + "node_modules/@capacitor/docgen/node_modules/@types/node": { + "version": "14.18.63", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.63.tgz", + "integrity": "sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@capacitor/docgen/node_modules/typescript": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz", + "integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/@capacitor/haptics": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@capacitor/haptics/-/haptics-6.0.1.tgz", + "integrity": "sha512-Q8hedLwfwTSWEYc3eoATzkdKHBaIceYe5bd7FjxQCENNH0is5Ft0EjSRPz/xpTn39ebK0ooZBDBCwsyl6tjiTA==", + "peerDependencies": { + "@capacitor/core": "^6.0.0" + } + }, + "node_modules/@capacitor/ios": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@capacitor/ios/-/ios-6.1.2.tgz", + "integrity": "sha512-HaeW68KisBd/7TmavzPDlL2bpoDK5AjR2ZYrqU4TlGwM88GtQfvduBCAlSCj20X0w/4+rWMkseD9dAAkacjiyQ==", + "peerDependencies": { + "@capacitor/core": "^6.1.0" + } + }, + "node_modules/@capacitor/keyboard": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@capacitor/keyboard/-/keyboard-6.0.2.tgz", + "integrity": "sha512-fOfO3rQ0ZXuTHpK03INVTwmBnpqMiH8EHPpNaHjwjKwdrVRWBvtgIFhuyHNXh53rdcXw+uHB+1RIiNabnCrITw==", + "peerDependencies": { + "@capacitor/core": "^6.0.0" + } + }, + "node_modules/@capacitor/local-notifications": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@capacitor/local-notifications/-/local-notifications-6.1.0.tgz", + "integrity": "sha512-EjEnbApdFiZYeJgxKIDtgFRNSmeHySnyAeyoTn6HUTYMkTOaHFGAd7NU964k7gbX4al/CBp0cMA8iMG0c7kh1w==", + "peerDependencies": { + "@capacitor/core": "^6.0.0" + } + }, + "node_modules/@capacitor/preferences": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@capacitor/preferences/-/preferences-6.0.2.tgz", + "integrity": "sha512-ccD4/9ybnipJncLeCWlRPNQS2jv3nn8ivVLKzdVIWkiUHLo/hvuSSP7awVzvBwDNtAhNxIipjjWH6TyzZgLCcg==", + "peerDependencies": { + "@capacitor/core": "^6.0.0" + } + }, + "node_modules/@capacitor/push-notifications": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@capacitor/push-notifications/-/push-notifications-6.0.2.tgz", + "integrity": "sha512-VYo8h+Dfw7B/JtsQCCnSKi34jr3oN9LacwmgCqwi3KPIE/sKID75lTEACZBQQ6c4rPct0yRQ0ihHdK/OPXl3Tw==", + "peerDependencies": { + "@capacitor/core": "^6.0.0" + } + }, + "node_modules/@capacitor/splash-screen": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@capacitor/splash-screen/-/splash-screen-6.0.2.tgz", + "integrity": "sha512-WC0KYZ+ev15up03xs4fTnoTKwBVUSxXsKKQr/8XAncvi/nAG8qrpanW8OlavSC5zF5e1IZZDLsI2GSv0SkZ7VQ==", + "peerDependencies": { + "@capacitor/core": "^6.0.0" + } + }, + "node_modules/@capacitor/status-bar": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@capacitor/status-bar/-/status-bar-6.0.1.tgz", + "integrity": "sha512-Usd9hZZQVAqy+jJfL7jRcYI7dcsxN09Na1yttwdl+F1bk3Ztoukk7CGPDm5VgKUSs53ihQBOy1+sczCACxhNiw==", + "peerDependencies": { + "@capacitor/core": "^6.0.0" + } + }, + "node_modules/@capacitor/toast": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@capacitor/toast/-/toast-6.0.2.tgz", + "integrity": "sha512-kw9a4jSbP278xSB7cfXzafkRG0wIjsQ+rv+alzmrQa9IQsVwA5c3BvY3g+O/iE0uDGr7s11ZJNszUm1GkzJKyQ==", + "peerDependencies": { + "@capacitor/core": "^6.0.0" + } + }, + "node_modules/@capawesome/capacitor-app-update": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@capawesome/capacitor-app-update/-/capacitor-app-update-6.0.0.tgz", + "integrity": "sha512-T4k0dC3XoJDgtX1QOQx0Rr5eMi3NhJn93QawQ6ZYYMmssnqCoRPpo2rg3VKVKMUZgAmIUN5Rwons9T4QkjTOzA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/capawesome-team/" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/capawesome" + } + ], + "peerDependencies": { + "@capacitor/core": "^6.0.0" + } + }, + "node_modules/@capgo/capacitor-updater": { + "version": "6.1.32", + "resolved": "https://registry.npmjs.org/@capgo/capacitor-updater/-/capacitor-updater-6.1.32.tgz", + "integrity": "sha512-egMt9qa9lAZdg14B+rtmruf/Nxkx4V9ykk8UyeInQV2PiSj4Fh3RDAv4yzEXsl3C/M2lHIfmbKwUH+z0BbXzYg==", + "peerDependencies": { + "@capacitor/core": "^6.0.0" + } + }, + "node_modules/@cloudflare/kv-asset-handler": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.3.4.tgz", + "integrity": "sha512-YLPHc8yASwjNkmcDMQMY35yiWjoKAKnhUbPRszBRS0YgH+IXtsMp61j+yTcnCE3oO2DgP0U3iejLC8FTtKDC8Q==", + "dev": true, + "license": "MIT OR Apache-2.0", + "dependencies": { + "mime": "^3.0.0" + }, + "engines": { + "node": ">=16.13" + } + }, + "node_modules/@cloudflare/kv-asset-handler/node_modules/mime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=10.0.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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@dabh/diagnostics": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", + "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "colorspace": "1.1.x", + "enabled": "2.0.x", + "kuler": "^2.0.0" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.6.3.tgz", + "integrity": "sha512-4B4OijXeVNOPZlYA2oEwWOTkzyltLao+xbotHQeqN++Rv27Y6s818+n2Qkp8q+Fxhn0t/5lA5X1Mxktud8eayQ==", + "dev": true, + "engines": { + "node": ">=14.17.0" + } + }, + "node_modules/@emnapi/core": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.3.1.tgz", + "integrity": "sha512-pVGjBIt1Y6gg3EJN8jTcfpP/+uuRksIo055oE/OBkDNcjZqVbfkWCksG1Jp4yZnj3iKWyWX8fdG/j6UDYPbFog==", + "dev": true, + "license": "MIT", + "dependencies": { + "@emnapi/wasi-threads": "1.0.1", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.3.1.tgz", + "integrity": "sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.0.1.tgz", + "integrity": "sha512-iIBu7mwkq4UQGeMEM8bLwNK962nXdhodeScX4slfQnRhEMMzvYivHhutCIk8uojvmASXXPC2WNEjwxFWk72Oqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@es-joy/jsdoccomment": { + "version": "0.46.0", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.46.0.tgz", + "integrity": "sha512-C3Axuq1xd/9VqFZpW4YAzOx5O9q/LP46uIQy/iNDpHG3fmPa6TBtvfglMCs3RBiBxAIi0Go97r8+jvTt55XMyQ==", + "dev": true, + "dependencies": { + "comment-parser": "1.4.1", + "esquery": "^1.6.0", + "jsdoc-type-pratt-parser": "~4.0.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz", + "integrity": "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.2.tgz", + "integrity": "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz", + "integrity": "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.2.tgz", + "integrity": "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz", + "integrity": "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz", + "integrity": "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz", + "integrity": "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz", + "integrity": "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz", + "integrity": "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz", + "integrity": "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz", + "integrity": "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz", + "integrity": "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz", + "integrity": "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz", + "integrity": "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz", + "integrity": "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz", + "integrity": "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz", + "integrity": "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.24.2.tgz", + "integrity": "sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz", + "integrity": "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz", + "integrity": "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz", + "integrity": "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz", + "integrity": "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz", + "integrity": "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz", + "integrity": "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.2.tgz", + "integrity": "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.2.tgz", + "integrity": "sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==", + "dev": true, + "dependencies": { + "@eslint/object-schema": "^2.1.6", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/core": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.10.0.tgz", + "integrity": "sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz", + "integrity": "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "9.19.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.19.0.tgz", + "integrity": "sha512-rbq9/g38qjfqFLOVPvwjIvFFdNziEC5S65jmjPw5r6A//QH+W91akh9irMwjDN8zKUTak6W9EsAv4m/7Wnw0UQ==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", + "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.5.tgz", + "integrity": "sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A==", + "dev": true, + "dependencies": { + "@eslint/core": "^0.10.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "dev": true, + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true, + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz", + "integrity": "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==", + "dev": true, + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz", + "integrity": "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "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.0.4" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz", + "integrity": "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==", + "cpu": [ + "x64" + ], + "dev": true, + "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-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz", + "integrity": "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz", + "integrity": "sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz", + "integrity": "sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz", + "integrity": "sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.4.tgz", + "integrity": "sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz", + "integrity": "sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz", + "integrity": "sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz", + "integrity": "sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz", + "integrity": "sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.0.5" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz", + "integrity": "sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.5.tgz", + "integrity": "sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.0.4" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz", + "integrity": "sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz", + "integrity": "sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz", + "integrity": "sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.5.tgz", + "integrity": "sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.2.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.5.tgz", + "integrity": "sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz", + "integrity": "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@inquirer/checkbox": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.1.1.tgz", + "integrity": "sha512-os5kFd/52gZTl/W6xqMfhaKVJHQM8V/U1P8jcSaQJ/C4Qhdrf2jEXdA/HaxfQs9iiUA/0yzYhk5d3oRHTxGDDQ==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.6", + "@inquirer/figures": "^1.0.10", + "@inquirer/type": "^3.0.4", + "ansi-escapes": "^4.3.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/confirm": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.1.tgz", + "integrity": "sha512-vVLSbGci+IKQvDOtzpPTCOiEJCNidHcAq9JYVoWTW0svb5FiwSLotkM+JXNXejfjnzVYV9n0DTBythl9+XgTxg==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.2", + "@inquirer/type": "^3.0.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/core": { + "version": "10.1.6", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.1.6.tgz", + "integrity": "sha512-Bwh/Zk6URrHwZnSSzAZAKH7YgGYi0xICIBDFOqBQoXNNAzBHw/bgXgLmChfp+GyR3PnChcTbiCTZGC6YJNJkMA==", + "dev": true, + "dependencies": { + "@inquirer/figures": "^1.0.10", + "@inquirer/type": "^3.0.4", + "ansi-escapes": "^4.3.2", + "cli-width": "^4.1.0", + "mute-stream": "^2.0.0", + "signal-exit": "^4.1.0", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/editor": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.6.tgz", + "integrity": "sha512-l0smvr8g/KAVdXx4I92sFxZiaTG4kFc06cFZw+qqwTirwdUHMFLnouXBB9OafWhpO3cfEkEz2CdPoCmor3059A==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.6", + "@inquirer/type": "^3.0.4", + "external-editor": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/expand": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.8.tgz", + "integrity": "sha512-k0ouAC6L+0Yoj/j0ys2bat0fYcyFVtItDB7h+pDFKaDDSFJey/C/YY1rmIOqkmFVZ5rZySeAQuS8zLcKkKRLmg==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.6", + "@inquirer/type": "^3.0.4", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/figures": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.10.tgz", + "integrity": "sha512-Ey6176gZmeqZuY/W/nZiUyvmb1/qInjcpiZjXWi6nON+nxJpD1bxtSoBxNliGISae32n6OwbY+TSXPZ1CfS4bw==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/input": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.1.5.tgz", + "integrity": "sha512-bB6wR5wBCz5zbIVBPnhp94BHv/G4eKbUEjlpCw676pI2chcvzTx1MuwZSCZ/fgNOdqDlAxkhQ4wagL8BI1D3Zg==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.6", + "@inquirer/type": "^3.0.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/number": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.8.tgz", + "integrity": "sha512-CTKs+dT1gw8dILVWATn8Ugik1OHLkkfY82J+Musb57KpmF6EKyskv8zmMiEJPzOnLTZLo05X/QdMd8VH9oulXw==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.6", + "@inquirer/type": "^3.0.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/password": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.8.tgz", + "integrity": "sha512-MgA+Z7o3K1df2lGY649fyOBowHGfrKRz64dx3+b6c1w+h2W7AwBoOkHhhF/vfhbs5S4vsKNCuDzS3s9r5DpK1g==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.6", + "@inquirer/type": "^3.0.4", + "ansi-escapes": "^4.3.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/prompts": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.2.1.tgz", + "integrity": "sha512-v2JSGri6/HXSfoGIwuKEn8sNCQK6nsB2BNpy2lSX6QH9bsECrMv93QHnj5+f+1ZWpF/VNioIV2B/PDox8EvGuQ==", + "dev": true, + "dependencies": { + "@inquirer/checkbox": "^4.0.4", + "@inquirer/confirm": "^5.1.1", + "@inquirer/editor": "^4.2.1", + "@inquirer/expand": "^4.0.4", + "@inquirer/input": "^4.1.1", + "@inquirer/number": "^3.0.4", + "@inquirer/password": "^4.0.4", + "@inquirer/rawlist": "^4.0.4", + "@inquirer/search": "^3.0.4", + "@inquirer/select": "^4.0.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/rawlist": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.0.8.tgz", + "integrity": "sha512-hl7rvYW7Xl4un8uohQRUgO6uc2hpn7PKqfcGkCOWC0AA4waBxAv6MpGOFCEDrUaBCP+pXPVqp4LmnpWmn1E1+g==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.6", + "@inquirer/type": "^3.0.4", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/search": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.0.8.tgz", + "integrity": "sha512-ihSE9D3xQAupNg/aGDZaukqoUSXG2KfstWosVmFCG7jbMQPaj2ivxWtsB+CnYY/T4D6LX1GHKixwJLunNCffww==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.6", + "@inquirer/figures": "^1.0.10", + "@inquirer/type": "^3.0.4", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/select": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.0.8.tgz", + "integrity": "sha512-Io2prxFyN2jOCcu4qJbVoilo19caiD3kqkD3WR0q3yDA5HUCo83v4LrRtg55ZwniYACW64z36eV7gyVbOfORjA==", + "dev": true, + "dependencies": { + "@inquirer/core": "^10.1.6", + "@inquirer/figures": "^1.0.10", + "@inquirer/type": "^3.0.4", + "ansi-escapes": "^4.3.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/type": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.4.tgz", + "integrity": "sha512-2MNFrDY8jkFYc9Il9DgLsHhMzuHnOYM1+CUYVWbzu9oT0hC7V7EcYvdCKeoll/Fcci04A+ERZ9wcc7cQ8lTkIA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@ionic/angular": { + "version": "8.4.3", + "resolved": "https://registry.npmjs.org/@ionic/angular/-/angular-8.4.3.tgz", + "integrity": "sha512-dIrO7luoj9Iepo4tYKTzhCEpVFWIqZ1RNgDPttKVHa8hE4xhvbb1y2Ou9zmpz7cI5QShAkr3tnAbb7rkYh4fFQ==", + "dependencies": { + "@ionic/core": "8.4.3", + "ionicons": "^7.0.0", + "jsonc-parser": "^3.0.0", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/core": ">=16.0.0", + "@angular/forms": ">=16.0.0", + "@angular/router": ">=16.0.0", + "rxjs": ">=7.5.0", + "zone.js": ">=0.13.0" + } + }, + "node_modules/@ionic/angular-server": { + "version": "8.4.3", + "resolved": "https://registry.npmjs.org/@ionic/angular-server/-/angular-server-8.4.3.tgz", + "integrity": "sha512-ldl1NYv+5+85MoQQqd1YryoTPvmb6dK3rzCO5VhiUCn0f2GP6YNbrVxhfnHdrWHuQh7eODZmNm77MPOmHIKacw==", + "dependencies": { + "@ionic/core": "8.4.3", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/core": ">=16.0.0", + "@angular/platform-server": ">=16.0.0", + "rxjs": ">=7.5.0", + "zone.js": ">=0.13.0" + } + }, + "node_modules/@ionic/angular-toolkit": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/@ionic/angular-toolkit/-/angular-toolkit-11.0.1.tgz", + "integrity": "sha512-dxx2RDbxDYM2nWRPIirKMJySHtqJ1u02T25PGbNb99W2Wlcmu1cza3+2/PQ8ga18yMz/dQqaGyEmPDf3ZSVO0w==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "^17.0.0", + "@angular-devkit/schematics": "^17.0.0", + "@schematics/angular": "^17.0.0" + } + }, + "node_modules/@ionic/angular-toolkit/node_modules/@angular-devkit/core": { + "version": "17.3.9", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-17.3.9.tgz", + "integrity": "sha512-/iKyn5YT7NW5ylrg9yufUydS8byExeQ2HHIwFC4Ebwb/JYYCz+k4tBf2LdP+zXpemDpLznXTQGWia0/yJjG8Vg==", + "dev": true, + "dependencies": { + "ajv": "8.12.0", + "ajv-formats": "2.1.1", + "jsonc-parser": "3.2.1", + "picomatch": "4.0.1", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^18.13.0 || >=20.9.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^3.5.2" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@ionic/angular-toolkit/node_modules/@angular-devkit/schematics": { + "version": "17.3.9", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-17.3.9.tgz", + "integrity": "sha512-9qg+uWywgAtaQlvbnCQv47hcL6ZuA+d9ucgZ0upZftBllZ2vp5WIthCPb2mB0uBkj84Csmtz9MsErFjOQtTj4g==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "17.3.9", + "jsonc-parser": "3.2.1", + "magic-string": "0.30.8", + "ora": "5.4.1", + "rxjs": "7.8.1" + }, + "engines": { + "node": "^18.13.0 || >=20.9.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@ionic/angular-toolkit/node_modules/@schematics/angular": { + "version": "17.3.9", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-17.3.9.tgz", + "integrity": "sha512-q6N8mbcYC6cgPyjTrMH7ehULQoUUwEYN4g7uo4ylZ/PFklSLJvpSp4BuuxANgW449qHSBvQfdIoui9ayAUXQzA==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "17.3.9", + "@angular-devkit/schematics": "17.3.9", + "jsonc-parser": "3.2.1" + }, + "engines": { + "node": "^18.13.0 || >=20.9.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@ionic/angular-toolkit/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@ionic/angular-toolkit/node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/@ionic/angular-toolkit/node_modules/jsonc-parser": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz", + "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==", + "dev": true + }, + "node_modules/@ionic/angular-toolkit/node_modules/magic-string": { + "version": "0.30.8", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz", + "integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@ionic/angular-toolkit/node_modules/picomatch": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.1.tgz", + "integrity": "sha512-xUXwsxNjwTQ8K3GnT4pCJm+xq3RUPQbmkYJTP5aFIfNIvbcc/4MUxgBaaRSZJ6yGJZiGSyYlM6MzwTsRk8SYCg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/@ionic/cli-framework-output": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/@ionic/cli-framework-output/-/cli-framework-output-2.2.8.tgz", + "integrity": "sha512-TshtaFQsovB4NWRBydbNFawql6yul7d5bMiW1WYYf17hd99V6xdDdk3vtF51bw6sLkxON3bDQpWsnUc9/hVo3g==", + "dev": true, + "dependencies": { + "@ionic/utils-terminal": "2.3.5", + "debug": "^4.0.0", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@ionic/core": { + "version": "8.4.3", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.4.3.tgz", + "integrity": "sha512-U9HdZ32bre6OKA5akJVmQMxNB8Art3Nqdn3s7m2W83I5NhLg9Tehaf8ua8jxPZtxCa1nuN7tUbzHmMCkcdqDTw==", + "dependencies": { + "@stencil/core": "4.20.0", + "ionicons": "^7.2.2", + "tslib": "^2.1.0" + } + }, + "node_modules/@ionic/eslint-config": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@ionic/eslint-config/-/eslint-config-0.4.0.tgz", + "integrity": "sha512-L8OXY29D3iGqNtteFj0iz3eoZIVgokBiVjCO8WMssNZa4GTHjYsase0rC9ASXGefMnLJu6rbNl3Gbx7NNxJRZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "^5.58.0", + "@typescript-eslint/parser": "^5.58.0", + "eslint-config-prettier": "^8.8.0", + "eslint-plugin-import": "^2.27.0" + }, + "peerDependencies": { + "eslint": ">=7" + } + }, + "node_modules/@ionic/eslint-config/node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", + "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.4.0", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/type-utils": "5.62.0", + "@typescript-eslint/utils": "5.62.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@ionic/eslint-config/node_modules/@typescript-eslint/parser": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", + "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@ionic/eslint-config/node_modules/@typescript-eslint/scope-manager": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", + "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ionic/eslint-config/node_modules/@typescript-eslint/type-utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", + "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/typescript-estree": "5.62.0", + "@typescript-eslint/utils": "5.62.0", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@ionic/eslint-config/node_modules/@typescript-eslint/types": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", + "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ionic/eslint-config/node_modules/@typescript-eslint/typescript-estree": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", + "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@ionic/eslint-config/node_modules/@typescript-eslint/utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", + "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "eslint-scope": "^5.1.1", + "semver": "^7.3.7" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@ionic/eslint-config/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", + "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ionic/eslint-config/node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@ionic/eslint-config/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@ionic/eslint-config/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@ionic/eslint-config/node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@ionic/eslint-config/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@ionic/eslint-config/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true, + "license": "0BSD" + }, + "node_modules/@ionic/eslint-config/node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/@ionic/swiftlint-config": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ionic/swiftlint-config/-/swiftlint-config-1.1.2.tgz", + "integrity": "sha512-UbE1AIlTowt9uR7fMzRtbQX4URcyuok7mcpdJfFDHAIGM6nDjohYMke+6xOr6ZYlLnEyVmBGNEg0+grEYRgcVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@ionic/utils-array": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@ionic/utils-array/-/utils-array-2.1.5.tgz", + "integrity": "sha512-HD72a71IQVBmQckDwmA8RxNVMTbxnaLbgFOl+dO5tbvW9CkkSFCv41h6fUuNsSEVgngfkn0i98HDuZC8mk+lTA==", + "dependencies": { + "debug": "^4.0.0", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=10.3.0" + } + }, + "node_modules/@ionic/utils-fs": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@ionic/utils-fs/-/utils-fs-3.1.7.tgz", + "integrity": "sha512-2EknRvMVfhnyhL1VhFkSLa5gOcycK91VnjfrTB0kbqkTFCOXyXgVLI5whzq7SLrgD9t1aqos3lMMQyVzaQ5gVA==", + "dependencies": { + "@types/fs-extra": "^8.0.0", + "debug": "^4.0.0", + "fs-extra": "^9.0.0", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@ionic/utils-fs/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@ionic/utils-object": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@ionic/utils-object/-/utils-object-2.1.6.tgz", + "integrity": "sha512-vCl7sl6JjBHFw99CuAqHljYJpcE88YaH2ZW4ELiC/Zwxl5tiwn4kbdP/gxi2OT3MQb1vOtgAmSNRtusvgxI8ww==", + "dev": true, + "dependencies": { + "debug": "^4.0.0", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@ionic/utils-process": { + "version": "2.1.12", + "resolved": "https://registry.npmjs.org/@ionic/utils-process/-/utils-process-2.1.12.tgz", + "integrity": "sha512-Jqkgyq7zBs/v/J3YvKtQQiIcxfJyplPgECMWgdO0E1fKrrH8EF0QGHNJ9mJCn6PYe2UtHNS8JJf5G21e09DfYg==", + "dev": true, + "dependencies": { + "@ionic/utils-object": "2.1.6", + "@ionic/utils-terminal": "2.3.5", + "debug": "^4.0.0", + "signal-exit": "^3.0.3", + "tree-kill": "^1.2.2", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@ionic/utils-process/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==", + "dev": true + }, + "node_modules/@ionic/utils-stream": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@ionic/utils-stream/-/utils-stream-3.1.5.tgz", + "integrity": "sha512-hkm46uHvEC05X/8PHgdJi4l4zv9VQDELZTM+Kz69odtO9zZYfnt8DkfXHJqJ+PxmtiE5mk/ehJWLnn/XAczTUw==", + "dev": true, + "dependencies": { + "debug": "^4.0.0", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=10.3.0" + } + }, + "node_modules/@ionic/utils-subprocess": { + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/@ionic/utils-subprocess/-/utils-subprocess-2.1.11.tgz", + "integrity": "sha512-6zCDixNmZCbMCy5np8klSxOZF85kuDyzZSTTQKQP90ZtYNCcPYmuFSzaqDwApJT4r5L3MY3JrqK1gLkc6xiUPw==", + "dev": true, + "dependencies": { + "@ionic/utils-array": "2.1.5", + "@ionic/utils-fs": "3.1.6", + "@ionic/utils-process": "2.1.10", + "@ionic/utils-stream": "3.1.5", + "@ionic/utils-terminal": "2.3.3", + "cross-spawn": "^7.0.3", + "debug": "^4.0.0", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=10.3.0" + } + }, + "node_modules/@ionic/utils-subprocess/node_modules/@ionic/utils-fs": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/@ionic/utils-fs/-/utils-fs-3.1.6.tgz", + "integrity": "sha512-eikrNkK89CfGPmexjTfSWl4EYqsPSBh0Ka7by4F0PLc1hJZYtJxUZV3X4r5ecA8ikjicUmcbU7zJmAjmqutG/w==", + "dev": true, + "dependencies": { + "@types/fs-extra": "^8.0.0", + "debug": "^4.0.0", + "fs-extra": "^9.0.0", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=10.3.0" + } + }, + "node_modules/@ionic/utils-subprocess/node_modules/@ionic/utils-object": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@ionic/utils-object/-/utils-object-2.1.5.tgz", + "integrity": "sha512-XnYNSwfewUqxq+yjER1hxTKggftpNjFLJH0s37jcrNDwbzmbpFTQTVAp4ikNK4rd9DOebX/jbeZb8jfD86IYxw==", + "dev": true, + "dependencies": { + "debug": "^4.0.0", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=10.3.0" + } + }, + "node_modules/@ionic/utils-subprocess/node_modules/@ionic/utils-process": { + "version": "2.1.10", + "resolved": "https://registry.npmjs.org/@ionic/utils-process/-/utils-process-2.1.10.tgz", + "integrity": "sha512-mZ7JEowcuGQK+SKsJXi0liYTcXd2bNMR3nE0CyTROpMECUpJeAvvaBaPGZf5ERQUPeWBVuwqAqjUmIdxhz5bxw==", + "dev": true, + "dependencies": { + "@ionic/utils-object": "2.1.5", + "@ionic/utils-terminal": "2.3.3", + "debug": "^4.0.0", + "signal-exit": "^3.0.3", + "tree-kill": "^1.2.2", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=10.3.0" + } + }, + "node_modules/@ionic/utils-subprocess/node_modules/@ionic/utils-terminal": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/@ionic/utils-terminal/-/utils-terminal-2.3.3.tgz", + "integrity": "sha512-RnuSfNZ5fLEyX3R5mtcMY97cGD1A0NVBbarsSQ6yMMfRJ5YHU7hHVyUfvZeClbqkBC/pAqI/rYJuXKCT9YeMCQ==", + "dev": true, + "dependencies": { + "@types/slice-ansi": "^4.0.0", + "debug": "^4.0.0", + "signal-exit": "^3.0.3", + "slice-ansi": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "tslib": "^2.0.1", + "untildify": "^4.0.0", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=10.3.0" + } + }, + "node_modules/@ionic/utils-subprocess/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==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@ionic/utils-subprocess/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==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@ionic/utils-subprocess/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==", + "dev": true + }, + "node_modules/@ionic/utils-subprocess/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@ionic/utils-subprocess/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==", + "dev": true + }, + "node_modules/@ionic/utils-subprocess/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@ionic/utils-terminal": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@ionic/utils-terminal/-/utils-terminal-2.3.5.tgz", + "integrity": "sha512-3cKScz9Jx2/Pr9ijj1OzGlBDfcmx7OMVBt4+P1uRR0SSW4cm1/y3Mo4OY3lfkuaYifMNBW8Wz6lQHbs1bihr7A==", + "dev": true, + "dependencies": { + "@types/slice-ansi": "^4.0.0", + "debug": "^4.0.0", + "signal-exit": "^3.0.3", + "slice-ansi": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "tslib": "^2.0.1", + "untildify": "^4.0.0", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@ionic/utils-terminal/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==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@ionic/utils-terminal/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==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@ionic/utils-terminal/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==", + "dev": true + }, + "node_modules/@ionic/utils-terminal/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==", + "dev": true + }, + "node_modules/@ionic/utils-terminal/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@ioredis/commands": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.2.0.tgz", + "integrity": "sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "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-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "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==", + "dev": true + }, + "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==", + "dev": true, + "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.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "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==", + "dev": true, + "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/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "dev": true, + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/expect-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", + "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-get-type": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/types/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/types/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": 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/@jest/types/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/types/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jest/types/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/types/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@jsonjoy.com/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==", + "dev": true, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/json-pack": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.1.1.tgz", + "integrity": "sha512-osjeBqMJ2lb/j/M8NCPjs1ylqWIcTRTycIhVB5pt6LgzgeRSb0YRZ7j9RfA8wIUrsr/medIuhVyonXRZWLyfdw==", + "dev": true, + "dependencies": { + "@jsonjoy.com/base64": "^1.1.1", + "@jsonjoy.com/util": "^1.1.2", + "hyperdyperid": "^1.2.0", + "thingies": "^1.20.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/util": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.5.0.tgz", + "integrity": "sha512-ojoNsrIuPI9g6o8UxhraZQSyF2ByJanAY4cTFbc8Mf2AXEF4aQRGY1dJxyJpuyav8r9FGflEt/Ff3u5Nt6YMPA==", + "dev": true, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", + "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", + "dev": true + }, + "node_modules/@listr2/prompt-adapter-inquirer": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/@listr2/prompt-adapter-inquirer/-/prompt-adapter-inquirer-2.0.18.tgz", + "integrity": "sha512-0hz44rAcrphyXcA8IS7EJ2SCoaBZD2u5goE8S/e+q/DL+dOGpqpcLidVOFeLG3VgML62SXmfRLAhWt0zL1oW4Q==", + "dev": true, + "dependencies": { + "@inquirer/type": "^1.5.5" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@inquirer/prompts": ">= 3 < 8" + } + }, + "node_modules/@listr2/prompt-adapter-inquirer/node_modules/@inquirer/type": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-1.5.5.tgz", + "integrity": "sha512-MzICLu4yS7V8AA61sANROZ9vT1H3ooca5dSmI1FjZkzq7o/koMsRfQSzRtFo+F3Ao4Sf1C0bpLKejpKB/+j6MA==", + "dev": true, + "dependencies": { + "mute-stream": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@listr2/prompt-adapter-inquirer/node_modules/mute-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", + "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@lmdb/lmdb-darwin-arm64": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-3.2.2.tgz", + "integrity": "sha512-WBSJT9Z7DTol5viq+DZD2TapeWOw7mlwXxiSBHgAzqVwsaVb0h/ekMD9iu/jDD8MUA20tO9N0WEdnT06fsUp+g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@lmdb/lmdb-darwin-x64": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-3.2.2.tgz", + "integrity": "sha512-4S13kUtR7c/j/MzkTIBJCXv52hQ41LG2ukeaqw4Eng9K0pNKLFjo1sDSz96/yKhwykxrWDb13ddJ/ZqD3rAhUA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@lmdb/lmdb-linux-arm": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-3.2.2.tgz", + "integrity": "sha512-uW31JmfuPAaLUYW7NsEU8gzwgDAzpGPwjvkxnKlcWd8iDutoPKDJi8Wk9lFmPEZRxVSB0j1/wDQ7N2qliR9UFA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-linux-arm64": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-3.2.2.tgz", + "integrity": "sha512-4hdgZtWI1idQlWRp+eleWXD9KLvObgboRaVoBj2POdPEYvsKANllvMW0El8tEQwtw74yB9NT6P8ENBB5UJf5+g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-linux-x64": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-3.2.2.tgz", + "integrity": "sha512-A0zjf4a2vM4B4GAx78ncuOTZ8Ka1DbTaG1Axf1e00Sa7f5coqlWiLg1PX7Gxvyibc2YqtqB+8tg1KKrE8guZVw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-win32-x64": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-3.2.2.tgz", + "integrity": "sha512-Y0qoSCAja+xZE7QQ0LCHoYAuyI1n9ZqukQJa8lv9X3yCvWahFF7OYHAgVH1ejp43XWstj3U89/PAAzcowgF/uQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@mapbox/node-pre-gyp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-2.0.0.tgz", + "integrity": "sha512-llMXd39jtP0HpQLVI37Bf1m2ADlEb35GYSh1SDSLsBhR+5iCxiNGlT31yqbNtVHygHAtMy6dWFERpU2JgufhPg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "consola": "^3.2.3", + "detect-libc": "^2.0.0", + "https-proxy-agent": "^7.0.5", + "node-fetch": "^2.6.7", + "nopt": "^8.0.0", + "semver": "^7.5.3", + "tar": "^7.4.0" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "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/@mapbox/node-pre-gyp/node_modules/minizlib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.1.tgz", + "integrity": "sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.4", + "rimraf": "^5.0.5" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/rimraf": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", + "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/tar": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", + "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", + "dev": true, + "license": "ISC", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.3.tgz", + "integrity": "sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.3.tgz", + "integrity": "sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.3.tgz", + "integrity": "sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.3.tgz", + "integrity": "sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.3.tgz", + "integrity": "sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.3.tgz", + "integrity": "sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@napi-rs/nice": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice/-/nice-1.0.1.tgz", + "integrity": "sha512-zM0mVWSXE0a0h9aKACLwKmD6nHcRiKrPpCfvaKqG1CqDEyjEawId0ocXxVzPMCAm6kkWr2P025msfxXEnt8UGQ==", + "dev": true, + "optional": true, + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "optionalDependencies": { + "@napi-rs/nice-android-arm-eabi": "1.0.1", + "@napi-rs/nice-android-arm64": "1.0.1", + "@napi-rs/nice-darwin-arm64": "1.0.1", + "@napi-rs/nice-darwin-x64": "1.0.1", + "@napi-rs/nice-freebsd-x64": "1.0.1", + "@napi-rs/nice-linux-arm-gnueabihf": "1.0.1", + "@napi-rs/nice-linux-arm64-gnu": "1.0.1", + "@napi-rs/nice-linux-arm64-musl": "1.0.1", + "@napi-rs/nice-linux-ppc64-gnu": "1.0.1", + "@napi-rs/nice-linux-riscv64-gnu": "1.0.1", + "@napi-rs/nice-linux-s390x-gnu": "1.0.1", + "@napi-rs/nice-linux-x64-gnu": "1.0.1", + "@napi-rs/nice-linux-x64-musl": "1.0.1", + "@napi-rs/nice-win32-arm64-msvc": "1.0.1", + "@napi-rs/nice-win32-ia32-msvc": "1.0.1", + "@napi-rs/nice-win32-x64-msvc": "1.0.1" + } + }, + "node_modules/@napi-rs/nice-android-arm-eabi": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-android-arm-eabi/-/nice-android-arm-eabi-1.0.1.tgz", + "integrity": "sha512-5qpvOu5IGwDo7MEKVqqyAxF90I6aLj4n07OzpARdgDRfz8UbBztTByBp0RC59r3J1Ij8uzYi6jI7r5Lws7nn6w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-android-arm64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-android-arm64/-/nice-android-arm64-1.0.1.tgz", + "integrity": "sha512-GqvXL0P8fZ+mQqG1g0o4AO9hJjQaeYG84FRfZaYjyJtZZZcMjXW5TwkL8Y8UApheJgyE13TQ4YNUssQaTgTyvA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-darwin-arm64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-darwin-arm64/-/nice-darwin-arm64-1.0.1.tgz", + "integrity": "sha512-91k3HEqUl2fsrz/sKkuEkscj6EAj3/eZNCLqzD2AA0TtVbkQi8nqxZCZDMkfklULmxLkMxuUdKe7RvG/T6s2AA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-darwin-x64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-darwin-x64/-/nice-darwin-x64-1.0.1.tgz", + "integrity": "sha512-jXnMleYSIR/+TAN/p5u+NkCA7yidgswx5ftqzXdD5wgy/hNR92oerTXHc0jrlBisbd7DpzoaGY4cFD7Sm5GlgQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-freebsd-x64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-freebsd-x64/-/nice-freebsd-x64-1.0.1.tgz", + "integrity": "sha512-j+iJ/ezONXRQsVIB/FJfwjeQXX7A2tf3gEXs4WUGFrJjpe/z2KB7sOv6zpkm08PofF36C9S7wTNuzHZ/Iiccfw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-arm-gnueabihf": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm-gnueabihf/-/nice-linux-arm-gnueabihf-1.0.1.tgz", + "integrity": "sha512-G8RgJ8FYXYkkSGQwywAUh84m946UTn6l03/vmEXBYNJxQJcD+I3B3k5jmjFG/OPiU8DfvxutOP8bi+F89MCV7Q==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-arm64-gnu": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm64-gnu/-/nice-linux-arm64-gnu-1.0.1.tgz", + "integrity": "sha512-IMDak59/W5JSab1oZvmNbrms3mHqcreaCeClUjwlwDr0m3BoR09ZiN8cKFBzuSlXgRdZ4PNqCYNeGQv7YMTjuA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-arm64-musl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm64-musl/-/nice-linux-arm64-musl-1.0.1.tgz", + "integrity": "sha512-wG8fa2VKuWM4CfjOjjRX9YLIbysSVV1S3Kgm2Fnc67ap/soHBeYZa6AGMeR5BJAylYRjnoVOzV19Cmkco3QEPw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-ppc64-gnu": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-ppc64-gnu/-/nice-linux-ppc64-gnu-1.0.1.tgz", + "integrity": "sha512-lxQ9WrBf0IlNTCA9oS2jg/iAjQyTI6JHzABV664LLrLA/SIdD+I1i3Mjf7TsnoUbgopBcCuDztVLfJ0q9ubf6Q==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-riscv64-gnu": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-riscv64-gnu/-/nice-linux-riscv64-gnu-1.0.1.tgz", + "integrity": "sha512-3xs69dO8WSWBb13KBVex+yvxmUeEsdWexxibqskzoKaWx9AIqkMbWmE2npkazJoopPKX2ULKd8Fm9veEn0g4Ig==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-s390x-gnu": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-s390x-gnu/-/nice-linux-s390x-gnu-1.0.1.tgz", + "integrity": "sha512-lMFI3i9rlW7hgToyAzTaEybQYGbQHDrpRkg+1gJWEpH0PLAQoZ8jiY0IzakLfNWnVda1eTYYlxxFYzW8Rqczkg==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-x64-gnu": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-x64-gnu/-/nice-linux-x64-gnu-1.0.1.tgz", + "integrity": "sha512-XQAJs7DRN2GpLN6Fb+ZdGFeYZDdGl2Fn3TmFlqEL5JorgWKrQGRUrpGKbgZ25UeZPILuTKJ+OowG2avN8mThBA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-x64-musl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-x64-musl/-/nice-linux-x64-musl-1.0.1.tgz", + "integrity": "sha512-/rodHpRSgiI9o1faq9SZOp/o2QkKQg7T+DK0R5AkbnI/YxvAIEHf2cngjYzLMQSQgUhxym+LFr+UGZx4vK4QdQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-win32-arm64-msvc": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-arm64-msvc/-/nice-win32-arm64-msvc-1.0.1.tgz", + "integrity": "sha512-rEcz9vZymaCB3OqEXoHnp9YViLct8ugF+6uO5McifTedjq4QMQs3DHz35xBEGhH3gJWEsXMUbzazkz5KNM5YUg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-win32-ia32-msvc": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-ia32-msvc/-/nice-win32-ia32-msvc-1.0.1.tgz", + "integrity": "sha512-t7eBAyPUrWL8su3gDxw9xxxqNwZzAqKo0Szv3IjVQd1GpXXVkb6vBBQUuxfIYaXMzZLwlxRQ7uzM2vdUE9ULGw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-win32-x64-msvc": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-x64-msvc/-/nice-win32-x64-msvc-1.0.1.tgz", + "integrity": "sha512-JlF+uDcatt3St2ntBG8H02F1mM45i5SF9W+bIKiReVE6wiy3o16oBP/yxt+RZ+N6LbCImJXJ6bXNO2kn9AXicg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.4.tgz", + "integrity": "sha512-9zESzOO5aDByvhIAsOy9TbpZ0Ur2AJbUI7UT73kcUTS2mxAMHOBaa1st/jAymNoCtvrit99kkzT1FZuXVcgfIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@emnapi/core": "^1.1.0", + "@emnapi/runtime": "^1.1.0", + "@tybys/wasm-util": "^0.9.0" + } + }, + "node_modules/@netlify/functions": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/@netlify/functions/-/functions-2.8.2.tgz", + "integrity": "sha512-DeoAQh8LuNPvBE4qsKlezjKj0PyXDryOFJfJKo3Z1qZLKzQ21sT314KQKPVjfvw6knqijj+IO+0kHXy/TJiqNA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@netlify/serverless-functions-api": "1.26.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@netlify/node-cookies": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@netlify/node-cookies/-/node-cookies-0.1.0.tgz", + "integrity": "sha512-OAs1xG+FfLX0LoRASpqzVntVV/RpYkgpI0VrUnw2u0Q1qiZUzcPffxRK8HF3gc4GjuhG5ahOEMJ9bswBiZPq0g==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.16.0 || >=16.0.0" + } + }, + "node_modules/@netlify/serverless-functions-api": { + "version": "1.26.1", + "resolved": "https://registry.npmjs.org/@netlify/serverless-functions-api/-/serverless-functions-api-1.26.1.tgz", + "integrity": "sha512-q3L9i3HoNfz0SGpTIS4zTcKBbRkxzCRpd169eyiTuk3IwcPC3/85mzLHranlKo2b+HYT0gu37YxGB45aD8A3Tw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@netlify/node-cookies": "^0.1.0", + "urlpattern-polyfill": "8.0.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@ngtools/webpack": { + "version": "19.1.5", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-19.1.5.tgz", + "integrity": "sha512-oIpE5Ci/Gl2iZqa0Hs6IOxaXEDHkF/zisHcflzYGkMnYcSFj+wRgYEuBFaHLCwuxQf9OdGu31i05w849i6tY1Q==", + "dev": true, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "@angular/compiler-cli": "^19.0.0", + "typescript": ">=5.5 <5.8", + "webpack": "^5.54.0" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@npmcli/agent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-3.0.0.tgz", + "integrity": "sha512-S79NdEgDQd/NGCay6TCoVzXSj74skRZIKJcpJjC5lOq34SZzyI6MqtiiWoiVWoVrTcGjNeC4ipbh1VIHlpfF5Q==", + "dev": true, + "dependencies": { + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^10.0.1", + "socks-proxy-agent": "^8.0.3" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/agent/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==", + "dev": true + }, + "node_modules/@npmcli/fs": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-4.0.0.tgz", + "integrity": "sha512-/xGlezI6xfGO9NwuJlnwz/K14qD1kCSAGtacBHnGzeAIuJGazcp45KP5NuyARXoKb7cwulAGWVsbeSxdG/cb0Q==", + "dev": true, + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/git": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-6.0.1.tgz", + "integrity": "sha512-BBWMMxeQzalmKadyimwb2/VVQyJB01PH0HhVSNLHNBDZN/M/h/02P6f8fxedIiFhpMj11SO9Ep5tKTBE7zL2nw==", + "dev": true, + "dependencies": { + "@npmcli/promise-spawn": "^8.0.0", + "ini": "^5.0.0", + "lru-cache": "^10.0.1", + "npm-pick-manifest": "^10.0.0", + "proc-log": "^5.0.0", + "promise-inflight": "^1.0.1", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/git/node_modules/ini": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-5.0.0.tgz", + "integrity": "sha512-+N0ngpO3e7cRUWOJAS7qw0IZIVc6XPrW4MlFBdD066F2L4k1L6ker3hLqSq7iXxU5tgS4WGkIUElWn5vogAEnw==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/git/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/@npmcli/git/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==", + "dev": true + }, + "node_modules/@npmcli/git/node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/installed-package-contents": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-3.0.0.tgz", + "integrity": "sha512-fkxoPuFGvxyrH+OQzyTkX2LUEamrF4jZSmxjAtPPHHGO0dqsQ8tTKjnIS8SAnPHdk2I03BDtSMR5K/4loKg79Q==", + "dev": true, + "dependencies": { + "npm-bundled": "^4.0.0", + "npm-normalize-package-bin": "^4.0.0" + }, + "bin": { + "installed-package-contents": "bin/index.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/node-gyp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-4.0.0.tgz", + "integrity": "sha512-+t5DZ6mO/QFh78PByMq1fGSAub/agLJZDRfJRMeOSNCt8s9YVlTjmGpIPwPhvXTGUIJk+WszlT0rQa1W33yzNA==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/package-json": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-6.1.1.tgz", + "integrity": "sha512-d5qimadRAUCO4A/Txw71VM7UrRZzV+NPclxz/dc+M6B2oYwjWTjqh8HA/sGQgs9VZuJ6I/P7XIAlJvgrl27ZOw==", + "dev": true, + "dependencies": { + "@npmcli/git": "^6.0.0", + "glob": "^10.2.2", + "hosted-git-info": "^8.0.0", + "json-parse-even-better-errors": "^4.0.0", + "proc-log": "^5.0.0", + "semver": "^7.5.3", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/package-json/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "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/@npmcli/promise-spawn": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-8.0.2.tgz", + "integrity": "sha512-/bNJhjc+o6qL+Dwz/bqfTQClkEO5nTQ1ZEcdCkAQjhkZMHIh22LPG7fNh1enJP1NKWDqYiiABnjFCY7E0zHYtQ==", + "dev": true, + "dependencies": { + "which": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/promise-spawn/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/@npmcli/promise-spawn/node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/redact": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@npmcli/redact/-/redact-3.1.1.tgz", + "integrity": "sha512-3Hc2KGIkrvJWJqTbvueXzBeZlmvoOxc2jyX00yzr3+sNFquJg0N8hH4SAPLPVrkWIRQICVpVgjrss971awXVnA==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/run-script": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-9.0.2.tgz", + "integrity": "sha512-cJXiUlycdizQwvqE1iaAb4VRUM3RX09/8q46zjvy+ct9GhfZRWd7jXYVc1tn/CfRlGPVkX/u4sstRlepsm7hfw==", + "dev": true, + "dependencies": { + "@npmcli/node-gyp": "^4.0.0", + "@npmcli/package-json": "^6.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "node-gyp": "^11.0.0", + "proc-log": "^5.0.0", + "which": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/run-script/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/@npmcli/run-script/node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@nx/devkit": { + "version": "20.4.0", + "resolved": "https://registry.npmjs.org/@nx/devkit/-/devkit-20.4.0.tgz", + "integrity": "sha512-qog9oGbuz7DDoXH5k+19tTI3WtaR1p9G5NobiDPfcWmsr1BTK2WH2V2/vVYFAfAcM/DEFgK3ITC5L3PSaJvMmw==", + "dev": true, + "license": "MIT", + "dependencies": { + "ejs": "^3.1.7", + "enquirer": "~2.3.6", + "ignore": "^5.0.4", + "minimatch": "9.0.3", + "semver": "^7.5.3", + "tmp": "~0.2.1", + "tslib": "^2.3.0", + "yargs-parser": "21.1.1" + }, + "peerDependencies": { + "nx": ">= 19 <= 21" + } + }, + "node_modules/@nx/devkit/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@nx/devkit/node_modules/tmp": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.14" + } + }, + "node_modules/@nx/js": { + "version": "20.4.0", + "resolved": "https://registry.npmjs.org/@nx/js/-/js-20.4.0.tgz", + "integrity": "sha512-7ly4gdJlP+yLA2FSANv86qrdiQSf64zTLVZj7Xu9KrSsrHr3OCX1DfzzcLgUVisumRkLxqvUrz7pzspooWdS/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.23.2", + "@babel/plugin-proposal-decorators": "^7.22.7", + "@babel/plugin-transform-class-properties": "^7.22.5", + "@babel/plugin-transform-runtime": "^7.23.2", + "@babel/preset-env": "^7.23.2", + "@babel/preset-typescript": "^7.22.5", + "@babel/runtime": "^7.22.6", + "@nx/devkit": "20.4.0", + "@nx/workspace": "20.4.0", + "@zkochan/js-yaml": "0.0.7", + "babel-plugin-const-enum": "^1.0.1", + "babel-plugin-macros": "^3.1.0", + "babel-plugin-transform-typescript-metadata": "^0.3.1", + "chalk": "^4.1.0", + "columnify": "^1.6.0", + "detect-port": "^1.5.1", + "enquirer": "~2.3.6", + "ignore": "^5.0.4", + "js-tokens": "^4.0.0", + "jsonc-parser": "3.2.0", + "minimatch": "9.0.3", + "npm-package-arg": "11.0.1", + "npm-run-path": "^4.0.1", + "ora": "5.3.0", + "semver": "^7.5.3", + "source-map-support": "0.5.19", + "tinyglobby": "^0.2.10", + "ts-node": "10.9.1", + "tsconfig-paths": "^4.1.2", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "verdaccio": "^5.0.4" + }, + "peerDependenciesMeta": { + "verdaccio": { + "optional": true + } + } + }, + "node_modules/@nx/js/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@nx/js/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": 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/@nx/js/node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@nx/js/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@nx/js/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/@nx/js/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@nx/js/node_modules/hosted-git-info": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", + "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@nx/js/node_modules/jsonc-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@nx/js/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==", + "dev": true, + "license": "ISC" + }, + "node_modules/@nx/js/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@nx/js/node_modules/npm-package-arg": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-11.0.1.tgz", + "integrity": "sha512-M7s1BD4NxdAvBKUPqqRW957Xwcl/4Zvo8Aj+ANrzvIPzGJZElrH7Z//rSaec2ORcND6FHHLnZeY8qgTpXDMFQQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "hosted-git-info": "^7.0.0", + "proc-log": "^3.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^5.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@nx/js/node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@nx/js/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@nx/js/node_modules/ora": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.3.0.tgz", + "integrity": "sha512-zAKMgGXUim0Jyd6CXK9lraBnD3H5yPGBPPOkC23a2BG6hsm4Zu6OQSjQuEtV0BHDf4aKHcUFvJiGRrFuW3MG8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^4.0.3", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "log-symbols": "^4.0.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@nx/js/node_modules/proc-log": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-3.0.0.tgz", + "integrity": "sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@nx/js/node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@nx/js/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==", + "dev": true, + "license": "ISC" + }, + "node_modules/@nx/js/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@nx/js/node_modules/source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/@nx/js/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@nx/js/node_modules/ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/@nx/js/node_modules/tsconfig-paths": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", + "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "json5": "^2.2.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@nx/js/node_modules/validate-npm-package-name": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.1.tgz", + "integrity": "sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@nx/nx-darwin-arm64": { + "version": "20.4.0", + "resolved": "https://registry.npmjs.org/@nx/nx-darwin-arm64/-/nx-darwin-arm64-20.4.0.tgz", + "integrity": "sha512-w07StYKNUIiH1koqBZY9Ew57d0wACyNdKpX96og4oiuSFYTTb+QhL4+vX2GOIYyEDfX7A97mA4lXcYUvN6R4zQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-darwin-x64": { + "version": "20.4.0", + "resolved": "https://registry.npmjs.org/@nx/nx-darwin-x64/-/nx-darwin-x64-20.4.0.tgz", + "integrity": "sha512-HS9SfQs9BKZm3mXnOggmDrsVPTdJOr4RYa0k8zhXd0GKOdAOmgvWYsCAFxHB1BV4FGq7wfc4YskXRYHra4Ornw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-freebsd-x64": { + "version": "20.4.0", + "resolved": "https://registry.npmjs.org/@nx/nx-freebsd-x64/-/nx-freebsd-x64-20.4.0.tgz", + "integrity": "sha512-5Ex4dV9YKbmO+4ZNI7qXOPvVD7A0t/guPUMcye/Rk/vJVx3Ixr/PZlc2SpBDXDLXye4quiTqICV92VrOrVBj8Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-linux-arm-gnueabihf": { + "version": "20.4.0", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-20.4.0.tgz", + "integrity": "sha512-mWu0QPZ4WQS39NuFOhbKy6Dwiytgn4SCzadZs/raXs/Sl9A1JtXIojMe5vy49rZocjhbpDuXCuKzHeFOi24TpA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-linux-arm64-gnu": { + "version": "20.4.0", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-20.4.0.tgz", + "integrity": "sha512-5ZOMKtEPoAQfSXgWYgQvMt+8JreWfnHC1rHBhQznb/66DyimKlPFv5TprzKCTqg2ElrYMe5NT5usU5fO94NDnA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-linux-arm64-musl": { + "version": "20.4.0", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-20.4.0.tgz", + "integrity": "sha512-RBF3KoBYEs0q9YZ1yBidKhcszI8x4znAfcZI+RQ1zWa/kT/GlnQKamdxinri4ov8/bEo9E4YTx4ITLg4RuVHLg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-linux-x64-gnu": { + "version": "20.4.0", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-20.4.0.tgz", + "integrity": "sha512-RSYAfAmulCatDIKXXbWDhLU/fm03YrAMTD5FtS5IeEvMGEHkQ3scmXEXTxkOF4q5LuqSrutjdb3s8wHkbFRVqw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-linux-x64-musl": { + "version": "20.4.0", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-20.4.0.tgz", + "integrity": "sha512-0eup79jxSzHoYEGl6OU3wb02wWQbEt4ZfOA58fiZ7c5mvCpKXQV9kg7Tu38zIA8nkcEXGb8JaR1R9TgMiAIZsw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-win32-arm64-msvc": { + "version": "20.4.0", + "resolved": "https://registry.npmjs.org/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-20.4.0.tgz", + "integrity": "sha512-EeHJL9YPVqi3ad9hXVCr1xDM2/PNgZIJvOlJ/ND6r9dVZ+UWw2Kk7G2r13zz4j4QAhrhQJ+kzrvXYkQlhiSH6g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-win32-x64-msvc": { + "version": "20.4.0", + "resolved": "https://registry.npmjs.org/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-20.4.0.tgz", + "integrity": "sha512-IUeCeLdehVocLML6Wub7OZVM96Sk97AshiWmeNnozI6/OYdS34hQ2+thH7ETUZas9nkC2nNkJ5jLwuAHm+5/vw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/vite": { + "version": "20.4.0", + "resolved": "https://registry.npmjs.org/@nx/vite/-/vite-20.4.0.tgz", + "integrity": "sha512-0aH/YjqfD1J3BGJ9mhy44dUIow1VWnSspz9W30FcaJrVk/a31vBXcPLxE4+0dSd0XHMUXVOjPRCBhzitFzamJA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nx/devkit": "20.4.0", + "@nx/js": "20.4.0", + "@phenomnomnominal/tsquery": "~5.0.1", + "@swc/helpers": "~0.5.0", + "enquirer": "~2.3.6", + "minimatch": "9.0.3", + "tsconfig-paths": "^4.1.2" + }, + "peerDependencies": { + "vite": "^5.0.0", + "vitest": "^1.3.1 || ^2.0.0" + } + }, + "node_modules/@nx/vite/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@nx/vite/node_modules/tsconfig-paths": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", + "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "json5": "^2.2.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@nx/workspace": { + "version": "20.4.0", + "resolved": "https://registry.npmjs.org/@nx/workspace/-/workspace-20.4.0.tgz", + "integrity": "sha512-UFSCl2ZXGW96er+VC8xpytzxmZ4mBHASIeQwk1RpIgB3h/Iif2T7OnnIFFg32Ag667TfXZhAPZ4P0pBNGdBeSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nx/devkit": "20.4.0", + "chalk": "^4.1.0", + "enquirer": "~2.3.6", + "nx": "20.4.0", + "tslib": "^2.3.0", + "yargs-parser": "21.1.1" + } + }, + "node_modules/@nx/workspace/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@nx/workspace/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": 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/@nx/workspace/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@nx/workspace/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/@nx/workspace/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@nx/workspace/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@oozcitak/dom": { + "version": "1.15.10", + "resolved": "https://registry.npmjs.org/@oozcitak/dom/-/dom-1.15.10.tgz", + "integrity": "sha512-0JT29/LaxVgRcGKvHmSrUTEvZ8BXvZhGl2LASRUgHqDTC1M5g1pLmVv56IYNyt3bG2CUjDkc67wnyZC14pbQrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oozcitak/infra": "1.0.8", + "@oozcitak/url": "1.0.4", + "@oozcitak/util": "8.3.8" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/@oozcitak/infra": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@oozcitak/infra/-/infra-1.0.8.tgz", + "integrity": "sha512-JRAUc9VR6IGHOL7OGF+yrvs0LO8SlqGnPAMqyzOuFZPSZSXI7Xf2O9+awQPSMXgIWGtgUf/dA6Hs6X6ySEaWTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oozcitak/util": "8.3.8" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/@oozcitak/url": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@oozcitak/url/-/url-1.0.4.tgz", + "integrity": "sha512-kDcD8y+y3FCSOvnBI6HJgl00viO/nGbQoCINmQ0h98OhnGITrWR3bOGfwYCthgcrV8AnTJz8MzslTQbC3SOAmw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oozcitak/infra": "1.0.8", + "@oozcitak/util": "8.3.8" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/@oozcitak/util": { + "version": "8.3.8", + "resolved": "https://registry.npmjs.org/@oozcitak/util/-/util-8.3.8.tgz", + "integrity": "sha512-T8TbSnGsxo6TDBJx/Sgv/BlVJL3tshxZP7Aq5R1mSnM5OcHY2dQaxLMu2+E8u3gN0MLOzdjurqN4ZRVuzQycOQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0" + } + }, + "node_modules/@parcel/watcher": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz", + "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "detect-libc": "^1.0.3", + "is-glob": "^4.0.3", + "micromatch": "^4.0.5", + "node-addon-api": "^7.0.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.5.1", + "@parcel/watcher-darwin-arm64": "2.5.1", + "@parcel/watcher-darwin-x64": "2.5.1", + "@parcel/watcher-freebsd-x64": "2.5.1", + "@parcel/watcher-linux-arm-glibc": "2.5.1", + "@parcel/watcher-linux-arm-musl": "2.5.1", + "@parcel/watcher-linux-arm64-glibc": "2.5.1", + "@parcel/watcher-linux-arm64-musl": "2.5.1", + "@parcel/watcher-linux-x64-glibc": "2.5.1", + "@parcel/watcher-linux-x64-musl": "2.5.1", + "@parcel/watcher-win32-arm64": "2.5.1", + "@parcel/watcher-win32-ia32": "2.5.1", + "@parcel/watcher-win32-x64": "2.5.1" + } + }, + "node_modules/@parcel/watcher-android-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz", + "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz", + "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz", + "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-freebsd-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz", + "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz", + "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz", + "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz", + "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz", + "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz", + "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz", + "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-wasm": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-wasm/-/watcher-wasm-2.5.1.tgz", + "integrity": "sha512-RJxlQQLkaMMIuWRozy+z2vEqbaQlCuaCgVZIUCzQLYggY22LZbP5Y1+ia+FD724Ids9e+XIyOLXLrLgQSHIthw==", + "bundleDependencies": [ + "napi-wasm" + ], + "dev": true, + "license": "MIT", + "dependencies": { + "is-glob": "^4.0.3", + "micromatch": "^4.0.5", + "napi-wasm": "^1.1.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-wasm/node_modules/napi-wasm": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/@parcel/watcher-win32-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz", + "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-ia32": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz", + "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz", + "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher/node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "dev": true, + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/@parcel/watcher/node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "dev": true + }, + "node_modules/@phenomnomnominal/tsquery": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@phenomnomnominal/tsquery/-/tsquery-5.0.1.tgz", + "integrity": "sha512-3nVv+e2FQwsW8Aw6qTU6f+1rfcJ3hrcnvH/mu9i8YhxO+9sqbOfpL8m6PbET5+xKOlz/VSbp0RoYWYCtIsnmuA==", + "dev": true, + "license": "MIT", + "dependencies": { + "esquery": "^1.4.0" + }, + "peerDependencies": { + "typescript": "^3 || ^4 || ^5" + } + }, + "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==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@pkgr/core": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", + "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.28", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.28.tgz", + "integrity": "sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@promptbook/utils": { + "version": "0.69.5", + "resolved": "https://registry.npmjs.org/@promptbook/utils/-/utils-0.69.5.tgz", + "integrity": "sha512-xm5Ti/Hp3o4xHrsK9Yy3MS6KbDxYbq485hDsFvxqaNA7equHLPdo8H8faTitTeb14QCDfLW4iwCxdVYu5sn6YQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://buymeacoffee.com/hejny" + }, + { + "type": "github", + "url": "https://github.com/webgptorg/promptbook/blob/main/README.md#%EF%B8%8F-contributing" + } + ], + "license": "CC-BY-4.0", + "dependencies": { + "spacetrim": "0.11.59" + } + }, + "node_modules/@puppeteer/browsers": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.6.1.tgz", + "integrity": "sha512-aBSREisdsGH890S2rQqK82qmQYU3uFpSH8wcZWHgHzl3LfzsxAKbLNiAG9mO8v1Y0UICBeClICxPJvyr0rcuxg==", + "dependencies": { + "debug": "^4.4.0", + "extract-zip": "^2.0.1", + "progress": "^2.0.3", + "proxy-agent": "^6.5.0", + "semver": "^7.6.3", + "tar-fs": "^3.0.6", + "unbzip2-stream": "^1.4.3", + "yargs": "^17.7.2" + }, + "bin": { + "browsers": "lib/cjs/main-cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@puppeteer/browsers/node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/@puppeteer/browsers/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@puppeteer/browsers/node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/@puppeteer/browsers/node_modules/tar-fs": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.6.tgz", + "integrity": "sha512-iokBDQQkUyeXhgPYaZxmczGPhnhXZ0CmrqI+MOb/WFGS9DW5wnfrLgtjUJBvz50vQ3qfRwJ62QVoCFu8mPVu5w==", + "dependencies": { + "pump": "^3.0.0", + "tar-stream": "^3.1.5" + }, + "optionalDependencies": { + "bare-fs": "^2.1.1", + "bare-path": "^2.1.0" + } + }, + "node_modules/@puppeteer/browsers/node_modules/tar-stream": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, + "node_modules/@redocly/ajv": { + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/@redocly/ajv/-/ajv-8.11.2.tgz", + "integrity": "sha512-io1JpnwtIcvojV7QKDUSIuMN/ikdOUd1ReEnUnMKGfDVridQZ31J0MmIuqwuRjWDZfmvr+Q0MqCcfHM2gTivOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js-replace": "^1.0.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@redocly/config": { + "version": "0.20.3", + "resolved": "https://registry.npmjs.org/@redocly/config/-/config-0.20.3.tgz", + "integrity": "sha512-Nyyv1Bj7GgYwj/l46O0nkH1GTKWbO3Ixe7KFcn021aZipkZd+z8Vlu1BwkhqtVgivcKaClaExtWU/lDHkjBzag==", + "dev": true, + "license": "MIT" + }, + "node_modules/@redocly/openapi-core": { + "version": "1.28.3", + "resolved": "https://registry.npmjs.org/@redocly/openapi-core/-/openapi-core-1.28.3.tgz", + "integrity": "sha512-PtUnjtU9rYA+72PlN3MiR/J++PQI0q6AMV7hIHJQmtsEMtB1OU8l3duT5Txkpc6JJi7deHg66UpzVznImz3OCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@redocly/ajv": "^8.11.2", + "@redocly/config": "^0.20.1", + "colorette": "^1.2.0", + "https-proxy-agent": "^7.0.5", + "js-levenshtein": "^1.1.6", + "js-yaml": "^4.1.0", + "minimatch": "^5.0.1", + "pluralize": "^8.0.0", + "yaml-ast-parser": "0.0.43" + }, + "engines": { + "node": ">=18.17.0", + "npm": ">=9.5.0" + } + }, + "node_modules/@redocly/openapi-core/node_modules/colorette": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", + "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@redocly/openapi-core/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@rollup/plugin-alias": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-5.1.1.tgz", + "integrity": "sha512-PR9zDb+rOzkRb2VD+EuKB7UC41vU5DIwZ5qqCpk0KJudcWAyi8rvYOhS7+L5aZCspw1stTViLgN5v6FF1p5cgQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-commonjs": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.2.tgz", + "integrity": "sha512-BEFI2EDqzl+vA1rl97IDRZ61AIwGH093d9nz8+dThxJNH8oSoB7MjWvPCX3dkaK1/RCJ/1v/R1XB15FuSs0fQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "commondir": "^1.0.1", + "estree-walker": "^2.0.2", + "fdir": "^6.2.0", + "is-reference": "1.2.1", + "magic-string": "^0.30.3", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=16.0.0 || 14 >= 14.17" + }, + "peerDependencies": { + "rollup": "^2.68.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-inject": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/@rollup/plugin-inject/-/plugin-inject-5.0.5.tgz", + "integrity": "sha512-2+DEJbNBoPROPkgTDNe8/1YXWcqxbN5DTjASVIOx8HS+pITXushyNiBV56RB08zuptzz8gT3YfkqriTBVycepg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.3" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-json": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-6.1.0.tgz", + "integrity": "sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.1.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-node-resolve": { + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.3.1.tgz", + "integrity": "sha512-tgg6b91pAybXHJQMAAwW9VuWBO6Thi+q7BCNARLwSqlmsHz0XYURtGvh/AuwSADXSI4h/2uHbs7s4FzlZDGSGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "@types/resolve": "1.20.2", + "deepmerge": "^4.2.2", + "is-module": "^1.0.0", + "resolve": "^1.22.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.78.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-replace": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-6.0.2.tgz", + "integrity": "sha512-7QaYCf8bqF04dOy7w/eHmJeNExxTYwvKAmlSAH/EaWWUzbT0h5sbF6bktFoX/0F/0qwng5/dWFMyf3gzaM8DsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "magic-string": "^0.30.3" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-terser": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz", + "integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "serialize-javascript": "^6.0.1", + "smob": "^1.0.0", + "terser": "^5.17.4" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.4.tgz", + "integrity": "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.30.1.tgz", + "integrity": "sha512-pSWY+EVt3rJ9fQ3IqlrEUtXh3cGqGtPDH1FQlNZehO2yYxCHEX1SPsz1M//NXwYfbTlcKr9WObLnJX9FsS9K1Q==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.30.1.tgz", + "integrity": "sha512-/NA2qXxE3D/BRjOJM8wQblmArQq1YoBVJjrjoTSBS09jgUisq7bqxNHJ8kjCHeV21W/9WDGwJEWSN0KQ2mtD/w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.30.1.tgz", + "integrity": "sha512-r7FQIXD7gB0WJ5mokTUgUWPl0eYIH0wnxqeSAhuIwvnnpjdVB8cRRClyKLQr7lgzjctkbp5KmswWszlwYln03Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.30.1.tgz", + "integrity": "sha512-x78BavIwSH6sqfP2xeI1hd1GpHL8J4W2BXcVM/5KYKoAD3nNsfitQhvWSw+TFtQTLZ9OmlF+FEInEHyubut2OA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.30.1.tgz", + "integrity": "sha512-HYTlUAjbO1z8ywxsDFWADfTRfTIIy/oUlfIDmlHYmjUP2QRDTzBuWXc9O4CXM+bo9qfiCclmHk1x4ogBjOUpUQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.30.1.tgz", + "integrity": "sha512-1MEdGqogQLccphhX5myCJqeGNYTNcmTyaic9S7CG3JhwuIByJ7J05vGbZxsizQthP1xpVx7kd3o31eOogfEirw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.30.1.tgz", + "integrity": "sha512-PaMRNBSqCx7K3Wc9QZkFx5+CX27WFpAMxJNiYGAXfmMIKC7jstlr32UhTgK6T07OtqR+wYlWm9IxzennjnvdJg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.30.1.tgz", + "integrity": "sha512-B8Rcyj9AV7ZlEFqvB5BubG5iO6ANDsRKlhIxySXcF1axXYUyqwBok+XZPgIYGBgs7LDXfWfifxhw0Ik57T0Yug==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.30.1.tgz", + "integrity": "sha512-hqVyueGxAj3cBKrAI4aFHLV+h0Lv5VgWZs9CUGqr1z0fZtlADVV1YPOij6AhcK5An33EXaxnDLmJdQikcn5NEw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.30.1.tgz", + "integrity": "sha512-i4Ab2vnvS1AE1PyOIGp2kXni69gU2DAUVt6FSXeIqUCPIR3ZlheMW3oP2JkukDfu3PsexYRbOiJrY+yVNSk9oA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.30.1.tgz", + "integrity": "sha512-fARcF5g296snX0oLGkVxPmysetwUk2zmHcca+e9ObOovBR++9ZPOhqFUM61UUZ2EYpXVPN1redgqVoBB34nTpQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.30.1.tgz", + "integrity": "sha512-GLrZraoO3wVT4uFXh67ElpwQY0DIygxdv0BNW9Hkm3X34wu+BkqrDrkcsIapAY+N2ATEbvak0XQ9gxZtCIA5Rw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.30.1.tgz", + "integrity": "sha512-0WKLaAUUHKBtll0wvOmh6yh3S0wSU9+yas923JIChfxOaaBarmb/lBKPF0w/+jTVozFnOXJeRGZ8NvOxvk/jcw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.30.1.tgz", + "integrity": "sha512-GWFs97Ruxo5Bt+cvVTQkOJ6TIx0xJDD/bMAOXWJg8TCSTEK8RnFeOeiFTxKniTc4vMIaWvCplMAFBt9miGxgkA==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.30.1.tgz", + "integrity": "sha512-UtgGb7QGgXDIO+tqqJ5oZRGHsDLO8SlpE4MhqpY9Llpzi5rJMvrK6ZGhsRCST2abZdBqIBeXW6WPD5fGK5SDwg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.30.1.tgz", + "integrity": "sha512-V9U8Ey2UqmQsBT+xTOeMzPzwDzyXmnAoO4edZhL7INkwQcaW1Ckv3WJX3qrrp/VHaDkEWIBWhRwP47r8cdrOow==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.30.1.tgz", + "integrity": "sha512-WabtHWiPaFF47W3PkHnjbmWawnX/aE57K47ZDT1BXTS5GgrBUEpvOzq0FI0V/UYzQJgdb8XlhVNH8/fwV8xDjw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.30.1.tgz", + "integrity": "sha512-pxHAU+Zv39hLUTdQQHUVHf4P+0C47y/ZloorHpzs2SXMRqeAWmGghzAhfOlzFHHwjvgokdFAhC4V+6kC1lRRfw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.30.1.tgz", + "integrity": "sha512-D6qjsXGcvhTjv0kI4fU8tUuBDF/Ueee4SVX79VfNDXZa64TfCW1Slkb6Z7O1p7vflqZjcmOVdZlqf8gvJxc6og==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true + }, + "node_modules/@schematics/angular": { + "version": "19.1.5", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-19.1.5.tgz", + "integrity": "sha512-Yks2QD87z2qJhVLi6O0tQDBG4pyX5n5c8BYEyZ+yiThjzIXBRkHjWS1jIFvd/y1+yU/NQFHYG/sy8sVOxfQ9IA==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "19.1.5", + "@angular-devkit/schematics": "19.1.5", + "jsonc-parser": "3.3.1" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@schematics/angular/node_modules/@angular-devkit/core": { + "version": "19.1.5", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.1.5.tgz", + "integrity": "sha512-wGKV+i5mCM/Hd/3CsdrIYcVi5G2Wg/D5941bUDXivrbsqHfKVINxAkI3OI1eaD90VnAL8ICrQEoAhh6ni2Umkg==", + "dev": true, + "dependencies": { + "ajv": "8.17.1", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.2", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^4.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sidvind/better-ajv-errors": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sidvind/better-ajv-errors/-/better-ajv-errors-3.0.1.tgz", + "integrity": "sha512-++1mEYIeozfnwWI9P1ECvOPoacy+CgDASrmGvXPMCcqgx0YUzB01vZ78uHdQ443V6sTY+e9MzHqmN9DOls02aw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "kleur": "^4.1.0" + }, + "engines": { + "node": ">= 16.14" + }, + "peerDependencies": { + "ajv": "^6.12.3 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@sigstore/bundle": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-3.1.0.tgz", + "integrity": "sha512-Mm1E3/CmDDCz3nDhFKTuYdB47EdRFRQMOE/EAbiG1MJW77/w1b3P7Qx7JSrVJs8PfwOLOVcKQCHErIwCTyPbag==", + "dev": true, + "dependencies": { + "@sigstore/protobuf-specs": "^0.4.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/core": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sigstore/core/-/core-2.0.0.tgz", + "integrity": "sha512-nYxaSb/MtlSI+JWcwTHQxyNmWeWrUXJJ/G4liLrGG7+tS4vAz6LF3xRXqLH6wPIVUoZQel2Fs4ddLx4NCpiIYg==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/protobuf-specs": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.4.0.tgz", + "integrity": "sha512-o09cLSIq9EKyRXwryWDOJagkml9XgQCoCSRjHOnHLnvsivaW7Qznzz6yjfV7PHJHhIvyp8OH7OX8w0Dc5bQK7A==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/sign": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-3.1.0.tgz", + "integrity": "sha512-knzjmaOHOov1Ur7N/z4B1oPqZ0QX5geUfhrVaqVlu+hl0EAoL4o+l0MSULINcD5GCWe3Z0+YJO8ues6vFlW0Yw==", + "dev": true, + "dependencies": { + "@sigstore/bundle": "^3.1.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.4.0", + "make-fetch-happen": "^14.0.2", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/tuf": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-3.1.0.tgz", + "integrity": "sha512-suVMQEA+sKdOz5hwP9qNcEjX6B45R+hFFr4LAWzbRc5O+U2IInwvay/bpG5a4s+qR35P/JK/PiKiRGjfuLy1IA==", + "dev": true, + "dependencies": { + "@sigstore/protobuf-specs": "^0.4.0", + "tuf-js": "^3.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/verify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@sigstore/verify/-/verify-2.1.0.tgz", + "integrity": "sha512-kAAM06ca4CzhvjIZdONAL9+MLppW3K48wOFy1TbuaWFW/OMfl8JuTgW0Bm02JB1WJGT/ET2eqav0KTEKmxqkIA==", + "dev": true, + "dependencies": { + "@sigstore/bundle": "^3.1.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.4.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sindresorhus/merge-streams": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", + "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@sliphua/lilconfig-ts-loader": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@sliphua/lilconfig-ts-loader/-/lilconfig-ts-loader-3.2.2.tgz", + "integrity": "sha512-nX2aBwAykiG50fSUzK9eyA5UvWcrEKzA0ZzCq9mLwHMwpKxM+U05YH8PHba1LJrbeZ7R1HSjJagWKMqFyq8cxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash.get": "^4", + "make-error": "^1", + "ts-node": "^9", + "tslib": "^2" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "lilconfig": ">=2" + } + }, + "node_modules/@sliphua/lilconfig-ts-loader/node_modules/ts-node": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz", + "integrity": "sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==", + "dev": true, + "license": "MIT", + "dependencies": { + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.17", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "typescript": ">=2.7" + } + }, + "node_modules/@stencil/core": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.20.0.tgz", + "integrity": "sha512-WPrTHFngvN081RY+dJPneKQLwnOFD60OMCOQGmmSHfCW0f4ujPMzzhwWU1gcSwXPWXz5O+8cBiiCaxAbJU7kAg==", + "bin": { + "stencil": "bin/stencil" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=7.10.0" + } + }, + "node_modules/@swc/helpers": { + "version": "0.5.15", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", + "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tootallnate/quickjs-emscripten": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", + "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==" + }, + "node_modules/@ts-morph/common": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.22.0.tgz", + "integrity": "sha512-HqNBuV/oIlMKdkLshXd1zKBqNQCsuPEsgQOkfFQ/eUKjRlwndXW1AjN9LVkBEIukm00gGXSRmfkl0Wv5VXLnlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-glob": "^3.3.2", + "minimatch": "^9.0.3", + "mkdirp": "^3.0.1", + "path-browserify": "^1.0.1" + } + }, + "node_modules/@ts-morph/common/node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tufjs/canonical-json": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-2.0.0.tgz", + "integrity": "sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==", + "dev": true, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@tufjs/models": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-3.0.1.tgz", + "integrity": "sha512-UUYHISyhCU3ZgN8yaear3cGATHb3SMuKHsQ/nVbHXcmnBf+LzQ/cQfhNG+rfaSHgqGKNEm2cOCLVLELStUQ1JA==", + "dev": true, + "dependencies": { + "@tufjs/canonical-json": "2.0.0", + "minimatch": "^9.0.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@tybys/wasm-util": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.9.0.tgz", + "integrity": "sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dev": true, + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/bonjour": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", + "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/canvas-confetti": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/@types/canvas-confetti/-/canvas-confetti-1.6.4.tgz", + "integrity": "sha512-fNyZ/Fdw/Y92X0vv7B+BD6ysHL4xVU5dJcgzgxLdGbn8O3PezZNIJpml44lKM0nsGur+o/6+NZbZeNTt00U1uA==", + "dev": true + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect-history-api-fallback": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", + "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", + "dev": true, + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "node_modules/@types/cordova": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@types/cordova/-/cordova-11.0.3.tgz", + "integrity": "sha512-kyuRQ40/NWQVhqGIHq78Ehu2Bf9Mlg0LhmSmis6ZFJK7z933FRfYi8tHe/k/0fB+PGfCf95rJC6TO7dopaFvAg==" + }, + "node_modules/@types/eslint": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", + "dev": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "dev": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true + }, + "node_modules/@types/ethereum-blockies": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@types/ethereum-blockies/-/ethereum-blockies-0.1.2.tgz", + "integrity": "sha512-jNYm7AK2zXorjV+B0mYWrzqKQ2+AY5vSJSVUU4/YrJnxLheBBwCEVTlCLNDZsWZ7mH6qHsAtLpwuQLlDs2+P0A==", + "dev": true + }, + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "dev": true, + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.6.tgz", + "integrity": "sha512-3xhRnjJPkULekpSzgtoNYYcTWgEZkp4myc+Saevii5JPnHNvHMRlBSHDbs7Bh1iPPoVTERHEZXyhyLbMEsExsA==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/express/node_modules/@types/express-serve-static-core": { + "version": "4.19.6", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", + "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/fs-extra": { + "version": "8.1.5", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.5.tgz", + "integrity": "sha512-0dzKcwO+S8s2kuF5Z9oUWatQJj5Uq/iqphEtE3GQJVRRYm/tD1LglU2UnXi2A8jLq5umkGouOXOR9y0n613ZwQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "dev": true + }, + "node_modules/@types/http-proxy": { + "version": "1.17.15", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.15.tgz", + "integrity": "sha512-25g5atgiVNTIv0LBDTg1H74Hvayx0ajtJPLLcYE3whFv75J0pWNtOBzaXJQgDTmrX1bx5U9YC2w/n65BN1HwRQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jasmine": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-5.1.4.tgz", + "integrity": "sha512-px7OMFO/ncXxixDe1zR13V1iycqWae0MxTaw62RpFlksUi5QuNWgQJFkTQjIOvrmutJbI7Fp2Y2N1F6D2R4G6w==", + "dev": true + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true + }, + "node_modules/@types/lodash": { + "version": "4.17.7", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.7.tgz", + "integrity": "sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA==", + "dev": true + }, + "node_modules/@types/lodash-es": { + "version": "4.17.12", + "resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.12.tgz", + "integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==", + "dev": true, + "dependencies": { + "@types/lodash": "*" + } + }, + "node_modules/@types/luxon": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-3.4.2.tgz", + "integrity": "sha512-TifLZlFudklWlMBfhubvgqTXRzLDI5pCbGa4P8a3wPyUQSW+1xQ5eDsreP9DWHX3tjq1ke96uYG/nwundroWcA==", + "dev": true + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "dev": true + }, + "node_modules/@types/mocha": { + "version": "10.0.10", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.10.tgz", + "integrity": "sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mute-stream": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/@types/mute-stream/-/mute-stream-0.0.4.tgz", + "integrity": "sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "22.13.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.10.tgz", + "integrity": "sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "node_modules/@types/node-forge": { + "version": "1.3.11", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", + "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node/node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "license": "MIT" + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/q": { + "version": "0.0.32", + "resolved": "https://registry.npmjs.org/@types/q/-/q-0.0.32.tgz", + "integrity": "sha512-qYi3YV9inU/REEfxwVcGZzbS3KG/Xs90lv0Pr+lDtuVjBPGd1A+eciXzVSaRvLify132BfcvhvEjeVahrUl0Ug==", + "dev": true + }, + "node_modules/@types/qs": { + "version": "6.9.18", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.18.tgz", + "integrity": "sha512-kK7dgTYDyGqS+e2Q4aK9X3D7q234CIZ1Bv0q/7Z5IwRDoADNU81xXJK/YVyLbLTZCoIwUoDoffFeF+p/eIklAA==", + "dev": true + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "dev": true + }, + "node_modules/@types/resolve": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", + "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/retry": { + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz", + "integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==", + "dev": true + }, + "node_modules/@types/selenium-webdriver": { + "version": "3.0.26", + "resolved": "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-3.0.26.tgz", + "integrity": "sha512-dyIGFKXfUFiwkMfNGn1+F6b80ZjR3uSYv1j6xVJSDlft5waZ2cwkHW4e7zNzvq7hiEackcgvBpmnXZrI1GltPg==", + "dev": true + }, + "node_modules/@types/semver": { + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dev": true, + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-index": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", + "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", + "dev": true, + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "dev": true, + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, + "node_modules/@types/sinonjs__fake-timers": { + "version": "8.1.5", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.5.tgz", + "integrity": "sha512-mQkU2jY8jJEF7YHjHvsQO8+3ughTL1mcnn96igfhONmR+fUPSKIkefQYpSe8bsly2Ep7oQbn/6VG5/9/0qcArQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-+OpjSaq85gvlZAYINyzKpLeiFkSC4EsC6IIiT6v6TLSU5k5U83fHGj9Lel8oKEXM0HqgrMVCjXPDPVICtxF7EQ==", + "dev": true + }, + "node_modules/@types/sockjs": { + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", + "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/which/-/which-2.0.2.tgz", + "integrity": "sha512-113D3mDkZDjo+EeUEHCFy0qniNc1ZpecGiAU7WSo7YDoSzolZIQKpYFHrPpjkB2nuyahcKfrmLXeQlh7gqJYdw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/wrap-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/wrap-ansi/-/wrap-ansi-3.0.0.tgz", + "integrity": "sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/ws": { + "version": "8.5.14", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.14.tgz", + "integrity": "sha512-bd/YFLW+URhBzMXurx7lWByOu+xzU9+kb3RboOteXYDfW+tr+JZa99OyNmPINEGB/ahzKrEuc8rcv4gnpJmxTw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/yargs": { + "version": "17.0.33", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", + "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/yauzl": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.22.0.tgz", + "integrity": "sha512-4Uta6REnz/xEJMvwf72wdUnC3rr4jAQf5jnTkeRQ9b6soxLxhDEbS/pfMPoJLDfFPNVRdryqWUIV/2GZzDJFZw==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.22.0", + "@typescript-eslint/type-utils": "8.22.0", + "@typescript-eslint/utils": "8.22.0", + "@typescript-eslint/visitor-keys": "8.22.0", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.22.0.tgz", + "integrity": "sha512-MqtmbdNEdoNxTPzpWiWnqNac54h8JDAmkWtJExBVVnSrSmi9z+sZUt0LfKqk9rjqmKOIeRhO4fHHJ1nQIjduIQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "8.22.0", + "@typescript-eslint/types": "8.22.0", + "@typescript-eslint/typescript-estree": "8.22.0", + "@typescript-eslint/visitor-keys": "8.22.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.22.0.tgz", + "integrity": "sha512-/lwVV0UYgkj7wPSw0o8URy6YI64QmcOdwHuGuxWIYznO6d45ER0wXUbksr9pYdViAofpUCNJx/tAzNukgvaaiQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.22.0", + "@typescript-eslint/visitor-keys": "8.22.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.22.0.tgz", + "integrity": "sha512-NzE3aB62fDEaGjaAYZE4LH7I1MUwHooQ98Byq0G0y3kkibPJQIXVUspzlFOmOfHhiDLwKzMlWxaNv+/qcZurJA==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "8.22.0", + "@typescript-eslint/utils": "8.22.0", + "debug": "^4.3.4", + "ts-api-utils": "^2.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.22.0.tgz", + "integrity": "sha512-0S4M4baNzp612zwpD4YOieP3VowOARgK2EkN/GBn95hpyF8E2fbMT55sRHWBq+Huaqk3b3XK+rxxlM8sPgGM6A==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.22.0.tgz", + "integrity": "sha512-SJX99NAS2ugGOzpyhMza/tX+zDwjvwAtQFLsBo3GQxiGcvaKlqGBkmZ+Y1IdiSi9h4Q0Lr5ey+Cp9CGWNY/F/w==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.22.0", + "@typescript-eslint/visitor-keys": "8.22.0", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.22.0.tgz", + "integrity": "sha512-T8oc1MbF8L+Bk2msAvCUzjxVB2Z2f+vXYfcucE2wOmYs7ZUwco5Ep0fYZw8quNwOiw9K8GYVL+Kgc2pETNTLOg==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.22.0", + "@typescript-eslint/types": "8.22.0", + "@typescript-eslint/typescript-estree": "8.22.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.22.0.tgz", + "integrity": "sha512-AWpYAXnUgvLNabGTy3uBylkgZoosva/miNd1I8Bz3SjotmQPbVqhO4Cczo8AsZ44XVErEBPr/CRSgaj8sG7g0w==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.22.0", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@vercel/nft": { + "version": "0.27.10", + "resolved": "https://registry.npmjs.org/@vercel/nft/-/nft-0.27.10.tgz", + "integrity": "sha512-zbaF9Wp/NsZtKLE4uVmL3FyfFwlpDyuymQM1kPbeT0mVOHKDQQNjnnfslB3REg3oZprmNFJuh3pkHBk2qAaizg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@mapbox/node-pre-gyp": "^2.0.0-rc.0", + "@rollup/pluginutils": "^5.1.3", + "acorn": "^8.6.0", + "acorn-import-attributes": "^1.9.5", + "async-sema": "^3.1.1", + "bindings": "^1.4.0", + "estree-walker": "2.0.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "node-gyp-build": "^4.2.2", + "picomatch": "^4.0.2", + "resolve-from": "^5.0.0" + }, + "bin": { + "nft": "out/cli.js" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@vercel/nft/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@vitejs/plugin-basic-ssl": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-1.2.0.tgz", + "integrity": "sha512-mkQnxTkcldAzIsomk1UuLfAu9n+kpQ3JbHcpCp7d2Oo6ITtji8pHS3QToOWjhPFvNQSnhlkAjmGbhv2QvwO/7Q==", + "dev": true, + "engines": { + "node": ">=14.21.3" + }, + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0" + } + }, + "node_modules/@vitest/coverage-v8": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.0.5.tgz", + "integrity": "sha512-zOOWIsj5fHh3jjGwQg+P+J1FW3s4jBu1Zqga0qW60yutsBtqEqNEJKWYh7cYn1yGD+1bdPsPdC/eL4eVK56xMg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.3.0", + "@bcoe/v8-coverage": "^1.0.2", + "debug": "^4.4.0", + "istanbul-lib-coverage": "^3.2.2", + "istanbul-lib-report": "^3.0.1", + "istanbul-lib-source-maps": "^5.0.6", + "istanbul-reports": "^3.1.7", + "magic-string": "^0.30.17", + "magicast": "^0.3.5", + "std-env": "^3.8.0", + "test-exclude": "^7.0.1", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@vitest/browser": "3.0.5", + "vitest": "3.0.5" + }, + "peerDependenciesMeta": { + "@vitest/browser": { + "optional": true + } + } + }, + "node_modules/@vitest/expect": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.0.5.tgz", + "integrity": "sha512-nNIOqupgZ4v5jWuQx2DSlHLEs7Q4Oh/7AYwNyE+k0UQzG7tSmjPXShUikn1mpNGzYEN2jJbTvLejwShMitovBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "3.0.5", + "@vitest/utils": "3.0.5", + "chai": "^5.1.2", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.0.5.tgz", + "integrity": "sha512-CLPNBFBIE7x6aEGbIjaQAX03ZZlBMaWwAjBdMkIf/cAn6xzLTiM3zYqO/WAbieEjsAZir6tO71mzeHZoodThvw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "3.0.5", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.17" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0 || ^6.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/mocker/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/@vitest/pretty-format": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.0.5.tgz", + "integrity": "sha512-CjUtdmpOcm4RVtB+up8r2vVDLR16Mgm/bYdkGFe3Yj/scRfCpbSi2W/BDSDcFK7ohw8UXvjMbOp9H4fByd/cOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.0.5.tgz", + "integrity": "sha512-BAiZFityFexZQi2yN4OX3OkJC6scwRo8EhRB0Z5HIGGgd2q+Nq29LgHU/+ovCtd0fOfXj5ZI6pwdlUmC5bpi8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "3.0.5", + "pathe": "^2.0.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner/node_modules/pathe": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.2.tgz", + "integrity": "sha512-15Ztpk+nov8DR524R4BF7uEuzESgzUEAV4Ah7CUMNGXdE5ELuvxElxGXndBl32vMSsWa1jpNf22Z+Er3sKwq+w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@vitest/snapshot": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.0.5.tgz", + "integrity": "sha512-GJPZYcd7v8QNUJ7vRvLDmRwl+a1fGg4T/54lZXe+UOGy47F9yUfE18hRCtXL5aHN/AONu29NGzIXSVFh9K0feA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "3.0.5", + "magic-string": "^0.30.17", + "pathe": "^2.0.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot/node_modules/pathe": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.2.tgz", + "integrity": "sha512-15Ztpk+nov8DR524R4BF7uEuzESgzUEAV4Ah7CUMNGXdE5ELuvxElxGXndBl32vMSsWa1jpNf22Z+Er3sKwq+w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@vitest/spy": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.0.5.tgz", + "integrity": "sha512-5fOzHj0WbUNqPK6blI/8VzZdkBlQLnT25knX0r4dbZI9qoZDf3qAdjoMmDcLG5A83W6oUUFJgUd0EYBc2P5xqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^3.0.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/ui": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-3.0.5.tgz", + "integrity": "sha512-gw2noso6WI+2PeMVCZFntdATS6xl9qhQcbhkPQ9sOmx/Xn0f4Bx4KDSbD90jpJPF0l5wOzSoGCmKyVR3W612mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "3.0.5", + "fflate": "^0.8.2", + "flatted": "^3.3.2", + "pathe": "^2.0.2", + "sirv": "^3.0.0", + "tinyglobby": "^0.2.10", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "vitest": "3.0.5" + } + }, + "node_modules/@vitest/ui/node_modules/pathe": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.2.tgz", + "integrity": "sha512-15Ztpk+nov8DR524R4BF7uEuzESgzUEAV4Ah7CUMNGXdE5ELuvxElxGXndBl32vMSsWa1jpNf22Z+Er3sKwq+w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@vitest/utils": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.0.5.tgz", + "integrity": "sha512-N9AX0NUoUtVwKwy21JtwzaqR5L5R5A99GAbrHfCCXK1lp593i/3AZAXhSP43wRQuxYsflrdzEfXZFo1reR1Nkg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "3.0.5", + "loupe": "^3.1.2", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@wdio/appium-service": { + "version": "9.11.0", + "resolved": "https://registry.npmjs.org/@wdio/appium-service/-/appium-service-9.11.0.tgz", + "integrity": "sha512-L5e2pNAQ/lTgzc96uX7LWs0PCZFE16Afp2sax8ZyzquE4iuBrPzGYY1D7+t/kQT+JHXncxWT3Q/LySMmDg4vBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@wdio/config": "9.11.0", + "@wdio/logger": "9.4.4", + "@wdio/types": "9.10.1", + "@wdio/utils": "9.11.0", + "change-case": "^5.4.3", + "get-port": "^7.0.0", + "import-meta-resolve": "^4.0.0", + "tree-kill": "^1.2.2", + "webdriverio": "9.11.0" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/@wdio/cli": { + "version": "9.11.0", + "resolved": "https://registry.npmjs.org/@wdio/cli/-/cli-9.11.0.tgz", + "integrity": "sha512-KaJMt69P8lxe9yaCcp9XdYL3TY/wt6vZYbnqg1miwVVjtThLTANKeG7fgplYMheMgTe1s5JDi+CDe141gM5y2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "^20.1.1", + "@vitest/snapshot": "^2.1.1", + "@wdio/config": "9.11.0", + "@wdio/globals": "9.11.0", + "@wdio/logger": "9.4.4", + "@wdio/protocols": "9.7.0", + "@wdio/types": "9.10.1", + "@wdio/utils": "9.11.0", + "async-exit-hook": "^2.0.1", + "chalk": "^5.2.0", + "chokidar": "^4.0.0", + "dotenv": "^16.3.1", + "ejs": "^3.1.9", + "execa": "^9.2.0", + "import-meta-resolve": "^4.0.0", + "inquirer": "^11.0.1", + "lodash.flattendeep": "^4.4.0", + "lodash.pickby": "^4.6.0", + "lodash.union": "^4.6.0", + "read-pkg-up": "^10.0.0", + "recursive-readdir": "^2.2.3", + "tsx": "^4.7.2", + "webdriverio": "9.11.0", + "yargs": "^17.7.2" + }, + "bin": { + "wdio": "bin/wdio.js" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/@wdio/cli/node_modules/@sindresorhus/merge-streams": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", + "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@wdio/cli/node_modules/@types/node": { + "version": "20.17.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.24.tgz", + "integrity": "sha512-d7fGCyB96w9BnWQrOsJtpyiSaBcAYYr75bnK6ZRjDbql2cGLj/3GsL5OYmLPNq76l7Gf2q4Rv9J2o6h5CrD9sA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/@wdio/cli/node_modules/@vitest/pretty-format": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.9.tgz", + "integrity": "sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@wdio/cli/node_modules/@vitest/snapshot": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.9.tgz", + "integrity": "sha512-oBO82rEjsxLNJincVhLhaxxZdEtV0EFHMK5Kmx5sJ6H9L183dHECjiefOAdnqpIgT5eZwT04PoggUnW88vOBNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "2.1.9", + "magic-string": "^0.30.12", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@wdio/cli/node_modules/chalk": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@wdio/cli/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@wdio/cli/node_modules/execa": { + "version": "9.5.2", + "resolved": "https://registry.npmjs.org/execa/-/execa-9.5.2.tgz", + "integrity": "sha512-EHlpxMCpHWSAh1dgS6bVeoLAXGnJNdR93aabr4QCGbzOM73o5XmRfM/e5FUqsw3aagP8S8XEWUWFAxnRBnAF0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/merge-streams": "^4.0.0", + "cross-spawn": "^7.0.3", + "figures": "^6.1.0", + "get-stream": "^9.0.0", + "human-signals": "^8.0.0", + "is-plain-obj": "^4.1.0", + "is-stream": "^4.0.1", + "npm-run-path": "^6.0.0", + "pretty-ms": "^9.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^4.0.0", + "yoctocolors": "^2.0.0" + }, + "engines": { + "node": "^18.19.0 || >=20.5.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/@wdio/cli/node_modules/figures": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz", + "integrity": "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-unicode-supported": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@wdio/cli/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==", + "dev": true, + "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/@wdio/cli/node_modules/human-signals": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.0.tgz", + "integrity": "sha512-/1/GPCpDUCCYwlERiYjxoczfP0zfvZMU/OWgQPMya9AbAE24vseigFdhAMObpc8Q4lc/kjutPfUddDYyAmejnA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@wdio/cli/node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@wdio/cli/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@wdio/cli/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@wdio/cli/node_modules/npm-run-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz", + "integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^4.0.0", + "unicorn-magic": "^0.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@wdio/cli/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@wdio/cli/node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@wdio/cli/node_modules/strip-final-newline": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz", + "integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@wdio/cli/node_modules/tinyrainbow": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", + "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@wdio/cli/node_modules/unicorn-magic": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", + "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@wdio/config": { + "version": "9.11.0", + "resolved": "https://registry.npmjs.org/@wdio/config/-/config-9.11.0.tgz", + "integrity": "sha512-lBcmd7r+3nHJwIWDZ/cLIXcIL9rCmQmMvMWQ+Ykcrlc2khePX92VZyd0igptrZATJGD3tQ7VySR5Bozz6uMzyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@wdio/logger": "9.4.4", + "@wdio/types": "9.10.1", + "@wdio/utils": "9.11.0", + "deepmerge-ts": "^7.0.3", + "glob": "^10.2.2", + "import-meta-resolve": "^4.0.0" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/@wdio/config/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "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/@wdio/dot-reporter": { + "version": "9.11.0", + "resolved": "https://registry.npmjs.org/@wdio/dot-reporter/-/dot-reporter-9.11.0.tgz", + "integrity": "sha512-qNq/cVjgMK+C4W8MKn/e8Jq/v20INPccIEhwpUNqTsR6mvThmI/AHFEsjVtWzTDcGIW7eSZbqpRrAZjflRdjUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@wdio/reporter": "9.11.0", + "@wdio/types": "9.10.1", + "chalk": "^5.0.1" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/@wdio/dot-reporter/node_modules/chalk": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@wdio/globals": { + "version": "9.11.0", + "resolved": "https://registry.npmjs.org/@wdio/globals/-/globals-9.11.0.tgz", + "integrity": "sha512-U0eSp9NcDjMIdEQuM5rUXlZdf4qA/qZAin9cUq3uRdjTz1dZxD/0kXhzctsjpVXj/Fp60UfLF38XwLLgYNoi6w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.20.0" + }, + "optionalDependencies": { + "expect-webdriverio": "^5.1.0", + "webdriverio": "9.11.0" + } + }, + "node_modules/@wdio/local-runner": { + "version": "9.11.0", + "resolved": "https://registry.npmjs.org/@wdio/local-runner/-/local-runner-9.11.0.tgz", + "integrity": "sha512-2w7p3I4xgj9uo7yuaWrY1O1yfSdLn+jva8msKF8PrDoQN+ShmfmK/tSOeJbyQds8aFxzDMYJ7IvH+ibbYBg3/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "^20.1.0", + "@wdio/logger": "9.4.4", + "@wdio/repl": "9.4.4", + "@wdio/runner": "9.11.0", + "@wdio/types": "9.10.1", + "async-exit-hook": "^2.0.1", + "split2": "^4.1.0", + "stream-buffers": "^3.0.2" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/@wdio/local-runner/node_modules/@types/node": { + "version": "20.17.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.24.tgz", + "integrity": "sha512-d7fGCyB96w9BnWQrOsJtpyiSaBcAYYr75bnK6ZRjDbql2cGLj/3GsL5OYmLPNq76l7Gf2q4Rv9J2o6h5CrD9sA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/@wdio/logger": { + "version": "9.4.4", + "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-9.4.4.tgz", + "integrity": "sha512-BXx8RXFUW2M4dcO6t5Le95Hi2ZkTQBRsvBQqLekT2rZ6Xmw8ZKZBPf0FptnoftFGg6dYmwnDidYv/0+4PiHjpQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^5.1.2", + "loglevel": "^1.6.0", + "loglevel-plugin-prefix": "^0.8.4", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/@wdio/logger/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@wdio/logger/node_modules/chalk": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@wdio/logger/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@wdio/mocha-framework": { + "version": "9.11.0", + "resolved": "https://registry.npmjs.org/@wdio/mocha-framework/-/mocha-framework-9.11.0.tgz", + "integrity": "sha512-b7Zg1v67dznpI7eyGDGdDEzdQb9GS37ccs91UOd7uHkkP6ktGRhGsSaOZKZCbvvWQK+jWsU2Tvs6kuaWGQQnQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mocha": "^10.0.6", + "@types/node": "^20.11.28", + "@wdio/logger": "9.4.4", + "@wdio/types": "9.10.1", + "@wdio/utils": "9.11.0", + "mocha": "^10.3.0" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/@wdio/mocha-framework/node_modules/@types/node": { + "version": "20.17.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.24.tgz", + "integrity": "sha512-d7fGCyB96w9BnWQrOsJtpyiSaBcAYYr75bnK6ZRjDbql2cGLj/3GsL5OYmLPNq76l7Gf2q4Rv9J2o6h5CrD9sA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/@wdio/protocols": { + "version": "9.7.0", + "resolved": "https://registry.npmjs.org/@wdio/protocols/-/protocols-9.7.0.tgz", + "integrity": "sha512-5DI8cqJqT9K6oQn8UpaSTmcGAl4ufkUWC5FoPT3oXdLjILfxvweZDf/2XNBCbGMk4+VOMKqB2ofOqKhDIB2nAg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@wdio/repl": { + "version": "9.4.4", + "resolved": "https://registry.npmjs.org/@wdio/repl/-/repl-9.4.4.tgz", + "integrity": "sha512-kchPRhoG/pCn4KhHGiL/ocNhdpR8OkD2e6sANlSUZ4TGBVi86YSIEjc2yXUwLacHknC/EnQk/SFnqd4MsNjGGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "^20.1.0" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/@wdio/repl/node_modules/@types/node": { + "version": "20.17.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.24.tgz", + "integrity": "sha512-d7fGCyB96w9BnWQrOsJtpyiSaBcAYYr75bnK6ZRjDbql2cGLj/3GsL5OYmLPNq76l7Gf2q4Rv9J2o6h5CrD9sA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/@wdio/reporter": { + "version": "9.11.0", + "resolved": "https://registry.npmjs.org/@wdio/reporter/-/reporter-9.11.0.tgz", + "integrity": "sha512-YTUlrTsJU2XT5olFOk+tsYm6DcUwmowk0us1gt5Me2zFI3UdUQpuUMfPEqFtayRsfcHwSaPGLKR7Eng+r3uXGQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "^20.1.0", + "@wdio/logger": "9.4.4", + "@wdio/types": "9.10.1", + "diff": "^7.0.0", + "object-inspect": "^1.12.0" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/@wdio/reporter/node_modules/@types/node": { + "version": "20.17.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.24.tgz", + "integrity": "sha512-d7fGCyB96w9BnWQrOsJtpyiSaBcAYYr75bnK6ZRjDbql2cGLj/3GsL5OYmLPNq76l7Gf2q4Rv9J2o6h5CrD9sA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/@wdio/reporter/node_modules/diff": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz", + "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/@wdio/runner": { + "version": "9.11.0", + "resolved": "https://registry.npmjs.org/@wdio/runner/-/runner-9.11.0.tgz", + "integrity": "sha512-74U+9+sJba7fDofVNt6+WhmMHij1Bs0hELwjn9ZhzfopaOpUr3LBuCQonpNP+mpn8Is7De+bAdHruhHfB3kX+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "^20.11.28", + "@wdio/config": "9.11.0", + "@wdio/dot-reporter": "9.11.0", + "@wdio/globals": "9.11.0", + "@wdio/logger": "9.4.4", + "@wdio/types": "9.10.1", + "@wdio/utils": "9.11.0", + "deepmerge-ts": "^7.0.3", + "expect-webdriverio": "^5.1.0", + "webdriver": "9.11.0", + "webdriverio": "9.11.0" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/@wdio/runner/node_modules/@types/node": { + "version": "20.17.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.24.tgz", + "integrity": "sha512-d7fGCyB96w9BnWQrOsJtpyiSaBcAYYr75bnK6ZRjDbql2cGLj/3GsL5OYmLPNq76l7Gf2q4Rv9J2o6h5CrD9sA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/@wdio/spec-reporter": { + "version": "9.11.0", + "resolved": "https://registry.npmjs.org/@wdio/spec-reporter/-/spec-reporter-9.11.0.tgz", + "integrity": "sha512-S8pd2hm8zWbE2yiAZqpDSgZ0gRnZRwV4xWAKO/dhHgAYWzHamQ1Hk7P0Sp1sQA/Pu+gyRId3uJ+WDiWVos8ftA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@wdio/reporter": "9.11.0", + "@wdio/types": "9.10.1", + "chalk": "^5.1.2", + "easy-table": "^1.2.0", + "pretty-ms": "^9.0.0" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/@wdio/spec-reporter/node_modules/chalk": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@wdio/types": { + "version": "9.10.1", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-9.10.1.tgz", + "integrity": "sha512-/t1VXPU5Ad1FQjRUP0WlK7IR0dCTX5hSkul8SpCuUpWbeyI4Iol/Wx2b1YU6nS+Ydh78rJCyHxtV0eE5TM1rbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "^20.1.0" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/@wdio/types/node_modules/@types/node": { + "version": "20.17.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.24.tgz", + "integrity": "sha512-d7fGCyB96w9BnWQrOsJtpyiSaBcAYYr75bnK6ZRjDbql2cGLj/3GsL5OYmLPNq76l7Gf2q4Rv9J2o6h5CrD9sA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/@wdio/utils": { + "version": "9.11.0", + "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-9.11.0.tgz", + "integrity": "sha512-chVbHqrjDlIKCLoAPLdrFK8Qozu/S+fbubqlyazohAKnouCUCa2goYs7faYR0lkmLqm92PllJS+KBRAha9V/tg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@puppeteer/browsers": "^2.2.0", + "@wdio/logger": "9.4.4", + "@wdio/types": "9.10.1", + "decamelize": "^6.0.0", + "deepmerge-ts": "^7.0.3", + "edgedriver": "^6.1.1", + "geckodriver": "^5.0.0", + "get-port": "^7.0.0", + "import-meta-resolve": "^4.0.0", + "locate-app": "^2.2.24", + "safaridriver": "^1.0.0", + "split2": "^4.2.0", + "wait-port": "^1.1.0" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/@wdio/utils/node_modules/decamelize": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-6.0.0.tgz", + "integrity": "sha512-Fv96DCsdOgB6mdGl67MT5JaTNKRzrzill5OH5s8bjYJXVlcXyPYGyPsUkWyGV5p1TXI5esYIYMMeDJL0hEIwaA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", + "dev": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", + "dev": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", + "dev": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", + "dev": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", + "dev": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xmldom/xmldom": { + "version": "0.8.10", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", + "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "node_modules/@yarnpkg/lockfile": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", + "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", + "dev": true + }, + "node_modules/@yarnpkg/parsers": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@yarnpkg/parsers/-/parsers-3.0.2.tgz", + "integrity": "sha512-/HcYgtUSiJiot/XWGLOlGxPYUG65+/31V8oqk17vZLW1xlCoR4PampyePljOxY2n8/3jz9+tIFzICsyGujJZoA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "js-yaml": "^3.10.0", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=18.12.0" + } + }, + "node_modules/@yarnpkg/parsers/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@yarnpkg/parsers/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@yarnpkg/parsers/node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@zip.js/zip.js": { + "version": "2.7.57", + "resolved": "https://registry.npmjs.org/@zip.js/zip.js/-/zip.js-2.7.57.tgz", + "integrity": "sha512-BtonQ1/jDnGiMed6OkV6rZYW78gLmLswkHOzyMrMb+CAR7CZO8phOHO6c2qw6qb1g1betN7kwEHhhZk30dv+NA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "bun": ">=0.7.0", + "deno": ">=1.0.0", + "node": ">=16.5.0" + } + }, + "node_modules/@zkochan/js-yaml": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/@zkochan/js-yaml/-/js-yaml-0.0.7.tgz", + "integrity": "sha512-nrUSn7hzt7J6JWgWGz78ZYI8wj+gdIJdk0Ynjpp8l+trkn58Uqsf6RYrYkEK+3X18EX+TNdtJI0WxAtc+L84SQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "deprecated": "Use your platform's native atob() and btoa() methods instead", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/abbrev": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-3.0.0.tgz", + "integrity": "sha512-+/kfrslGQ7TNV2ecmQwMJj/B65g5KVq1/L3SGVZ3tCYGqlzFuFCGBZJtMP99wH3NpEUyAjn0zPdPUg0D+DwrOA==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "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==", + "dev": true, + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/address": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", + "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/adjust-sourcemap-loader": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz", + "integrity": "sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==", + "dev": true, + "dependencies": { + "loader-utils": "^2.0.0", + "regex-parser": "^2.2.11" + }, + "engines": { + "node": ">=8.9" + } + }, + "node_modules/adjust-sourcemap-loader/node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/adm-zip": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.16.tgz", + "integrity": "sha512-TGw5yVi4saajsSEgz25grObGHEUaDrniwvA2qwSC060KfqGPdglhvPMA2lPIoxs3PQIItj2iag35fONcQqgUaQ==", + "dev": true, + "engines": { + "node": ">=12.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", + "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", + "engines": { + "node": ">= 14" + } + }, + "node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", + "dev": true, + "engines": [ + "node >= 0.8.0" + ], + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "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==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/app-root-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.1.0.tgz", + "integrity": "sha512-biN3PwB2gUtjaYy/isrU3aNWI5w+fAfvHkSvCKeQGxhmYpwKFUxudR3Yya+KqVRHBmEDYh+/lTozYCFbmzX4nA==", + "dev": true, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/appium": { + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/appium/-/appium-2.16.2.tgz", + "integrity": "sha512-Vxhm4SqhbidJApU8iDsNaxJtuvxnIyJcglaXAJqcoLP/uKeDTY3Im1vYcDd8vb5ZJkjt3+gvXh+6SyUyM/Cmtw==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@appium/base-driver": "^9.16.2", + "@appium/base-plugin": "^2.3.3", + "@appium/docutils": "^1.0.32", + "@appium/logger": "^1.6.1", + "@appium/schema": "^0.8.1", + "@appium/support": "^6.0.6", + "@appium/types": "^0.25.1", + "@sidvind/better-ajv-errors": "3.0.1", + "ajv": "8.17.1", + "ajv-formats": "3.0.1", + "argparse": "2.0.1", + "async-lock": "1.4.1", + "asyncbox": "3.0.0", + "axios": "1.7.9", + "bluebird": "3.7.2", + "lilconfig": "3.1.3", + "lodash": "4.17.21", + "lru-cache": "10.4.3", + "ora": "5.4.1", + "package-changed": "3.0.0", + "resolve-from": "5.0.0", + "semver": "7.7.1", + "source-map-support": "0.5.21", + "teen_process": "2.2.3", + "type-fest": "4.35.0", + "winston": "3.17.0", + "wrap-ansi": "7.0.0", + "ws": "8.18.0", + "yaml": "2.7.0" + }, + "bin": { + "appium": "index.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0", + "npm": ">=8" + } + }, + "node_modules/appium-uiautomator2-driver": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/appium-uiautomator2-driver/-/appium-uiautomator2-driver-4.1.1.tgz", + "integrity": "sha512-KoFyivgRlbL+BhPdHVBvJE6dpvScruVEcYdhdzDf/CUsPyb5Ugjd8n3oCEkAHn9Cou+dxnZWPE4wJQz+AVpIiw==", + "dev": true, + "hasShrinkwrap": true, + "license": "Apache-2.0", + "dependencies": { + "appium-adb": "^12.12.0", + "appium-android-driver": "^10.2.1", + "appium-uiautomator2-server": "^7.2.0", + "asyncbox": "^3.0.0", + "axios": "^1.6.5", + "bluebird": "^3.5.1", + "css-selector-parser": "^3.0.0", + "io.appium.settings": "^5.14.3", + "lodash": "^4.17.4", + "portscanner": "^2.2.0", + "source-map-support": "^0.x", + "teen_process": "^2.2.0", + "type-fest": "^4.4.0" + }, + "engines": { + "node": ">=14", + "npm": ">=8" + }, + "peerDependencies": { + "appium": "^2.4.1 || ^3.0.0-beta.0" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/@appium/base-driver": { + "version": "9.16.2", + "resolved": "https://registry.npmjs.org/@appium/base-driver/-/base-driver-9.16.2.tgz", + "integrity": "sha512-vuQf9XQKGAMl5d5pM63FOrnRJUSVjw6J5kPXApfnkTJovwyV9SViYptnCB/TcahjX2bHQ+fUka82MWzHKPzpHg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@appium/support": "^6.0.6", + "@appium/types": "^0.25.1", + "@colors/colors": "1.6.0", + "async-lock": "1.4.1", + "asyncbox": "3.0.0", + "axios": "1.7.9", + "bluebird": "3.7.2", + "body-parser": "1.20.3", + "express": "4.21.2", + "fastest-levenshtein": "1.0.16", + "http-status-codes": "2.3.0", + "lodash": "4.17.21", + "lru-cache": "10.4.3", + "method-override": "3.0.0", + "morgan": "1.10.0", + "path-to-regexp": "8.2.0", + "serve-favicon": "2.5.0", + "source-map-support": "0.5.21", + "type-fest": "4.35.0", + "validate.js": "0.13.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0", + "npm": ">=8" + }, + "optionalDependencies": { + "spdy": "4.0.2" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/@appium/base-driver/node_modules/axios": { + "version": "1.7.9", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz", + "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==", + "dev": true, + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/@appium/base-driver/node_modules/type-fest": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.35.0.tgz", + "integrity": "sha512-2/AwEFQDFEy30iOLjrvHDIH7e4HEWH+f1Yl1bI5XMqzuoCUqwYCdxachgsgv0og/JdVZUhbfjcJAoHj5L1753A==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/@appium/base-plugin": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/@appium/base-plugin/-/base-plugin-2.3.3.tgz", + "integrity": "sha512-wPGgTfG02O2HzCcUWbEuN4fjjs/zoA3Il/tcbaT6rnZYAbOAW2uC4B6l+eqisFRLepj1p8djf0XQyPAVyeIZzw==", + "extraneous": true, + "license": "Apache-2.0", + "dependencies": { + "@appium/base-driver": "^9.16.2", + "@appium/support": "^6.0.6" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0", + "npm": ">=8" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/@appium/docutils": { + "version": "1.0.32", + "resolved": "https://registry.npmjs.org/@appium/docutils/-/docutils-1.0.32.tgz", + "integrity": "sha512-8kGYxaasCQYlYZrOD++hIPvKMgFuxjvtcATSL2bszRZvzWq6cXmVUS4guym/RzXtlAYq6NrTqshY8x5xKcSi3w==", + "extraneous": true, + "license": "Apache-2.0", + "dependencies": { + "@appium/support": "^6.0.6", + "@appium/tsconfig": "^0.3.4", + "@sliphua/lilconfig-ts-loader": "3.2.2", + "chalk": "4.1.2", + "consola": "3.4.0", + "diff": "7.0.0", + "json5": "2.2.3", + "lilconfig": "3.1.3", + "lodash": "4.17.21", + "pkg-dir": "5.0.0", + "read-pkg": "5.2.0", + "semver": "7.7.1", + "source-map-support": "0.5.21", + "teen_process": "2.2.3", + "type-fest": "4.35.0", + "typescript": "5.7.3", + "yaml": "2.7.0", + "yargs": "17.7.2", + "yargs-parser": "21.1.1" + }, + "bin": { + "appium-docs": "bin/appium-docs.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0", + "npm": ">=8" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/@appium/docutils/node_modules/teen_process": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/teen_process/-/teen_process-2.2.3.tgz", + "integrity": "sha512-8L540OalWH83qc6LHV5VMr0DjdP7KWUHQwTOImtWaG2ElW8BvLTh6M9871oGmmpOMb2BpOJQn2+09ZHWYsdTUA==", + "extraneous": true, + "license": "Apache-2.0", + "dependencies": { + "bluebird": "^3.7.2", + "lodash": "^4.17.21", + "shell-quote": "^1.8.1", + "source-map-support": "^0.x" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0", + "npm": ">=8" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/@appium/docutils/node_modules/type-fest": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.35.0.tgz", + "integrity": "sha512-2/AwEFQDFEy30iOLjrvHDIH7e4HEWH+f1Yl1bI5XMqzuoCUqwYCdxachgsgv0og/JdVZUhbfjcJAoHj5L1753A==", + "extraneous": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/@appium/docutils/node_modules/typescript": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", + "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", + "extraneous": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/@appium/logger": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@appium/logger/-/logger-1.6.1.tgz", + "integrity": "sha512-3TWpLR1qVQ0usLJ6R49iN4TV9Zs0nog1oL3hakCglwP0g4ZllwwEbp+2b1ovJfX6oOv1wXNREyokq2uxU5gB/Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "console-control-strings": "1.1.0", + "lodash": "4.17.21", + "lru-cache": "10.4.3", + "set-blocking": "2.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0", + "npm": ">=8" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/@appium/schema": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@appium/schema/-/schema-0.8.1.tgz", + "integrity": "sha512-3yzfQ/K7RMGnfYDgFG7JdCPsjjN3eS33n2SBeGJtd28mDtgO7EzcmtiUBQjbkxyu0Q7h8KOexiqndvgTCgHeGQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "json-schema": "0.4.0", + "source-map-support": "0.5.21" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0", + "npm": ">=8" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/@appium/support": { + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/@appium/support/-/support-6.0.6.tgz", + "integrity": "sha512-qgj1uxHF7Suqi8wdWFBrG12dhLMAthpX973L7JHutM2jneynoIUaKtSXdd6zg0ZG/9clfY0C/06pIQTQljj+Lg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@appium/logger": "^1.6.1", + "@appium/tsconfig": "^0.3.4", + "@appium/types": "^0.25.1", + "@colors/colors": "1.6.0", + "archiver": "7.0.1", + "axios": "1.7.9", + "base64-stream": "1.0.0", + "bluebird": "3.7.2", + "bplist-creator": "0.1.1", + "bplist-parser": "0.3.2", + "form-data": "4.0.2", + "get-stream": "6.0.1", + "glob": "10.4.5", + "jsftp": "2.1.3", + "klaw": "4.1.0", + "lockfile": "1.0.4", + "lodash": "4.17.21", + "log-symbols": "4.1.0", + "moment": "2.30.1", + "mv": "2.1.1", + "ncp": "2.0.0", + "pkg-dir": "5.0.0", + "plist": "3.1.0", + "pluralize": "8.0.0", + "read-pkg": "5.2.0", + "resolve-from": "5.0.0", + "sanitize-filename": "1.6.3", + "semver": "7.7.1", + "shell-quote": "1.8.2", + "source-map-support": "0.5.21", + "supports-color": "8.1.1", + "teen_process": "2.2.3", + "type-fest": "4.35.0", + "uuid": "11.1.0", + "which": "4.0.0", + "yauzl": "3.2.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0", + "npm": ">=8" + }, + "optionalDependencies": { + "sharp": "0.33.5" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/@appium/support/node_modules/axios": { + "version": "1.7.9", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz", + "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==", + "dev": true, + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/@appium/support/node_modules/teen_process": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/teen_process/-/teen_process-2.2.3.tgz", + "integrity": "sha512-8L540OalWH83qc6LHV5VMr0DjdP7KWUHQwTOImtWaG2ElW8BvLTh6M9871oGmmpOMb2BpOJQn2+09ZHWYsdTUA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "bluebird": "^3.7.2", + "lodash": "^4.17.21", + "shell-quote": "^1.8.1", + "source-map-support": "^0.x" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0", + "npm": ">=8" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/@appium/support/node_modules/type-fest": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.35.0.tgz", + "integrity": "sha512-2/AwEFQDFEy30iOLjrvHDIH7e4HEWH+f1Yl1bI5XMqzuoCUqwYCdxachgsgv0og/JdVZUhbfjcJAoHj5L1753A==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/@appium/tsconfig": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@appium/tsconfig/-/tsconfig-0.3.4.tgz", + "integrity": "sha512-tX719/ekarAWmJb+AaG6//8+3qQITshTgTZor0EbdEwA2KG3bGPwMIoCp10np6/qFr+sMZC0CbuKJruHSCDhhw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@tsconfig/node14": "14.1.2" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0", + "npm": ">=8" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/@appium/types": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@appium/types/-/types-0.25.1.tgz", + "integrity": "sha512-2Lu5qwFNQa+iPw98XdB5/7tXKO7dugZHXfAsF050wgJkJJ4kDemVFJ4yr1YqM7DYmgqZnt+k0EfzshLODCHXTA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@appium/logger": "^1.6.1", + "@appium/schema": "^0.8.1", + "@appium/tsconfig": "^0.3.4", + "type-fest": "4.35.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0", + "npm": ">=8" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/@appium/types/node_modules/type-fest": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.35.0.tgz", + "integrity": "sha512-2/AwEFQDFEy30iOLjrvHDIH7e4HEWH+f1Yl1bI5XMqzuoCUqwYCdxachgsgv0og/JdVZUhbfjcJAoHj5L1753A==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/@babel/code-frame": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/@dabh/diagnostics": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", + "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", + "extraneous": true, + "license": "MIT", + "dependencies": { + "colorspace": "1.1.x", + "enabled": "2.0.x", + "kuler": "^2.0.0" + } + }, + "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==", + "dev": true, + "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.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "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/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/@sidvind/better-ajv-errors": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sidvind/better-ajv-errors/-/better-ajv-errors-3.0.1.tgz", + "integrity": "sha512-++1mEYIeozfnwWI9P1ECvOPoacy+CgDASrmGvXPMCcqgx0YUzB01vZ78uHdQ443V6sTY+e9MzHqmN9DOls02aw==", + "extraneous": true, + "license": "Apache-2.0", + "dependencies": { + "kleur": "^4.1.0" + }, + "engines": { + "node": ">= 16.14" + }, + "peerDependencies": { + "ajv": "^6.12.3 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/@sliphua/lilconfig-ts-loader": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@sliphua/lilconfig-ts-loader/-/lilconfig-ts-loader-3.2.2.tgz", + "integrity": "sha512-nX2aBwAykiG50fSUzK9eyA5UvWcrEKzA0ZzCq9mLwHMwpKxM+U05YH8PHba1LJrbeZ7R1HSjJagWKMqFyq8cxw==", + "extraneous": true, + "license": "MIT", + "dependencies": { + "lodash.get": "^4", + "make-error": "^1", + "ts-node": "^9", + "tslib": "^2" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "lilconfig": ">=2" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/@sliphua/lilconfig-ts-loader/node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "extraneous": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/@sliphua/lilconfig-ts-loader/node_modules/ts-node": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz", + "integrity": "sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==", + "extraneous": true, + "license": "MIT", + "dependencies": { + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.17", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "typescript": ">=2.7" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/@tsconfig/node14": { + "version": "14.1.2", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-14.1.2.tgz", + "integrity": "sha512-1vncsbfCZ3TBLPxesRYz02Rn7SNJfbLoDVkcZ7F/ixOV6nwxwgdhD1mdPcc5YQ413qBJ8CvMxXMFfJ7oawjo7Q==", + "dev": true, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/appium-uiautomator2-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==", + "extraneous": true, + "license": "MIT" + }, + "node_modules/appium-uiautomator2-driver/node_modules/@xmldom/xmldom": { + "version": "0.9.8", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.9.8.tgz", + "integrity": "sha512-p96FSY54r+WJ50FIOsCOjyj/wavs8921hG5+kVMmZgKcvIKxMXHTrjNJvRgWa/zuX3B6t2lijLNFaOyuxUH+2A==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "extraneous": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "extraneous": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "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==", + "dev": true, + "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": { + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/appium/-/appium-2.16.2.tgz", + "integrity": "sha512-Vxhm4SqhbidJApU8iDsNaxJtuvxnIyJcglaXAJqcoLP/uKeDTY3Im1vYcDd8vb5ZJkjt3+gvXh+6SyUyM/Cmtw==", + "extraneous": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@appium/base-driver": "^9.16.2", + "@appium/base-plugin": "^2.3.3", + "@appium/docutils": "^1.0.32", + "@appium/logger": "^1.6.1", + "@appium/schema": "^0.8.1", + "@appium/support": "^6.0.6", + "@appium/types": "^0.25.1", + "@sidvind/better-ajv-errors": "3.0.1", + "ajv": "8.17.1", + "ajv-formats": "3.0.1", + "argparse": "2.0.1", + "async-lock": "1.4.1", + "asyncbox": "3.0.0", + "axios": "1.7.9", + "bluebird": "3.7.2", + "lilconfig": "3.1.3", + "lodash": "4.17.21", + "lru-cache": "10.4.3", + "ora": "5.4.1", + "package-changed": "3.0.0", + "resolve-from": "5.0.0", + "semver": "7.7.1", + "source-map-support": "0.5.21", + "teen_process": "2.2.3", + "type-fest": "4.35.0", + "winston": "3.17.0", + "wrap-ansi": "7.0.0", + "ws": "8.18.0", + "yaml": "2.7.0" + }, + "bin": { + "appium": "index.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0", + "npm": ">=8" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/appium-adb": { + "version": "12.12.1", + "resolved": "https://registry.npmjs.org/appium-adb/-/appium-adb-12.12.1.tgz", + "integrity": "sha512-CgdvLBBtLkZeObJegsCQo2eUTzuHESkeewbfWROFNtrVmxKS30J9y9YV4h5WIYJbyhgQCJeX+yDa+1gO/ejFjA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@appium/support": "^6.0.0", + "async-lock": "^1.0.0", + "asyncbox": "^3.0.0", + "bluebird": "^3.4.7", + "ini": "^5.0.0", + "lodash": "^4.0.0", + "lru-cache": "^10.0.0", + "semver": "^7.0.0", + "source-map-support": "^0.x", + "teen_process": "^2.2.0" + }, + "engines": { + "node": ">=14", + "npm": ">=8" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/appium-android-driver": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/appium-android-driver/-/appium-android-driver-10.2.1.tgz", + "integrity": "sha512-zRi8tSTvaqh8r14eD8doC/NlGQNdcwXEbMwWhInBGonhbn7HPBgtp9iSFXfStfB0PTJsJnyItuTJDC3iXwoDxw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@appium/support": "^6.0.0", + "@colors/colors": "^1.6.0", + "appium-adb": "^12.12.0", + "appium-chromedriver": "^7.0.6", + "asyncbox": "^3.0.0", + "axios": "^1.x", + "bluebird": "^3.4.7", + "io.appium.settings": "^5.14.3", + "lodash": "^4.17.4", + "lru-cache": "^10.0.1", + "moment": "^2.24.0", + "moment-timezone": "^0.x", + "portscanner": "^2.2.0", + "semver": "^7.0.0", + "source-map-support": "^0.x", + "teen_process": "^2.0.0", + "type-fest": "^4.4.0", + "ws": "^8.0.0" + }, + "engines": { + "node": ">=14", + "npm": ">=8" + }, + "peerDependencies": { + "appium": "^2.0.0" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/appium-chromedriver": { + "version": "7.0.8", + "resolved": "https://registry.npmjs.org/appium-chromedriver/-/appium-chromedriver-7.0.8.tgz", + "integrity": "sha512-X2MfK/xMVoUHFuQHSTuJaEF/ZGmP0tGc/5P6AzCYWdmOUmloxEXTeq+jkodh6/5MAanOcnnI3bhBpqGvwCjqjQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@appium/base-driver": "^9.1.0", + "@appium/support": "^6.0.0", + "@xmldom/xmldom": "^0.x", + "appium-adb": "^12.0.0", + "asyncbox": "^3.0.0", + "axios": "^1.6.5", + "bluebird": "^3.5.1", + "compare-versions": "^6.0.0", + "lodash": "^4.17.4", + "semver": "^7.0.0", + "source-map-support": "^0.x", + "teen_process": "^2.2.0", + "xpath": "^0.x" + }, + "engines": { + "node": ">=14", + "npm": ">=8" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/appium-uiautomator2-server": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/appium-uiautomator2-server/-/appium-uiautomator2-server-7.2.5.tgz", + "integrity": "sha512-Q4h7U4QOYfWL5IdYW4WNUveg7j/wjmJLFtfahgiZmKcAapCLqmwu9WFJmvGsThlsn3nj6yt7QVhOh/wa4/01Bg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=14", + "npm": ">=8" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/appium/node_modules/axios": { + "version": "1.7.9", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz", + "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==", + "extraneous": true, + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/appium/node_modules/teen_process": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/teen_process/-/teen_process-2.2.3.tgz", + "integrity": "sha512-8L540OalWH83qc6LHV5VMr0DjdP7KWUHQwTOImtWaG2ElW8BvLTh6M9871oGmmpOMb2BpOJQn2+09ZHWYsdTUA==", + "extraneous": true, + "license": "Apache-2.0", + "dependencies": { + "bluebird": "^3.7.2", + "lodash": "^4.17.21", + "shell-quote": "^1.8.1", + "source-map-support": "^0.x" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0", + "npm": ">=8" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/appium/node_modules/type-fest": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.35.0.tgz", + "integrity": "sha512-2/AwEFQDFEy30iOLjrvHDIH7e4HEWH+f1Yl1bI5XMqzuoCUqwYCdxachgsgv0og/JdVZUhbfjcJAoHj5L1753A==", + "extraneous": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "extraneous": true, + "license": "MIT" + }, + "node_modules/appium-uiautomator2-driver/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/appium-uiautomator2-driver/node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/appium-uiautomator2-driver/node_modules/asyncbox": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/asyncbox/-/asyncbox-3.0.0.tgz", + "integrity": "sha512-X7U0nedUMKV3nn9c4R0Zgvdvv6cw97tbDlHSZicq1snGPi/oX9DgGmFSURWtxDdnBWd3V0YviKhqAYAVvoWQ/A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "bluebird": "^3.5.1", + "lodash": "^4.17.4", + "source-map-support": "^0.x" + }, + "engines": { + "node": ">=16" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/appium-uiautomator2-driver/node_modules/axios": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.2.tgz", + "integrity": "sha512-ls4GYBm5aig9vWx8AWDSGLpnpDQRtWAfrjU+EuytuODrFBkqesN2RkOQCBzrA1RQNHw1SmRMSDDDSwzNAYQ6Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/b4a": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.7.tgz", + "integrity": "sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==", + "dev": true, + "license": "Apache-2.0" + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/appium-uiautomator2-driver/node_modules/bare-events": { + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.5.4.tgz", + "integrity": "sha512-+gFfDkR8pj4/TrWCGUGWmJIkBwuxPS5F+a5yWjOHQt2hHvNZd5YLzadjmDUtFmMM4y429bnKLa8bYBMHcYdnQA==", + "dev": true, + "license": "Apache-2.0", + "optional": true + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/basic-auth/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==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "license": "Unlicense", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "extraneous": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/bl/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==", + "extraneous": true, + "license": "MIT", + "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/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/appium-uiautomator2-driver/node_modules/body-parser": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "big-integer": "1.6.x" + }, + "engines": { + "node": ">= 5.10.0" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "extraneous": true, + "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.1.13" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": 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/appium-uiautomator2-driver/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "extraneous": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "extraneous": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "extraneous": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/cliui/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==", + "extraneous": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/cliui/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==", + "extraneous": true, + "license": "MIT" + }, + "node_modules/appium-uiautomator2-driver/node_modules/cliui/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==", + "extraneous": true, + "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/cliui/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==", + "extraneous": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "extraneous": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/appium-uiautomator2-driver/node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/colorspace": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", + "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", + "extraneous": true, + "license": "MIT", + "dependencies": { + "color": "^3.1.3", + "text-hex": "1.0.x" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/colorspace/node_modules/color": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", + "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "extraneous": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.3", + "color-string": "^1.6.0" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/colorspace/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "extraneous": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/colorspace/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "extraneous": true, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "extraneous": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/appium-uiautomator2-driver/node_modules/consola": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.0.tgz", + "integrity": "sha512-EiPU8G6dQG0GFHNR8ljnZFki/8a+cQwEQ+7wpxdChl02Q8HXlwEZWD5lqAF8vC2sEC3Tehr8hy7vErz88LHyUA==", + "extraneous": true, + "license": "MIT", + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, + "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==", + "dev": true, + "license": "ISC" + }, + "node_modules/appium-uiautomator2-driver/node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "crc-32": "^1.2.0", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "extraneous": true, + "license": "MIT" + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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.0.5", + "resolved": "https://registry.npmjs.org/css-selector-parser/-/css-selector-parser-3.0.5.tgz", + "integrity": "sha512-3itoDFbKUNx1eKmVpYMFyqKX04Ww9osZ+dLgrk6GEv6KMVeXUhUnp4I5X+evw+u3ZxVU6RFXSSRxlTeMh8bA+g==", + "dev": true, + "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.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "extraneous": true, + "license": "MIT", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/appium-uiautomator2-driver/node_modules/diff": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz", + "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==", + "extraneous": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/appium-uiautomator2-driver/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/appium-uiautomator2-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==", + "extraneous": true, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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/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/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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/express": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.7.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.3.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.12", + "proxy-addr": "~2.0.7", + "qs": "6.13.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.19.0", + "serve-static": "1.16.2", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/appium-uiautomator2-driver/node_modules/express/node_modules/path-to-regexp": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/appium-uiautomator2-driver/node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "extraneous": true, + "license": "MIT" + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/appium-uiautomator2-driver/node_modules/fast-uri": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", + "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "extraneous": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/appium-uiautomator2-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==", + "extraneous": true, + "license": "MIT" + }, + "node_modules/appium-uiautomator2-driver/node_modules/finalhandler": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/appium-uiautomator2-driver/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/appium-uiautomator2-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==", + "extraneous": true, + "license": "MIT" + }, + "node_modules/appium-uiautomator2-driver/node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/form-data": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz", + "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/appium-uiautomator2-driver/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/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==", + "dev": true, + "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==", + "dev": true, + "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": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "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/glob/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/glob/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/appium-uiautomator2-driver/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true, + "license": "ISC" + }, + "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==", + "dev": true, + "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/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT", + "optional": true + }, + "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==", + "dev": true, + "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/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==", + "dev": true, + "license": "MIT", + "optional": true + }, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/appium-uiautomator2-driver/node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/appium-uiautomator2-driver/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "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/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "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==", + "dev": true, + "license": "ISC" + }, + "node_modules/appium-uiautomator2-driver/node_modules/ini": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-5.0.0.tgz", + "integrity": "sha512-+N0ngpO3e7cRUWOJAS7qw0IZIVc6XPrW4MlFBdD066F2L4k1L6ker3hLqSq7iXxU5tgS4WGkIUElWn5vogAEnw==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/io.appium.settings": { + "version": "5.14.4", + "resolved": "https://registry.npmjs.org/io.appium.settings/-/io.appium.settings-5.14.4.tgz", + "integrity": "sha512-6W+sGscwQUtF55ffbSI/1jSoycPD081hQs4bARE3ojGLlOQBPcYVfqUDXyubr0FViqyqk5my/rEHv4mTShOaSQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@appium/logger": "^1.3.0", + "asyncbox": "^3.0.0", + "bluebird": "^3.5.1", + "lodash": "^4.2.1", + "semver": "^7.5.4", + "source-map-support": "^0.x", + "teen_process": "^2.0.0" + }, + "engines": { + "node": ">=14", + "npm": ">=8" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, + "node_modules/appium-uiautomator2-driver/node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "extraneous": true, + "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==", + "dev": true, + "license": "ISC", + "dependencies": { + "lodash.isfinite": "^3.3.2" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "license": "(AFL-2.1 OR BSD-3-Clause)" + }, + "node_modules/appium-uiautomator2-driver/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "extraneous": true, + "license": "MIT" + }, + "node_modules/appium-uiautomator2-driver/node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "extraneous": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.14.0" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "extraneous": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/kuler": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", + "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==", + "extraneous": true, + "license": "MIT" + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "^2.0.5" + }, + "engines": { + "node": ">= 0.6.3" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/lazystream/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "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/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==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "extraneous": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/appium-uiautomator2-driver/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "dev": true, + "license": "ISC", + "dependencies": { + "signal-exit": "^3.0.2" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true, + "license": "MIT" + }, + "node_modules/appium-uiautomator2-driver/node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", + "deprecated": "This package is deprecated. Use the optional chaining (?.) operator instead.", + "extraneous": true, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/appium-uiautomator2-driver/node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/appium-uiautomator2-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==", + "extraneous": true, + "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-uiautomator2-driver/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==", + "dev": true, + "license": "ISC" + }, + "node_modules/appium-uiautomator2-driver/node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "extraneous": true, + "license": "ISC" + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "dev": true, + "license": "MIT", + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/appium-uiautomator2-driver/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/appium-uiautomator2-driver/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/appium-uiautomator2-driver/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/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==", + "dev": true, + "license": "ISC", + "optional": true + }, + "node_modules/appium-uiautomator2-driver/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/moment-timezone": { + "version": "0.5.47", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.47.tgz", + "integrity": "sha512-UbNt/JAWS0m/NJOebR0QMRHBk0hu03r5dx9GK8Cs0AS3I81yDcOc9k+DytPItgVvBP7J6Mf6U2n3BPAacAV9oA==", + "dev": true, + "license": "MIT", + "dependencies": { + "moment": "^2.29.4" + }, + "engines": { + "node": "*" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/morgan": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", + "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "basic-auth": "~2.0.1", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-finished": "~2.3.0", + "on-headers": "~1.0.2" + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/appium-uiautomator2-driver/node_modules/mv": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", + "integrity": "sha512-at/ZndSy3xEGJ8i0ygALh8ru9qy7gWW1cmkaqBN29JmMlIvM//MEO9y1sk/avxuwnPcfhkejkLsuPxH81BrkSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mkdirp": "~0.5.1", + "ncp": "~2.0.0", + "rimraf": "~2.4.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/mv/node_modules/glob": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "integrity": "sha512-MKZeRNyYZAVVVG1oZeLaWie1uweH40m9AZwIwxyPbTSX4hHrVYSzLg0Ro5Z5R7XKkIX+Cc6oD1rqeDJnwsB8/A==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/mv/node_modules/rimraf": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", + "integrity": "sha512-J5xnxTyqaiw06JjMftq7L9ouA448dw/E7dKghkP9WpKNuwmARNNg+Gk8/u5ryb9N/Yo2+z3MCwuqFK/+qPOPfQ==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^6.0.1" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "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==", + "dev": true, + "license": "MIT", + "bin": { + "ncp": "bin/ncp" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "dev": true, + "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==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/appium-uiautomator2-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==", + "extraneous": true, + "license": "MIT", + "dependencies": { + "fn.name": "1.x.x" + } + }, + "node_modules/appium-uiautomator2-driver/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/appium-uiautomator2-driver/node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "extraneous": true, + "license": "MIT", + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/ora/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==", + "extraneous": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/ora/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==", + "extraneous": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/package-changed": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/package-changed/-/package-changed-3.0.0.tgz", + "integrity": "sha512-HSRbrO+Ab5AuqqYGSevtKJ1Yt96jW1VKV7wrp8K4SKj5tyDp/7D96uPCQyCPiNtWTEH/7nA3hZ4z2slbc9yFxg==", + "extraneous": true, + "license": "ISC", + "dependencies": { + "commander": "^6.2.0" + }, + "bin": { + "package-changed": "bin/package-changed.js" + } + }, + "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==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/appium-uiautomator2-driver/node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/appium-uiautomator2-driver/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==", + "dev": true, + "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/path-to-regexp": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz", + "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "ISC" + }, + "node_modules/appium-uiautomator2-driver/node_modules/pkg-dir": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz", + "integrity": "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^5.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "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==", + "dev": true, + "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.10", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", + "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true, + "license": "MIT" + }, + "node_modules/appium-uiautomator2-driver/node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.0.6" + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/readdir-glob/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "extraneous": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "extraneous": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "extraneous": true, + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/appium-uiautomator2-driver/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==", + "dev": true, + "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/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==", + "extraneous": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/appium-uiautomator2-driver/node_modules/sanitize-filename": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz", + "integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/appium-uiautomator2-driver/node_modules/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/send": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/appium-uiautomator2-driver/node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/send/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/serve-favicon": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/serve-favicon/-/serve-favicon-2.5.0.tgz", + "integrity": "sha512-FMW2RvqNr03x+C0WxTyu6sOv21oOjkq5j8tjquWccwa6ScNyGFOGJVpuS1NmTVGBAHS07xnSKotgf2ehQmf9iA==", + "dev": true, + "license": "MIT", + "dependencies": { + "etag": "~1.8.1", + "fresh": "0.5.2", + "ms": "2.1.1", + "parseurl": "~1.3.2", + "safe-buffer": "5.1.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/serve-favicon/node_modules/ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/appium-uiautomator2-driver/node_modules/serve-favicon/node_modules/safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", + "dev": true, + "license": "MIT" + }, + "node_modules/appium-uiautomator2-driver/node_modules/serve-static": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "ISC" + }, + "node_modules/appium-uiautomator2-driver/node_modules/sharp": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.5.tgz", + "integrity": "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.3", + "semver": "^7.6.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.33.5", + "@img/sharp-darwin-x64": "0.33.5", + "@img/sharp-libvips-darwin-arm64": "1.0.4", + "@img/sharp-libvips-darwin-x64": "1.0.4", + "@img/sharp-libvips-linux-arm": "1.0.5", + "@img/sharp-libvips-linux-arm64": "1.0.4", + "@img/sharp-libvips-linux-s390x": "1.0.4", + "@img/sharp-libvips-linux-x64": "1.0.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.0.4", + "@img/sharp-libvips-linuxmusl-x64": "1.0.4", + "@img/sharp-linux-arm": "0.33.5", + "@img/sharp-linux-arm64": "0.33.5", + "@img/sharp-linux-s390x": "0.33.5", + "@img/sharp-linux-x64": "0.33.5", + "@img/sharp-linuxmusl-arm64": "0.33.5", + "@img/sharp-linuxmusl-x64": "0.33.5", + "@img/sharp-wasm32": "0.33.5", + "@img/sharp-win32-ia32": "0.33.5", + "@img/sharp-win32-x64": "0.33.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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/shell-quote": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.2.tgz", + "integrity": "sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==", + "dev": true, + "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==", + "dev": true, + "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.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "ISC" + }, + "node_modules/appium-uiautomator2-driver/node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/appium-uiautomator2-driver/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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.21", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.21.tgz", + "integrity": "sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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/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==", + "extraneous": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "duplexer": "~0.1.1", + "through": "~2.3.4" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/streamx": { + "version": "2.22.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.22.0.tgz", + "integrity": "sha512-sLh1evHOzBy/iWRiR6d1zRcLao4gGZr3C1kzNz4fopCOKJb6xD9ub8Mpi9Mr1R6id5o43S+d93fI48UC5uM9aw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-fifo": "^1.3.2", + "text-decoder": "^1.1.0" + }, + "optionalDependencies": { + "bare-events": "^2.2.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==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/appium-uiautomator2-driver/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==", + "dev": true, + "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/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==", + "dev": true, + "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/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/string-width-cjs/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/appium-uiautomator2-driver/node_modules/string-width-cjs/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/tar-stream": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/teen_process": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/teen_process/-/teen_process-2.3.1.tgz", + "integrity": "sha512-duT4gPj7HxEYy+AR4bJ9MNwf8GMLpJd+sNRAK2PTx53FpCcaiXVft3ePZh3hO6PY8NFWZMxTC3ZAtxyztScEsw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "bluebird": "^3.7.2", + "lodash": "^4.17.21", + "shell-quote": "^1.8.1", + "source-map-support": "^0.x" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0", + "npm": ">=8" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/text-decoder": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz", + "integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "b4a": "^1.6.4" + } + }, + "node_modules/appium-uiautomator2-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==", + "extraneous": true, + "license": "MIT" + }, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/appium-uiautomator2-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==", + "extraneous": true, + "license": "MIT", + "engines": { + "node": ">= 14.0.0" + } + }, + "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==", + "dev": true, + "license": "WTFPL", + "dependencies": { + "utf8-byte-length": "^1.0.1" + } + }, + "node_modules/appium-uiautomator2-driver/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==", + "extraneous": true, + "license": "0BSD" + }, + "node_modules/appium-uiautomator2-driver/node_modules/type-fest": { + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.37.0.tgz", + "integrity": "sha512-S/5/0kFftkq27FPNye0XM1e2NsnoD/3FS+pBmbjmmtLT6I+i344KoOf7pvXreaFsDamWeaJX55nczA1m5PsBDg==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/typescript": { + "version": "5.8.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz", + "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==", + "extraneous": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/appium-uiautomator2-driver/node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/uuid": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", + "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", + "dev": true, + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/esm/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==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/validate.js": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/validate.js/-/validate.js-0.13.1.tgz", + "integrity": "sha512-PnFM3xiZ+kYmLyTiMgTYmU7ZHkjBZz2/+F0DaALc/uUtVzdCt1wAosvYJ5hFQi/hz8O4zb52FQhHZRC+uVkJ+g==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "extraneous": true, + "license": "MIT", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/which": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/winston": { + "version": "3.17.0", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.17.0.tgz", + "integrity": "sha512-DLiFIXYC5fMPxaRg832S6F5mJYvePtmO5G9v9IgUFPhXm9/GkXarH/TUrBAVzhTCzAj9anE/+GjrgXp/54nOgw==", + "extraneous": true, + "license": "MIT", + "dependencies": { + "@colors/colors": "^1.6.0", + "@dabh/diagnostics": "^2.0.2", + "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-uiautomator2-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==", + "extraneous": true, + "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-uiautomator2-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==", + "extraneous": true, + "license": "MIT", + "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/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==", + "extraneous": true, + "license": "MIT", + "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/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==", + "extraneous": true, + "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/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==", + "dev": true, + "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/wrap-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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/wrap-ansi-cjs/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/appium-uiautomator2-driver/node_modules/wrap-ansi-cjs/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==", + "dev": true, + "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/wrap-ansi-cjs/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/wrap-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==", + "extraneous": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/wrap-ansi/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==", + "extraneous": true, + "license": "MIT" + }, + "node_modules/appium-uiautomator2-driver/node_modules/wrap-ansi/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==", + "extraneous": true, + "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/wrap-ansi/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==", + "extraneous": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "license": "ISC" + }, + "node_modules/appium-uiautomator2-driver/node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/appium-uiautomator2-driver/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/appium-uiautomator2-driver/node_modules/yaml": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz", + "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==", + "extraneous": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "extraneous": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "extraneous": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/yargs/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==", + "extraneous": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/yargs/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==", + "extraneous": true, + "license": "MIT" + }, + "node_modules/appium-uiautomator2-driver/node_modules/yargs/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==", + "extraneous": true, + "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/yargs/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==", + "extraneous": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/yauzl": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-3.2.0.tgz", + "integrity": "sha512-Ow9nuGZE+qp1u4JIPvg+uCiUr7xGQWdff7JQSk5VGYTAZMDe2q8lxJ10ygv10qmSj031Ty/6FNJpLO4o1Sgc+w==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "extraneous": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/appium-uiautomator2-driver/node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "archiver-utils": "^5.0.0", + "compress-commons": "^6.0.2", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/appium/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/appium/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/appium/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/appium/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==", + "dev": true, + "license": "ISC" + }, + "node_modules/appium/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/appium/node_modules/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/appium/node_modules/type-fest": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.35.0.tgz", + "integrity": "sha512-2/AwEFQDFEy30iOLjrvHDIH7e4HEWH+f1Yl1bI5XMqzuoCUqwYCdxachgsgv0og/JdVZUhbfjcJAoHj5L1753A==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/appium/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "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/archiver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-7.0.1.tgz", + "integrity": "sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==", + "dev": true, + "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==", + "dev": true, + "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/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/archiver-utils/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "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/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/archiver-utils/node_modules/readable-stream": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", + "dev": true, + "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/archiver/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/archiver/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==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/archiver/node_modules/readable-stream": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", + "dev": true, + "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/archiver/node_modules/tar-stream": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "dev": true, + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, + "node_modules/are-docs-informative": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz", + "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==", + "dev": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "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==" + }, + "node_modules/aria-query": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-3.0.0.tgz", + "integrity": "sha512-majUxHgLehQTeSA+hClx+DY09OVUqG3GtezWkF1krgLGNdlDu9l9V8DaqNMWbq4Eddc8wsyDA0hpDUtnYxQEXw==", + "dev": true, + "dependencies": { + "ast-types-flow": "0.0.7", + "commander": "^2.11.0" + } + }, + "node_modules/aria-query/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true + }, + "node_modules/array-includes": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", + "dev": true, + "dependencies": { + "array-uniq": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", + "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dev": true, + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/ast-types": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ast-types-flow": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", + "integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==", + "dev": true + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "dev": true + }, + "node_modules/async-exit-hook": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/async-exit-hook/-/async-exit-hook-2.0.1.tgz", + "integrity": "sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/async-mutex": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.2.6.tgz", + "integrity": "sha512-Hs4R+4SPgamu6rSGW8C7cV9gaWUKEHykfzCCvIRuaVv636Ju10ZdeUbvb4TBEW0INuq2DHZqXbK4Nd3yG4RaRw==", + "dependencies": { + "tslib": "^2.0.0" + } + }, + "node_modules/async-sema": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/async-sema/-/async-sema-3.1.1.tgz", + "integrity": "sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg==", + "dev": true, + "license": "MIT" + }, + "node_modules/asyncbox": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/asyncbox/-/asyncbox-3.0.0.tgz", + "integrity": "sha512-X7U0nedUMKV3nn9c4R0Zgvdvv6cw97tbDlHSZicq1snGPi/oX9DgGmFSURWtxDdnBWd3V0YviKhqAYAVvoWQ/A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "bluebird": "^3.5.1", + "lodash": "^4.17.4", + "source-map-support": "^0.x" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/autoprefixer": { + "version": "10.4.20", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", + "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "browserslist": "^4.23.3", + "caniuse-lite": "^1.0.30001646", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.2.tgz", + "integrity": "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==", + "dev": true + }, + "node_modules/axios": { + "version": "1.7.9", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz", + "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==", + "dev": true, + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/axios/node_modules/form-data": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/axobject-query": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.0.2.tgz", + "integrity": "sha512-MCeek8ZH7hKyO1rWUbKNQBbl4l2eY0ntk7OGi+q0RlafrCnfPxC06WZA+uebCfmYp4mNU9jRBP1AhGyf8+W3ww==", + "dev": true, + "dependencies": { + "ast-types-flow": "0.0.7" + } + }, + "node_modules/b4a": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz", + "integrity": "sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==" + }, + "node_modules/babel-loader": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.2.1.tgz", + "integrity": "sha512-fqe8naHt46e0yIdkjUZYqddSXfej3AHajX+CSO5X7oy0EmPc6o5Xh+RClNoHjnieWz9AW4kZxW9yyFMhVB1QLA==", + "dev": true, + "dependencies": { + "find-cache-dir": "^4.0.0", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 14.15.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0", + "webpack": ">=5" + } + }, + "node_modules/babel-plugin-const-enum": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-const-enum/-/babel-plugin-const-enum-1.2.0.tgz", + "integrity": "sha512-o1m/6iyyFnp9MRsK1dHF3bneqyf3AlM2q3A/YbgQr2pCat6B6XJVDv2TXqzfY2RYUi4mak6WAksSBPlyYGx9dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-typescript": "^7.3.3", + "@babel/traverse": "^7.16.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, + "node_modules/babel-plugin-macros/node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/babel-plugin-macros/node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-macros/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.12", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.12.tgz", + "integrity": "sha512-CPWT6BwvhrTO2d8QVorhTCQw9Y43zOu7G9HigcfxvepOU6b8o3tcWad6oVgZIsZCTt42FFv97aA7ZJsbM4+8og==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.6.3", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.10.6", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz", + "integrity": "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.2", + "core-js-compat": "^3.38.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.3.tgz", + "integrity": "sha512-LiWSbl4CRSIa5x/JAU6jZiG9eit9w6mz+yVMFwDE83LAWvt0AfGBoZ7HS/mkhrKuh2ZlzfVZYKoLjXdqw6Yt7Q==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.3" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-transform-typescript-metadata": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-typescript-metadata/-/babel-plugin-transform-typescript-metadata-0.3.2.tgz", + "integrity": "sha512-mWEvCQTgXQf48yDqgN7CH50waTyYBeP2Lpqx4nNWab9sxEpdXVeKgfj1qYI2/TgUPQtNFZ85i3PemRtnXVYYJg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "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==", + "dev": true + }, + "node_modules/bare-events": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.4.2.tgz", + "integrity": "sha512-qMKFd2qG/36aA4GwvKq8MxnPgCQAmBWmSyLWsJcbn8v03wvIPQ/hG1Ms8bPzndZxMDoHpxez5VOS+gC9Yi24/Q==", + "optional": true + }, + "node_modules/bare-fs": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.3.5.tgz", + "integrity": "sha512-SlE9eTxifPDJrT6YgemQ1WGFleevzwY+XAP1Xqgl56HtcrisC2CHCZ2tq6dBpcH2TnNxwUEUGhweo+lrQtYuiw==", + "optional": true, + "dependencies": { + "bare-events": "^2.0.0", + "bare-path": "^2.0.0", + "bare-stream": "^2.0.0" + } + }, + "node_modules/bare-os": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.4.4.tgz", + "integrity": "sha512-z3UiI2yi1mK0sXeRdc4O1Kk8aOa/e+FNWZcTiPB/dfTWyLypuE99LibgRaQki914Jq//yAWylcAt+mknKdixRQ==", + "optional": true + }, + "node_modules/bare-path": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-2.1.3.tgz", + "integrity": "sha512-lh/eITfU8hrj9Ru5quUp0Io1kJWIk1bTjzo7JH1P5dWmQ2EL4hFUlfI8FonAhSlgIfhn63p84CDY/x+PisgcXA==", + "optional": true, + "dependencies": { + "bare-os": "^2.1.0" + } + }, + "node_modules/bare-stream": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.6.1.tgz", + "integrity": "sha512-eVZbtKM+4uehzrsj49KtCy3Pbg7kO1pJ3SKZ1SFrIH/0pnj9scuGGgUlNDf/7qS8WKtGdiJY5Kyhs/ivYPTB/g==", + "optional": true, + "dependencies": { + "streamx": "^2.21.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" + } + ] + }, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/basic-auth/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/basic-ftp": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", + "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", + "dev": true + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "dev": true, + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/beasties": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/beasties/-/beasties-0.2.0.tgz", + "integrity": "sha512-Ljqskqx/tbZagIglYoJIMzH5zgssyp+in9+9sAyh15N22AornBeIDnb8EZ6Rk+6ShfMxd92uO3gfpT0NtZbpow==", + "dev": true, + "dependencies": { + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "htmlparser2": "^9.1.0", + "picocolors": "^1.1.1", + "postcss": "^8.4.49", + "postcss-media-query-parser": "^0.2.3" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/bignumber.js": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", + "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/blocking-proxy": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/blocking-proxy/-/blocking-proxy-1.0.1.tgz", + "integrity": "sha512-KE8NFMZr3mN2E0HcvCgRtX7DjhiIQrwle+nSVJVC/yqFb9+xznHl2ZcoBp2L9qzkI4t4cBFJ1efXF8Dwi132RA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "blocking-proxy": "built/lib/bin.js" + }, + "engines": { + "node": ">=6.9.x" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/body-parser": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/bonjour-service": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.3.0.tgz", + "integrity": "sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "stream-buffers": "2.2.x" + } + }, + "node_modules/bplist-creator/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==", + "dev": true, + "license": "Unlicense", + "engines": { + "node": ">= 0.10.0" + } + }, + "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==", + "dev": true, + "dependencies": { + "big-integer": "1.6.x" + }, + "engines": { + "node": ">= 5.10.0" + } + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true, + "license": "ISC" + }, + "node_modules/browserslist": { + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", + "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001688", + "electron-to-chromium": "^1.5.73", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.1" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/browserstack": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/browserstack/-/browserstack-1.6.1.tgz", + "integrity": "sha512-GxtFjpIaKdbAyzHfFDKixKO8IBT7wR3NjbzrGc78nNs/Ciys9wU3/nBtsqsWv5nDSrdI5tz0peKuzCPuNXNUiw==", + "dev": true, + "dependencies": { + "https-proxy-agent": "^2.2.1" + } + }, + "node_modules/browserstack/node_modules/agent-base": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", + "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", + "dev": true, + "dependencies": { + "es6-promisify": "^5.0.0" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/browserstack/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/browserstack/node_modules/https-proxy-agent": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", + "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", + "dev": true, + "dependencies": { + "agent-base": "^4.3.0", + "debug": "^3.1.0" + }, + "engines": { + "node": ">= 4.5.0" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "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==", + "engines": { + "node": "*" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha512-wxXCdllwGhI2kCC0MnvTGYTMvnVZTvqgypkiTI8Pa5tcz2i6VqsqwYGgqwXji+4RgCzms6EajE4IxiUH6HH8nQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "dev": true, + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/c12": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/c12/-/c12-2.0.1.tgz", + "integrity": "sha512-Z4JgsKXHG37C6PYUtIxCfLJZvo6FyhHJoClwwb9ftUkLpPSkuYqn6Tr+vnaN8hymm0kIbcg6Ey3kv/Q71k5w/A==", + "dev": true, + "license": "MIT", + "dependencies": { + "chokidar": "^4.0.1", + "confbox": "^0.1.7", + "defu": "^6.1.4", + "dotenv": "^16.4.5", + "giget": "^1.2.3", + "jiti": "^2.3.0", + "mlly": "^1.7.1", + "ohash": "^1.1.4", + "pathe": "^1.1.2", + "perfect-debounce": "^1.0.0", + "pkg-types": "^1.2.0", + "rc9": "^2.1.2" + }, + "peerDependencies": { + "magicast": "^0.3.5" + }, + "peerDependenciesMeta": { + "magicast": { + "optional": true + } + } + }, + "node_modules/c12/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/c12/node_modules/jiti": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", + "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/c12/node_modules/readdirp": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.1.tgz", + "integrity": "sha512-h80JrZu/MHUZCyHu5ciuoI0+WxsCxzxJTILn6Fs8rxSnFPh+UVHYfeIxK1nVGugMqkfC4vJcBOYbkfkwYK0+gw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cacache": { + "version": "19.0.1", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-19.0.1.tgz", + "integrity": "sha512-hdsUxulXCi5STId78vRVYEtDAjq99ICAUktLTeTYsLoTE6Z8dS0c8pWNCxwdrk9YfJeobDZc2Y186hD/5ZQgFQ==", + "dev": true, + "dependencies": { + "@npmcli/fs": "^4.0.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^10.0.1", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^7.0.2", + "ssri": "^12.0.0", + "tar": "^7.4.3", + "unique-filename": "^4.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/cacache/node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/cacache/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "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/cacache/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==", + "dev": true + }, + "node_modules/cacache/node_modules/minizlib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.1.tgz", + "integrity": "sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==", + "dev": true, + "dependencies": { + "minipass": "^7.0.4", + "rimraf": "^5.0.5" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/cacache/node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "dev": true, + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/rimraf": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", + "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", + "dev": true, + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/tar": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", + "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", + "dev": true, + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/cacache/node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz", + "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz", + "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001697", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001697.tgz", + "integrity": "sha512-GwNPlWJin8E+d7Gxq96jxM6w0w+VFeyyXRsjU58emtkYqnbwHqXm5uT2uCmO0RQE9htWknOP4xtBlLmM/gWxvQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/canvas-confetti": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/canvas-confetti/-/canvas-confetti-1.9.3.tgz", + "integrity": "sha512-rFfTURMvmVEX1gyXFgn5QMn81bYk70qa0HLzcIOSVEyl57n6o9ItHeBtUSWdvKAPY0xlvBHno4/v3QPrT83q9g==", + "funding": { + "type": "donate", + "url": "https://www.paypal.me/kirilvatev" + } + }, + "node_modules/capacitor-navigationbarnx": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/capacitor-navigationbarnx/-/capacitor-navigationbarnx-0.1.6.tgz", + "integrity": "sha512-Z/1636u53k0Zw4BGTEMSvwV9yxVc4Fny0pSowlfHNViJxxz9r281D7Hhuo1OFlVpF3BAzWGeaHQ1iB4lf1WuXQ==", + "dependencies": { + "@capacitor/core": "^5.0.0" + } + }, + "node_modules/capacitor-navigationbarnx/node_modules/@capacitor/core": { + "version": "5.7.8", + "resolved": "https://registry.npmjs.org/@capacitor/core/-/core-5.7.8.tgz", + "integrity": "sha512-rrZcm/2vJM0WdWRQup1TUidbjQV9PfIadSkV4rAGLD7R6PuzZSMPGT0gmoZzCRlXkqrazrWWDkurei3ozU02FA==", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "dev": true + }, + "node_modules/chai": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.2.tgz", + "integrity": "sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/change-case": { + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/change-case/-/change-case-5.4.4.tgz", + "integrity": "sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "node_modules/check-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", + "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + } + }, + "node_modules/cheerio": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0.tgz", + "integrity": "sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "encoding-sniffer": "^0.2.0", + "htmlparser2": "^9.1.0", + "parse5": "^7.1.2", + "parse5-htmlparser2-tree-adapter": "^7.0.0", + "parse5-parser-stream": "^7.1.2", + "undici": "^6.19.5", + "whatwg-mimetype": "^4.0.0" + }, + "engines": { + "node": ">=18.17" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cheerio/node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/chevrotain": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-6.5.0.tgz", + "integrity": "sha512-BwqQ/AgmKJ8jcMEjaSnfMybnKMgGTrtDKowfTP3pX4jwVy0kNjRsT/AP6h+wC3+3NC+X8X15VWBnTCQlX+wQFg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "regexp-to-ast": "0.4.0" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "dev": true, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/chromium-bidi": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.11.0.tgz", + "integrity": "sha512-6CJWHkNRoyZyjV9Rwv2lYONZf1Xm0IuDyNq97nwSsxxP3wf5Bwy15K5rOvVKMtJ127jJBmxFUanSAOjgFRxgrA==", + "dependencies": { + "mitt": "3.0.1", + "zod": "3.23.8" + }, + "peerDependencies": { + "devtools-protocol": "*" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/citty": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/citty/-/citty-0.1.6.tgz", + "integrity": "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "consola": "^3.2.3" + } + }, + "node_modules/cli-cursor": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", + "dev": true, + "dependencies": { + "restore-cursor": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", + "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", + "dev": true, + "dependencies": { + "slice-ansi": "^5.0.0", + "string-width": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/cli-truncate/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cli-truncate/node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "dev": true + }, + "node_modules/cli-truncate/node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/cli-truncate/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==", + "dev": true, + "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/cli-truncate/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/clipboardy": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-4.0.0.tgz", + "integrity": "sha512-5mOlNS0mhX0707P2I0aZ2V/cmHUEO/fL7VFLqszkhUsxt7RwnmrInf/eEQKlf5GzvYeHIjT+Ov1HRfNmymlG0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "execa": "^8.0.1", + "is-wsl": "^3.1.0", + "is64bit": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/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==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cliui/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==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/cliui/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==" + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "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/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/cluster-key-slot": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", + "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/code-block-writer": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-12.0.0.tgz", + "integrity": "sha512-q4dMFMlXtKR3XNBHyMHt/3pwYNA69EDk00lloMOaaUMKPUXBw6lpXtbu3MMVG6/uOihGnRDOlkyqsONEUj60+w==", + "dev": true, + "license": "MIT" + }, + "node_modules/codelyzer": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/codelyzer/-/codelyzer-6.0.2.tgz", + "integrity": "sha512-v3+E0Ucu2xWJMOJ2fA/q9pDT/hlxHftHGPUay1/1cTgyPV5JTHFdO9hqo837Sx2s9vKBMTt5gO+lhF95PO6J+g==", + "dev": true, + "dependencies": { + "@angular/compiler": "9.0.0", + "@angular/core": "9.0.0", + "app-root-path": "^3.0.0", + "aria-query": "^3.0.0", + "axobject-query": "2.0.2", + "css-selector-tokenizer": "^0.7.1", + "cssauron": "^1.4.0", + "damerau-levenshtein": "^1.0.4", + "rxjs": "^6.5.3", + "semver-dsl": "^1.0.1", + "source-map": "^0.5.7", + "sprintf-js": "^1.1.2", + "tslib": "^1.10.0", + "zone.js": "~0.10.3" + }, + "peerDependencies": { + "@angular/compiler": ">=2.3.1 <13.0.0 || ^12.0.0-next || ^12.1.0-next || ^12.2.0-next", + "@angular/core": ">=2.3.1 <13.0.0 || ^12.0.0-next || ^12.1.0-next || ^12.2.0-next", + "tslint": "^5.0.0 || ^6.0.0" + } + }, + "node_modules/codelyzer/node_modules/@angular/compiler": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-9.0.0.tgz", + "integrity": "sha512-ctjwuntPfZZT2mNj2NDIVu51t9cvbhl/16epc5xEwyzyDt76pX9UgwvY+MbXrf/C/FWwdtmNtfP698BKI+9leQ==", + "dev": true, + "peerDependencies": { + "tslib": "^1.10.0" + } + }, + "node_modules/codelyzer/node_modules/@angular/core": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-9.0.0.tgz", + "integrity": "sha512-6Pxgsrf0qF9iFFqmIcWmjJGkkCaCm6V5QNnxMy2KloO3SDq6QuMVRbN9RtC8Urmo25LP+eZ6ZgYqFYpdD8Hd9w==", + "dev": true, + "peerDependencies": { + "rxjs": "^6.5.3", + "tslib": "^1.10.0", + "zone.js": "~0.10.2" + } + }, + "node_modules/codelyzer/node_modules/rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/codelyzer/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/codelyzer/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/codelyzer/node_modules/zone.js": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.10.3.tgz", + "integrity": "sha512-LXVLVEq0NNOqK/fLJo3d0kfzd4sxwn2/h67/02pjCjfKDxgx1i9QqpvtHD8CrBnSSwMw5+dy11O7FRX5mkO7Cg==", + "dev": true + }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/color/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==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color/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==" + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true + }, + "node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/colorspace": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", + "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "color": "^3.1.3", + "text-hex": "1.0.x" + } + }, + "node_modules/colorspace/node_modules/color": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", + "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.3", + "color-string": "^1.6.0" + } + }, + "node_modules/columnify": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/columnify/-/columnify-1.6.0.tgz", + "integrity": "sha512-lomjuFZKfM6MSAnV9aCZC9sc0qGbmZdfygNv+nCpqVkSKdCxCklLtd16O0EILGkImHw9ZpHkAnHaB+8Zxq5W6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "strip-ansi": "^6.0.1", + "wcwidth": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "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==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || >=14" + } + }, + "node_modules/comment-parser": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", + "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==", + "dev": true, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/common-path-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", + "dev": true + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true, + "license": "MIT" + }, + "node_modules/compatx": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/compatx/-/compatx-0.1.8.tgz", + "integrity": "sha512-jcbsEAR81Bt5s1qOFymBufmCbXCXbk0Ql+K5ouj6gCyx2yHlu6AgmGIi9HxfKixpUDO5bCFJUHQ5uM6ecbTebw==", + "dev": true, + "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==", + "dev": true, + "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/compress-commons/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/compress-commons/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==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/compress-commons/node_modules/readable-stream": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", + "dev": true, + "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/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dev": true, + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.5.tgz", + "integrity": "sha512-bQJ0YRck5ak3LgtnpKkiabX5pNF7tMUh1BSy2ZBOTh0Dim0BUu6aPPwByIns6/A5Prh8PufSPerMDUklpzes2Q==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "compressible": "~2.0.18", + "debug": "2.6.9", + "negotiator": "~0.6.4", + "on-headers": "~1.0.2", + "safe-buffer": "5.2.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/compression/node_modules/negotiator": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/connect-history-api-fallback": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", + "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/consola": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.0.tgz", + "integrity": "sha512-EiPU8G6dQG0GFHNR8ljnZFki/8a+cQwEQ+7wpxdChl02Q8HXlwEZWD5lqAF8vC2sEC3Tehr8hy7vErz88LHyUA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, + "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==", + "dev": true, + "license": "ISC" + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, + "node_modules/cookie-es": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-es/-/cookie-es-1.2.2.tgz", + "integrity": "sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true + }, + "node_modules/copy-anything": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz", + "integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==", + "dev": true, + "dependencies": { + "is-what": "^3.14.1" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/copy-webpack-plugin": { + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-12.0.2.tgz", + "integrity": "sha512-SNwdBeHyII+rWvee/bTnAYyO8vfVdcSTud4EIb6jcZ8inLeWucJE0DnxXQBjlQ5zlteuuvooGQy3LIyGxhvlOA==", + "dev": true, + "dependencies": { + "fast-glob": "^3.3.2", + "glob-parent": "^6.0.1", + "globby": "^14.0.0", + "normalize-path": "^3.0.0", + "schema-utils": "^4.2.0", + "serialize-javascript": "^6.0.2" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/cordova-plugin-purchase": { + "version": "13.12.1", + "resolved": "https://registry.npmjs.org/cordova-plugin-purchase/-/cordova-plugin-purchase-13.12.1.tgz", + "integrity": "sha512-IRYOLqv8iEn/i+JnTXZI6yITphiwO8Bn6qm0f6+5t0the9Wb/jYdk7Q6rB7l3AO21Is5AcBLptQAwLTY3tY1Rg==" + }, + "node_modules/cordova-res": { + "version": "0.15.4", + "resolved": "https://registry.npmjs.org/cordova-res/-/cordova-res-0.15.4.tgz", + "integrity": "sha512-TjFZhjUtK8qq4DVrgR+KI7tKcUL704cnkTPRhHbKlCPzefHoz1tBOX93wc76dOMmOWKTsbJz83DIm6mqdp5Pmg==", + "dependencies": { + "@ionic/utils-array": "^2.1.5", + "@ionic/utils-fs": "^3.1.5", + "debug": "^4.2.0", + "elementtree": "^0.1.7", + "sharp": "^0.29.2", + "tslib": "^2.0.3" + }, + "bin": { + "cordova-res": "bin/cordova-res" + }, + "engines": { + "node": ">=10.3.0" + } + }, + "node_modules/core-js-compat": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.40.0.tgz", + "integrity": "sha512-0XEDpr5y5mijvw8Lbc6E5AkjrHfp7eEoPlu36SWeAbcL8fn1G1ANe8DBlo2XoNN89oVpxWwOjYIPVzR4ZvsKCQ==", + "dev": true, + "dependencies": { + "browserslist": "^4.24.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "dev": true + }, + "node_modules/cosmiconfig": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", + "dependencies": { + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "dependencies": { + "crc-32": "^1.2.0", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/crc32-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==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/crc32-stream/node_modules/readable-stream": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", + "dev": true, + "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/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/croner": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/croner/-/croner-9.0.0.tgz", + "integrity": "sha512-onMB0OkDjkXunhdW9htFjEhqrD54+M94i6ackoUkjHKbRnXdyEyKRelp4nJ1kAz32+s27jP1FsebpJCVl0BsvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crossws": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/crossws/-/crossws-0.3.3.tgz", + "integrity": "sha512-/71DJT3xJlqSnBr83uGJesmVHSzZEvgxHt/fIKxBAAngqMHmnBWQNxCphVxxJ2XL3xleu5+hJD6IQ3TglBedcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "uncrypto": "^0.1.3" + } + }, + "node_modules/css-loader": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-7.1.2.tgz", + "integrity": "sha512-6WvYYn7l/XEGN8Xu2vWFt9nVzrCn39vKyTEFf/ExEyoksJjjSZV/0/35XPlMbpnr6VGhZIUg5yJrL8tGfes/FA==", + "dev": true, + "dependencies": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.33", + "postcss-modules-extract-imports": "^3.1.0", + "postcss-modules-local-by-default": "^4.0.5", + "postcss-modules-scope": "^3.2.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.27.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-selector-tokenizer": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.3.tgz", + "integrity": "sha512-jWQv3oCEL5kMErj4wRnK/OPoBi0D+P1FR2cDCKYPaMeD2eW3/mttav8HT4hT1CKopiJI/psEULjkClhvJo4Lvg==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "fastparse": "^1.1.2" + } + }, + "node_modules/css-shorthand-properties": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/css-shorthand-properties/-/css-shorthand-properties-1.1.2.tgz", + "integrity": "sha512-C2AugXIpRGQTxaCW0N7n5jD/p5irUmCrwl03TrnMFBHDbdq44CFWR2zO7rK9xPN4Eo3pUxC4vQzQgbIpzrD1PQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/css-value": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/css-value/-/css-value-0.0.1.tgz", + "integrity": "sha512-FUV3xaJ63buRLgHrLQVlVgQnQdR4yqdLGaDu7g8CQcWjInDfM9plBTPI9FRfpahju1UBSaMckeb2/46ApS/V1Q==", + "dev": true + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "dev": true, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssauron": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/cssauron/-/cssauron-1.4.0.tgz", + "integrity": "sha512-Ht70DcFBh+/ekjVrYS2PlDMdSQEl3OFNmjK6lcn49HptBgilXf/Zwg4uFh9Xn0pX3Q8YOkSjIFOfK2osvdqpBw==", + "dev": true, + "dependencies": { + "through": "X.X.X" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cssstyle": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-3.0.0.tgz", + "integrity": "sha512-N4u2ABATi3Qplzf0hWbVCdjenim8F3ojEXpBDF5hBpjzW182MjNGLqfmQ0SkSPeQ+V86ZXgeH8aXj6kayd4jgg==", + "dev": true, + "license": "MIT", + "dependencies": { + "rrweb-cssom": "^0.6.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", + "dev": true + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/data-uri-to-buffer": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", + "engines": { + "node": ">= 14" + } + }, + "node_modules/data-urls": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-4.0.0.tgz", + "integrity": "sha512-/mMTei/JXPqvFqQtfyTowxmJVwr2PVAeCcDxyFf6LhoOu/09TX2OX3kb2wzi4DMXcfj4OItwDOnhl5oziPnT6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "abab": "^2.0.6", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^12.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/data-urls/node_modules/tr46": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", + "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.3.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/data-urls/node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/data-urls/node_modules/whatwg-url": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-12.0.1.tgz", + "integrity": "sha512-Ed/LrqB8EPlGxjS+TrsXcpUond1mhccS3pchLhzSgPCnTimUCKj3IZE75pAs5m6heB2U2TMerKFUXheyHY+VDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "^4.1.1", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/db0": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/db0/-/db0-0.2.3.tgz", + "integrity": "sha512-PunuHESDNefmwVy1LDpY663uWwKt2ogLGoB6NOz2sflGREWqDreMwDgF8gfkXxgNXW+dqviyiJGm924H1BaGiw==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@electric-sql/pglite": "*", + "@libsql/client": "*", + "better-sqlite3": "*", + "drizzle-orm": "*", + "mysql2": "*", + "sqlite3": "*" + }, + "peerDependenciesMeta": { + "@electric-sql/pglite": { + "optional": true + }, + "@libsql/client": { + "optional": true + }, + "better-sqlite3": { + "optional": true + }, + "drizzle-orm": { + "optional": true + }, + "mysql2": { + "optional": true + }, + "sqlite3": { + "optional": true + } + } + }, + "node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decimal.js": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.5.0.tgz", + "integrity": "sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==", + "dev": true, + "license": "MIT" + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/deepmerge-ts": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/deepmerge-ts/-/deepmerge-ts-7.1.5.tgz", + "integrity": "sha512-HOJkrhaYsweh+W+e74Yn7YStZOilkoPb6fycpwNLKzSPtruFs48nYis0zy5yJz1+ktUhHxoRDJ27RQAWLIJVJw==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/default-browser": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", + "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", + "dev": true, + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", + "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/defu": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz", + "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==", + "dev": true, + "license": "MIT" + }, + "node_modules/degenerator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", + "dependencies": { + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/del": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", + "integrity": "sha512-Z4fzpbIRjOu7lO5jCETSWoqUDVe0IPOlfugBsF6suen2LKDlVb4QZpKEM9P+buNJ4KI1eN7I083w/pbKUpsrWQ==", + "dev": true, + "dependencies": { + "globby": "^5.0.0", + "is-path-cwd": "^1.0.0", + "is-path-in-cwd": "^1.0.0", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "rimraf": "^2.2.8" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/del/node_modules/globby": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", + "integrity": "sha512-HJRTIH2EeH44ka+LWig+EqT2ONSYpVlNfx6pyd592/VF1TbfljJ7elwie7oSwcViLGqOdWocSdu2txwBF9bjmQ==", + "dev": true, + "dependencies": { + "array-union": "^1.0.1", + "arrify": "^1.0.0", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/del/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/denque": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", + "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=0.10" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destr": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/destr/-/destr-2.0.3.tgz", + "integrity": "sha512-2N3BOUU4gYMpTP24s5rF5iP7BDr7uNTCs4ozw3kf/eKfvWSIu93GEBi5m427YoyJoeOzQ5smuu4nNAPGb8idSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "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==", + "dev": true + }, + "node_modules/detect-port": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.6.1.tgz", + "integrity": "sha512-CmnVc+Hek2egPx1PeTFVta2W78xy2K/9Rkf6cC4T59S50tVnzKj+tnx5mmx5lwvCkujZ4uRrpRSuV+IVs3f90Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "address": "^1.0.1", + "debug": "4" + }, + "bin": { + "detect": "bin/detect-port.js", + "detect-port": "bin/detect-port.js" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/devtools-protocol": { + "version": "0.0.1367902", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1367902.tgz", + "integrity": "sha512-XxtPuC3PGakY6PD7dG66/o8KwJ/LkH2/EKe19Dcw58w53dv4/vSQEkn/SzuyhHE2q4zPgCkxQBxus3VV4ql+Pg==" + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dir-glob/node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/dns-packet": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "dev": true, + "dependencies": { + "@leichtgewicht/ip-codec": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dev": true, + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domexception": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", + "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", + "deprecated": "Use your platform's native DOMException instead", + "dev": true, + "license": "MIT", + "dependencies": { + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/domexception/node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dev": true, + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "dev": true, + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dot-prop": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-9.0.0.tgz", + "integrity": "sha512-1gxPBJpI/pcjQhKgIU91II6Wkay+dLcN3M6rf2uwP8hRur3HtQXjVrdAK3sjC0piaEuxzMwjXChcETiJl47lAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^4.18.2" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dot-prop/node_modules/type-fest": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.33.0.tgz", + "integrity": "sha512-s6zVrxuyKbbAsSAD5ZPTB77q4YIdRctkTbJ2/Dqlinwz+8ooH2gd+YA7VA6Pa93KML9GockVvoxjZ2vHP+mu8g==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dotenv": { + "version": "16.4.7", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz", + "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dotenv-expand": { + "version": "11.0.7", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-11.0.7.tgz", + "integrity": "sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dotenv": "^16.4.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true + }, + "node_modules/easy-table": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/easy-table/-/easy-table-1.2.0.tgz", + "integrity": "sha512-OFzVOv03YpvtcWGe5AayU5G2hgybsg3iqA6drU8UaoZyB9jLGMTrz9+asnLp/E+6qPh88yEI1gvyZFZ41dmgww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "optionalDependencies": { + "wcwidth": "^1.0.1" + } + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "dev": true, + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/ecc-jsbn/node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "dev": true + }, + "node_modules/echarts": { + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/echarts/-/echarts-5.5.1.tgz", + "integrity": "sha512-Fce8upazaAXUVUVsjgV6mBnGuqgO+JNDlcgF79Dksy4+wgGpQB2lmYoO4TSweFg/mZITdpGHomw/cNBJZj1icA==", + "dependencies": { + "tslib": "2.3.0", + "zrender": "5.6.0" + } + }, + "node_modules/echarts/node_modules/tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" + }, + "node_modules/edge-paths": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/edge-paths/-/edge-paths-3.0.5.tgz", + "integrity": "sha512-sB7vSrDnFa4ezWQk9nZ/n0FdpdUuC6R1EOrlU3DL+bovcNFK28rqu2emmAUjujYEJTWIgQGqgVVWUZXMnc8iWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/which": "^2.0.1", + "which": "^2.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/shirshak55" + } + }, + "node_modules/edgedriver": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/edgedriver/-/edgedriver-6.1.1.tgz", + "integrity": "sha512-/dM/PoBf22Xg3yypMWkmRQrBKEnSyNaZ7wHGCT9+qqT14izwtFT+QvdR89rjNkMfXwW+bSFoqOfbcvM+2Cyc7w==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@wdio/logger": "^9.1.3", + "@zip.js/zip.js": "^2.7.53", + "decamelize": "^6.0.0", + "edge-paths": "^3.0.5", + "fast-xml-parser": "^4.5.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.5", + "node-fetch": "^3.3.2", + "which": "^5.0.0" + }, + "bin": { + "edgedriver": "bin/edgedriver.js" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/edgedriver/node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/edgedriver/node_modules/decamelize": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-6.0.0.tgz", + "integrity": "sha512-Fv96DCsdOgB6mdGl67MT5JaTNKRzrzill5OH5s8bjYJXVlcXyPYGyPsUkWyGV5p1TXI5esYIYMMeDJL0hEIwaA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/edgedriver/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/edgedriver/node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/edgedriver/node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "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==", + "dev": true + }, + "node_modules/ejs": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.92", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.92.tgz", + "integrity": "sha512-BeHgmNobs05N1HMmMZ7YIuHfYBGlq/UmvlsTgg+fsbFs9xVMj+xJHFg19GN04+9Q+r8Xnh9LXqaYIyEWElnNgQ==", + "dev": true + }, + "node_modules/elementtree": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/elementtree/-/elementtree-0.1.7.tgz", + "integrity": "sha512-wkgGT6kugeQk/P6VZ/f4T+4HB41BVgNBq5CDIZVbQ02nvTVqAiVTbskxxu3eA/X96lMlfYOwnLQpN2v5E1zDEg==", + "dependencies": { + "sax": "1.1.4" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "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==" + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dev": true, + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/encoding-sniffer": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.0.tgz", + "integrity": "sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "^0.6.3", + "whatwg-encoding": "^3.1.1" + }, + "funding": { + "url": "https://github.com/fb55/encoding-sniffer?sponsor=1" + } + }, + "node_modules/encoding-sniffer/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/encoding-sniffer/node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "devOptional": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "dev": true + }, + "node_modules/errno": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "dev": true, + "optional": true, + "dependencies": { + "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.23.9", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.9.tgz", + "integrity": "sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.0", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-regex": "^1.2.1", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.0", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.3", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.18" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", + "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "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==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "dev": true, + "dependencies": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", + "dev": true + }, + "node_modules/es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==", + "dev": true, + "dependencies": { + "es6-promise": "^4.0.3" + } + }, + "node_modules/esbuild": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.2.tgz", + "integrity": "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.24.2", + "@esbuild/android-arm": "0.24.2", + "@esbuild/android-arm64": "0.24.2", + "@esbuild/android-x64": "0.24.2", + "@esbuild/darwin-arm64": "0.24.2", + "@esbuild/darwin-x64": "0.24.2", + "@esbuild/freebsd-arm64": "0.24.2", + "@esbuild/freebsd-x64": "0.24.2", + "@esbuild/linux-arm": "0.24.2", + "@esbuild/linux-arm64": "0.24.2", + "@esbuild/linux-ia32": "0.24.2", + "@esbuild/linux-loong64": "0.24.2", + "@esbuild/linux-mips64el": "0.24.2", + "@esbuild/linux-ppc64": "0.24.2", + "@esbuild/linux-riscv64": "0.24.2", + "@esbuild/linux-s390x": "0.24.2", + "@esbuild/linux-x64": "0.24.2", + "@esbuild/netbsd-arm64": "0.24.2", + "@esbuild/netbsd-x64": "0.24.2", + "@esbuild/openbsd-arm64": "0.24.2", + "@esbuild/openbsd-x64": "0.24.2", + "@esbuild/sunos-x64": "0.24.2", + "@esbuild/win32-arm64": "0.24.2", + "@esbuild/win32-ia32": "0.24.2", + "@esbuild/win32-x64": "0.24.2" + } + }, + "node_modules/esbuild-wasm": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.24.2.tgz", + "integrity": "sha512-03/7Z1gD+ohDnScFztvI4XddTAbKVmMEzCvvkBpQdWKEXJ+73dTyeNrmdxP1Q0zpDMFjzUJwtK4rLjqwiHbzkw==", + "dev": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "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==", + "dev": true + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/escodegen/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint": { + "version": "9.19.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.19.0.tgz", + "integrity": "sha512-ug92j0LepKlbbEv6hD911THhoRHmbdXt2gX+VDABAW/Ir7D3nqKdv5Pf5vtlyY6HQMTEP2skXY43ueqTCWssEA==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.19.0", + "@eslint/core": "^0.10.0", + "@eslint/eslintrc": "^3.2.0", + "@eslint/js": "9.19.0", + "@eslint/plugin-kit": "^0.2.5", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.1", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.2.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-config-prettier": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz", + "integrity": "sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==", + "dev": true, + "license": "MIT", + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz", + "integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==", + "dev": true, + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.31.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz", + "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==", + "dev": true, + "dependencies": { + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.8", + "array.prototype.findlastindex": "^1.2.5", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.12.0", + "hasown": "^2.0.2", + "is-core-module": "^2.15.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.0", + "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.8", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-import/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-jsdoc": { + "version": "48.11.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.11.0.tgz", + "integrity": "sha512-d12JHJDPNo7IFwTOAItCeJY1hcqoIxE0lHA8infQByLilQ9xkqrRa6laWCnsuCrf+8rUnvxXY1XuTbibRBNylA==", + "dev": true, + "dependencies": { + "@es-joy/jsdoccomment": "~0.46.0", + "are-docs-informative": "^0.0.2", + "comment-parser": "1.4.1", + "debug": "^4.3.5", + "escape-string-regexp": "^4.0.0", + "espree": "^10.1.0", + "esquery": "^1.6.0", + "parse-imports": "^2.1.1", + "semver": "^7.6.3", + "spdx-expression-parse": "^4.0.0", + "synckit": "^0.9.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-jsdoc/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-plugin-jsdoc/node_modules/spdx-expression-parse": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz", + "integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/eslint-plugin-prefer-arrow": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-prefer-arrow/-/eslint-plugin-prefer-arrow-1.2.2.tgz", + "integrity": "sha512-C8YMhL+r8RMeMdYAw/rQtE6xNdMulj+zGWud/qIGnlmomiPRaLDGLMeskZ3alN6uMBojmooRimtdrXebLN4svQ==", + "dev": true, + "peerDependencies": { + "eslint": ">=2.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", + "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/eslint/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==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "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/eslint/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==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/eslint/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==", + "dev": true + }, + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/eslint/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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint/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==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/espree": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", + "dev": true, + "dependencies": { + "acorn": "^8.14.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ethereum-blockies": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ethereum-blockies/-/ethereum-blockies-0.1.1.tgz", + "integrity": "sha512-ED+noMZ6z7RrzzhvrQna1L30C27MX+ZsdB5c/d5vygXtHjEyAQjQS2TgCYhPxs+z3U+u2YQsL9PiRkNl1f+ugg==" + }, + "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==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/execa/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/execa/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/expect-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.1.0.tgz", + "integrity": "sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/expect-webdriverio": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/expect-webdriverio/-/expect-webdriverio-5.1.0.tgz", + "integrity": "sha512-4u3q+Dqx/lXNgvCx1gKia4CfS28z1UxGGfVUkoMNbrsBlTBB2fYqXG+4+YtYoerxvp/XPwIb/+89IGEdyPbDXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/snapshot": "^2.0.5", + "expect": "^29.7.0", + "jest-matcher-utils": "^29.7.0", + "lodash.isequal": "^4.5.0" + }, + "engines": { + "node": ">=18 || >=20 || >=22" + }, + "peerDependencies": { + "@wdio/globals": "^9.0.0", + "@wdio/logger": "^9.0.0", + "webdriverio": "^9.0.0" + }, + "peerDependenciesMeta": { + "@wdio/globals": { + "optional": false + }, + "@wdio/logger": { + "optional": false + }, + "webdriverio": { + "optional": false + } + } + }, + "node_modules/expect-webdriverio/node_modules/@vitest/pretty-format": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.9.tgz", + "integrity": "sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/expect-webdriverio/node_modules/@vitest/snapshot": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.9.tgz", + "integrity": "sha512-oBO82rEjsxLNJincVhLhaxxZdEtV0EFHMK5Kmx5sJ6H9L183dHECjiefOAdnqpIgT5eZwT04PoggUnW88vOBNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "2.1.9", + "magic-string": "^0.30.12", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/expect-webdriverio/node_modules/tinyrainbow": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", + "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/exponential-backoff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz", + "integrity": "sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==", + "dev": true + }, + "node_modules/express": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "dev": true, + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.7.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.3.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.12", + "proxy-addr": "~2.0.7", + "qs": "6.13.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.19.0", + "serve-static": "1.16.2", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express/node_modules/cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/express/node_modules/finalhandler": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/express/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "dev": true, + "engines": [ + "node >=0.6.0" + ] + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "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==" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fast-uri": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.1.tgz", + "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==", + "dev": true + }, + "node_modules/fast-xml-parser": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.3.tgz", + "integrity": "sha512-RKihhV+SHsIUGXObeVy9AXiBbFwkVk7Syp8XgwN5U3JV416+Gwp/GO9i0JYKmikykgz/UHRrrV4ROuZEo/T0ig==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "dependencies": { + "strnum": "^1.1.1" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/fastparse": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz", + "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dev": true, + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/fdir": { + "version": "6.4.3", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.3.tgz", + "integrity": "sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, + "node_modules/fflate": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", + "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", + "dev": true, + "license": "MIT" + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true, + "license": "MIT" + }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-cache-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", + "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", + "dev": true, + "dependencies": { + "common-path-prefix": "^3.0.0", + "pkg-dir": "^7.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz", + "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==", + "dev": true, + "license": "ISC" + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/follow-redirects": { + "version": "1.15.8", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.8.tgz", + "integrity": "sha512-xgrmBhBToVKay1q2Tao5LI26B83UhrB/vM1avwVSDzt8rx3rO6AizBAaF46EgksTVr+rFTQaqZZ9MVBfUe4nig==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-each": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.4.tgz", + "integrity": "sha512-kKaIINnFpzW6ffJNDjjyjrk21BkDx38c0xa/klsT8VzLCaMEefv4ZTacrcVR4DmgTeBra++jMDAfS/tS799YDw==", + "dev": true, + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/foreground-child": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "dev": true, + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/front-matter": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/front-matter/-/front-matter-4.0.2.tgz", + "integrity": "sha512-I8ZuJ/qG92NWX8i5x1Y8qyj3vizhXS31OxjKDu3LKP+7/qBgfIKValiZIEwoVoJKUHlhWtYrktkxV1XsX+pPlg==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-yaml": "^3.13.1" + } + }, + "node_modules/front-matter/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/front-matter/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/front-matter/node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, + "node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fs-minipass": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", + "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/geckodriver": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/geckodriver/-/geckodriver-5.0.0.tgz", + "integrity": "sha512-vn7TtQ3b9VMJtVXsyWtQQl1fyBVFhQy7UvJF96kPuuJ0or5THH496AD3eUyaDD11+EqCxH9t6V+EP9soZQk4YQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@wdio/logger": "^9.1.3", + "@zip.js/zip.js": "^2.7.53", + "decamelize": "^6.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.5", + "node-fetch": "^3.3.2", + "tar-fs": "^3.0.6", + "which": "^5.0.0" + }, + "bin": { + "geckodriver": "bin/geckodriver.js" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/geckodriver/node_modules/bare-fs": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.0.1.tgz", + "integrity": "sha512-ilQs4fm/l9eMfWY2dY0WCIUplSUp7U0CT1vrqMg1MUdeZl4fypu5UP0XcDBK5WBQPJAKP1b7XEodISmekH/CEg==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "bare-events": "^2.0.0", + "bare-path": "^3.0.0", + "bare-stream": "^2.0.0" + }, + "engines": { + "bare": ">=1.7.0" + } + }, + "node_modules/geckodriver/node_modules/bare-os": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.5.1.tgz", + "integrity": "sha512-LvfVNDcWLw2AnIw5f2mWUgumW3I3N/WYGiWeimhQC1Ybt71n2FjlS9GJKeCnFeg1MKZHxzIFmpFnBXDI+sBeFg==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "engines": { + "bare": ">=1.14.0" + } + }, + "node_modules/geckodriver/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==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "bare-os": "^3.0.1" + } + }, + "node_modules/geckodriver/node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/geckodriver/node_modules/decamelize": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-6.0.0.tgz", + "integrity": "sha512-Fv96DCsdOgB6mdGl67MT5JaTNKRzrzill5OH5s8bjYJXVlcXyPYGyPsUkWyGV5p1TXI5esYIYMMeDJL0hEIwaA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/geckodriver/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/geckodriver/node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/geckodriver/node_modules/tar-fs": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.8.tgz", + "integrity": "sha512-ZoROL70jptorGAlgAYiLoBLItEKw/fUxg9BSYK/dF/GAGYFJOJJJMvjPAKDJraCXFwadD456FCuvLWgfhMsPwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0", + "tar-stream": "^3.1.5" + }, + "optionalDependencies": { + "bare-fs": "^4.0.1", + "bare-path": "^3.0.0" + } + }, + "node_modules/geckodriver/node_modules/tar-stream": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, + "node_modules/geckodriver/node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "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==", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz", + "integrity": "sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz", + "integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "function-bind": "^1.1.2", + "get-proto": "^1.0.0", + "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-port": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-7.1.0.tgz", + "integrity": "sha512-QB9NKEeDg3xxVwCCwJQ9+xycaz6pBB6iQ76wiWMl1927n0Kir6alPiP+yuiICLLU4jpMe08dXfpebuQppFA2zw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-port-please": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/get-port-please/-/get-port-please-3.1.2.tgz", + "integrity": "sha512-Gxc29eLs1fbn6LQ4jSU4vXjlwyZhF5HsGuMAa7gqBP4Rw4yxxltyDUuF5MBclFzDTXO+ACchGQoeela4DSfzdQ==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-tsconfig": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.0.tgz", + "integrity": "sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/get-uri": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.4.tgz", + "integrity": "sha512-E1b1lFFLvLgak2whF2xDBcOy6NLVGZBqqjJjsIhvopKfWWEi64pLVTWWehV8KlLerZkfNTA95sTe2OdJKm1OzQ==", + "dependencies": { + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^6.0.2", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/giget": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/giget/-/giget-1.2.4.tgz", + "integrity": "sha512-Wv+daGyispVoA31TrWAVR+aAdP7roubTPEM/8JzRnqXhLbdJH0T9eQyXVFF8fjk3WKTsctII6QcyxILYgNp2DA==", + "dev": true, + "license": "MIT", + "dependencies": { + "citty": "^0.1.6", + "consola": "^3.4.0", + "defu": "^6.1.4", + "node-fetch-native": "^1.6.6", + "nypm": "^0.5.1", + "ohash": "^1.1.4", + "pathe": "^2.0.2", + "tar": "^6.2.1" + }, + "bin": { + "giget": "dist/cli.mjs" + } + }, + "node_modules/giget/node_modules/pathe": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.2.tgz", + "integrity": "sha512-15Ztpk+nov8DR524R4BF7uEuzESgzUEAV4Ah7CUMNGXdE5ELuvxElxGXndBl32vMSsWa1jpNf22Z+Er3sKwq+w==", + "dev": true, + "license": "MIT" + }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" + }, + "node_modules/github-slugger": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.5.0.tgz", + "integrity": "sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw==", + "dev": true, + "license": "ISC" + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globby": { + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.2.tgz", + "integrity": "sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==", + "dev": true, + "dependencies": { + "@sindresorhus/merge-streams": "^2.1.0", + "fast-glob": "^3.3.2", + "ignore": "^5.2.4", + "path-type": "^5.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globrex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", + "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", + "dev": true, + "license": "MIT" + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "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==" + }, + "node_modules/grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/gzip-size": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-7.0.0.tgz", + "integrity": "sha512-O1Ld7Dr+nqPnmGpdhzLmMTQ4vAsD+rHwMm1NLUmoUFFymBOMKxCCrtDxqdBRYXdeEPEi3SyoR4TizJLQrnKBNA==", + "dev": true, + "license": "MIT", + "dependencies": { + "duplexer": "^0.1.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/h3": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/h3/-/h3-1.14.0.tgz", + "integrity": "sha512-ao22eiONdgelqcnknw0iD645qW0s9NnrJHr5OBz4WOMdBdycfSas1EQf1wXRsm+PcB2Yoj43pjBPwqIpJQTeWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cookie-es": "^1.2.2", + "crossws": "^0.3.2", + "defu": "^6.1.4", + "destr": "^2.0.3", + "iron-webcrypto": "^1.2.1", + "ohash": "^1.1.4", + "radix3": "^1.1.2", + "ufo": "^1.5.4", + "uncrypto": "^0.1.3", + "unenv": "^1.10.0" + } + }, + "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==", + "dev": true + }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", + "dev": true, + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/har-validator/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/har-validator/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-ansi/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "dev": true, + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/highcharts": { + "version": "11.4.8", + "resolved": "https://registry.npmjs.org/highcharts/-/highcharts-11.4.8.tgz", + "integrity": "sha512-5Tke9LuzZszC4osaFisxLIcw7xgNGz4Sy3Jc9pRMV+ydm6sYqsPYdU8ELOgpzGNrbrRNDRBtveoR5xS3SzneEA==" + }, + "node_modules/hookable": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz", + "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/hosted-git-info": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-8.0.2.tgz", + "integrity": "sha512-sYKnA7eGln5ov8T8gnYlkSOxFJvywzEx9BueN6xo/GKO8PGiI6uK6xx+DIGe45T3bdVjLAQDQW1aicT8z8JwQg==", + "dev": true, + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/hosted-git-info/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==", + "dev": true + }, + "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==", + "dev": 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==", + "dev": 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/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==", + "dev": true + }, + "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==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-encoding": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true, + "license": "MIT" + }, + "node_modules/htmlfy": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/htmlfy/-/htmlfy-0.6.1.tgz", + "integrity": "sha512-aXlXhSv/40ZRWSW8auSRgPkF5owlJE2c2EkOKTe3n+I1fa/MKWfiNWP9ukexW4Pnj94k7x8TK5sa44l2ySWQ6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/htmlparser2": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", + "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "entities": "^4.5.0" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", + "dev": true + }, + "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==", + "dev": true + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-errors/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.9.tgz", + "integrity": "sha512-n1XsPy3rXVxlqxVioEWdC+0+M+SQw0DpJynwtOPo1X+ZlvdzTLtDBIJJlDQTnwZIFJrZSzSGmIOUdP8tu+SgLw==", + "dev": true + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dev": true, + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/http-proxy-middleware": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-3.0.3.tgz", + "integrity": "sha512-usY0HG5nyDUwtqpiZdETNbmKtw3QQ1jwYFZ9wi5iHzX2BcILwQKtYDJPo7XHTsu5Z0B2Hj3W9NNnbd+AjFWjqg==", + "dev": true, + "dependencies": { + "@types/http-proxy": "^1.17.15", + "debug": "^4.3.6", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.3", + "is-plain-object": "^5.0.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/http-proxy-middleware/node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/http-shutdown": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/http-shutdown/-/http-shutdown-1.2.2.tgz", + "integrity": "sha512-S9wWkJ/VSY9/k4qcjG318bqJNruzE4HySUhFYknwmu6LBP97KLLfwNf+n4V1BHurvFNkSKLFnK/RsuUnRTf9Vw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/httpxy": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/httpxy/-/httpxy-0.1.7.tgz", + "integrity": "sha512-pXNx8gnANKAndgga5ahefxc++tJvNL87CXoRwxn1cJE2ZkWEojF3tNfQIEhZX/vfpt+wzeAzpUI4qkediX1MLQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/hyperdyperid": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz", + "integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==", + "dev": true, + "engines": { + "node": ">=10.18" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "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" + } + ] + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/ignore-walk": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-7.0.0.tgz", + "integrity": "sha512-T4gbf83A4NH95zvhVYZc+qWocBBGlpzUXLPGurJggw/WIOwicfXJChLDP/iBZnN5WqROSu5Bm3hhle4z8a8YGQ==", + "dev": true, + "dependencies": { + "minimatch": "^9.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/image-size": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", + "integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==", + "dev": true, + "optional": true, + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", + "dev": true + }, + "node_modules/immutable": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.0.3.tgz", + "integrity": "sha512-P8IdPQHq3lA1xVeBRi5VPqUm5HDgKnx0Ru51wZz5mjxHr5n3RWhjIpOFU7ybkUxfB+5IToy+OLaHYDBIWsv+uw==", + "dev": true + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-meta-resolve": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", + "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/index-to-position": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/index-to-position/-/index-to-position-0.1.2.tgz", + "integrity": "sha512-MWDKS3AS1bGCHLBA2VLImJz42f7bJh8wQsTGCzI3j519/CASStoDONUBVz2I/VID0MpiX3SGSnbOD2xUalbE5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ini": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.3.tgz", + "integrity": "sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/inquirer": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-11.1.0.tgz", + "integrity": "sha512-CmLAZT65GG/v30c+D2Fk8+ceP6pxD6RL+hIUOWAltCmeyEqWYwqu9v76q03OvjyZ3AB0C1Ala2stn1z/rMqGEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^9.2.1", + "@inquirer/prompts": "^6.0.1", + "@inquirer/type": "^2.0.0", + "@types/mute-stream": "^0.0.4", + "ansi-escapes": "^4.3.2", + "mute-stream": "^1.0.0", + "run-async": "^3.0.0", + "rxjs": "^7.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/inquirer/node_modules/@inquirer/checkbox": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-3.0.1.tgz", + "integrity": "sha512-0hm2nrToWUdD6/UHnel/UKGdk1//ke5zGUpHIvk5ZWmaKezlGxZkOJXNSWsdxO/rEqTkbB3lNC2J6nBElV2aAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^9.2.1", + "@inquirer/figures": "^1.0.6", + "@inquirer/type": "^2.0.0", + "ansi-escapes": "^4.3.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/inquirer/node_modules/@inquirer/confirm": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-4.0.1.tgz", + "integrity": "sha512-46yL28o2NJ9doViqOy0VDcoTzng7rAb6yPQKU7VDLqkmbCaH4JqK4yk4XqlzNWy9PVC5pG1ZUXPBQv+VqnYs2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^9.2.1", + "@inquirer/type": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/inquirer/node_modules/@inquirer/core": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-9.2.1.tgz", + "integrity": "sha512-F2VBt7W/mwqEU4bL0RnHNZmC/OxzNx9cOYxHqnXX3MP6ruYvZUZAW9imgN9+h/uBT/oP8Gh888J2OZSbjSeWcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/figures": "^1.0.6", + "@inquirer/type": "^2.0.0", + "@types/mute-stream": "^0.0.4", + "@types/node": "^22.5.5", + "@types/wrap-ansi": "^3.0.0", + "ansi-escapes": "^4.3.2", + "cli-width": "^4.1.0", + "mute-stream": "^1.0.0", + "signal-exit": "^4.1.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/inquirer/node_modules/@inquirer/editor": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-3.0.1.tgz", + "integrity": "sha512-VA96GPFaSOVudjKFraokEEmUQg/Lub6OXvbIEZU1SDCmBzRkHGhxoFAVaF30nyiB4m5cEbDgiI2QRacXZ2hw9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^9.2.1", + "@inquirer/type": "^2.0.0", + "external-editor": "^3.1.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/inquirer/node_modules/@inquirer/expand": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-3.0.1.tgz", + "integrity": "sha512-ToG8d6RIbnVpbdPdiN7BCxZGiHOTomOX94C2FaT5KOHupV40tKEDozp12res6cMIfRKrXLJyexAZhWVHgbALSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^9.2.1", + "@inquirer/type": "^2.0.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/inquirer/node_modules/@inquirer/input": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-3.0.1.tgz", + "integrity": "sha512-BDuPBmpvi8eMCxqC5iacloWqv+5tQSJlUafYWUe31ow1BVXjW2a5qe3dh4X/Z25Wp22RwvcaLCc2siHobEOfzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^9.2.1", + "@inquirer/type": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/inquirer/node_modules/@inquirer/number": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-2.0.1.tgz", + "integrity": "sha512-QpR8jPhRjSmlr/mD2cw3IR8HRO7lSVOnqUvQa8scv1Lsr3xoAMMworcYW3J13z3ppjBFBD2ef1Ci6AE5Qn8goQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^9.2.1", + "@inquirer/type": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/inquirer/node_modules/@inquirer/password": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-3.0.1.tgz", + "integrity": "sha512-haoeEPUisD1NeE2IanLOiFr4wcTXGWrBOyAyPZi1FfLJuXOzNmxCJPgUrGYKVh+Y8hfGJenIfz5Wb/DkE9KkMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^9.2.1", + "@inquirer/type": "^2.0.0", + "ansi-escapes": "^4.3.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/inquirer/node_modules/@inquirer/prompts": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-6.0.1.tgz", + "integrity": "sha512-yl43JD/86CIj3Mz5mvvLJqAOfIup7ncxfJ0Btnl0/v5TouVUyeEdcpknfgc+yMevS/48oH9WAkkw93m7otLb/A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/checkbox": "^3.0.1", + "@inquirer/confirm": "^4.0.1", + "@inquirer/editor": "^3.0.1", + "@inquirer/expand": "^3.0.1", + "@inquirer/input": "^3.0.1", + "@inquirer/number": "^2.0.1", + "@inquirer/password": "^3.0.1", + "@inquirer/rawlist": "^3.0.1", + "@inquirer/search": "^2.0.1", + "@inquirer/select": "^3.0.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/inquirer/node_modules/@inquirer/rawlist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-3.0.1.tgz", + "integrity": "sha512-VgRtFIwZInUzTiPLSfDXK5jLrnpkuSOh1ctfaoygKAdPqjcjKYmGh6sCY1pb0aGnCGsmhUxoqLDUAU0ud+lGXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^9.2.1", + "@inquirer/type": "^2.0.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/inquirer/node_modules/@inquirer/search": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-2.0.1.tgz", + "integrity": "sha512-r5hBKZk3g5MkIzLVoSgE4evypGqtOannnB3PKTG9NRZxyFRKcfzrdxXXPcoJQsxJPzvdSU2Rn7pB7lw0GCmGAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^9.2.1", + "@inquirer/figures": "^1.0.6", + "@inquirer/type": "^2.0.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/inquirer/node_modules/@inquirer/select": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-3.0.1.tgz", + "integrity": "sha512-lUDGUxPhdWMkN/fHy1Lk7pF3nK1fh/gqeyWXmctefhxLYxlDsc7vsPBEpxrfVGDsVdyYJsiJoD4bJ1b623cV1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^9.2.1", + "@inquirer/figures": "^1.0.6", + "@inquirer/type": "^2.0.0", + "ansi-escapes": "^4.3.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/inquirer/node_modules/@inquirer/type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-2.0.0.tgz", + "integrity": "sha512-XvJRx+2KR3YXyYtPUUy+qd9i7p+GO9Ko6VIIpWlBrpWwXDv8WLFeHTxz35CfQFUiBMLXlGHhGzys7lqit9gWag==", + "dev": true, + "license": "MIT", + "dependencies": { + "mute-stream": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/inquirer/node_modules/mute-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", + "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/intl": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/intl/-/intl-1.2.5.tgz", + "integrity": "sha512-rK0KcPHeBFBcqsErKSpvZnrOmWOj+EmDkyJ57e90YWaQNqbcivcqmKDlHEeNprDWOsKzPsh1BfSpPQdDvclHVw==" + }, + "node_modules/ionicons": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/ionicons/-/ionicons-7.4.0.tgz", + "integrity": "sha512-ZK94MMqgzMCPPMhmk8Ouu6goyVHFIlw/ACP6oe3FrikcI0N7CX0xcwVaEbUc0G/v3W0shI93vo+9ve/KpvcNhQ==", + "dependencies": { + "@stencil/core": "^4.0.3" + } + }, + "node_modules/ioredis": { + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.4.2.tgz", + "integrity": "sha512-0SZXGNGZ+WzISQ67QDyZ2x0+wVxjjUndtD8oSeik/4ajifeiRufed8fCb8QW8VMyi4MXcS+UO1k/0NGhvq1PAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ioredis/commands": "^1.1.1", + "cluster-key-slot": "^1.1.0", + "debug": "^4.3.4", + "denque": "^2.1.0", + "lodash.defaults": "^4.2.0", + "lodash.isarguments": "^3.1.0", + "redis-errors": "^1.2.0", + "redis-parser": "^3.0.0", + "standard-as-callback": "^2.1.0" + }, + "engines": { + "node": ">=12.22.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ioredis" + } + }, + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/ipaddr.js": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", + "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/iron-webcrypto": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/iron-webcrypto/-/iron-webcrypto-1.2.1.tgz", + "integrity": "sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/brc-dd" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "dev": true, + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.1.tgz", + "integrity": "sha512-l9qO6eFlUETHtuihLcYOaLKByJ1f+N4kthcU9YjHy3N+B3hWv0y/2Nd0mu/7lTFnRQHTrSdXF50HQ3bl5fEnng==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "dev": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", + "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "get-proto": "^1.0.0", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dev": true, + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-network-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.1.0.tgz", + "integrity": "sha512-tUdRRAnhT+OtCZR/LxZelH/C7QtjtFrTu5tXCA8pl55eTUElUHT+GPYV8MBMBvea/j+NxQqVt3LbWMRir7Gx9g==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-path-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha512-cnS56eR9SPAscL77ik76ATVqoPARTqPIVkMDVxRaWH06zT+6+CzIroYRJ0VVvm0Z1zfAvxvz9i/D3Ppjaqt5Nw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-path-in-cwd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", + "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", + "dev": true, + "dependencies": { + "is-path-inside": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-path-in-cwd/node_modules/is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha512-qhsCR/Esx4U4hg/9I19OVUAJkGWtjRYHMRgUMZE2TDdj+Ag+kttZanLupfddNyglzz50cUlmWzUaI37GDfNx/g==", + "dev": true, + "dependencies": { + "path-is-inside": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-reference": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", + "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.0.tgz", + "integrity": "sha512-SXM8Nwyys6nT5WP6pltOwKytLV7FqQ4UiibxVmW+EIosHcmCqkkjViTb5SNssDlkCiEYRP1/pdWUKVvZBmsR2Q==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-what": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz", + "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==", + "dev": true + }, + "node_modules/is-wsl": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "dev": true, + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is64bit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is64bit/-/is64bit-2.0.0.tgz", + "integrity": "sha512-jv+8jaWCl0g2lSBkNSVXdzfBA0npK1HGC2KtWM9FumFRoGS94g3NbCCLVnCYHLjp4GrW2KZeeSTMo5ddtznmGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "system-architecture": "^0.1.0" + }, + "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==", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", + "dev": true + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", + "dev": true, + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz", + "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.23", + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jake": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", + "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.4", + "minimatch": "^3.1.2" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jake/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jake/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/jake/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": 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/jake/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jake/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/jake/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jake/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/jake/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jasmine": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-2.8.0.tgz", + "integrity": "sha512-KbdGQTf5jbZgltoHs31XGiChAPumMSY64OZMWLNYnEnMfG5uwGBhffePwuskexjT+/Jea/gU3qAU8344hNohSw==", + "dev": true, + "dependencies": { + "exit": "^0.1.2", + "glob": "^7.0.6", + "jasmine-core": "~2.8.0" + }, + "bin": { + "jasmine": "bin/jasmine.js" + } + }, + "node_modules/jasmine-core": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-5.1.2.tgz", + "integrity": "sha512-2oIUMGn00FdUiqz6epiiJr7xcFyNYj3rDcfmnzfkBnHyBQ3cBQUs4mmyGsOb7TTLb9kxk7dBcmEmqhDKkBoDyA==", + "dev": true + }, + "node_modules/jasmine-spec-reporter": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/jasmine-spec-reporter/-/jasmine-spec-reporter-5.0.2.tgz", + "integrity": "sha512-6gP1LbVgJ+d7PKksQBc2H0oDGNRQI3gKUsWlswKaQ2fif9X5gzhQcgM5+kiJGCQVurOG09jqNhk7payggyp5+g==", + "dev": true, + "dependencies": { + "colors": "1.4.0" + } + }, + "node_modules/jasmine/node_modules/jasmine-core": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.8.0.tgz", + "integrity": "sha512-SNkOkS+/jMZvLhuSx1fjhcNWUC/KG6oVyFUGkSBEr9n1axSNduWU8GlI7suaHXr4yxjet6KjrUZxUTE5WzzWwQ==", + "dev": true + }, + "node_modules/jasminewd2": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/jasminewd2/-/jasminewd2-2.2.0.tgz", + "integrity": "sha512-Rn0nZe4rfDhzA63Al3ZGh0E+JTmM6ESZYXJGKuqKGZObsAB9fwXPD03GjtIEvJBDOhN94T5MzbwZSqzFHSQPzg==", + "dev": true, + "engines": { + "node": ">= 6.9.x" + } + }, + "node_modules/java-parser": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/java-parser/-/java-parser-1.0.2.tgz", + "integrity": "sha512-lBXc+F62ds2W83eH5MwGnzuWdb6kgGBV0x0R7w0B4JKGDrJzolMUEhRMzzzlIX68HvRU7XtfPon22YaB+dVg+A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "chevrotain": "6.5.0", + "lodash": "4.17.21" + } + }, + "node_modules/jest-diff": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-diff/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": 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/jest-diff/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-diff/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-diff/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-diff/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": 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/jest-matcher-utils/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-matcher-utils/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-matcher-utils/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-matcher-utils/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": 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/jest-message-util/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-message-util/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-message-util/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-util/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": 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/jest-util/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-util/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-util/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-util/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/jest-util/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jetifier": { + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/jetifier/-/jetifier-1.6.8.tgz", + "integrity": "sha512-3Zi16h6L5tXDRQJTb221cnRoVG9/9OvreLdLU2/ZjRv/GILL+2Cemt0IKvkowwkDpvouAU1DQPOJ7qaiHeIdrw==", + "bin": { + "jetifier": "bin/jetify", + "jetifier-standalone": "bin/jetifier-standalone", + "jetify": "bin/jetify" + } + }, + "node_modules/jiti": { + "version": "1.21.6", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", + "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", + "dev": true, + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/js-levenshtein": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz", + "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.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==" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==" + }, + "node_modules/jsdoc-type-pratt-parser": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.0.0.tgz", + "integrity": "sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==", + "dev": true, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/jsdom": { + "version": "22.1.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-22.1.0.tgz", + "integrity": "sha512-/9AVW7xNbsBv6GfWho4TTNjEo9fe6Zhf9O7s0Fhhr3u+awPwAJMKwAMXnkk5vBxflqLW9hTHX/0cs+P3gW+cQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "abab": "^2.0.6", + "cssstyle": "^3.0.0", + "data-urls": "^4.0.0", + "decimal.js": "^10.4.3", + "domexception": "^4.0.0", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.1", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.4", + "parse5": "^7.1.2", + "rrweb-cssom": "^0.6.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.1.2", + "w3c-xmlserializer": "^4.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^2.0.0", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^12.0.1", + "ws": "^8.13.0", + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jsdom/node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/jsdom/node_modules/form-data": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jsdom/node_modules/http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jsdom/node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jsdom/node_modules/tough-cookie": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", + "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsdom/node_modules/tr46": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", + "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.3.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/jsdom/node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/jsdom/node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/jsdom/node_modules/whatwg-url": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-12.0.1.tgz", + "integrity": "sha512-Ed/LrqB8EPlGxjS+TrsXcpUond1mhccS3pchLhzSgPCnTimUCKj3IZE75pAs5m6heB2U2TMerKFUXheyHY+VDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "^4.1.1", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsftp": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/jsftp/-/jsftp-2.1.3.tgz", + "integrity": "sha512-r79EVB8jaNAZbq8hvanL8e8JGu2ZNr2bXdHC4ZdQhRImpSPpnWwm5DYVzQ5QxJmtGtKhNNuvqGgbNaFl604fEQ==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "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==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "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==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==" + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "dev": true, + "engines": [ + "node >= 0.2.0" + ] + }, + "node_modules/jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "dev": true, + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/jszip": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", + "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", + "dev": true, + "dependencies": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "setimmediate": "^1.0.5" + } + }, + "node_modules/jszip/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==", + "dev": 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/jszip/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==", + "dev": true + }, + "node_modules/jszip/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==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/karma-source-map-support": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/karma-source-map-support/-/karma-source-map-support-1.4.0.tgz", + "integrity": "sha512-RsBECncGO17KAoJCYXjv+ckIz+Ii9NCi+9enk+rq6XC81ezYkb4/RHE6CTXdA7IOJqoF3wcaLfVG0CPmE5ca6A==", + "dev": true, + "dependencies": { + "source-map-support": "^0.5.5" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/klaw": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-4.1.0.tgz", + "integrity": "sha512-1zGZ9MF9H22UnkpVeuaGKOjfA2t6WrfdrJmGjy16ykcjnKQDmHVX+KI477rpbGevz/5FD4MC3xf1oxylBgcaQw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.14.0" + } + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/klona": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz", + "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/knitwork": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/knitwork/-/knitwork-1.2.0.tgz", + "integrity": "sha512-xYSH7AvuQ6nXkq42x0v5S8/Iry+cfulBz/DJQzhIyESdLD7425jXsPy4vn5cCXU+HhRN2kVw51Vd1K6/By4BQg==", + "dev": true, + "license": "MIT" + }, + "node_modules/kuler": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", + "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==", + "dev": true, + "license": "MIT" + }, + "node_modules/launch-editor": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.9.1.tgz", + "integrity": "sha512-Gcnl4Bd+hRO9P9icCP/RVVT2o8SFlPXofuCxvA2SaZuH45whSvf5p8x5oih5ftLiVhEI4sp5xDY+R+b3zJBh5w==", + "dev": true, + "dependencies": { + "picocolors": "^1.0.0", + "shell-quote": "^1.8.1" + } + }, + "node_modules/lazystream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", + "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", + "dev": true, + "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==", + "dev": 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/lazystream/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==", + "dev": true + }, + "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==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/less": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/less/-/less-4.2.1.tgz", + "integrity": "sha512-CasaJidTIhWmjcqv0Uj5vccMI7pJgfD9lMkKtlnTHAdJdYK/7l8pM9tumLyJ0zhbD4KJLo/YvTj+xznQd5NBhg==", + "dev": true, + "dependencies": { + "copy-anything": "^2.0.1", + "parse-node-version": "^1.0.1", + "tslib": "^2.3.0" + }, + "bin": { + "lessc": "bin/lessc" + }, + "engines": { + "node": ">=6" + }, + "optionalDependencies": { + "errno": "^0.1.1", + "graceful-fs": "^4.1.2", + "image-size": "~0.5.0", + "make-dir": "^2.1.0", + "mime": "^1.4.1", + "needle": "^3.1.0", + "source-map": "~0.6.0" + } + }, + "node_modules/less-loader": { + "version": "12.2.0", + "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-12.2.0.tgz", + "integrity": "sha512-MYUxjSQSBUQmowc0l5nPieOYwMzGPUaTzB6inNW/bdPEG9zOL3eAAD1Qw5ZxSPk7we5dMojHwNODYMV1hq4EVg==", + "dev": true, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "less": "^3.5.0 || ^4.0.0", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/less/node_modules/make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "optional": true, + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/less/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "optional": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/less/node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/less/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "optional": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/less/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/license-webpack-plugin": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-4.0.2.tgz", + "integrity": "sha512-771TFWFD70G1wLTC4oU2Cw4qvtmNrIw+wRvBtn+okgHl7slJVi7zfNcdmqDL72BojM30VNJ2UHylr1o77U37Jw==", + "dev": true, + "dependencies": { + "webpack-sources": "^3.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-sources": { + "optional": true + } + } + }, + "node_modules/lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "dev": true, + "dependencies": { + "immediate": "~3.0.5" + } + }, + "node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + }, + "node_modules/listhen": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/listhen/-/listhen-1.9.0.tgz", + "integrity": "sha512-I8oW2+QL5KJo8zXNWX046M134WchxsXC7SawLPvRQpogCbkyQIaFxPE89A2HiwR7vAK2Dm2ERBAmyjTYGYEpBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/watcher": "^2.4.1", + "@parcel/watcher-wasm": "^2.4.1", + "citty": "^0.1.6", + "clipboardy": "^4.0.0", + "consola": "^3.2.3", + "crossws": ">=0.2.0 <0.4.0", + "defu": "^6.1.4", + "get-port-please": "^3.1.2", + "h3": "^1.12.0", + "http-shutdown": "^1.2.2", + "jiti": "^2.1.2", + "mlly": "^1.7.1", + "node-forge": "^1.3.1", + "pathe": "^1.1.2", + "std-env": "^3.7.0", + "ufo": "^1.5.4", + "untun": "^0.1.3", + "uqr": "^0.1.2" + }, + "bin": { + "listen": "bin/listhen.mjs", + "listhen": "bin/listhen.mjs" + } + }, + "node_modules/listhen/node_modules/jiti": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", + "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/listr2": { + "version": "8.2.5", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.2.5.tgz", + "integrity": "sha512-iyAZCeyD+c1gPyE9qpFu8af0Y+MRtmKOncdGoA2S5EY8iFq99dmmvkNnHiWo+pj0s7yH7l3KPIgee77tKpXPWQ==", + "dev": true, + "dependencies": { + "cli-truncate": "^4.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.1.0", + "rfdc": "^1.4.1", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/listr2/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/listr2/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/listr2/node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "dev": true + }, + "node_modules/listr2/node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "dev": true + }, + "node_modules/listr2/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==", + "dev": true, + "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/listr2/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/listr2/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "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/lmdb": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/lmdb/-/lmdb-3.2.2.tgz", + "integrity": "sha512-LriG93la4PbmPMwI7Hbv8W+0ncLK7549w4sbZSi4QGDjnnxnmNMgxUkaQTEMzH8TpwsfFvgEjpLX7V8B/I9e3g==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "dependencies": { + "msgpackr": "^1.11.2", + "node-addon-api": "^6.1.0", + "node-gyp-build-optional-packages": "5.2.2", + "ordered-binary": "^1.5.3", + "weak-lru-cache": "^1.2.2" + }, + "bin": { + "download-lmdb-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@lmdb/lmdb-darwin-arm64": "3.2.2", + "@lmdb/lmdb-darwin-x64": "3.2.2", + "@lmdb/lmdb-linux-arm": "3.2.2", + "@lmdb/lmdb-linux-arm64": "3.2.2", + "@lmdb/lmdb-linux-x64": "3.2.2", + "@lmdb/lmdb-win32-x64": "3.2.2" + } + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "dev": true, + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/loader-utils": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.3.1.tgz", + "integrity": "sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==", + "dev": true, + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/local-pkg": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-1.0.0.tgz", + "integrity": "sha512-bbgPw/wmroJsil/GgL4qjDzs5YLTBMQ99weRsok1XCDccQeehbHA/I1oRvk2NPtr7KGZgT/Y5tPRnAtMqeG2Kg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mlly": "^1.7.3", + "pkg-types": "^1.3.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/locate-app": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/locate-app/-/locate-app-2.5.0.tgz", + "integrity": "sha512-xIqbzPMBYArJRmPGUZD9CzV9wOqmVtQnaAn3wrj3s6WYW0bQvPI7x+sPYUGmDTYMHefVK//zc6HEYZ1qnxIK+Q==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://buymeacoffee.com/hejny" + }, + { + "type": "github", + "url": "https://github.com/hejny/locate-app/blob/main/README.md#%EF%B8%8F-contributing" + } + ], + "license": "Apache-2.0", + "dependencies": { + "@promptbook/utils": "0.69.5", + "type-fest": "4.26.0", + "userhome": "1.0.1" + } + }, + "node_modules/locate-app/node_modules/type-fest": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.26.0.tgz", + "integrity": "sha512-OduNjVJsFbifKb57UqZ2EMP1i4u64Xwow3NYXUtBbD4vIwJdQd4+xl8YDou1dlm4DVrtwT/7Ky8z8WyCULVfxw==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lockfile": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lockfile/-/lockfile-1.0.4.tgz", + "integrity": "sha512-cvbTwETRfsFh4nHsL1eGWapU1XFi5Ot9E85sWAwia7Y7EgB7vfqcZhTKZ+l7hCGxSPoushMv5GKhT5PdLv03WA==", + "dev": true, + "license": "ISC", + "dependencies": { + "signal-exit": "^3.0.2" + } + }, + "node_modules/lockfile/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==", + "dev": true, + "license": "ISC" + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true + }, + "node_modules/lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", + "deprecated": "This package is deprecated. Use the optional chaining (?.) operator instead.", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", + "deprecated": "This package is deprecated. Use require('node:util').isDeepStrictEqual instead.", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lodash.pickby": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.pickby/-/lodash.pickby-4.6.0.tgz", + "integrity": "sha512-AZV+GsS/6ckvPOVQPXSiFFacKvKB4kOQu6ynt9wz0F3LO4R9Ij4K1ddYsIytDpSgLz88JHd9P+oaLeej5/Sl7Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.union": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", + "integrity": "sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.zip": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.zip/-/lodash.zip-4.2.0.tgz", + "integrity": "sha512-C7IOaBBK/0gMORRBd8OETNx3kmOkgIWIPvyDpZSCTwUrpYmgZwJkjZeOD8ww4xbOUOs4/attY+pciKvadNfFbg==", + "dev": true, + "license": "MIT" + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/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==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "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/log-symbols/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==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/log-symbols/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==", + "dev": true + }, + "node_modules/log-symbols/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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/log-symbols/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==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/log-update": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", + "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", + "dev": true, + "dependencies": { + "ansi-escapes": "^7.0.0", + "cli-cursor": "^5.0.0", + "slice-ansi": "^7.1.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-escapes": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.0.0.tgz", + "integrity": "sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==", + "dev": true, + "dependencies": { + "environment": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/log-update/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-update/node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "dev": true + }, + "node_modules/log-update/node_modules/is-fullwidth-code-point": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz", + "integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==", + "dev": true, + "dependencies": { + "get-east-asian-width": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz", + "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/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==", + "dev": true, + "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/log-update/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "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/logform": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.7.0.tgz", + "integrity": "sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ==", + "dev": true, + "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/loglevel": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.9.2.tgz", + "integrity": "sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/loglevel" + } + }, + "node_modules/loglevel-plugin-prefix": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/loglevel-plugin-prefix/-/loglevel-plugin-prefix-0.8.4.tgz", + "integrity": "sha512-WpG9CcFAOjz/FtNht+QJeGpvVl/cdR6P0z6OcXSkr8wFJOsV2GRj2j10JLfjuA4aYkcKCNIEqRGCyTife9R8/g==", + "dev": true, + "license": "MIT" + }, + "node_modules/loupe": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.3.tgz", + "integrity": "sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==", + "dev": true, + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/luxon": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.5.0.tgz", + "integrity": "sha512-rh+Zjr6DNfUYR3bPwJEnuwDdqMbxZW7LOQfUN4B54+Cl+0o5zaU9RJ6bcidfDtC1cWCZXQ+nvX8bf6bAji37QQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/magicast": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.5.tgz", + "integrity": "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.25.4", + "@babel/types": "^7.25.4", + "source-map-js": "^1.2.0" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/make-fetch-happen": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-14.0.3.tgz", + "integrity": "sha512-QMjGbFTP0blj97EeidG5hk/QhKQ3T4ICckQGLgz38QF7Vgbk6e6FTARN8KhKxyBbWn8R0HU+bnw8aSoFPD4qtQ==", + "dev": true, + "dependencies": { + "@npmcli/agent": "^3.0.0", + "cacache": "^19.0.1", + "http-cache-semantics": "^4.1.1", + "minipass": "^7.0.2", + "minipass-fetch": "^4.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^1.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "ssri": "^12.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/make-fetch-happen/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==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memfs": { + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.17.0.tgz", + "integrity": "sha512-4eirfZ7thblFmqFjywlTmuWVSvccHAJbn1r8qQLzmTO11qcqpohOjmY2mFce6x7x7WtskzRqApPD0hv+Oa74jg==", + "dev": true, + "dependencies": { + "@jsonjoy.com/json-pack": "^1.0.3", + "@jsonjoy.com/util": "^1.3.0", + "tree-dump": "^1.0.1", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">= 4.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mini-css-extract-plugin": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.2.tgz", + "integrity": "sha512-GJuACcS//jtq4kCtd5ii/M0SZf7OZRH+BxdqXZHaJfb8TJiVl+NgQRPwiYt2EuqeSkNydn/7vP+bcE27C5mb9w==", + "dev": true, + "dependencies": { + "schema-utils": "^4.0.0", + "tapable": "^2.2.1" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "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==", + "dev": true + }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-collect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", + "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-fetch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-4.0.0.tgz", + "integrity": "sha512-2v6aXUXwLP1Epd/gc32HAMIWoczx+fZwEPRHm/VwtrJzRGwR1qGZXEYV3Zp8ZjjbwaZhMrM6uHV4KVkk+XCc2w==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^3.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/minipass-fetch/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "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/minipass-fetch/node_modules/minizlib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.1.tgz", + "integrity": "sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==", + "dev": true, + "dependencies": { + "minipass": "^7.0.4", + "rimraf": "^5.0.5" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/minipass-fetch/node_modules/rimraf": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", + "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", + "dev": true, + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-flush/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-flush/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==" + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" + }, + "node_modules/mlly": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.4.tgz", + "integrity": "sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.14.0", + "pathe": "^2.0.1", + "pkg-types": "^1.3.0", + "ufo": "^1.5.4" + } + }, + "node_modules/mlly/node_modules/pathe": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.2.tgz", + "integrity": "sha512-15Ztpk+nov8DR524R4BF7uEuzESgzUEAV4Ah7CUMNGXdE5ELuvxElxGXndBl32vMSsWa1jpNf22Z+Er3sKwq+w==", + "dev": true, + "license": "MIT" + }, + "node_modules/mocha": { + "version": "10.8.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.8.2.tgz", + "integrity": "sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.3", + "browser-stdout": "^1.3.1", + "chokidar": "^3.5.3", + "debug": "^4.3.5", + "diff": "^5.2.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^8.1.0", + "he": "^1.2.0", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^5.1.6", + "ms": "^2.1.3", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^6.5.1", + "yargs": "^16.2.0", + "yargs-parser": "^20.2.9", + "yargs-unparser": "^2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha.js" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/mocha/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/mocha/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/mocha/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/mocha/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/mocha/node_modules/diff": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/mocha/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mocha/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/mocha/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/mocha/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "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/mocha/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/morgan": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", + "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "basic-auth": "~2.0.1", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-finished": "~2.3.0", + "on-headers": "~1.0.2" + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/mrmime": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", + "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "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==" + }, + "node_modules/msgpackr": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.2.tgz", + "integrity": "sha512-F9UngXRlPyWCDEASDpTf6c9uNhGPTqnTeLVt7bN+bU1eajoR/8V9ys2BRaV5C/e5ihE6sJ9uPIKaYt6bFuO32g==", + "dev": true, + "optional": true, + "optionalDependencies": { + "msgpackr-extract": "^3.0.2" + } + }, + "node_modules/msgpackr-extract": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.3.tgz", + "integrity": "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "dependencies": { + "node-gyp-build-optional-packages": "5.2.2" + }, + "bin": { + "download-msgpackr-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3" + } + }, + "node_modules/multicast-dns": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", + "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", + "dev": true, + "dependencies": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + }, + "bin": { + "multicast-dns": "cli.js" + } + }, + "node_modules/mute-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", + "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/mv": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", + "integrity": "sha512-at/ZndSy3xEGJ8i0ygALh8ru9qy7gWW1cmkaqBN29JmMlIvM//MEO9y1sk/avxuwnPcfhkejkLsuPxH81BrkSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mkdirp": "~0.5.1", + "ncp": "~2.0.0", + "rimraf": "~2.4.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/mv/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/mv/node_modules/glob": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "integrity": "sha512-MKZeRNyYZAVVVG1oZeLaWie1uweH40m9AZwIwxyPbTSX4hHrVYSzLg0Ro5Z5R7XKkIX+Cc6oD1rqeDJnwsB8/A==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/mv/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/mv/node_modules/rimraf": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", + "integrity": "sha512-J5xnxTyqaiw06JjMftq7L9ouA448dw/E7dKghkP9WpKNuwmARNNg+Gk8/u5ryb9N/Yo2+z3MCwuqFK/+qPOPfQ==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^6.0.1" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" + }, + "node_modules/native-run": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/native-run/-/native-run-2.0.1.tgz", + "integrity": "sha512-XfG1FBZLM50J10xH9361whJRC9SHZ0Bub4iNRhhI61C8Jv0e1ud19muex6sNKB51ibQNUJNuYn25MuYET/rE6w==", + "dev": true, + "dependencies": { + "@ionic/utils-fs": "^3.1.7", + "@ionic/utils-terminal": "^2.3.4", + "bplist-parser": "^0.3.2", + "debug": "^4.3.4", + "elementtree": "^0.1.7", + "ini": "^4.1.1", + "plist": "^3.1.0", + "split2": "^4.2.0", + "through2": "^4.0.2", + "tslib": "^2.6.2", + "yauzl": "^2.10.0" + }, + "bin": { + "native-run": "bin/native-run" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "bin": { + "ncp": "bin/ncp" + } + }, + "node_modules/needle": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/needle/-/needle-3.3.1.tgz", + "integrity": "sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==", + "dev": true, + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.3", + "sax": "^1.2.4" + }, + "bin": { + "needle": "bin/needle" + }, + "engines": { + "node": ">= 4.4.x" + } + }, + "node_modules/needle/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/needle/node_modules/sax": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", + "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", + "dev": true, + "optional": true + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node_modules/netmask": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", + "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/ng2-tooltip-directive-major-angular-updates": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/ng2-tooltip-directive-major-angular-updates/-/ng2-tooltip-directive-major-angular-updates-2.12.1.tgz", + "integrity": "sha512-jVn577OvvFEkUV9bIxMywbXYKoPpKISIblRflb8bjf1KSeUhLHCYZRscSith+/I2X7yLJME8Sg82UpA9F4hIyA==", + "dependencies": { + "tslib": "^2.4.1" + }, + "peerDependencies": { + "@angular/common": ">=15.0.4", + "@angular/core": ">=15.0.4" + } + }, + "node_modules/ngx-echarts": { + "version": "17.2.0", + "resolved": "https://registry.npmjs.org/ngx-echarts/-/ngx-echarts-17.2.0.tgz", + "integrity": "sha512-i3XDE9d53zmJH4bp8RQ/271oPlhBkczO1M3VtWk8nCXdxQq9qx8UckjWEQ7oV1AbSDLGK5sRiFu5EaY5hvdWPA==", + "dependencies": { + "tslib": "^2.3.0" + }, + "peerDependencies": { + "echarts": ">=5.0.0" + } + }, + "node_modules/ngx-timeago": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ngx-timeago/-/ngx-timeago-3.0.0.tgz", + "integrity": "sha512-oz+X8qbPJD6uFHXVWUTE+scjLPskOKbrAVlUG0pUwrn8wru7woryGdK/xdjvS74n187tbo5+e8AXgLCqEvUSjw==", + "dependencies": { + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/core": ">=16.0.0", + "rxjs": ">=7.0.0" + } + }, + "node_modules/nitropack": { + "version": "2.10.4", + "resolved": "https://registry.npmjs.org/nitropack/-/nitropack-2.10.4.tgz", + "integrity": "sha512-sJiG/MIQlZCVSw2cQrFG1H6mLeSqHlYfFerRjLKz69vUfdu0EL2l0WdOxlQbzJr3mMv/l4cOlCCLzVRzjzzF/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cloudflare/kv-asset-handler": "^0.3.4", + "@netlify/functions": "^2.8.2", + "@rollup/plugin-alias": "^5.1.1", + "@rollup/plugin-commonjs": "^28.0.1", + "@rollup/plugin-inject": "^5.0.5", + "@rollup/plugin-json": "^6.1.0", + "@rollup/plugin-node-resolve": "^15.3.0", + "@rollup/plugin-replace": "^6.0.1", + "@rollup/plugin-terser": "^0.4.4", + "@rollup/pluginutils": "^5.1.3", + "@types/http-proxy": "^1.17.15", + "@vercel/nft": "^0.27.5", + "archiver": "^7.0.1", + "c12": "2.0.1", + "chokidar": "^3.6.0", + "citty": "^0.1.6", + "compatx": "^0.1.8", + "confbox": "^0.1.8", + "consola": "^3.2.3", + "cookie-es": "^1.2.2", + "croner": "^9.0.0", + "crossws": "^0.3.1", + "db0": "^0.2.1", + "defu": "^6.1.4", + "destr": "^2.0.3", + "dot-prop": "^9.0.0", + "esbuild": "^0.24.0", + "escape-string-regexp": "^5.0.0", + "etag": "^1.8.1", + "fs-extra": "^11.2.0", + "globby": "^14.0.2", + "gzip-size": "^7.0.0", + "h3": "^1.13.0", + "hookable": "^5.5.3", + "httpxy": "^0.1.5", + "ioredis": "^5.4.1", + "jiti": "^2.4.0", + "klona": "^2.0.6", + "knitwork": "^1.1.0", + "listhen": "^1.9.0", + "magic-string": "^0.30.12", + "magicast": "^0.3.5", + "mime": "^4.0.4", + "mlly": "^1.7.2", + "node-fetch-native": "^1.6.4", + "ofetch": "^1.4.1", + "ohash": "^1.1.4", + "openapi-typescript": "^7.4.2", + "pathe": "^1.1.2", + "perfect-debounce": "^1.0.0", + "pkg-types": "^1.2.1", + "pretty-bytes": "^6.1.1", + "radix3": "^1.1.2", + "rollup": "^4.24.3", + "rollup-plugin-visualizer": "^5.12.0", + "scule": "^1.3.0", + "semver": "^7.6.3", + "serve-placeholder": "^2.0.2", + "serve-static": "^1.16.2", + "std-env": "^3.7.0", + "ufo": "^1.5.4", + "uncrypto": "^0.1.3", + "unctx": "^2.3.1", + "unenv": "^1.10.0", + "unimport": "^3.13.1", + "unstorage": "^1.13.1", + "untyped": "^1.5.1", + "unwasm": "^0.3.9" + }, + "bin": { + "nitro": "dist/cli/index.mjs", + "nitropack": "dist/cli/index.mjs" + }, + "engines": { + "node": "^16.11.0 || >=17.0.0" + }, + "peerDependencies": { + "xml2js": "^0.6.2" + }, + "peerDependenciesMeta": { + "xml2js": { + "optional": true + } + } + }, + "node_modules/nitropack/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/nitropack/node_modules/jiti": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", + "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/nitropack/node_modules/mime": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/mime/-/mime-4.0.6.tgz", + "integrity": "sha512-4rGt7rvQHBbaSOF9POGkk1ocRP16Md1x36Xma8sz8h8/vfCUI2OtEIeCqe4Ofes853x4xDoPiFLIT47J5fI/7A==", + "dev": true, + "funding": [ + "https://github.com/sponsors/broofa" + ], + "license": "MIT", + "bin": { + "mime": "bin/cli.js" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/node-abi": { + "version": "3.67.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.67.0.tgz", + "integrity": "sha512-bLn/fU/ALVBE9wj+p4Y21ZJWYFjUXLXPi/IewyLZkx3ApxKDNBWCKdReeKOtD8dWpOdDCeMyLh6ZewzcLsG2Nw==", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-addon-api": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", + "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==", + "dev": true, + "optional": true + }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-fetch-native": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.6.tgz", + "integrity": "sha512-8Mc2HhqPdlIfedsuZoc3yioPuzp6b+L5jRCRY1QzuWZh2EGJVQrGppC6V6cF0bLdbW0+O2YpqCA25aF/1lvipQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "dev": true, + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-gyp": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-11.0.0.tgz", + "integrity": "sha512-zQS+9MTTeCMgY0F3cWPyJyRFAkVltQ1uXm+xXu/ES6KFgC6Czo1Seb9vQW2wNxSX2OrDTiqL0ojtkFxBQ0ypIw==", + "dev": true, + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "glob": "^10.3.10", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^14.0.3", + "nopt": "^8.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.5", + "tar": "^7.4.3", + "which": "^5.0.0" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "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==", + "dev": true, + "license": "MIT", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/node-gyp-build-optional-packages": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz", + "integrity": "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==", + "dev": true, + "optional": true, + "dependencies": { + "detect-libc": "^2.0.1" + }, + "bin": { + "node-gyp-build-optional-packages": "bin.js", + "node-gyp-build-optional-packages-optional": "optional.js", + "node-gyp-build-optional-packages-test": "build-test.js" + } + }, + "node_modules/node-gyp/node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/node-gyp/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "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/node-gyp/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/node-gyp/node_modules/minizlib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.1.tgz", + "integrity": "sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==", + "dev": true, + "dependencies": { + "minipass": "^7.0.4", + "rimraf": "^5.0.5" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/node-gyp/node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "dev": true, + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/node-gyp/node_modules/rimraf": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", + "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", + "dev": true, + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/node-gyp/node_modules/tar": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", + "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", + "dev": true, + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/node-gyp/node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/node-gyp/node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/node-machine-id": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/node-machine-id/-/node-machine-id-1.1.12.tgz", + "integrity": "sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "dev": true + }, + "node_modules/nopt": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-8.1.0.tgz", + "integrity": "sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==", + "dev": true, + "dependencies": { + "abbrev": "^3.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/normalize-package-data": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz", + "integrity": "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^7.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/normalize-package-data/node_modules/hosted-git-info": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", + "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/normalize-package-data/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==", + "dev": true, + "license": "ISC" + }, + "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==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-bundled": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-4.0.0.tgz", + "integrity": "sha512-IxaQZDMsqfQ2Lz37VvyyEtKLe8FsRZuysmedy/N06TU1RyVppYKXrO4xIhR0F+7ubIBox6Q7nir6fQI3ej39iA==", + "dev": true, + "dependencies": { + "npm-normalize-package-bin": "^4.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-install-checks": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-7.1.1.tgz", + "integrity": "sha512-u6DCwbow5ynAX5BdiHQ9qvexme4U3qHW3MWe5NqH+NeBm0LbiH6zvGjNNew1fY+AZZUtVHbOPF3j7mJxbUzpXg==", + "dev": true, + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "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==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-package-arg": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-12.0.1.tgz", + "integrity": "sha512-aDxjFfPV3Liw0WOBWlyZLMBqtbgbg03rmGvHDJa2Ttv7tIz+1oB5qWec4psCDFZcZi9b5XdGkPdQiJxOPzvQRQ==", + "dev": true, + "dependencies": { + "hosted-git-info": "^8.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^6.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-packlist": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-9.0.0.tgz", + "integrity": "sha512-8qSayfmHJQTx3nJWYbbUmflpyarbLMBc6LCAjYsiGtXxDB68HaZpb8re6zeaLGxZzDuMdhsg70jryJe+RrItVQ==", + "dev": true, + "dependencies": { + "ignore-walk": "^7.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-pick-manifest": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-10.0.0.tgz", + "integrity": "sha512-r4fFa4FqYY8xaM7fHecQ9Z2nE9hgNfJR+EmoKv0+chvzWkBcORX3r0FpTByP+CbOVJDladMXnPQGVN8PBLGuTQ==", + "dev": true, + "dependencies": { + "npm-install-checks": "^7.1.0", + "npm-normalize-package-bin": "^4.0.0", + "npm-package-arg": "^12.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-registry-fetch": { + "version": "18.0.2", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-18.0.2.tgz", + "integrity": "sha512-LeVMZBBVy+oQb5R6FDV9OlJCcWDU+al10oKpe+nsvcHnG24Z3uM3SvJYKfGJlfGjVU8v9liejCrUR/M5HO5NEQ==", + "dev": true, + "dependencies": { + "@npmcli/redact": "^3.0.0", + "jsonparse": "^1.3.1", + "make-fetch-happen": "^14.0.0", + "minipass": "^7.0.2", + "minipass-fetch": "^4.0.0", + "minizlib": "^3.0.1", + "npm-package-arg": "^12.0.0", + "proc-log": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-registry-fetch/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "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/npm-registry-fetch/node_modules/minizlib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.1.tgz", + "integrity": "sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==", + "dev": true, + "dependencies": { + "minipass": "^7.0.4", + "rimraf": "^5.0.5" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/npm-registry-fetch/node_modules/rimraf": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", + "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", + "dev": true, + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/nwsapi": { + "version": "2.2.16", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.16.tgz", + "integrity": "sha512-F1I/bimDpj3ncaNDhfyMWuFqmQDBwDB0Fogc2qpL3BWvkQteFD/8BzWuIRl83rq0DXfm8SGt/HFhLXZyljTXcQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/nx": { + "version": "20.4.0", + "resolved": "https://registry.npmjs.org/nx/-/nx-20.4.0.tgz", + "integrity": "sha512-barpwhq8noc30U0d5j2bSp9x/HDL33TCYsP2fl6FvpssbL64PwLOSBqIdZ9ATxVxAE/xAc/s+z72cYDkaYouPA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@napi-rs/wasm-runtime": "0.2.4", + "@yarnpkg/lockfile": "^1.1.0", + "@yarnpkg/parsers": "3.0.2", + "@zkochan/js-yaml": "0.0.7", + "axios": "^1.7.4", + "chalk": "^4.1.0", + "cli-cursor": "3.1.0", + "cli-spinners": "2.6.1", + "cliui": "^8.0.1", + "dotenv": "~16.4.5", + "dotenv-expand": "~11.0.6", + "enquirer": "~2.3.6", + "figures": "3.2.0", + "flat": "^5.0.2", + "front-matter": "^4.0.2", + "ignore": "^5.0.4", + "jest-diff": "^29.4.1", + "jsonc-parser": "3.2.0", + "lines-and-columns": "2.0.3", + "minimatch": "9.0.3", + "node-machine-id": "1.1.12", + "npm-run-path": "^4.0.1", + "open": "^8.4.0", + "ora": "5.3.0", + "resolve.exports": "2.0.3", + "semver": "^7.5.3", + "string-width": "^4.2.3", + "tar-stream": "~2.2.0", + "tmp": "~0.2.1", + "tsconfig-paths": "^4.1.2", + "tslib": "^2.3.0", + "yaml": "^2.6.0", + "yargs": "^17.6.2", + "yargs-parser": "21.1.1" + }, + "bin": { + "nx": "bin/nx.js", + "nx-cloud": "bin/nx-cloud.js" + }, + "optionalDependencies": { + "@nx/nx-darwin-arm64": "20.4.0", + "@nx/nx-darwin-x64": "20.4.0", + "@nx/nx-freebsd-x64": "20.4.0", + "@nx/nx-linux-arm-gnueabihf": "20.4.0", + "@nx/nx-linux-arm64-gnu": "20.4.0", + "@nx/nx-linux-arm64-musl": "20.4.0", + "@nx/nx-linux-x64-gnu": "20.4.0", + "@nx/nx-linux-x64-musl": "20.4.0", + "@nx/nx-win32-arm64-msvc": "20.4.0", + "@nx/nx-win32-x64-msvc": "20.4.0" + }, + "peerDependencies": { + "@swc-node/register": "^1.8.0", + "@swc/core": "^1.3.85" + }, + "peerDependenciesMeta": { + "@swc-node/register": { + "optional": true + }, + "@swc/core": { + "optional": true + } + } + }, + "node_modules/nx/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/nx/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": 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/nx/node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nx/node_modules/cli-spinners": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz", + "integrity": "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/nx/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/nx/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/nx/node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/nx/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/nx/node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/nx/node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nx/node_modules/jsonc-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", + "dev": true, + "license": "MIT" + }, + "node_modules/nx/node_modules/lines-and-columns": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-2.0.3.tgz", + "integrity": "sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/nx/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/nx/node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nx/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/nx/node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/nx/node_modules/ora": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.3.0.tgz", + "integrity": "sha512-zAKMgGXUim0Jyd6CXK9lraBnD3H5yPGBPPOkC23a2BG6hsm4Zu6OQSjQuEtV0BHDf4aKHcUFvJiGRrFuW3MG8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^4.0.3", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "log-symbols": "^4.0.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/nx/node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nx/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==", + "dev": true, + "license": "ISC" + }, + "node_modules/nx/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nx/node_modules/tmp": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.14" + } + }, + "node_modules/nx/node_modules/tsconfig-paths": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", + "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "json5": "^2.2.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/nypm": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/nypm/-/nypm-0.5.2.tgz", + "integrity": "sha512-AHzvnyUJYSrrphPhRWWZNcoZfArGNp3Vrc4pm/ZurO74tYNTgAPrEyBQEKy+qioqmWlPXwvMZCG2wOaHlPG0Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "citty": "^0.1.6", + "consola": "^3.4.0", + "pathe": "^2.0.2", + "pkg-types": "^1.3.1", + "tinyexec": "^0.3.2", + "ufo": "^1.5.4" + }, + "bin": { + "nypm": "dist/cli.mjs" + }, + "engines": { + "node": "^14.16.0 || >=16.10.0" + } + }, + "node_modules/nypm/node_modules/pathe": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.2.tgz", + "integrity": "sha512-15Ztpk+nov8DR524R4BF7uEuzESgzUEAV4Ah7CUMNGXdE5ELuvxElxGXndBl32vMSsWa1jpNf22Z+Er3sKwq+w==", + "dev": true, + "license": "MIT" + }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", + "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.values": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "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==", + "dev": true + }, + "node_modules/ofetch": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/ofetch/-/ofetch-1.4.1.tgz", + "integrity": "sha512-QZj2DfGplQAr2oj9KzceK9Hwz6Whxazmn85yYeVuS3u9XTMOGMRx0kO95MQ+vLsj/S/NwBDMMLU5hpxvI6Tklw==", + "dev": true, + "license": "MIT", + "dependencies": { + "destr": "^2.0.3", + "node-fetch-native": "^1.6.4", + "ufo": "^1.5.4" + } + }, + "node_modules/ohash": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/ohash/-/ohash-1.1.4.tgz", + "integrity": "sha512-FlDryZAahJmEF3VR3w1KogSEdWX3WhA5GPakFx4J81kEAiHyLMpdLLElS8n8dfNadMgAne/MywcvmogzscVt4g==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "dev": true, + "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==", + "dependencies": { + "wrappy": "1" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "fn.name": "1.x.x" + } + }, + "node_modules/onetime": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "dev": true, + "dependencies": { + "mimic-function": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.1.0.tgz", + "integrity": "sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==", + "dev": true, + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/openapi-typescript": { + "version": "7.6.1", + "resolved": "https://registry.npmjs.org/openapi-typescript/-/openapi-typescript-7.6.1.tgz", + "integrity": "sha512-F7RXEeo/heF3O9lOXo2bNjCOtfp7u+D6W3a3VNEH2xE6v+fxLtn5nq0uvUcA1F5aT+CMhNeC5Uqtg5tlXFX/ag==", + "dev": true, + "license": "MIT", + "dependencies": { + "@redocly/openapi-core": "^1.28.0", + "ansi-colors": "^4.1.3", + "change-case": "^5.4.4", + "parse-json": "^8.1.0", + "supports-color": "^9.4.0", + "yargs-parser": "^21.1.1" + }, + "bin": { + "openapi-typescript": "bin/cli.js" + }, + "peerDependencies": { + "typescript": "^5.x" + } + }, + "node_modules/openapi-typescript/node_modules/parse-json": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.1.0.tgz", + "integrity": "sha512-rum1bPifK5SSar35Z6EKZuYPJx85pkNaFrxBK3mwdfSJ1/WKbYrjoW/zTPSjRRamfmVX1ACBIdFAO0VRErW/EA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.22.13", + "index-to-position": "^0.1.2", + "type-fest": "^4.7.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/openapi-typescript/node_modules/supports-color": { + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.4.0.tgz", + "integrity": "sha512-VL+lNrEoIXww1coLPOmiEmK/0sGigko5COxI09KzHc2VJXJsQ37UaQ+8quuxjDeA7+KnLGTWRyOXSLLR2Wb4jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/openapi-typescript/node_modules/type-fest": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.33.0.tgz", + "integrity": "sha512-s6zVrxuyKbbAsSAD5ZPTB77q4YIdRctkTbJ2/Dqlinwz+8ooH2gd+YA7VA6Pa93KML9GockVvoxjZ2vHP+mu8g==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/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==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ora/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "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/ora/node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/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==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/ora/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==", + "dev": true + }, + "node_modules/ora/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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/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==", + "dev": true + }, + "node_modules/ora/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==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ordered-binary": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.5.3.tgz", + "integrity": "sha512-oGFr3T+pYdTGJ+YFEILMpS3es+GiIbs9h/XQrclBXUtd44ey7XwfsMzM31f64I1SQOawDoDr/D823kNCADI8TA==", + "dev": true, + "optional": true + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.3.tgz", + "integrity": "sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-retry": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.1.tgz", + "integrity": "sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==", + "dev": true, + "dependencies": { + "@types/retry": "0.12.2", + "is-network-error": "^1.0.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-retry/node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/pac-proxy-agent": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.1.0.tgz", + "integrity": "sha512-Z5FnLVVZSnX7WjBg0mhDtydeRZ1xMcATZThjySQUHqr+0ksP8kqaw23fNKkaaN/Z8gwLUs/W7xdl0I75eP2Xyw==", + "dependencies": { + "@tootallnate/quickjs-emscripten": "^0.23.0", + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "get-uri": "^6.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.6", + "pac-resolver": "^7.0.1", + "socks-proxy-agent": "^8.0.5" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-resolver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", + "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", + "dependencies": { + "degenerator": "^5.0.0", + "netmask": "^2.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/package-changed": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/package-changed/-/package-changed-3.0.0.tgz", + "integrity": "sha512-HSRbrO+Ab5AuqqYGSevtKJ1Yt96jW1VKV7wrp8K4SKj5tyDp/7D96uPCQyCPiNtWTEH/7nA3hZ4z2slbc9yFxg==", + "dev": true, + "license": "ISC", + "dependencies": { + "commander": "^6.2.0" + }, + "bin": { + "package-changed": "bin/package-changed.js" + } + }, + "node_modules/package-changed/node_modules/commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", + "dev": true + }, + "node_modules/pacote": { + "version": "20.0.0", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-20.0.0.tgz", + "integrity": "sha512-pRjC5UFwZCgx9kUFDVM9YEahv4guZ1nSLqwmWiLUnDbGsjs+U5w7z6Uc8HNR1a6x8qnu5y9xtGE6D1uAuYz+0A==", + "dev": true, + "dependencies": { + "@npmcli/git": "^6.0.0", + "@npmcli/installed-package-contents": "^3.0.0", + "@npmcli/package-json": "^6.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "@npmcli/run-script": "^9.0.0", + "cacache": "^19.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^7.0.2", + "npm-package-arg": "^12.0.0", + "npm-packlist": "^9.0.0", + "npm-pick-manifest": "^10.0.0", + "npm-registry-fetch": "^18.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "sigstore": "^3.0.0", + "ssri": "^12.0.0", + "tar": "^6.1.11" + }, + "bin": { + "pacote": "bin/index.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-imports": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/parse-imports/-/parse-imports-2.2.1.tgz", + "integrity": "sha512-OL/zLggRp8mFhKL0rNORUTR4yBYujK/uU+xZL+/0Rgm2QE4nLO9v8PzEweSJEbMGKmDRjJE4R3IMJlL2di4JeQ==", + "dev": true, + "dependencies": { + "es-module-lexer": "^1.5.3", + "slashes": "^3.0.12" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-json/node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + }, + "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==", + "dev": true, + "engines": { + "node": ">=0.6.21" + } + }, + "node_modules/parse-ms": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz", + "integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-node-version": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", + "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "devOptional": true, + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-html-rewriting-stream": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5-html-rewriting-stream/-/parse5-html-rewriting-stream-7.0.0.tgz", + "integrity": "sha512-mazCyGWkmCRWDI15Zp+UiCqMp/0dgEmkZRvhlsqqKYr4SsVm/TvnSpD9fCvqCA2zoWJcfRym846ejWBBHRiYEg==", + "dev": true, + "dependencies": { + "entities": "^4.3.0", + "parse5": "^7.0.0", + "parse5-sax-parser": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", + "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "domhandler": "^5.0.3", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-parser-stream": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", + "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", + "dev": true, + "license": "MIT", + "dependencies": { + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-sax-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5-sax-parser/-/parse5-sax-parser-7.0.0.tgz", + "integrity": "sha512-5A+v2SNsq8T6/mG3ahcz8ZtQ0OUFTatxPbeidoMB7tkJSGDY3tdfl4MHovtLQHkEn5CGxijNWRQHhRQ6IRpXKg==", + "dev": true, + "dependencies": { + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", + "dev": true + }, + "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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "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==", + "dev": true, + "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/path-scurry/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==", + "dev": true + }, + "node_modules/path-to-regexp": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "dev": true + }, + "node_modules/path-type": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", + "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathval": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", + "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16" + } + }, + "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==" + }, + "node_modules/perfect-debounce": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz", + "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==", + "dev": true, + "license": "MIT" + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" + }, + "node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", + "dev": true, + "dependencies": { + "pinkie": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/piscina": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/piscina/-/piscina-4.8.0.tgz", + "integrity": "sha512-EZJb+ZxDrQf3dihsUL7p42pjNyrNIFJCrRHPMgxu/svsj+P3xS3fuEWp7k2+rfsavfl1N0G29b1HGs7J0m8rZA==", + "dev": true, + "optionalDependencies": { + "@napi-rs/nice": "^1.0.1" + } + }, + "node_modules/pkg-dir": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", + "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", + "dev": true, + "dependencies": { + "find-up": "^6.3.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "dev": true, + "dependencies": { + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "dev": true, + "dependencies": { + "p-locate": "^6.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "dev": true, + "dependencies": { + "p-limit": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/pkg-dir/node_modules/yocto-queue": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", + "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", + "dev": true, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-types": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", + "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "confbox": "^0.1.8", + "mlly": "^1.7.4", + "pathe": "^2.0.1" + } + }, + "node_modules/pkg-types/node_modules/pathe": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.2.tgz", + "integrity": "sha512-15Ztpk+nov8DR524R4BF7uEuzESgzUEAV4Ah7CUMNGXdE5ELuvxElxGXndBl32vMSsWa1jpNf22Z+Er3sKwq+w==", + "dev": true, + "license": "MIT" + }, + "node_modules/plist": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz", + "integrity": "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==", + "dev": true, + "dependencies": { + "@xmldom/xmldom": "^0.8.8", + "base64-js": "^1.5.1", + "xmlbuilder": "^15.1.1" + }, + "engines": { + "node": ">=10.4.0" + } + }, + "node_modules/pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss": { + "version": "8.4.49", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", + "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-loader": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-8.1.1.tgz", + "integrity": "sha512-0IeqyAsG6tYiDRCYKQJLAmgQr47DX6N7sFSWvQxt6AcupX8DIdmykuk/o/tx0Lze3ErGHJEp5OSRxrelC6+NdQ==", + "dev": true, + "dependencies": { + "cosmiconfig": "^9.0.0", + "jiti": "^1.20.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "postcss": "^7.0.0 || ^8.0.1", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/postcss-media-query-parser": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", + "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==", + "dev": true + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", + "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz", + "integrity": "sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==", + "dev": true, + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz", + "integrity": "sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "dev": true, + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, + "node_modules/prebuild-install": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.2.tgz", + "integrity": "sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==", + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-plugin-java": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/prettier-plugin-java/-/prettier-plugin-java-1.0.2.tgz", + "integrity": "sha512-YgcN1WGZlrH0E+bHdqtIYtfDp6k2PHBnIaGjzdff/7t/NyDWAA6ypAmnD7YQVG2OuoIaXYkC37HN7cz68lLWLg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "java-parser": "1.0.2", + "lodash": "4.17.21", + "prettier": "2.2.1" + } + }, + "node_modules/prettier-plugin-java/node_modules/prettier": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz", + "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/pretty-bytes": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.1.1.tgz", + "integrity": "sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/pretty-ms": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.2.0.tgz", + "integrity": "sha512-4yf0QO/sllf/1zbZWYnvWw3NxCQwLXKzIj0G849LSufP15BXKM0rbD2Z3wVnkMfjdn/CB0Dpp444gYAACdsplg==", + "dev": true, + "license": "MIT", + "dependencies": { + "parse-ms": "^4.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/proc-log": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-5.0.0.tgz", + "integrity": "sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "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==", + "dev": true, + "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==", + "dev": true + }, + "node_modules/promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", + "dev": true + }, + "node_modules/promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "dev": true, + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prompts/node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/protractor": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/protractor/-/protractor-7.0.0.tgz", + "integrity": "sha512-UqkFjivi4GcvUQYzqGYNe0mLzfn5jiLmO8w9nMhQoJRLhy2grJonpga2IWhI6yJO30LibWXJJtA4MOIZD2GgZw==", + "deprecated": "We have news to share - Protractor is deprecated and will reach end-of-life by Summer 2023. To learn more and find out about other options please refer to this post on the Angular blog. Thank you for using and contributing to Protractor. https://goo.gle/state-of-e2e-in-angular", + "dev": true, + "dependencies": { + "@types/q": "^0.0.32", + "@types/selenium-webdriver": "^3.0.0", + "blocking-proxy": "^1.0.0", + "browserstack": "^1.5.1", + "chalk": "^1.1.3", + "glob": "^7.0.3", + "jasmine": "2.8.0", + "jasminewd2": "^2.1.0", + "q": "1.4.1", + "saucelabs": "^1.5.0", + "selenium-webdriver": "3.6.0", + "source-map-support": "~0.4.0", + "webdriver-js-extender": "2.1.0", + "webdriver-manager": "^12.1.7", + "yargs": "^15.3.1" + }, + "bin": { + "protractor": "bin/protractor", + "webdriver-manager": "bin/webdriver-manager" + }, + "engines": { + "node": ">=10.13.x" + } + }, + "node_modules/protractor/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/protractor/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/protractor/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/protractor/node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/protractor/node_modules/cliui/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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/protractor/node_modules/cliui/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==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/protractor/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/protractor/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/protractor/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/protractor/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/protractor/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/protractor/node_modules/source-map-support": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", + "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", + "dev": true, + "dependencies": { + "source-map": "^0.5.6" + } + }, + "node_modules/protractor/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/protractor/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/protractor/node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "node_modules/protractor/node_modules/yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/protractor/node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "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==", + "dev": true, + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-addr/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==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-agent": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz", + "integrity": "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.1", + "https-proxy-agent": "^7.0.6", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.1.0", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.5" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/proxy-agent/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "node_modules/prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", + "dev": true, + "optional": true + }, + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "dev": true + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/puppeteer": { + "version": "23.11.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-23.11.0.tgz", + "integrity": "sha512-UaHfTIcg02bTahmZjrjrpU8efyjNeItrNvANu+DdnYMEcQ24X8LOkBWv2Z4bqDzkOzFymqJkADS0bdSDMUNi1A==", + "hasInstallScript": true, + "dependencies": { + "@puppeteer/browsers": "2.6.1", + "chromium-bidi": "0.11.0", + "cosmiconfig": "^9.0.0", + "devtools-protocol": "0.0.1367902", + "puppeteer-core": "23.11.0", + "typed-query-selector": "^2.12.0" + }, + "bin": { + "puppeteer": "lib/cjs/puppeteer/node/cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/puppeteer-core": { + "version": "23.11.0", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-23.11.0.tgz", + "integrity": "sha512-fr5Xp8KeZGRiLrYmosAxPAObi1vmb09vmwak9lqS7KvKMbcN+mk+bDpnDKXPd7QN9b7b/mb9Fgp0A6+024XbVA==", + "dependencies": { + "@puppeteer/browsers": "2.6.1", + "chromium-bidi": "0.11.0", + "debug": "^4.4.0", + "devtools-protocol": "0.0.1367902", + "typed-query-selector": "^2.12.0", + "ws": "^8.18.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/q": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz", + "integrity": "sha512-/CdEdaw49VZVmyIDGUQKDDT53c7qBkO6g5CefWz91Ae+l4+cRtcDYwMTXh6me4O8TMldeGHG3N2Bl84V78Ywbg==", + "deprecated": "You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other.\n\n(For a CapTP with native promises, see @endo/eventual-send and @endo/captp)", + "dev": true, + "engines": { + "node": ">=0.6.0", + "teleport": ">=0.2.0" + } + }, + "node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/query-selector-shadow-dom": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/query-selector-shadow-dom/-/query-selector-shadow-dom-1.0.1.tgz", + "integrity": "sha512-lT5yCqEBgfoMYpf3F2xQRK7zEr1rhIIZuceDK6+xRkJQ4NMbHTwXqk4NkwDwQMNqXgG9r9fyHnzwNVs6zV5KRw==", + "dev": true, + "license": "MIT" + }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/queue-tick": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", + "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==" + }, + "node_modules/radix3": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/radix3/-/radix3-1.1.2.tgz", + "integrity": "sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==", + "dev": true, + "license": "MIT" + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rc9": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/rc9/-/rc9-2.1.2.tgz", + "integrity": "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "defu": "^6.1.4", + "destr": "^2.0.3" + } + }, + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/read-pkg": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-8.1.0.tgz", + "integrity": "sha512-PORM8AgzXeskHO/WEv312k9U03B8K9JSiWF/8N9sUuFjBa+9SF2u6K7VClzXwDXab51jCd8Nd36CNM+zR97ScQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/normalize-package-data": "^2.4.1", + "normalize-package-data": "^6.0.0", + "parse-json": "^7.0.0", + "type-fest": "^4.2.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-10.1.0.tgz", + "integrity": "sha512-aNtBq4jR8NawpKJQldrQcSW9y/d+KWH4v24HWkHljOZ7H0av+YTGANBzRh9A5pw7v/bLVsLVPpOhJ7gHNVy8lA==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^6.3.0", + "read-pkg": "^8.1.0", + "type-fest": "^4.2.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^6.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/read-pkg-up/node_modules/type-fest": { + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.37.0.tgz", + "integrity": "sha512-S/5/0kFftkq27FPNye0XM1e2NsnoD/3FS+pBmbjmmtLT6I+i344KoOf7pvXreaFsDamWeaJX55nczA1m5PsBDg==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/yocto-queue": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.0.tgz", + "integrity": "sha512-KHBC7z61OJeaMGnF3wqNZj+GGNXOyypZviiKpQeiHirG5Ib1ImwcLBH70rbMSkKfSmUNBsdf2PwaEJtKvgmkNw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg/node_modules/json-parse-even-better-errors": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz", + "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/read-pkg/node_modules/lines-and-columns": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-2.0.4.tgz", + "integrity": "sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/read-pkg/node_modules/parse-json": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-7.1.1.tgz", + "integrity": "sha512-SgOTCX/EZXtZxBE5eJ97P4yGM5n37BwRU+YMsH4vNzFqJV/oWFXXCmwFlgWUM4PrakybVOueJJ6pwHqSVhTFDw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.21.4", + "error-ex": "^1.3.2", + "json-parse-even-better-errors": "^3.0.0", + "lines-and-columns": "^2.0.3", + "type-fest": "^3.8.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg/node_modules/parse-json/node_modules/type-fest": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz", + "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg/node_modules/type-fest": { + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.37.0.tgz", + "integrity": "sha512-S/5/0kFftkq27FPNye0XM1e2NsnoD/3FS+pBmbjmmtLT6I+i344KoOf7pvXreaFsDamWeaJX55nczA1m5PsBDg==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "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==", + "dev": true, + "dependencies": { + "minimatch": "^5.1.0" + } + }, + "node_modules/readdir-glob/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/readdirp/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/recursive-readdir": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", + "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/recursive-readdir/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/recursive-readdir/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/redis-errors": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz", + "integrity": "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/redis-parser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz", + "integrity": "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==", + "dev": true, + "license": "MIT", + "dependencies": { + "redis-errors": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/reflect-metadata": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", + "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==", + "dev": true + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz", + "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==", + "dev": true, + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true + }, + "node_modules/regenerator-transform": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/regex-parser": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.3.0.tgz", + "integrity": "sha512-TVILVSz2jY5D47F4mA4MppkBrafEaiUWJO/TcZHEIuI13AqoZMkK1WMA4Om1YkYbTx+9Ki1/tSUXbceyr9saRg==", + "dev": true + }, + "node_modules/regexp-to-ast": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/regexp-to-ast/-/regexp-to-ast-0.4.0.tgz", + "integrity": "sha512-4qf/7IsIKfSNHQXSwial1IFmfM1Cc/whNBQqRwe0V2stPe7KmN1U0tWQiIx6JiirgSrisjE0eECdNf7Tav1Ntw==", + "dev": true, + "license": "MIT" + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexpu-core": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz", + "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==", + "dev": true, + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.2.0", + "regjsgen": "^0.8.0", + "regjsparser": "^0.12.0", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", + "dev": true + }, + "node_modules/regjsparser": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz", + "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==", + "dev": true, + "dependencies": { + "jsesc": "~3.0.2" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dev": true, + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/request/node_modules/qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "dev": true, + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/resolve-url-loader": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-5.0.0.tgz", + "integrity": "sha512-uZtduh8/8srhBoMx//5bwqjQ+rfYOUq8zC9NrMUGtjBiGTtFJM42s58/36+hTqeqINcnYe08Nj3LkK9lW4N8Xg==", + "dev": true, + "dependencies": { + "adjust-sourcemap-loader": "^4.0.0", + "convert-source-map": "^1.7.0", + "loader-utils": "^2.0.0", + "postcss": "^8.2.14", + "source-map": "0.6.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/resolve-url-loader/node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/resolve-url-loader/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve.exports": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz", + "integrity": "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/resq": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/resq/-/resq-1.11.0.tgz", + "integrity": "sha512-G10EBz+zAAy3zUd/CDoBbXRL6ia9kOo3xRHrMDsHljI0GDkhYlyjwoCx5+3eCC4swi1uCoZQhskuJkj7Gp57Bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^2.0.1" + } + }, + "node_modules/resq/node_modules/fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==", + "dev": true, + "license": "MIT" + }, + "node_modules/restore-cursor": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", + "dev": true, + "dependencies": { + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "dev": true + }, + "node_modules/rgb2hex": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/rgb2hex/-/rgb2hex-0.2.5.tgz", + "integrity": "sha512-22MOP1Rh7sAo1BZpDG6R5RFYzR2lYEgwq7HEmyW2qcsOqR2lQKmn+O//xV3YG/0rrhMC6KVX2hU+ZXuaw9a5bw==", + "dev": true, + "license": "MIT" + }, + "node_modules/rimraf": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.4.1.tgz", + "integrity": "sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==", + "dev": true, + "dependencies": { + "glob": "^9.2.0" + }, + "bin": { + "rimraf": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "9.3.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz", + "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "minimatch": "^8.0.2", + "minipass": "^4.2.4", + "path-scurry": "^1.6.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz", + "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/minipass": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", + "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/rollup": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.30.1.tgz", + "integrity": "sha512-mlJ4glW020fPuLi7DkM/lN97mYEZGWeqBnrljzN0gs7GLctqX3lNWxKQ7Gl712UAX+6fog/L3jh4gb7R6aVi3w==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.6" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.30.1", + "@rollup/rollup-android-arm64": "4.30.1", + "@rollup/rollup-darwin-arm64": "4.30.1", + "@rollup/rollup-darwin-x64": "4.30.1", + "@rollup/rollup-freebsd-arm64": "4.30.1", + "@rollup/rollup-freebsd-x64": "4.30.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.30.1", + "@rollup/rollup-linux-arm-musleabihf": "4.30.1", + "@rollup/rollup-linux-arm64-gnu": "4.30.1", + "@rollup/rollup-linux-arm64-musl": "4.30.1", + "@rollup/rollup-linux-loongarch64-gnu": "4.30.1", + "@rollup/rollup-linux-powerpc64le-gnu": "4.30.1", + "@rollup/rollup-linux-riscv64-gnu": "4.30.1", + "@rollup/rollup-linux-s390x-gnu": "4.30.1", + "@rollup/rollup-linux-x64-gnu": "4.30.1", + "@rollup/rollup-linux-x64-musl": "4.30.1", + "@rollup/rollup-win32-arm64-msvc": "4.30.1", + "@rollup/rollup-win32-ia32-msvc": "4.30.1", + "@rollup/rollup-win32-x64-msvc": "4.30.1", + "fsevents": "~2.3.2" + } + }, + "node_modules/rollup-plugin-visualizer": { + "version": "5.14.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-visualizer/-/rollup-plugin-visualizer-5.14.0.tgz", + "integrity": "sha512-VlDXneTDaKsHIw8yzJAFWtrzguoJ/LnQ+lMpoVfYJ3jJF4Ihe5oYLAqLklIK/35lgUY+1yEzCkHyZ1j4A5w5fA==", + "dev": true, + "license": "MIT", + "dependencies": { + "open": "^8.4.0", + "picomatch": "^4.0.2", + "source-map": "^0.7.4", + "yargs": "^17.5.1" + }, + "bin": { + "rollup-plugin-visualizer": "dist/bin/cli.js" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "rolldown": "1.x", + "rollup": "2.x || 3.x || 4.x" + }, + "peerDependenciesMeta": { + "rolldown": { + "optional": true + }, + "rollup": { + "optional": true + } + } + }, + "node_modules/rollup-plugin-visualizer/node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/rollup-plugin-visualizer/node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/rollup-plugin-visualizer/node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/rollup-plugin-visualizer/node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/rrweb-cssom": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", + "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/run-applescript": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz", + "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/run-async": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz", + "integrity": "sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safaridriver": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safaridriver/-/safaridriver-1.0.0.tgz", + "integrity": "sha512-J92IFbskyo7OYB3Dt4aTdyhag1GlInrfbPCmMteb7aBK7PwlnGz1HI0+oyNN97j7pV9DqUAVoVgkNRMrfY47mQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-array-concat/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "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" + } + ] + }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-push-apply/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/sanitize-filename": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz", + "integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==", + "dev": true, + "license": "WTFPL OR ISC", + "dependencies": { + "truncate-utf8-bytes": "^1.0.0" + } + }, + "node_modules/sass": { + "version": "1.83.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.83.1.tgz", + "integrity": "sha512-EVJbDaEs4Rr3F0glJzFSOvtg2/oy2V/YrGFPqPY24UqcLDWcI9ZY5sN+qyO3c/QCZwzgfirvhXvINiJCE/OLcA==", + "dev": true, + "dependencies": { + "chokidar": "^4.0.0", + "immutable": "^5.0.2", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + }, + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" + } + }, + "node_modules/sass-loader": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-16.0.4.tgz", + "integrity": "sha512-LavLbgbBGUt3wCiYzhuLLu65+fWXaXLmq7YxivLhEqmiupCFZ5sKUAipK3do6V80YSU0jvSxNhEdT13IXNr3rg==", + "dev": true, + "dependencies": { + "neo-async": "^2.6.2" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0", + "sass": "^1.3.0", + "sass-embedded": "*", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "node-sass": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/sass/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/sass/node_modules/readdirp": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.1.tgz", + "integrity": "sha512-h80JrZu/MHUZCyHu5ciuoI0+WxsCxzxJTILn6Fs8rxSnFPh+UVHYfeIxK1nVGugMqkfC4vJcBOYbkfkwYK0+gw==", + "dev": true, + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/saucelabs": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/saucelabs/-/saucelabs-1.5.0.tgz", + "integrity": "sha512-jlX3FGdWvYf4Q3LFfFWS1QvPg3IGCGWxIc8QBFdPTbpTJnt/v17FHXYVAn7C8sHf1yUXo2c7yIM0isDryfYtHQ==", + "dev": true, + "dependencies": { + "https-proxy-agent": "^2.2.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/saucelabs/node_modules/agent-base": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", + "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", + "dev": true, + "dependencies": { + "es6-promisify": "^5.0.0" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/saucelabs/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/saucelabs/node_modules/https-proxy-agent": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", + "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", + "dev": true, + "dependencies": { + "agent-base": "^4.3.0", + "debug": "^3.1.0" + }, + "engines": { + "node": ">= 4.5.0" + } + }, + "node_modules/sax": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.1.4.tgz", + "integrity": "sha512-5f3k2PbGGp+YtKJjOItpg3P99IMD84E4HOvcfleTb5joCHNXYLsR9yWFPOYGgaeMPDubQILTCMdsFb2OMeOjtg==" + }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, + "node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/schema-utils/node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/scule": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/scule/-/scule-1.3.0.tgz", + "integrity": "sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true + }, + "node_modules/selenium-webdriver": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-3.6.0.tgz", + "integrity": "sha512-WH7Aldse+2P5bbFBO4Gle/nuQOdVwpHMTL6raL3uuBj/vPG07k6uzt3aiahu352ONBr5xXh0hDlM3LhtXPOC4Q==", + "dev": true, + "dependencies": { + "jszip": "^3.1.3", + "rimraf": "^2.5.4", + "tmp": "0.0.30", + "xml2js": "^0.4.17" + }, + "engines": { + "node": ">= 6.9.0" + } + }, + "node_modules/selenium-webdriver/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/selenium-webdriver/node_modules/tmp": { + "version": "0.0.30", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.30.tgz", + "integrity": "sha512-HXdTB7lvMwcb55XFfrTM8CPr/IYREk4hVBFaQ4b/6nInrluSL86hfHm7vu0luYKCfyBZp2trCjpc8caC3vVM3w==", + "dev": true, + "dependencies": { + "os-tmpdir": "~1.0.1" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/selenium-webdriver/node_modules/xml2js": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", + "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", + "dev": true, + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/selenium-webdriver/node_modules/xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/selfsigned": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", + "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", + "dev": true, + "dependencies": { + "@types/node-forge": "^1.3.0", + "node-forge": "^1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver-dsl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/semver-dsl/-/semver-dsl-1.0.1.tgz", + "integrity": "sha512-e8BOaTo007E3dMuQQTnPdalbKTABKNS7UxoBIDnwOqRa+QwMrCPjynB8zAlPF6xlqUfdLPPLIJ13hJNmhtq8Ng==", + "dev": true, + "dependencies": { + "semver": "^5.3.0" + } + }, + "node_modules/semver-dsl/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/send": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/send/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/send/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/serialize-error": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-11.0.3.tgz", + "integrity": "sha512-2G2y++21dhj2R7iHAdd0FIzjGwuKZld+7Pl/bTU6YIkrC2ZMbVUjm+luj6A6V34Rv9XfKJDKpTWu9W4Gse1D9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^2.12.2" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/serialize-error/node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-favicon": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/serve-favicon/-/serve-favicon-2.5.0.tgz", + "integrity": "sha512-FMW2RvqNr03x+C0WxTyu6sOv21oOjkq5j8tjquWccwa6ScNyGFOGJVpuS1NmTVGBAHS07xnSKotgf2ehQmf9iA==", + "dev": true, + "license": "MIT", + "dependencies": { + "etag": "~1.8.1", + "fresh": "0.5.2", + "ms": "2.1.1", + "parseurl": "~1.3.2", + "safe-buffer": "5.1.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-favicon/node_modules/ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/serve-favicon/node_modules/safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", + "dev": true, + "license": "MIT" + }, + "node_modules/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "dev": true, + "dependencies": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-index/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/serve-index/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "dev": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "dev": true + }, + "node_modules/serve-index/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + }, + "node_modules/serve-placeholder": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/serve-placeholder/-/serve-placeholder-2.0.2.tgz", + "integrity": "sha512-/TMG8SboeiQbZJWRlfTCqMs2DD3SZgWp0kDQePz9yUuCnDfDh/92gf7/PxGhzXTKBIPASIHxFcZndoNbp6QOLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "defu": "^6.1.4" + } + }, + "node_modules/serve-static": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "dev": true, + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-static/node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "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==", + "dev": true + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "dev": true + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/sharp": { + "version": "0.29.3", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.29.3.tgz", + "integrity": "sha512-fKWUuOw77E4nhpyzCCJR1ayrttHoFHBT2U/kR/qEMRhvPEcluG4BKj324+SCO1e84+knXHwhJ1HHJGnUt4ElGA==", + "hasInstallScript": true, + "dependencies": { + "color": "^4.0.1", + "detect-libc": "^1.0.3", + "node-addon-api": "^4.2.0", + "prebuild-install": "^7.0.0", + "semver": "^7.3.5", + "simple-get": "^4.0.0", + "tar-fs": "^2.1.1", + "tunnel-agent": "^0.6.0" + }, + "engines": { + "node": ">=12.13.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/sharp/node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/sharp/node_modules/node-addon-api": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", + "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==" + }, + "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==", + "dev": true, + "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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.2.tgz", + "integrity": "sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==", + "dev": true, + "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==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "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==", + "dev": true, + "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/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, + "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==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sigstore": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-3.1.0.tgz", + "integrity": "sha512-ZpzWAFHIFqyFE56dXqgX/DkDRZdz+rRcjoIk/RQU4IX0wiCv1l8S7ZrXDHcCc+uaf+6o7w3h2l3g6GYG5TKN9Q==", + "dev": true, + "dependencies": { + "@sigstore/bundle": "^3.1.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.4.0", + "@sigstore/sign": "^3.1.0", + "@sigstore/tuf": "^3.1.0", + "@sigstore/verify": "^2.1.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, + "node_modules/sirv": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.0.tgz", + "integrity": "sha512-BPwJGUeDaDCHihkORDchNyyTvWFhcusy1XMmhEVTQTwGeybFbp8YEmB+njbPnth1FibULBSBVwCQni25XlCUDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/slashes": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/slashes/-/slashes-3.0.12.tgz", + "integrity": "sha512-Q9VME8WyGkc7pJf6QEkj3wE+2CnvZMI+XJhwdTPR8Z/kWQRXi7boAWLDibRPyHRTUTPx5FaU7MsyrjI3yLB4HA==", + "dev": true + }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/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==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/slice-ansi/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==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/slice-ansi/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==", + "dev": true + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/smob": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/smob/-/smob-1.5.0.tgz", + "integrity": "sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==", + "dev": true, + "license": "MIT" + }, + "node_modules/sockjs": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "dev": true, + "dependencies": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "node_modules/sockjs/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==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/socks": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", + "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", + "dependencies": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", + "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-loader": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-5.0.0.tgz", + "integrity": "sha512-k2Dur7CbSLcAH73sBcIkV5xjPV4SzqO1NJ7+XaQl8if3VODDUj3FNchNGpqgJSKbvUfJuhVdv8K2Eu8/TNl2eA==", + "dev": true, + "dependencies": { + "iconv-lite": "^0.6.3", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.72.1" + } + }, + "node_modules/source-map-loader/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/spacetrim": { + "version": "0.11.59", + "resolved": "https://registry.npmjs.org/spacetrim/-/spacetrim-0.11.59.tgz", + "integrity": "sha512-lLYsktklSRKprreOm7NXReW8YiX2VBjbgmXYEziOoGf/qsJqAEACaDvoTtUOycwjpaSh+bT8eu0KrJn7UNxiCg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://buymeacoffee.com/hejny" + }, + { + "type": "github", + "url": "https://github.com/hejny/spacetrim/blob/main/README.md#%EF%B8%8F-contributing" + } + ], + "license": "Apache-2.0" + }, + "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==", + "dev": true, + "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==", + "dev": true + }, + "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==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.20", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz", + "integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==", + "dev": true + }, + "node_modules/spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "dev": 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==", + "dev": 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/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "dev": true, + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==" + }, + "node_modules/sshpk": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", + "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", + "dev": true, + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sshpk/node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "dev": true + }, + "node_modules/ssri": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-12.0.0.tgz", + "integrity": "sha512-S7iGNosepx9RadX82oimUkvr0Ct7IjJbEbs4mJcTxst8um95J3sDYU1RBEOvdu6oL1Wek2ODI5i4MAw+dZ6cAQ==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/standard-as-callback": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz", + "integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==", + "dev": true, + "license": "MIT" + }, + "node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/std-env": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.0.tgz", + "integrity": "sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/storage-mirror": { + "resolved": "storage-mirror", + "link": true + }, + "node_modules/stream-buffers": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-3.0.3.tgz", + "integrity": "sha512-pqMqwQCso0PBJt2PQmDO0cFj0lyqmiwOMiMSkVtRokl7e+ZTRYgDHKnuZNbqjiJXgsg4nuqtD/zxuo9KqTp0Yw==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "duplexer": "~0.1.1", + "through": "~2.3.4" + } + }, + "node_modules/streamx": { + "version": "2.21.1", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.21.1.tgz", + "integrity": "sha512-PhP9wUnFLa+91CPy3N6tiQsK+gnYyUNuk15S3YG/zjYE7RuPeCjJngqnzpC31ow0lzBHQ+QGO4cNJnd0djYUsw==", + "dependencies": { + "fast-fifo": "^1.3.2", + "queue-tick": "^1.0.1", + "text-decoder": "^1.1.0" + }, + "optionalDependencies": { + "bare-events": "^2.2.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==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "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==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "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==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-literal": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.1.1.tgz", + "integrity": "sha512-631UJ6O00eNGfMiWG78ck80dfBab8X6IVFB51jZK5Icd7XAs60Z5y7QdSd/wGIklnWvRbUNloVzhOKKmutxQ6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^9.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/strip-literal/node_modules/js-tokens": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", + "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/strnum": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.1.2.tgz", + "integrity": "sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT" + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/swiftlint": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/swiftlint/-/swiftlint-1.0.2.tgz", + "integrity": "sha512-YhcS0N3vkwBatnZf/iJPg89LGQk7MbFnz67Cg3EZ6Ppqm2H8y6x7A1t6KMQ0jYVQpea9wQiFiFRFhkoChaQ29Q==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@ionic/utils-fs": "3.1.6", + "@ionic/utils-subprocess": "2.1.11", + "cosmiconfig": "^6.0.0" + }, + "bin": { + "node-swiftlint": "bin.js" + } + }, + "node_modules/swiftlint/node_modules/@ionic/utils-fs": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/@ionic/utils-fs/-/utils-fs-3.1.6.tgz", + "integrity": "sha512-eikrNkK89CfGPmexjTfSWl4EYqsPSBh0Ka7by4F0PLc1hJZYtJxUZV3X4r5ecA8ikjicUmcbU7zJmAjmqutG/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/fs-extra": "^8.0.0", + "debug": "^4.0.0", + "fs-extra": "^9.0.0", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=10.3.0" + } + }, + "node_modules/swiftlint/node_modules/cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.7.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/swiftlint/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/swiftlint/node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/swiftlint/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/symbol-observable": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz", + "integrity": "sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true, + "license": "MIT" + }, + "node_modules/synckit": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.2.tgz", + "integrity": "sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==", + "dev": true, + "dependencies": { + "@pkgr/core": "^0.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/system-architecture": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/system-architecture/-/system-architecture-0.1.0.tgz", + "integrity": "sha512-ulAk51I9UVUyJgxlv9M6lFot2WP3e7t8Kz9+IS6D4rVba1tR9kON+Ey69f+1R4Q8cd45Lod6a4IcJIxnzGc/zA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "dev": true, + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-fs/node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar/node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/teen_process": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/teen_process/-/teen_process-2.2.3.tgz", + "integrity": "sha512-8L540OalWH83qc6LHV5VMr0DjdP7KWUHQwTOImtWaG2ElW8BvLTh6M9871oGmmpOMb2BpOJQn2+09ZHWYsdTUA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "bluebird": "^3.7.2", + "lodash": "^4.17.21", + "shell-quote": "^1.8.1", + "source-map-support": "^0.x" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0", + "npm": ">=8" + } + }, + "node_modules/terser": { + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.37.0.tgz", + "integrity": "sha512-B8wRRkmre4ERucLM/uXx4MOV5cbnOlVAqUst+1+iLKPI0dOgFO28f84ptoQt9HEI537PMzfYa/d+GEPKTRXmYA==", + "dev": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", + "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.20", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/terser-webpack-plugin/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/test-exclude": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.1.tgz", + "integrity": "sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^10.4.1", + "minimatch": "^9.0.4" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/test-exclude/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "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/text-decoder": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.0.tgz", + "integrity": "sha512-n1yg1mOj9DNpk3NeZOx7T6jchTbyJS3i3cucbNN6FcdPriMZx7NsgrGpWWdWZZGxD7ES1XB+3uoqHMgOKaN+fg==", + "dependencies": { + "b4a": "^1.6.4" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/thingies": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/thingies/-/thingies-1.21.0.tgz", + "integrity": "sha512-hsqsJsFMsV+aD4s3CWKk85ep/3I9XzYV/IXaSouJMYIoDlgyi11cBhsqYe9/geRfB0YIikBQg6raRaM+nIMP9g==", + "dev": true, + "engines": { + "node": ">=10.18" + }, + "peerDependencies": { + "tslib": "^2" + } + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" + }, + "node_modules/through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dev": true, + "dependencies": { + "readable-stream": "3" + } + }, + "node_modules/thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "dev": true + }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.10.tgz", + "integrity": "sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.4.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/tinypool": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.2.tgz", + "integrity": "sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/tinyrainbow": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", + "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz", + "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true, + "license": "MIT" + }, + "node_modules/tree-dump": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.0.2.tgz", + "integrity": "sha512-dpev9ABuLWdEubk+cIaI9cHwRNNDjkBBLXTwI4UCUFdQ5xXKqNXoK4FEciw/vxf+NQ7Cb7sGUyeUtORvHIdRXQ==", + "dev": true, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "bin": { + "tree-kill": "cli.js" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.0.0" + } + }, + "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==", + "dev": true, + "license": "WTFPL", + "dependencies": { + "utf8-byte-length": "^1.0.1" + } + }, + "node_modules/ts-api-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.1.tgz", + "integrity": "sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w==", + "dev": true, + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/ts-morph": { + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-21.0.1.tgz", + "integrity": "sha512-dbDtVdEAncKctzrVZ+Nr7kHpHkv+0JDJb2MjjpBaj8bFeCkePU9rHfMklmhuLFnpeq/EJZk2IhStY6NzqgjOkg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ts-morph/common": "~0.22.0", + "code-block-writer": "^12.0.0" + } + }, + "node_modules/ts-node": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.3.0.tgz", + "integrity": "sha512-dyNS/RqyVTDcmNM4NIBAeDMpsAdaQ+ojdf0GOLqE6nwJOgzEkdRNzJywhDfwnuvB10oa6NLVG1rUJQCpRN7qoQ==", + "dev": true, + "dependencies": { + "arg": "^4.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.6", + "yn": "^3.0.0" + }, + "bin": { + "ts-node": "dist/bin.js" + }, + "engines": { + "node": ">=4.2.0" + }, + "peerDependencies": { + "typescript": ">=2.0" + } + }, + "node_modules/tsconfck": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.1.5.tgz", + "integrity": "sha512-CLDfGgUp7XPswWnezWwsCRxNmgQjhYq3VXHM0/XIRxhVrKw0M1if9agzryh1QS3nxjCROvV+xWxoJO1YctzzWg==", + "dev": true, + "license": "MIT", + "bin": { + "tsconfck": "bin/tsconfck.js" + }, + "engines": { + "node": "^18 || >=20" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "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==" + }, + "node_modules/tslint": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz", + "integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==", + "deprecated": "TSLint has been deprecated in favor of ESLint. Please see https://github.com/palantir/tslint/issues/4534 for more information.", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^4.0.1", + "glob": "^7.1.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.3", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.13.0", + "tsutils": "^2.29.0" + }, + "bin": { + "tslint": "bin/tslint" + }, + "engines": { + "node": ">=4.8.0" + }, + "peerDependencies": { + "typescript": ">=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev || >= 4.0.0-dev" + } + }, + "node_modules/tslint/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/tslint/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/tslint/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/tslint/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/tslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tslint/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/tslint/node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/tslint/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "peerDependencies": { + "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev" + } + }, + "node_modules/tsutils/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/tsx": { + "version": "4.19.3", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.3.tgz", + "integrity": "sha512-4H8vUNGNjQ4V2EOoGw005+c+dGuPSnhpPBPHBtsZdGZBk/iJb4kguGlPWaZTZ3q5nMtFOEsY0nRDlh9PJyd6SQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "~0.25.0", + "get-tsconfig": "^4.7.5" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, + "node_modules/tsx/node_modules/@esbuild/aix-ppc64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.1.tgz", + "integrity": "sha512-kfYGy8IdzTGy+z0vFGvExZtxkFlA4zAxgKEahG9KE1ScBjpQnFsNOX8KTU5ojNru5ed5CVoJYXFtoxaq5nFbjQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/android-arm": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.1.tgz", + "integrity": "sha512-dp+MshLYux6j/JjdqVLnMglQlFu+MuVeNrmT5nk6q07wNhCdSnB7QZj+7G8VMUGh1q+vj2Bq8kRsuyA00I/k+Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/android-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.1.tgz", + "integrity": "sha512-50tM0zCJW5kGqgG7fQ7IHvQOcAn9TKiVRuQ/lN0xR+T2lzEFvAi1ZcS8DiksFcEpf1t/GYOeOfCAgDHFpkiSmA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/android-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.1.tgz", + "integrity": "sha512-GCj6WfUtNldqUzYkN/ITtlhwQqGWu9S45vUXs7EIYf+7rCiiqH9bCloatO9VhxsL0Pji+PF4Lz2XXCES+Q8hDw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/darwin-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.1.tgz", + "integrity": "sha512-5hEZKPf+nQjYoSr/elb62U19/l1mZDdqidGfmFutVUjjUZrOazAtwK+Kr+3y0C/oeJfLlxo9fXb1w7L+P7E4FQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/darwin-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.1.tgz", + "integrity": "sha512-hxVnwL2Dqs3fM1IWq8Iezh0cX7ZGdVhbTfnOy5uURtao5OIVCEyj9xIzemDi7sRvKsuSdtCAhMKarxqtlyVyfA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.1.tgz", + "integrity": "sha512-1MrCZs0fZa2g8E+FUo2ipw6jw5qqQiH+tERoS5fAfKnRx6NXH31tXBKI3VpmLijLH6yriMZsxJtaXUyFt/8Y4A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/freebsd-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.1.tgz", + "integrity": "sha512-0IZWLiTyz7nm0xuIs0q1Y3QWJC52R8aSXxe40VUxm6BB1RNmkODtW6LHvWRrGiICulcX7ZvyH6h5fqdLu4gkww==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-arm": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.1.tgz", + "integrity": "sha512-NdKOhS4u7JhDKw9G3cY6sWqFcnLITn6SqivVArbzIaf3cemShqfLGHYMx8Xlm/lBit3/5d7kXvriTUGa5YViuQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.1.tgz", + "integrity": "sha512-jaN3dHi0/DDPelk0nLcXRm1q7DNJpjXy7yWaWvbfkPvI+7XNSc/lDOnCLN7gzsyzgu6qSAmgSvP9oXAhP973uQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-ia32": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.1.tgz", + "integrity": "sha512-OJykPaF4v8JidKNGz8c/q1lBO44sQNUQtq1KktJXdBLn1hPod5rE/Hko5ugKKZd+D2+o1a9MFGUEIUwO2YfgkQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-loong64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.1.tgz", + "integrity": "sha512-nGfornQj4dzcq5Vp835oM/o21UMlXzn79KobKlcs3Wz9smwiifknLy4xDCLUU0BWp7b/houtdrgUz7nOGnfIYg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-mips64el": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.1.tgz", + "integrity": "sha512-1osBbPEFYwIE5IVB/0g2X6i1qInZa1aIoj1TdL4AaAb55xIIgbg8Doq6a5BzYWgr+tEcDzYH67XVnTmUzL+nXg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-ppc64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.1.tgz", + "integrity": "sha512-/6VBJOwUf3TdTvJZ82qF3tbLuWsscd7/1w+D9LH0W/SqUgM5/JJD0lrJ1fVIfZsqB6RFmLCe0Xz3fmZc3WtyVg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-riscv64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.1.tgz", + "integrity": "sha512-nSut/Mx5gnilhcq2yIMLMe3Wl4FK5wx/o0QuuCLMtmJn+WeWYoEGDN1ipcN72g1WHsnIbxGXd4i/MF0gTcuAjQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-s390x": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.1.tgz", + "integrity": "sha512-cEECeLlJNfT8kZHqLarDBQso9a27o2Zd2AQ8USAEoGtejOrCYHNtKP8XQhMDJMtthdF4GBmjR2au3x1udADQQQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.1.tgz", + "integrity": "sha512-xbfUhu/gnvSEg+EGovRc+kjBAkrvtk38RlerAzQxvMzlB4fXpCFCeUAYzJvrnhFtdeyVCDANSjJvOvGYoeKzFA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.1.tgz", + "integrity": "sha512-O96poM2XGhLtpTh+s4+nP7YCCAfb4tJNRVZHfIE7dgmax+yMP2WgMd2OecBuaATHKTHsLWHQeuaxMRnCsH8+5g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/netbsd-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.1.tgz", + "integrity": "sha512-X53z6uXip6KFXBQ+Krbx25XHV/NCbzryM6ehOAeAil7X7oa4XIq+394PWGnwaSQ2WRA0KI6PUO6hTO5zeF5ijA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.1.tgz", + "integrity": "sha512-Na9T3szbXezdzM/Kfs3GcRQNjHzM6GzFBeU1/6IV/npKP5ORtp9zbQjvkDJ47s6BCgaAZnnnu/cY1x342+MvZg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/openbsd-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.1.tgz", + "integrity": "sha512-T3H78X2h1tszfRSf+txbt5aOp/e7TAz3ptVKu9Oyir3IAOFPGV6O9c2naym5TOriy1l0nNf6a4X5UXRZSGX/dw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/sunos-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.1.tgz", + "integrity": "sha512-2H3RUvcmULO7dIE5EWJH8eubZAI4xw54H1ilJnRNZdeo8dTADEZ21w6J22XBkXqGJbe0+wnNJtw3UXRoLJnFEg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/win32-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.1.tgz", + "integrity": "sha512-GE7XvrdOzrb+yVKB9KsRMq+7a2U/K5Cf/8grVFRAGJmfADr/e/ODQ134RK2/eeHqYV5eQRFxb1hY7Nr15fv1NQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/win32-ia32": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.1.tgz", + "integrity": "sha512-uOxSJCIcavSiT6UnBhBzE8wy3n0hOkJsBOzy7HDAuTDE++1DJMRRVCPGisULScHL+a/ZwdXPpXD3IyFKjA7K8A==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/win32-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.1.tgz", + "integrity": "sha512-Y1EQdcfwMSeQN/ujR5VayLOJ1BHaK+ssyk0AEzPjC+t1lITgsnccPqFjb6V+LsTp/9Iov4ysfjxLaGJ9RPtkVg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/esbuild": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.1.tgz", + "integrity": "sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.1", + "@esbuild/android-arm": "0.25.1", + "@esbuild/android-arm64": "0.25.1", + "@esbuild/android-x64": "0.25.1", + "@esbuild/darwin-arm64": "0.25.1", + "@esbuild/darwin-x64": "0.25.1", + "@esbuild/freebsd-arm64": "0.25.1", + "@esbuild/freebsd-x64": "0.25.1", + "@esbuild/linux-arm": "0.25.1", + "@esbuild/linux-arm64": "0.25.1", + "@esbuild/linux-ia32": "0.25.1", + "@esbuild/linux-loong64": "0.25.1", + "@esbuild/linux-mips64el": "0.25.1", + "@esbuild/linux-ppc64": "0.25.1", + "@esbuild/linux-riscv64": "0.25.1", + "@esbuild/linux-s390x": "0.25.1", + "@esbuild/linux-x64": "0.25.1", + "@esbuild/netbsd-arm64": "0.25.1", + "@esbuild/netbsd-x64": "0.25.1", + "@esbuild/openbsd-arm64": "0.25.1", + "@esbuild/openbsd-x64": "0.25.1", + "@esbuild/sunos-x64": "0.25.1", + "@esbuild/win32-arm64": "0.25.1", + "@esbuild/win32-ia32": "0.25.1", + "@esbuild/win32-x64": "0.25.1" + } + }, + "node_modules/tuf-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-3.0.1.tgz", + "integrity": "sha512-+68OP1ZzSF84rTckf3FA95vJ1Zlx/uaXyiiKyPd1pA4rZNkpEvDAKmsu1xUSmbF/chCRYgZ6UZkDwC7PmzmAyA==", + "dev": true, + "dependencies": { + "@tufjs/models": "3.0.1", + "debug": "^4.3.6", + "make-fetch-happen": "^14.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "dev": true + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-assert": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/typed-assert/-/typed-assert-1.0.9.tgz", + "integrity": "sha512-KNNZtayBCtmnNmbo5mG47p1XsCyrx6iVqomjcZnec/1Y5GGARaxPs6r49RnSPeUP3YjNYiU9sQHAtY4BBvnZwg==", + "dev": true + }, + "node_modules/typed-query-selector": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/typed-query-selector/-/typed-query-selector-2.12.0.tgz", + "integrity": "sha512-SbklCd1F0EiZOyPiW192rrHZzZ5sBijB6xM+cpmrwDqObvdtunOHHIk9fCGsoK5JVIYXoyEp4iEdE3upFH3PAg==" + }, + "node_modules/typescript": { + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ufo": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.4.tgz", + "integrity": "sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/unbzip2-stream": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", + "dependencies": { + "buffer": "^5.2.1", + "through": "^2.3.8" + } + }, + "node_modules/uncrypto": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/uncrypto/-/uncrypto-0.1.3.tgz", + "integrity": "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/unctx": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/unctx/-/unctx-2.4.1.tgz", + "integrity": "sha512-AbaYw0Nm4mK4qjhns67C+kgxR2YWiwlDBPzxrN8h8C6VtAdCgditAY5Dezu3IJy4XVqAnbrXt9oQJvsn3fyozg==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.14.0", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.17", + "unplugin": "^2.1.0" + } + }, + "node_modules/unctx/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/undici": { + "version": "6.21.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.1.tgz", + "integrity": "sha512-q/1rj5D0/zayJB2FraXdaWxbhWiNKDvu8naDT2dl1yTlvJp4BLtOcp2a5BvgGNQpYYJzau7tf1WgKv3b+7mqpQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.17" + } + }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true + }, + "node_modules/unenv": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/unenv/-/unenv-1.10.0.tgz", + "integrity": "sha512-wY5bskBQFL9n3Eca5XnhH6KbUo/tfvkwm9OpcdCvLaeA7piBNbavbOKJySEwQ1V0RH6HvNlSAFRTpvTqgKRQXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "consola": "^3.2.3", + "defu": "^6.1.4", + "mime": "^3.0.0", + "node-fetch-native": "^1.6.4", + "pathe": "^1.1.2" + } + }, + "node_modules/unenv/node_modules/mime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz", + "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/unimport": { + "version": "3.14.6", + "resolved": "https://registry.npmjs.org/unimport/-/unimport-3.14.6.tgz", + "integrity": "sha512-CYvbDaTT04Rh8bmD8jz3WPmHYZRG/NnvYVzwD6V1YAlvvKROlAeNDUBhkBGzNav2RKaeuXvlWYaa1V4Lfi/O0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.1.4", + "acorn": "^8.14.0", + "escape-string-regexp": "^5.0.0", + "estree-walker": "^3.0.3", + "fast-glob": "^3.3.3", + "local-pkg": "^1.0.0", + "magic-string": "^0.30.17", + "mlly": "^1.7.4", + "pathe": "^2.0.1", + "picomatch": "^4.0.2", + "pkg-types": "^1.3.0", + "scule": "^1.3.0", + "strip-literal": "^2.1.1", + "unplugin": "^1.16.1" + } + }, + "node_modules/unimport/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/unimport/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/unimport/node_modules/pathe": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.2.tgz", + "integrity": "sha512-15Ztpk+nov8DR524R4BF7uEuzESgzUEAV4Ah7CUMNGXdE5ELuvxElxGXndBl32vMSsWa1jpNf22Z+Er3sKwq+w==", + "dev": true, + "license": "MIT" + }, + "node_modules/unimport/node_modules/unplugin": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.16.1.tgz", + "integrity": "sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.14.0", + "webpack-virtual-modules": "^0.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/unique-filename": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-4.0.0.tgz", + "integrity": "sha512-XSnEewXmQ+veP7xX2dS5Q4yZAvO40cBN2MWkJ7D/6sW4Dg6wYBNwM1Vrnz1FhH5AdeLIlUXRI9e28z1YZi71NQ==", + "dev": true, + "dependencies": { + "unique-slug": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/unique-slug": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-5.0.0.tgz", + "integrity": "sha512-9OdaqO5kwqR+1kVgHAhsp5vPNU0hnxRa26rBFNfNgM7M6pNtgzeBn3s/xbyCQL3dcjzOatcef6UUHpB/6MaETg==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unorm": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/unorm/-/unorm-1.6.0.tgz", + "integrity": "sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA==", + "dev": true, + "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==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/unplugin": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-2.1.2.tgz", + "integrity": "sha512-Q3LU0e4zxKfRko1wMV2HmP8lB9KWislY7hxXpxd+lGx0PRInE4vhMBVEZwpdVYHvtqzhSrzuIfErsob6bQfCzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.14.0", + "webpack-virtual-modules": "^0.6.2" + }, + "engines": { + "node": ">=18.12.0" + } + }, + "node_modules/unstorage": { + "version": "1.14.4", + "resolved": "https://registry.npmjs.org/unstorage/-/unstorage-1.14.4.tgz", + "integrity": "sha512-1SYeamwuYeQJtJ/USE1x4l17LkmQBzg7deBJ+U9qOBoHo15d1cDxG4jM31zKRgF7pG0kirZy4wVMX6WL6Zoscg==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "^3.1.3", + "chokidar": "^3.6.0", + "destr": "^2.0.3", + "h3": "^1.13.0", + "lru-cache": "^10.4.3", + "node-fetch-native": "^1.6.4", + "ofetch": "^1.4.1", + "ufo": "^1.5.4" + }, + "peerDependencies": { + "@azure/app-configuration": "^1.8.0", + "@azure/cosmos": "^4.2.0", + "@azure/data-tables": "^13.3.0", + "@azure/identity": "^4.5.0", + "@azure/keyvault-secrets": "^4.9.0", + "@azure/storage-blob": "^12.26.0", + "@capacitor/preferences": "^6.0.3", + "@deno/kv": ">=0.8.4", + "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0", + "@planetscale/database": "^1.19.0", + "@upstash/redis": "^1.34.3", + "@vercel/blob": ">=0.27.0", + "@vercel/kv": "^1.0.1", + "aws4fetch": "^1.0.20", + "db0": ">=0.2.1", + "idb-keyval": "^6.2.1", + "ioredis": "^5.4.2", + "uploadthing": "^7.4.1" + }, + "peerDependenciesMeta": { + "@azure/app-configuration": { + "optional": true + }, + "@azure/cosmos": { + "optional": true + }, + "@azure/data-tables": { + "optional": true + }, + "@azure/identity": { + "optional": true + }, + "@azure/keyvault-secrets": { + "optional": true + }, + "@azure/storage-blob": { + "optional": true + }, + "@capacitor/preferences": { + "optional": true + }, + "@deno/kv": { + "optional": true + }, + "@netlify/blobs": { + "optional": true + }, + "@planetscale/database": { + "optional": true + }, + "@upstash/redis": { + "optional": true + }, + "@vercel/blob": { + "optional": true + }, + "@vercel/kv": { + "optional": true + }, + "aws4fetch": { + "optional": true + }, + "db0": { + "optional": true + }, + "idb-keyval": { + "optional": true + }, + "ioredis": { + "optional": true + }, + "uploadthing": { + "optional": true + } + } + }, + "node_modules/unstorage/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==", + "dev": true, + "license": "ISC" + }, + "node_modules/untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/untun": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/untun/-/untun-0.1.3.tgz", + "integrity": "sha512-4luGP9LMYszMRZwsvyUd9MrxgEGZdZuZgpVQHEEX0lCYFESasVRvZd0EYpCkOIbJKHMuv0LskpXc/8Un+MJzEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "citty": "^0.1.5", + "consola": "^3.2.3", + "pathe": "^1.1.1" + }, + "bin": { + "untun": "bin/untun.mjs" + } + }, + "node_modules/untyped": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/untyped/-/untyped-1.5.2.tgz", + "integrity": "sha512-eL/8PlhLcMmlMDtNPKhyyz9kEBDS3Uk4yMu/ewlkT2WFbtzScjHWPJLdQLmaGPUKjXzwe9MumOtOgc4Fro96Kg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.26.0", + "@babel/standalone": "^7.26.4", + "@babel/types": "^7.26.3", + "citty": "^0.1.6", + "defu": "^6.1.4", + "jiti": "^2.4.1", + "knitwork": "^1.2.0", + "scule": "^1.3.0" + }, + "bin": { + "untyped": "dist/cli.mjs" + } + }, + "node_modules/untyped/node_modules/jiti": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", + "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/unwasm": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/unwasm/-/unwasm-0.3.9.tgz", + "integrity": "sha512-LDxTx/2DkFURUd+BU1vUsF/moj0JsoTvl+2tcg2AUOiEzVturhGGx17/IMgGvKUYdZwr33EJHtChCJuhu9Ouvg==", + "dev": true, + "license": "MIT", + "dependencies": { + "knitwork": "^1.0.0", + "magic-string": "^0.30.8", + "mlly": "^1.6.1", + "pathe": "^1.1.2", + "pkg-types": "^1.0.3", + "unplugin": "^1.10.0" + } + }, + "node_modules/unwasm/node_modules/unplugin": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.16.1.tgz", + "integrity": "sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.14.0", + "webpack-virtual-modules": "^0.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz", + "integrity": "sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uqr": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/uqr/-/uqr-0.1.2.tgz", + "integrity": "sha512-MJu7ypHq6QasgF5YRTjqscSzQp/W11zoUk6kvmlH+fmWEs63Y0Eib13hYFwAzagRJcVY8WVnlV+eBDUGMJ5IbA==", + "dev": true, + "license": "MIT" + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/uri-js-replace": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uri-js-replace/-/uri-js-replace-1.0.1.tgz", + "integrity": "sha512-W+C9NWNLFOoBI2QWDp4UT9pv65r2w5Cx+3sTYFvtMdDBxkKt1syCqsUdSFAChbEe1uK5TfS04wt/nGwmaeIQ0g==", + "dev": true, + "license": "MIT" + }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "node_modules/urlpattern-polyfill": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-8.0.2.tgz", + "integrity": "sha512-Qp95D4TPJl1kC9SKigDcqgyM2VDVO4RiJc2d4qe5GrYm+zbIQCWWKAFaJNQ4BhdFeDGwBmAxqJBwWSJDb9T3BQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/userhome": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/userhome/-/userhome-1.0.1.tgz", + "integrity": "sha512-5cnLm4gseXjAclKowC4IjByaGsjtAoV6PrOQOljplNB54ReUYJP8HdAFq2muHinSDAh09PPX/uXDPfdxRHvuSA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "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==", + "dev": true, + "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==" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/validate-npm-package-name": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-6.0.0.tgz", + "integrity": "sha512-d7KLgL1LD3U3fgnvWEY1cQXoO/q6EQ1BSz48Sa149V/5zVTAbgmZIpyI8TRi6U9/JNyeYLlTKsEMPtLC27RFUg==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/validate.js": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/validate.js/-/validate.js-0.13.1.tgz", + "integrity": "sha512-PnFM3xiZ+kYmLyTiMgTYmU7ZHkjBZz2/+F0DaALc/uUtVzdCt1wAosvYJ5hFQi/hz8O4zb52FQhHZRC+uVkJ+g==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/vfile": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vite": { + "version": "6.0.11", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.0.11.tgz", + "integrity": "sha512-4VL9mQPKoHy4+FE0NnRE/kbY51TOfaknxAjt3fJbGJxhIpBZiqVzlZDEesWWsuREXHwNdAoOFZ9MkPEVXczHwg==", + "dev": true, + "dependencies": { + "esbuild": "^0.24.2", + "postcss": "^8.4.49", + "rollup": "^4.23.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.0.5.tgz", + "integrity": "sha512-02JEJl7SbtwSDJdYS537nU6l+ktdvcREfLksk/NDAqtdKWGqHl+joXzEubHROmS3E6pip+Xgu2tFezMu75jH7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.4.0", + "es-module-lexer": "^1.6.0", + "pathe": "^2.0.2", + "vite": "^5.0.0 || ^6.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vite-node/node_modules/pathe": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.2.tgz", + "integrity": "sha512-15Ztpk+nov8DR524R4BF7uEuzESgzUEAV4Ah7CUMNGXdE5ELuvxElxGXndBl32vMSsWa1jpNf22Z+Er3sKwq+w==", + "dev": true, + "license": "MIT" + }, + "node_modules/vite-tsconfig-paths": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-4.3.2.tgz", + "integrity": "sha512-0Vd/a6po6Q+86rPlntHye7F31zA2URZMbH8M3saAZ/xR9QoGN/L21bxEGfXdWmFdNkqPpRdxFT7nmNe12e9/uA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.1", + "globrex": "^0.1.2", + "tsconfck": "^3.0.3" + }, + "peerDependencies": { + "vite": "*" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, + "node_modules/vitefu": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-0.2.5.tgz", + "integrity": "sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, + "node_modules/vitest": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.0.5.tgz", + "integrity": "sha512-4dof+HvqONw9bvsYxtkfUp2uHsTN9bV2CZIi1pWgoFpL1Lld8LA1ka9q/ONSsoScAKG7NVGf2stJTI7XRkXb2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "3.0.5", + "@vitest/mocker": "3.0.5", + "@vitest/pretty-format": "^3.0.5", + "@vitest/runner": "3.0.5", + "@vitest/snapshot": "3.0.5", + "@vitest/spy": "3.0.5", + "@vitest/utils": "3.0.5", + "chai": "^5.1.2", + "debug": "^4.4.0", + "expect-type": "^1.1.0", + "magic-string": "^0.30.17", + "pathe": "^2.0.2", + "std-env": "^3.8.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.2", + "tinypool": "^1.0.2", + "tinyrainbow": "^2.0.0", + "vite": "^5.0.0 || ^6.0.0", + "vite-node": "3.0.5", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/debug": "^4.1.12", + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "@vitest/browser": "3.0.5", + "@vitest/ui": "3.0.5", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/debug": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/vitest/node_modules/pathe": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.2.tgz", + "integrity": "sha512-15Ztpk+nov8DR524R4BF7uEuzESgzUEAV4Ah7CUMNGXdE5ELuvxElxGXndBl32vMSsWa1jpNf22Z+Er3sKwq+w==", + "dev": true, + "license": "MIT" + }, + "node_modules/w3c-xmlserializer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", + "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/wait-port": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/wait-port/-/wait-port-1.1.0.tgz", + "integrity": "sha512-3e04qkoN3LxTMLakdqeWth8nih8usyg+sf1Bgdf9wwUkp05iuK1eSY/QpLvscT/+F/gA89+LpUmmgBtesbqI2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2", + "commander": "^9.3.0", + "debug": "^4.3.4" + }, + "bin": { + "wait-port": "bin/wait-port.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/wait-port/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wait-port/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": 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/wait-port/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wait-port/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/wait-port/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wait-port/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/watchpack": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", + "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", + "dev": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "dev": true, + "dependencies": { + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dev": true, + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/weak-lru-cache": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/weak-lru-cache/-/weak-lru-cache-1.2.2.tgz", + "integrity": "sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==", + "dev": true, + "optional": true + }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/webdriver": { + "version": "9.11.0", + "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-9.11.0.tgz", + "integrity": "sha512-KQdI5sK+YwnUqol8MhvW9y6V+fhaW82KRhqMYnVCOrG4sJFWg7A9OIqR11Buco804HpzxyocRO6MnOQrNvP0vQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "^20.1.0", + "@types/ws": "^8.5.3", + "@wdio/config": "9.11.0", + "@wdio/logger": "9.4.4", + "@wdio/protocols": "9.7.0", + "@wdio/types": "9.10.1", + "@wdio/utils": "9.11.0", + "deepmerge-ts": "^7.0.3", + "undici": "^6.20.1", + "ws": "^8.8.0" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/webdriver-js-extender": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/webdriver-js-extender/-/webdriver-js-extender-2.1.0.tgz", + "integrity": "sha512-lcUKrjbBfCK6MNsh7xaY2UAUmZwe+/ib03AjVOpFobX4O7+83BUveSrLfU0Qsyb1DaKJdQRbuU+kM9aZ6QUhiQ==", + "dev": true, + "dependencies": { + "@types/selenium-webdriver": "^3.0.0", + "selenium-webdriver": "^3.0.1" + }, + "engines": { + "node": ">=6.9.x" + } + }, + "node_modules/webdriver-manager": { + "version": "12.1.9", + "resolved": "https://registry.npmjs.org/webdriver-manager/-/webdriver-manager-12.1.9.tgz", + "integrity": "sha512-Yl113uKm8z4m/KMUVWHq1Sjtla2uxEBtx2Ue3AmIlnlPAKloDn/Lvmy6pqWCUersVISpdMeVpAaGbNnvMuT2LQ==", + "dev": true, + "dependencies": { + "adm-zip": "^0.5.2", + "chalk": "^1.1.1", + "del": "^2.2.0", + "glob": "^7.0.3", + "ini": "^1.3.4", + "minimist": "^1.2.0", + "q": "^1.4.1", + "request": "^2.87.0", + "rimraf": "^2.5.2", + "semver": "^5.3.0", + "xml2js": "^0.4.17" + }, + "bin": { + "webdriver-manager": "bin/webdriver-manager" + }, + "engines": { + "node": ">=6.9.x" + } + }, + "node_modules/webdriver-manager/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webdriver-manager/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webdriver-manager/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webdriver-manager/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "node_modules/webdriver-manager/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/webdriver-manager/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/webdriver-manager/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webdriver-manager/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/webdriver-manager/node_modules/xml2js": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", + "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", + "dev": true, + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/webdriver-manager/node_modules/xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/webdriver/node_modules/@types/node": { + "version": "20.17.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.24.tgz", + "integrity": "sha512-d7fGCyB96w9BnWQrOsJtpyiSaBcAYYr75bnK6ZRjDbql2cGLj/3GsL5OYmLPNq76l7Gf2q4Rv9J2o6h5CrD9sA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/webdriverio": { + "version": "9.11.0", + "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-9.11.0.tgz", + "integrity": "sha512-FYdq/3OJj04t4a+hooXt6GQ1L7i8BpZyB9BmKOW5iEKnG8vyyOE9nyOEj5SaAKU9dVJFrR8jBNdIALFDmABpRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "^20.11.30", + "@types/sinonjs__fake-timers": "^8.1.5", + "@wdio/config": "9.11.0", + "@wdio/logger": "9.4.4", + "@wdio/protocols": "9.7.0", + "@wdio/repl": "9.4.4", + "@wdio/types": "9.10.1", + "@wdio/utils": "9.11.0", + "archiver": "^7.0.1", + "aria-query": "^5.3.0", + "cheerio": "^1.0.0-rc.12", + "css-shorthand-properties": "^1.1.1", + "css-value": "^0.0.1", + "grapheme-splitter": "^1.0.4", + "htmlfy": "^0.6.0", + "is-plain-obj": "^4.1.0", + "jszip": "^3.10.1", + "lodash.clonedeep": "^4.5.0", + "lodash.zip": "^4.2.0", + "query-selector-shadow-dom": "^1.0.1", + "resq": "^1.11.0", + "rgb2hex": "0.2.5", + "serialize-error": "^11.0.3", + "urlpattern-polyfill": "^10.0.0", + "webdriver": "9.11.0" + }, + "engines": { + "node": ">=18.20.0" + }, + "peerDependencies": { + "puppeteer-core": "^22.3.0" + }, + "peerDependenciesMeta": { + "puppeteer-core": { + "optional": true + } + } + }, + "node_modules/webdriverio/node_modules/@types/node": { + "version": "20.17.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.24.tgz", + "integrity": "sha512-d7fGCyB96w9BnWQrOsJtpyiSaBcAYYr75bnK6ZRjDbql2cGLj/3GsL5OYmLPNq76l7Gf2q4Rv9J2o6h5CrD9sA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/webdriverio/node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/webdriverio/node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/webdriverio/node_modules/urlpattern-polyfill": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz", + "integrity": "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==", + "dev": true, + "license": "MIT" + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/webpack": { + "version": "5.97.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.97.1.tgz", + "integrity": "sha512-EksG6gFY3L1eFMROS/7Wzgrii5mBAFe4rIr3r2BTfo7bcc+DWwFZ4OJ/miOuHJO/A85HwyI4eQ0F6IKXesO7Fg==", + "dev": true, + "dependencies": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.6", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.14.0", + "browserslist": "^4.24.0", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.1", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-middleware": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.4.2.tgz", + "integrity": "sha512-xOO8n6eggxnwYpy1NlzUKpvrjfJTvae5/D6WOK0S2LSo7vjmo5gCM1DbLUmFqrMTJP+W/0YZNctm7jasWvLuBA==", + "dev": true, + "dependencies": { + "colorette": "^2.0.10", + "memfs": "^4.6.0", + "mime-types": "^2.1.31", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.2.0.tgz", + "integrity": "sha512-90SqqYXA2SK36KcT6o1bvwvZfJFcmoamqeJY7+boioffX9g9C0wjjJRGUrQIuh43pb0ttX7+ssavmj/WN2RHtA==", + "dev": true, + "dependencies": { + "@types/bonjour": "^3.5.13", + "@types/connect-history-api-fallback": "^1.5.4", + "@types/express": "^4.17.21", + "@types/serve-index": "^1.9.4", + "@types/serve-static": "^1.15.5", + "@types/sockjs": "^0.3.36", + "@types/ws": "^8.5.10", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.2.1", + "chokidar": "^3.6.0", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "express": "^4.21.2", + "graceful-fs": "^4.2.6", + "http-proxy-middleware": "^2.0.7", + "ipaddr.js": "^2.1.0", + "launch-editor": "^2.6.1", + "open": "^10.0.3", + "p-retry": "^6.2.0", + "schema-utils": "^4.2.0", + "selfsigned": "^2.4.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^7.4.2", + "ws": "^8.18.0" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/http-proxy-middleware": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz", + "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==", + "dev": true, + "dependencies": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } + } + }, + "node_modules/webpack-merge": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz", + "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==", + "dev": true, + "dependencies": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack-subresource-integrity": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/webpack-subresource-integrity/-/webpack-subresource-integrity-5.1.0.tgz", + "integrity": "sha512-sacXoX+xd8r4WKsy9MvH/q/vBtEHr86cpImXwyg74pFIpERKt6FmB8cXpeuh0ZLgclOlHI4Wcll7+R5L02xk9Q==", + "dev": true, + "dependencies": { + "typed-assert": "^1.0.8" + }, + "engines": { + "node": ">= 12" + }, + "peerDependencies": { + "html-webpack-plugin": ">= 5.0.0-beta.1 < 6", + "webpack": "^5.12.0" + }, + "peerDependenciesMeta": { + "html-webpack-plugin": { + "optional": true + } + } + }, + "node_modules/webpack-virtual-modules": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz", + "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/webpack/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/webpack/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/webpack/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/webpack/node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/webpack/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/webpack/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dev": true, + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/whatwg-mimetype": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", + "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "dev": true, + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-module": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", + "dev": true + }, + "node_modules/which-typed-array": { + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.18.tgz", + "integrity": "sha512-qEcY+KJYlWyLH9vNbsr6/5j59AXk5ni5aakf8ldzBvGde6Iz4sxZGkJyWSAueTG7QhOvNRYb1lDdFmL5Td0QKA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "dev": true + }, + "node_modules/winston": { + "version": "3.17.0", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.17.0.tgz", + "integrity": "sha512-DLiFIXYC5fMPxaRg832S6F5mJYvePtmO5G9v9IgUFPhXm9/GkXarH/TUrBAVzhTCzAj9anE/+GjrgXp/54nOgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@colors/colors": "^1.6.0", + "@dabh/diagnostics": "^2.0.2", + "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/winston-transport": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.9.0.tgz", + "integrity": "sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "logform": "^2.7.0", + "readable-stream": "^3.6.2", + "triple-beam": "^1.3.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/winston/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/workerpool": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", + "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/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==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/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==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi-cjs/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==", + "dev": true + }, + "node_modules/wrap-ansi/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==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/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==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/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==", + "dev": true + }, + "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==" + }, + "node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "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/xml-name-validator": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", + "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12" + } + }, + "node_modules/xml2js": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", + "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", + "dev": true, + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/xml2js/node_modules/xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/xmlbuilder": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", + "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", + "dev": true, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/xmlbuilder2": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/xmlbuilder2/-/xmlbuilder2-3.1.1.tgz", + "integrity": "sha512-WCSfbfZnQDdLQLiMdGUQpMxxckeQ4oZNMNhLVkcekTu7xhD4tuUDyAPoY8CwXvBYE6LwBHd6QW2WZXlOWr1vCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oozcitak/dom": "1.15.10", + "@oozcitak/infra": "1.0.8", + "@oozcitak/util": "8.3.8", + "js-yaml": "3.14.1" + }, + "engines": { + "node": ">=12.0" + } + }, + "node_modules/xmlbuilder2/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/xmlbuilder2/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/xmlbuilder2/node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true, + "license": "MIT" + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/yaml": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz", + "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==", + "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/yaml-ast-parser": { + "version": "0.0.43", + "resolved": "https://registry.npmjs.org/yaml-ast-parser/-/yaml-ast-parser-0.0.43.tgz", + "integrity": "sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yargs-unparser/node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yargs-unparser/node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yoctocolors": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.1.tgz", + "integrity": "sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yoctocolors-cjs": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.2.tgz", + "integrity": "sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zip-a-folder": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/zip-a-folder/-/zip-a-folder-3.1.7.tgz", + "integrity": "sha512-pnY1fwTBYiwqXexCYCK8D/asfBhJ9BnnBlt6Qjx53cjBq+9JO+hhOZSt/1N05d3xf/21DhWySSugelyj6dLrYA==", + "dev": true, + "dependencies": { + "archiver": "^7.0.1", + "glob": "^10.4.1", + "is-glob": "^4.0.3" + } + }, + "node_modules/zip-a-folder/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "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/zip-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-6.0.1.tgz", + "integrity": "sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==", + "dev": true, + "dependencies": { + "archiver-utils": "^5.0.0", + "compress-commons": "^6.0.2", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/zip-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==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/zip-stream/node_modules/readable-stream": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", + "dev": true, + "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/zod": { + "version": "3.23.8", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", + "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zone.js": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.15.0.tgz", + "integrity": "sha512-9oxn0IIjbCZkJ67L+LkhYWRyAy7axphb3VgE2MBDlOqnmHMPWGYMxJxBYFueFq/JGY2GMwS0rU+UCLunEmy5UA==", + "license": "MIT" + }, + "node_modules/zrender": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/zrender/-/zrender-5.6.0.tgz", + "integrity": "sha512-uzgraf4njmmHAbEUxMJ8Oxg+P3fT04O+9p7gY+wJRVxo8Ge+KmYv0WJev945EH4wFuc4OY2NLXz46FZrWS9xJg==", + "dependencies": { + "tslib": "2.3.0" + } + }, + "node_modules/zrender/node_modules/tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" + }, + "storage-mirror": { + "version": "0.0.1", + "license": "GPLv3", + "devDependencies": { + "@capacitor/android": "^6.0.0", + "@capacitor/core": "^6.0.0", + "@capacitor/docgen": "^0.2.2", + "@capacitor/ios": "^6.0.0", + "@ionic/eslint-config": "^0.4.0", + "@ionic/prettier-config": "^1.0.1", + "@ionic/swiftlint-config": "^1.1.2", + "eslint": "^9.16.0", + "eslint-plugin-import": "^2.29.1", + "eslint-plugin-jsdoc": "^48.2.1", + "eslint-plugin-prefer-arrow": "1.2.2", + "prettier": "~2.3.0", + "prettier-plugin-java": "~1.0.2", + "rimraf": "^3.0.2", + "rollup": "^2.32.0", + "swiftlint": "^1.0.1", + "typescript": "~5.0.0" + }, + "peerDependencies": { + "@capacitor/core": "^6.0.0" + } + }, + "storage-mirror/node_modules/@ionic/prettier-config": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@ionic/prettier-config/-/prettier-config-1.0.1.tgz", + "integrity": "sha512-/v8UOW7rxkw/hvrRe/QfjlQsdjkm3sfAHoE3uqffO5BoNGijQMARrT32JT9Ei0g6KySXPyxxW+7LzPHrQmfzCw==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "prettier": "^2.0.0" + } + }, + "storage-mirror/node_modules/prettier": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz", + "integrity": "sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "storage-mirror/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "storage-mirror/node_modules/rollup": { + "version": "2.79.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", + "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", + "dev": true, + "license": "MIT", + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "storage-mirror/node_modules/typescript": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz", + "integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=12.20" + } + } + } } diff --git a/package.json b/package.json index 6cfaae20..7cb3662b 100644 --- a/package.json +++ b/package.json @@ -1,93 +1,128 @@ { - "name": "beaconchain-dashboard", - "version": "2.0.0", - "author": "Bitfly GmbH", - "homepage": "https://beaconcha.in", - "scripts": { - "test": "ng test", - "serve": "ionic serve --live-reload --no-open --configuration=development", - "build-android-for-release": "ionic cap build android --prod --release --source-map=true", - "build-ios-for-release": "ionic cap build ios --prod --release --source-map=true", - "prettier-format": "prettier --config .prettierrc.yml 'src/**/*.{ts,html,scss}' --write", - "prettier-check": "prettier -c --config .prettierrc.yml 'src/**/*.{ts,html,scss}'", - "lint": "eslint . --ext .ts" - }, - "private": true, - "dependencies": { - "@angular/animations": "^16.2.5", - "@angular/cdk": "^16.2.7", - "@angular/common": "~16.2.5", - "@angular/core": "~16.2.5", - "@angular/forms": "~16.2.5", - "@angular/platform-browser": "~16.2.5", - "@angular/platform-browser-dynamic": "~16.2.5", - "@angular/router": "~16.2.5", - "@awesome-cordova-plugins/core": "^6.4.0", - "@awesome-cordova-plugins/splash-screen": "^6.4.0", - "@awesome-cordova-plugins/status-bar": "^6.4.0", - "@byteowls/capacitor-oauth2": "^5.0.0", - "@capacitor/android": "^6.0.0", - "@capacitor/app": "^6.0.0", - "@capacitor/browser": "^6.0.0", - "@capacitor/clipboard": "^6.0.0", - "@capacitor/core": "^6.0.0", - "@capacitor/device": "^6.0.0", - "@capacitor/haptics": "^6.0.0", - "@capacitor/ios": "^6.0.0", - "@capacitor/keyboard": "^6.0.0", - "@capacitor/local-notifications": "^6.0.0", - "@capacitor/preferences": "^6.0.0", - "@capacitor/push-notifications": "^6.0.0", - "@capacitor/splash-screen": "^6.0.0", - "@capacitor/status-bar": "^6.0.0", - "@capacitor/toast": "^6.0.0", - "@ionic/angular": "^7.4.3", - "async-mutex": "^0.2.6", - "bignumber.js": "^9.1.2", - "canvas-confetti": "^1.3.3", - "capacitor-navigationbarnx": "0.1.6", - "cordova-plugin-purchase": "^13.11.1", - "cordova-res": "^0.15.2", - "ethereum-blockies": "^0.1.1", - "hammerjs": "^2.0.8", - "highcharts": "^11.1.0", - "intl": "^1.2.5", - "jetifier": "^1.6.6", - "magic-snowflakes": "^4.1.6", - "ng2-tooltip-directive-major-angular-updates": "^2.11.0", - "ngx-timeago": "^3.0.0", - "rxjs": "~7.8.1", - "tslib": "^2.6.2", - "zone.js": "~0.13.0" - }, - "devDependencies": { - "@angular-devkit/build-angular": "^16.2.5", - "@angular/cli": "~16.2.5", - "@angular/compiler": "~16.2.8", - "@angular/compiler-cli": "~16.2.5", - "@angular/language-service": "~16.2.5", - "@capacitor/cli": "^6.0.0", - "@ionic/angular-toolkit": "^10.0.0", - "@types/jasmine": "~5.1.0", - "@types/jasminewd2": "~2.0.11", - "@typescript-eslint/eslint-plugin": "^6.7.5", - "@typescript-eslint/parser": "^6.7.5", - "ajv": "^8.12.0", - "codelyzer": "^6.0.0", - "eslint": "^8.51.0", - "jasmine-core": "~5.1.1", - "jasmine-spec-reporter": "~7.0.0", - "karma": "~6.4.2", - "karma-chrome-launcher": "~3.2.0", - "karma-coverage-istanbul-reporter": "~3.0.3", - "karma-jasmine": "~5.1.0", - "karma-jasmine-html-reporter": "^2.1.0", - "karma-phantomjs-launcher": "^1.0.4", - "prettier": "2.8.0", - "protractor": "~7.0.0", - "ts-node": "~8.3.0", - "tslint": "~6.1.3", - "typescript": "~5.1.6" - }, - "description": "An Ionic project" -} \ No newline at end of file + "name": "beaconchain-dashboard", + "version": "2.0.0", + "author": "bitfly explorer GmbH", + "homepage": "https://beaconcha.in", + "scripts": { + "test": "ng test", + "generate-cert": "node local_env/generate-cert.js", + "dev": "(trap 'kill 0' SIGINT; ionic serve --live-reload --no-open --disable-host-check --configuration=development --host=app-dev.beaconcha.in --port=8100 --strictPort=true & sleep 13; node local_env/run.js)", + "dev-android": "ionic cap run android --livereload --external --no-open --configuration=development", + "build-android": "npm run increment-build && ionic cap build android --prod --release --source-map=true", + "build-ios": "npm run increment-build && ionic cap build ios --prod --release --source-map=true", + "prettier-format": "prettier --config .prettierrc.yml 'src/**/*.{ts,html,scss}' --write", + "prettier-check": "prettier -c --config .prettierrc.yml 'src/**/*.{ts,html,scss}'", + "lint": "eslint .", + "increment-build": "node increment-build.js", + "build-bundle": "npm run increment-build && ionic build --prod --release && node seal-bundle.js", + "build": "ionic build --prod --release", + "app-e2e-tests": "npx wdio wdio.conf.js" + }, + "private": true, + "dependencies": { + "@angular/animations": "^19.1.4", + "@angular/cdk": "^18.2.3", + "@angular/common": "~19.1.4", + "@angular/core": "~19.1.4", + "@angular/forms": "~19.1.4", + "@angular/platform-browser": "~19.1.4", + "@angular/platform-browser-dynamic": "~19.1.4", + "@angular/router": "~19.1.4", + "@awesome-cordova-plugins/core": "^6.8.0", + "@awesome-cordova-plugins/splash-screen": "^6.8.0", + "@awesome-cordova-plugins/status-bar": "^6.8.0", + "@byteowls/capacitor-oauth2": "^5.0.0", + "@capacitor/android": "^6.1.2", + "@capacitor/app": "^6.0.1", + "@capacitor/browser": "^6.0.2", + "@capacitor/clipboard": "^6.0.1", + "@capacitor/core": "^6.1.2", + "@capacitor/device": "^6.0.1", + "@capacitor/haptics": "^6.0.1", + "@capacitor/ios": "^6.1.2", + "@capacitor/keyboard": "^6.0.2", + "@capacitor/local-notifications": "^6.1.0", + "@capacitor/preferences": "^6.0.2", + "@capacitor/push-notifications": "^6.0.2", + "@capacitor/splash-screen": "^6.0.2", + "@capacitor/status-bar": "^6.0.1", + "@capacitor/toast": "^6.0.2", + "@capawesome/capacitor-app-update": "^6.0.0", + "@capgo/capacitor-updater": "^6.1.32", + "@ionic/angular": "^8.4.3", + "@ionic/angular-server": "^8.4.3", + "@ionic/core": "^8.4.3", + "async-mutex": "^0.2.6", + "bignumber.js": "^9.1.2", + "canvas-confetti": "^1.9.3", + "capacitor-navigationbarnx": "0.1.6", + "cordova-plugin-purchase": "^13.12.1", + "cordova-res": "^0.15.4", + "echarts": "^5.5.1", + "ethereum-blockies": "^0.1.1", + "highcharts": "^11.4.8", + "intl": "^1.2.5", + "jetifier": "^1.6.8", + "lodash-es": "^4.17.21", + "luxon": "^3.5.0", + "ng2-tooltip-directive-major-angular-updates": "^2.12.1", + "ngx-echarts": "^17.2.0", + "ngx-timeago": "^3.0.0", + "puppeteer": "^23.11.0", + "rxjs": "~7.8.1", + "storage-mirror": "file:storage-mirror", + "tslib": "^2.7.0", + "zone.js": "^0.15.0" + }, + "devDependencies": { + "@analogjs/platform": "^1.13.0", + "@analogjs/vite-plugin-angular": "^1.13.0", + "@analogjs/vitest-angular": "^1.13.0", + "@angular-devkit/build-angular": "^19.1.5", + "@angular/cli": "~19.1.5", + "@angular/compiler": "~19.1.4", + "@angular/compiler-cli": "~19.1.4", + "@angular/language-service": "~19.1.4", + "@capacitor/cli": "^6.1.2", + "@ionic/angular-toolkit": "^11.0.1", + "@nx/devkit": "^20.4.0", + "@nx/vite": "^20.0.0", + "@types/canvas-confetti": "^1.6.4", + "@types/ethereum-blockies": "^0.1.2", + "@types/jasmine": "~5.1.0", + "@types/lodash-es": "^4.17.12", + "@types/luxon": "^3.4.2", + "@typescript-eslint/eslint-plugin": "^8.22.0", + "@typescript-eslint/parser": "^8.22.0", + "@vitest/coverage-v8": "^3.0.5", + "@vitest/ui": "^3.0.5", + "@wdio/appium-service": "^9.11.0", + "@wdio/cli": "^9.11.0", + "@wdio/local-runner": "^9.11.0", + "@wdio/mocha-framework": "^9.11.0", + "@wdio/spec-reporter": "^9.11.0", + "ajv": "^8.12.0", + "appium": "^2.16.2", + "appium-uiautomator2-driver": "^4.1.1", + "codelyzer": "^6.0.2", + "eslint": "^9.16.0", + "eslint-plugin-import": "^2.29.1", + "eslint-plugin-jsdoc": "^48.2.1", + "eslint-plugin-prefer-arrow": "1.2.2", + "fs-extra": "^11.2.0", + "jasmine-core": "~5.1.0", + "jasmine-spec-reporter": "~5.0.0", + "jsdom": "^22.0.0", + "nx": "^20.4.0", + "prettier": "3.3.3", + "protractor": "~7.0.0", + "ts-node": "~8.3.0", + "tslint": "~6.1.3", + "typescript": "~5.5.4", + "vite": "^6.0.0", + "vite-tsconfig-paths": "^4.2.0", + "vitest": "^3.0.5", + "zip-a-folder": "^3.1.7" + }, + "description": "An Ionic project" +} diff --git a/seal-bundle.js b/seal-bundle.js new file mode 100644 index 00000000..39b9ef7a --- /dev/null +++ b/seal-bundle.js @@ -0,0 +1,81 @@ +const fs = require('fs'); +const path = require('path'); +const { zip } = require('zip-a-folder'); +const fse = require('fs-extra'); + +const versionFilePath = path.join('./src', 'version.json'); + +// Function to read version.json and return its data +async function getVersionInfo() { + try { + const data = fs.readFileSync(versionFilePath, 'utf8'); + return JSON.parse(data); + } catch (error) { + console.error('Error reading version file:', error); + process.exit(1); + } +} + +async function moveSourceMaps() { + const wwwFolder = path.join("./", 'www'); + const sourcemapFolder = path.join("./", 'www-sourcemap'); + + // Ensure the www-sourcemap folder exists + if (!fs.existsSync(sourcemapFolder)) { + fs.mkdirSync(sourcemapFolder); + } + + // Read the contents of the www folder + const files = fs.readdirSync(wwwFolder); + + // Move all .map files from www to www-sourcemap + files.forEach(file => { + if (file.endsWith('.map')) { + const oldPath = path.join(wwwFolder, file); + const newPath = path.join(sourcemapFolder, file); + + fse.moveSync(oldPath, newPath, { overwrite: true }); + console.log(`Moved Sourcemap: ${file} to ${newPath}`); + } + }); +} + +async function zipFolders(buildNumber, formattedVersion) { + const wwwFolder = path.join("./", 'www'); + const sourcemapFolder = path.join("./", 'www-sourcemap'); + // Dynamically create zip file names based on the version info + const wwwZipPath = path.join("./", `bundle_${buildNumber}_${formattedVersion}.zip`); + const sourcemapZipPath = path.join("./", `bundle_sourcemap_${buildNumber}_${formattedVersion}.zip`); + + + // Zip the www folder + try { + await zip(wwwFolder, wwwZipPath); + console.log(`Zipped www folder to ${wwwZipPath}`); + } catch (error) { + console.error('Error zipping www folder:', error); + } + + // Zip the www-sourcemap folder + try { + await zip(sourcemapFolder, sourcemapZipPath); + console.log(`Zipped www-sourcemap folder to ${sourcemapZipPath}`); + } catch (error) { + console.error('Error zipping www-sourcemap folder:', error); + } +} + +// Execute the functions in sequence +async function main() { + try { + const versionInfo = await getVersionInfo(); + const { buildNumber, formattedVersion } = versionInfo; + + await moveSourceMaps(); + await zipFolders(buildNumber, formattedVersion); + } catch (error) { + console.error('Error during operation:', error); + } +} + +main(); \ No newline at end of file diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 506eb44e..b1cef794 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -26,10 +25,6 @@ const routes: Routes = [ path: '', loadChildren: () => import('./tabs/tabs.module').then((m) => m.TabsPageModule), }, - { - path: 'validatordetail', - loadChildren: () => import('./pages/validatordetail/validatordetail.module').then((m) => m.ValidatordetailPageModule), - }, { path: 'helppage', loadChildren: () => import('./pages/helppage/helppage.module').then((m) => m.HelppagePageModule), @@ -50,21 +45,13 @@ const routes: Routes = [ path: 'dev', loadChildren: () => import('./pages/dev/dev.module').then((m) => m.DevPageModule), }, - { - path: 'notifications', - loadChildren: () => import('./pages/notifications/notifications.module').then((m) => m.NotificationsPageModule), - }, { path: 'logview', loadChildren: () => import('./pages/logview/logview.module').then((m) => m.LogviewPageModule), }, - { - path: 'merge-checklist', - loadChildren: () => import('./pages/merge-checklist/merge-checklist.module').then((m) => m.MergeChecklistPageModule), - }, { path: 'tab-blocks', - loadChildren: () => import('./tab-blocks/tab-blocks.module').then((m) => m.TabBlocksPageModule), + loadChildren: () => import('./tabs/tab-blocks/tab-blocks.module').then((m) => m.TabBlocksPageModule), }, { path: 'block-detail', @@ -74,6 +61,11 @@ const routes: Routes = [ path: 'clients', loadChildren: () => import('./pages/clients/clients.module').then((m) => m.ClientsPageModule), }, + { + path: 'notification-history', + loadChildren: () => + import('./pages/notification-history/notification-history-routing.module').then((m) => m.NotificationHistoryPageRoutingModule), + }, ] @NgModule({ imports: [RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })], diff --git a/src/app/app.component.html b/src/app/app.component.html index 4eb8063e..538d3314 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -1,5 +1,5 @@ + +
- - {{ block.blockNumber }} + + {{ block.block || '-' }}
-
- Reward: {{ producerReward | mcurrency : 'WEI' : unit.pref.Exec }} - - Proposer: {{ block.posConsensus.proposerIndex }} +
+ Reward: {{ producerReward | mcurrency: 'WEI' : unit.pref.Exec }} + + Proposer: {{ block.proposer }} - - To: {{ feeRecipient | slice : 0 : 8 }}…{{ feeRecipient | slice : 35 : 42 }} + + To: {{ feeRecipient | slice: 0 : 6 }}…{{ feeRecipient | slice: 37 : 42 }} To: {{ resolvedName }} + Status: {{ block.status }} - - {{ timestamp | timeago }} +
+
+ + {{ timestamp | shortertimeago }}
+
diff --git a/src/app/components/block/block.component.scss b/src/app/components/block/block.component.scss index fd7b44f3..abc6e0b0 100644 --- a/src/app/components/block/block.component.scss +++ b/src/app/components/block/block.component.scss @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -18,53 +17,20 @@ * // along with Beaconchain Dashboard. If not, see . */ -@import '../../../theme/variables.scss'; - -.blockie { - position: absolute; - top: 20px; - left: 22px; - border-radius: 20%; - height: 59px; - width: 56px; - image-rendering: pixelated; -} - -.container { -} - -.blocknr { - top: 83px; - text-align: center; - padding-top: 75px; - width: 66px; - font-size: 0.72rem; -} - -.inner { - padding-top: 0px; - padding-bottom: 0px; -} +@use '../../../theme/variables.scss'; ion-item { background: var(--ion-card-background); + margin: auto; } ion-icon { position: absolute !important; - top: 2px; - right: 20px; + top: 5px; + right: 5px; margin-top: 0px !important; padding-top: 0px !important; margin-bottom: 29px; - height: 56px; -} - -.info { - margin-top: 15px; - margin-left: 0px; - margin-right: 5px; - margin-bottom: 15px; } .balance { @@ -76,9 +42,10 @@ ion-icon { font-weight: bold; } -.smaller-info { - font-size: 0.8rem; - color: var(--ion-text-color-secondary); +.status-container { + height: 78px; + margin-right: 2px; + margin-left: 0px; } .smoothing { @@ -88,3 +55,15 @@ ion-icon { .ethpool { color: #ee7112; } + +.orphaned { + color: var(--ion-color-warning) !important; +} + +.missed { + color: var(--ion-color-danger) !important; +} + +.scheduled { + color: var(--ion-color-secondary) !important; +} diff --git a/src/app/components/block/block.component.spec.ts b/src/app/components/block/block.component.spec.ts deleted file mode 100644 index 0ff43b4a..00000000 --- a/src/app/components/block/block.component.spec.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing' -import { IonicModule } from '@ionic/angular' - -import { BlockComponent } from './block.component' - -describe('BlockComponent', () => { - let component: BlockComponent - let fixture: ComponentFixture - - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [BlockComponent], - imports: [IonicModule.forRoot()], - }).compileComponents() - - fixture = TestBed.createComponent(BlockComponent) - component = fixture.componentInstance - fixture.detectChanges() - })) - - it('should create', () => { - expect(component).toBeTruthy() - }) -}) diff --git a/src/app/components/block/block.component.ts b/src/app/components/block/block.component.ts index 6247f1a2..dbf30fa4 100644 --- a/src/app/components/block/block.component.ts +++ b/src/app/components/block/block.component.ts @@ -1,67 +1,62 @@ -import { Component, Input, OnInit } from '@angular/core' -import { BlockResponse } from 'src/app/requests/requests' +import { Component, Input } from '@angular/core' import * as blockies from 'ethereum-blockies' -import { UnitconvService } from 'src/app/services/unitconv.service' -import { BlockUtils, ETHPOOL, ROCKETPOOL_SMOOTHING_POOL } from 'src/app/utils/BlockUtils' +import { UnitconvService } from '@services/unitconv.service' +import { ETHPOOL, ROCKETPOOL_SMOOTHING_POOL } from '@utils/BlockUtils' import BigNumber from 'bignumber.js' -import { ValidatorUtils } from 'src/app/utils/ValidatorUtils' +import { VDBBlocksTableRow } from '@requests/types/validator_dashboard' +import { slotToSecondsTimestamp } from '@utils/TimeUtils' @Component({ selector: 'app-block', templateUrl: './block.component.html', styleUrls: ['./block.component.scss'], + standalone: false, }) -export class BlockComponent implements OnInit { - @Input() block: BlockResponse +export class BlockComponent { + @Input() block: VDBBlocksTableRow + @Input() first: boolean + @Input() last: boolean + @Input() chainID: number - fadeIn = 'fade-in' - imgData = null + imgData: string = null timestamp = 0 producerReward = new BigNumber(0) - feeRecipient = '' - resolvedName = null + feeRecipient: string = null + resolvedName: string = null resolvedClass = '' - constructor(public unit: UnitconvService, public blockUtils: BlockUtils, private validatorUtils: ValidatorUtils) { - this.validatorUtils.registerListener(() => { - this.ngOnChanges() - }) - } + constructor(public unit: UnitconvService) {} - async ngOnChanges() { + ngOnChanges() { this.imgData = this.getBlockies() - this.timestamp = this.block.timestamp * 1000 - this.producerReward = await this.blockUtils.getBlockRewardWithShare(this.block) + this.timestamp = slotToSecondsTimestamp(this.chainID, this.block.slot) * 1000 + if (this.block.reward) { + this.producerReward = new BigNumber(this.block.reward.el).plus(new BigNumber(this.block.reward.cl)) + } this.resolvedName = null - this.feeRecipient = this.block.feeRecipient - if (this.block.relay) { - this.feeRecipient = this.block.relay.producerFeeRecipient + this.feeRecipient = this.block.reward_recipient?.hash + if (this.block.reward_recipient?.ens != null) { + this.resolvedName = this.block.reward_recipient.ens } - if (this.feeRecipient.toLocaleLowerCase() == ROCKETPOOL_SMOOTHING_POOL) { + if (this.block.reward_recipient?.hash?.toLocaleLowerCase() == ROCKETPOOL_SMOOTHING_POOL) { this.resolvedName = 'Smoothing Pool' this.resolvedClass = 'smoothing' - } else if (this.feeRecipient.toLocaleLowerCase() == ETHPOOL) { + } else if (this.block.reward_recipient?.hash?.toLocaleLowerCase() == ETHPOOL) { this.resolvedName = 'ethpool.eth' this.resolvedClass = 'ethpool' } } - setInput(block: BlockResponse) { + setInput(block: VDBBlocksTableRow) { this.block = block this.ngOnChanges() } - ngOnInit() { - setTimeout(() => { - this.fadeIn = null - }, 500) - } - private getBlockies() { // TODO: figure out why the first blockie image is always black - blockies.create({ seed: this.block.blockHash }).toDataURL() - const dataurl = blockies.create({ seed: this.block.blockHash, size: 8, scale: 7 }).toDataURL() + blockies.create({ seed: this.block.slot.toString() }).toDataURL() + const dataurl = blockies.create({ seed: this.block.slot.toString(), size: 8, scale: 7 }).toDataURL() return dataurl } } diff --git a/src/app/components/block/block.module.ts b/src/app/components/block/block.module.ts index c37723fa..d52dcd17 100644 --- a/src/app/components/block/block.module.ts +++ b/src/app/components/block/block.module.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // diff --git a/src/app/components/bool-checked/bool-checked.component.html b/src/app/components/bool-checked/bool-checked.component.html new file mode 100644 index 00000000..b3721048 --- /dev/null +++ b/src/app/components/bool-checked/bool-checked.component.html @@ -0,0 +1 @@ + diff --git a/src/app/components/bool-checked/bool-checked.component.scss b/src/app/components/bool-checked/bool-checked.component.scss new file mode 100644 index 00000000..0154b369 --- /dev/null +++ b/src/app/components/bool-checked/bool-checked.component.scss @@ -0,0 +1,28 @@ +/** + * Copyright (C) 2024 bitfly explorer GmbH + * + * This file is part of Beaconchain Dashboard. + * + * Beaconchain Dashboard is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Beaconchain Dashboard is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Beaconchain Dashboard. If not, see . + */ + +@use '../../../theme/variables.scss'; + +.check { + color: var(--ion-color-success); +} + +.nocheck { + color: var(--ion-color-danger); +} diff --git a/src/app/components/bool-checked/bool-checked.component.ts b/src/app/components/bool-checked/bool-checked.component.ts new file mode 100644 index 00000000..14f37141 --- /dev/null +++ b/src/app/components/bool-checked/bool-checked.component.ts @@ -0,0 +1,13 @@ +import { CommonModule } from '@angular/common' +import { Component, Input } from '@angular/core' +import { IonIcon } from '@ionic/angular/standalone' + +@Component({ + selector: 'app-bool-checked', + imports: [IonIcon, CommonModule], + templateUrl: './bool-checked.component.html', + styleUrl: './bool-checked.component.scss', +}) +export class BoolCheckedComponent { + @Input() value: boolean = false +} diff --git a/src/app/components/clientupdate/clientupdate.component.html b/src/app/components/clientupdate/clientupdate.component.html index ab7b4554..e922206d 100644 --- a/src/app/components/clientupdate/clientupdate.component.html +++ b/src/app/components/clientupdate/clientupdate.component.html @@ -1,5 +1,5 @@ + + + + + + Migrate dashboard + Copy to clipboard + Rename + Delete + + + + +
diff --git a/src/app/components/dashboard-item/dashboard-item.component.scss b/src/app/components/dashboard-item/dashboard-item.component.scss new file mode 100644 index 00000000..2353abab --- /dev/null +++ b/src/app/components/dashboard-item/dashboard-item.component.scss @@ -0,0 +1,80 @@ +@use '../../../theme/variables.scss'; + +.dashboard-card { + background-color: var(--ion-item-background); +} + +.selected ion-label { + //color: var(--ion-color-primary); +} + +.opacity-icon { + color: var(--ion-tab-button-color); + opacity: 0.95; +} + +.touch-icon-padding { + padding: 0px 0px 9px 9px; +} + +ion-badge { + --padding-end: 8px; + --padding-start: 8px; + --padding-top: 6px; + --padding-bottom: 6px; + min-width: 36px; +} + +.ethereum { + --background: #497493; +} + +.gnosis { + --background: #3e6957; +} + +.holesky { + --background: #8695a0; +} + +.sepolia { + --background: #a0869e; +} + +.star { + color: var(--ion-color-primary); +} + +.network { + //font-size: small; +} + +.maxed { + color: var(--ion-color-danger) !important; +} + +.stat-count { + font-weight: bold; +} + +.action { + // height: 25px; + // width: 25px; + font-size: 21px; +} + +.badge { + margin-top: -1px; + font-size: 0.63rem; + padding: 5px 8px; + padding-top: 6px; // seems to be off by 1px? + border-radius: 5px; +} + +.ios .title { + padding-top: 9px; +} + +.title { + padding-top: 5px; +} diff --git a/src/app/components/dashboard-item/dashboard-item.component.ts b/src/app/components/dashboard-item/dashboard-item.component.ts new file mode 100644 index 00000000..3334d85a --- /dev/null +++ b/src/app/components/dashboard-item/dashboard-item.component.ts @@ -0,0 +1,293 @@ +import { CommonModule } from '@angular/common' +import { Component, computed, effect, EventEmitter, Input, OnChanges, Output, WritableSignal } from '@angular/core' +import { Toast } from '@capacitor/toast' +import { AlertController, IonicModule } from '@ionic/angular' +import { ValidatorDashboard } from '@requests/types/dashboard' +import { dashboardID, V2ChangeDashboardName, V2DeleteDashboard } from '@requests/v2-dashboard' +import { AlertService } from '@services/alert.service' +import { ApiService } from '@services/api.service' +import { StorageService } from '@services/storage.service' +import { DashboardUtils } from '@utils/DashboardUtils' +import { MerchantUtils } from '@utils/MerchantUtils' +import { findChainNetworkById } from '@utils/NetworkData' +import { ValidatorUtils } from '@utils/ValidatorUtils' +import { Clipboard } from '@capacitor/clipboard' +import { changeNetwork } from 'src/app/tabs/tab-preferences/tab-preferences.page' +import { UnitconvService } from '@services/unitconv.service' +import ThemeUtils from '@utils/ThemeUtils' + +@Component({ + selector: 'app-dashboard-item', + imports: [CommonModule, IonicModule], + templateUrl: './dashboard-item.component.html', + styleUrl: './dashboard-item.component.scss', +}) +export class DashboardItemComponent implements OnChanges { + @Input() data: ValidatorDashboard + @Input() defaultDashboard: WritableSignal + @Input() legacyDashboard: boolean = false + + @Output() refresh = new EventEmitter() + @Output() legacyAdd = new EventEmitter() + triggerID: string + + selected: boolean + + nameTruncated = computed(() => { + return this.data.name.length > 21 ? this.data.name.substring(0, 21) + '...' : this.data.name + }) + + networkName = computed(() => { + const network = findChainNetworkById(this.data.network) + return network.name.toUpperCase().substring(0, 3) + }) + + networkColor = computed(() => { + const network = findChainNetworkById(this.data.network) + return network.name + //return this.data.network + }) + + reachedMaxGroupClassStyle = computed(() => { + return this.data.group_count >= this.merchant.getCurrentPlanMaxGroups() ? 'maxed' : '' + }) + + reachedMaxValidatorClassStyle = computed(() => { + return this.data.validator_count >= this.merchant.getCurrentPlanMaxValidator() ? 'maxed' : '' + }) + + constructor( + private alertController: AlertController, + private api: ApiService, + private alert: AlertService, + private dashboardUtils: DashboardUtils, + private storage: StorageService, + protected merchant: MerchantUtils, + private validatorUtils: ValidatorUtils, + private unit: UnitconvService, + private theme: ThemeUtils + ) { + effect(() => { + this.selected = this.defaultDashboard() === this.data.id && this.data.network === this.api.networkConfig.supportedChainIds + }) + } + + ngOnChanges() { + this.triggerID = 'click-trigger-' + this.data.id + } + + async setAsDefault() { + if (this.legacyDashboard) { + const alert = await this.alertController.create({ + cssClass: 'my-custom-class', + header: 'Legacy Dashboard', + message: `Legacy dashboards were created using an older version of this app + and can not be viewed nor set as default.

You can migrate your dashboard to the new version + or get a list of all validators of that dashboard.`, + buttons: [ + { + text: 'Show', + handler: () => { + this.legacyCopyToClipboard() + }, + }, + { + text: 'Migrate', + handler: () => { + this.legacyAddToCurrent() + }, + }, + { + text: 'Cancel', + role: 'cancel', + cssClass: 'secondary', + handler: () => { + return + }, + }, + ], + }) + await alert.present() + return + } + if (this.data.network !== this.api.networkConfig.supportedChainIds) { + const loading = await this.alert.presentLoading('Loading...') + loading.present() + await changeNetwork( + findChainNetworkById(this.data.network).legacyKey, + this.storage, + this.api, + this.unit, + this.theme, + this.alert, + this.merchant, + true, + this.dashboardUtils + ) + loading.dismiss() + } + this.defaultDashboard.set(this.data.id) + } + + async rename() { + if (!(await this.storage.isLoggedIn())) { + Toast.show({ + text: 'Please log in to manage dashboards', + }) + return + } + + const alert = await this.alertController.create({ + cssClass: 'my-custom-class', + header: 'Rename my dashboard', + inputs: [ + { + name: 'newName', + type: 'text', + placeholder: 'New Name', + value: this.data.name, + }, + ], + buttons: [ + { + text: 'Cancel', + role: 'cancel', + cssClass: 'secondary', + handler: () => { + return + }, + }, + { + text: 'Save', + handler: async (alertData) => { + const loading = await this.alert.presentLoading('Applying changes...') + loading.present() + + const result = await this.api.executeOnChainID(new V2ChangeDashboardName(this.data.id, alertData.newName), null, this.data.network) + if (result.error) { + Toast.show({ + text: 'Error renaming dashboard, please try again later', + }) + } else { + this.data.name = alertData.newName + Toast.show({ + text: 'Dashboard renamed', + }) + this.refresh.emit() + } + + loading.dismiss() + }, + }, + ], + }) + + await alert.present() + } + + async legacyCopyToClipboard() { + await Clipboard.write({ + string: (await this.validatorUtils.getMyLocalValidators(this.legacyGetNetwork())).sort().join(','), + }) + Toast.show({ + text: 'All validator indices copied to clipboard', + duration: 'long', + }) + } + + legacyGetNetwork() { + let networkName = findChainNetworkById(this.data.network).name + if (networkName == 'ethereum') { + networkName = 'main' + } + return networkName + } + + async legacyAddToCurrent() { + this.legacyAdd.emit({ + indices: await this.validatorUtils.getMyLocalValidators(this.legacyGetNetwork()), + network: this.legacyGetNetwork(), + } as LegacyAdd) + } + + removeLegacy() { + this.alert.confirmDialog( + 'Remove Legacy dashboard', + 'This will permanently remove the dashboard and all associated validators. If you have already migrated this old dashboard to the new one, you can safely delete it.

Are you sure you want to proceed?', + 'Remove', + () => { + this.alert.confirmDialogReverse( + 'Are you really sure?', + 'Please note that this action can NOT be undone.

Delete: ' + this.data.name, + 'Remove', + async () => { + const loading = await this.alert.presentLoading('Removing dashboard...') + loading.present() + + await this.validatorUtils.deleteAll(this.legacyGetNetwork()) + + loading.dismiss() + this.refresh.emit() + }, + 'error-btn' + ) + }, + 'error-btn' + ) + } + + async removev2() { + if (!(await this.storage.isLoggedIn())) { + Toast.show({ + text: 'Please log in to manage dashboards', + }) + return + } + this.alert.confirmDialog( + 'Remove dashboard', + 'This will permanently remove the dashboard and all associated groups and validators.

Are you sure you want to continue?', + 'Remove', + () => { + this.alert.confirmDialogReverse( + 'Are you really sure?', + 'Please note that this action can NOT be undone.

Delete: ' + this.data.name, + 'Remove', + async () => { + const loading = await this.alert.presentLoading('Removing dashboard...') + loading.present() + + const result = await this.api.executeOnChainID(new V2DeleteDashboard(this.data.id), null, this.data.network) + if (result.error) { + Toast.show({ + text: 'Error removing dashboard, please try again later', + }) + } else { + Toast.show({ + text: 'Dashboard removed', + }) + this.data = null + if (this.selected) { + this.dashboardUtils.dashboardAwareListener.notifyAll() + } + this.refresh.emit() + } + + loading.dismiss() + }, + 'error-btn' + ) + }, + 'error-btn' + ) + } + + remove() { + if (this.legacyDashboard) this.removeLegacy() + else this.removev2() + } +} + +export interface LegacyAdd { + indices: number[] + network: string +} diff --git a/src/app/components/dashboard/dashboard.component.html b/src/app/components/dashboard/dashboard.component.html index db3d39ef..8c90d810 100644 --- a/src/app/components/dashboard/dashboard.component.html +++ b/src/app/components/dashboard/dashboard.component.html @@ -1,5 +1,5 @@ -
- -
-
- -
- -
- - {{ data.dashboardState.title }} - - -
- - {{ d.text }} -
-
+ +
+ +
+
+
-
- - {{ data.dashboardState.extendedDescriptionPre }}{{ data.dashboardState.extendedDescription }} +
+ + {{ data.dashboardState()?.title }} -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Staking - - - -
-
-
- - {{ data.overallBalance | mcurrency : 'GWEI' : unit.pref.Cons }} - -
-
- Balance -
-
-
-
- - - {{ data.attrEffectiveness !== -1 ? data.attrEffectiveness + ' %' : 'NaN' }} - - - - - - -
-
- - - Effectiveness - - +
+ + {{ d.text }} +
+
-
-
- - - - - - - Rewards - - - - Combined - - - Consensus - - - Blocks - - - - -
- - - - - -
-
-
- - - Rocketpool Smoothing Pool - - - - -
-
-
- - {{ smoothingClaimed.plus(smoothingUnclaimed) | mcurrency : 'GWEI' : unit.pref.Exec }} - -
-
- - Total Earned - -
-
-
-
- - {{ smoothingUnclaimed | mcurrency : 'GWEI' : unit.pref.Exec }} - -
-
- - Unclaimed +
+ + {{ data.dashboardState()?.extendedDescriptionPre }}{{ data.dashboardState()?.extendedDescription }}
- - - - - Rocketpool - - - - -
-
-
- - {{ rplProjectedClaim | mcurrency : 'WEI' : 'RPL_NAKED' }} - - - {{ rplProjectedClaim | mcurrency : 'WEI' : 'RPL' : false | mcurrency : 'ETHER' : unit.pref.RPL }} - -
-
- - Next Claim - -
-
- -
-
- - {{ totalRplEarned | mcurrency : 'WEI' : 'RPL_NAKED' }} - - - {{ totalRplEarned | mcurrency : 'WEI' : 'RPL' : false | mcurrency : 'ETHER' : unit.pref.RPL }} - -
-
- - Total Earned - -
-
- -
-
- - {{ unclaimedRpl | mcurrency : 'WEI' : 'RPL_NAKED' }} - - - {{ unclaimedRpl | mcurrency : 'WEI' : 'RPL' : false | mcurrency : 'ETHER' : unit.pref.RPL }} - -
-
- - Unclaimed RPL - -
-
- -
-
- - {{ - data.rocketpool.cheatingStatus.strikes - }} - / - {{ - data.rocketpool.cheatingStatus.penalties - }} - -
-
- - - Cheating - - -
-
- -
-
- - {{ 1 | mcurrency : 'ETHER' : 'RPL' : false | mcurrency : 'ETHER' : unit.pref.RPL }} - -
-
- RPL Price -
-
- -
-
- {{ rplApr }} % -
-
- - RPL APR - -
-
- -
-
- - {{ data.rocketpool.currentRpl | mcurrency : 'WEI' : 'RPL_NAKED' }} - - - {{ data.rocketpool.currentRpl | mcurrency : 'WEI' : 'RPL' : false | mcurrency : 'ETHER' : unit.pref.RPL }} - - - {{ rplDisplay }} % - -
-
- - - Collateral - - -
-
- -
-
- {{ data.rocketpool.fee }} % -
-
- - - Minipool Fee - - - Avg Fee - - -
-
- -
-
- - {{ data.rocketpool.minRpl | mcurrency : 'WEI' : 'NO_CURRENCY' }} - {{ data.rocketpool.maxRpl | mcurrency : 'WEI' : 'NO_CURRENCY' }} RPL - - - {{ data.rocketpool.minRpl | mcurrency : 'WEI' : 'RPL' : false | mcurrency : 'ETHER' : unit.pref.RPL }} - - {{ data.rocketpool.maxRpl | mcurrency : 'WEI' : 'RPL' : false | mcurrency : 'ETHER' : unit.pref.RPL }} - -
-
- - Coll. Range - -
-
+ -
-
- - {{ nextRewardRound | date : 'MMM dd, h:mm a' }} - -
-
- - - Next RPL Round - - -
-
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -
-
- - {{ data.rocketpool.depositType }} - -
-
- Deposit Type -
+ + Staking + + + +
+ + {{ data.overviewData()?.balances.total || 0 | mcurrency: 'WEI' : unit.pref.Cons }} + + + + + {{ + (data.summaryCurrentGroup()?.efficiency || 0) !== -1 ? (data.summaryCurrentGroup()?.efficiency || 0 | number: '1.0-2') + ' %' : 'NaN' + }} + + - +
+
+
-
-
- - {{ data.foreignValidatorItem.rocketpool.node_deposit_balance | mcurrency : 'WEI' : unit.pref.Cons }} - -
-
- - Deposit - -
-
-
- - + - - Charts & Stats + Rewards - - - Income + + + Combined + + + Consensus - - Proposals + + Blocks -
-
-
- -
- -
-
-
- -
- - Blocks - - - - Proposals - - - - {{ proposals.good }} / - {{ proposals.bad }} - - - - Luck - - {{ data.proposalLuckResponse.proposal_luck * 100 | number : '1.0-1' }}% - - - +
+ + + + + +
-
- -
- - Sync Committees - + + {{ selectedExtraTabTimeframe() }} {{ selectedExtraTabTitle() }} + + + + + Income + + + Efficiency + + + +
+ + + +
+
+ + + - - Total Committees + Missed Rewards + + + {{ data.getTotalMissedRewards() | mcurrency: 'WEI' : unit.pref.Cons }} + - {{ data.syncCommitteesStats.committeesParticipated }} - Participation +    Attestations + + {{ data.summaryGroup().missed_rewards.attestations | mcurrency: 'WEI' : unit.pref.Cons }} + + + +    Block Consensus + + {{ data.summaryGroup().missed_rewards.proposer_rewards.cl | mcurrency: 'WEI' : unit.pref.Cons }} + + + - {{ data.syncCommitteesStats.efficiency }}% + [hideDelayAfterClick]="5000"> +    Block Execution* + + {{ data.summaryGroup().missed_rewards.proposer_rewards.el | mcurrency: 'WEI' : unit.pref.Cons }} + - - Current Progress - - - {{ data.syncCommitteesStats.slotsLeftInSyncCommittee }} / {{ data.syncCommitteesStats.slotsPerSyncCommittee }} - + +    Sync + + {{ data.summaryGroup().missed_rewards.sync | mcurrency: 'WEI' : unit.pref.Cons }} + + + + + + + + + + - Luck - - {{ data.syncCommitteesStats.luck | number : '1.0-1' }}% - - - + Avg. Incl. Distance + + {{ this.data.summaryGroup().attestation_avg_incl_dist | number: '1.0-2' }} + -
- - General - + + + + Rocket Pool + + + + {{ formatAddress(item.node) }} + + + + + + +
+
+ + + {{ this.data.totalSmoothingPool() | mcurrency: 'WEI' : unit.pref.Exec }} + + + + + + {{ this.data?.rocketpool()?.[0]?.smoothingpool_unclaimed | mcurrency: 'WEI' : unit.pref.Exec }} + + +
+ + + + {{ item.rpl_estimate | mcurrency: 'WEI' : 'RPL_NAKED' }} + + + {{ item.rpl_estimate | mcurrency: 'WEI' : 'RPL' : false | mcurrency: 'ETHER' : unit.pref.RPL }} + + + + + + {{ data.totalRPL() | mcurrency: 'WEI' : 'RPL_NAKED' }} + + + {{ data.totalRPL() | mcurrency: 'WEI' : 'RPL' : false | mcurrency: 'ETHER' : unit.pref.RPL }} + + + + + + {{ item.rpl_unclaimed | mcurrency: 'WEI' : 'RPL_NAKED' }} + + + {{ item.rpl_unclaimed | mcurrency: 'WEI' : 'RPL' : false | mcurrency: 'ETHER' : unit.pref.RPL }} + + + + + + + 0 + / + + + 0 + + + + + {{ 1 | mcurrency: 'ETHER' : 'RPL' : false | mcurrency: 'ETHER' : unit.pref.RPL }} + + + + {{ item.rpl_apr | number: '1.0-2' }} % + + + + + {{ item.staked_rpl | mcurrency: 'WEI' : 'RPL_NAKED' }} + + + {{ item.staked_rpl | mcurrency: 'WEI' : 'RPL' : false | mcurrency: 'ETHER' : unit.pref.RPL }} + + + {{ item.collateral.percentage | number: '1.0-2' }} % + + + + + {{ item.avg_commission | number: '1.0-2' }} % + + + + + {{ item.collateral.min_value | mcurrency: 'WEI' : 'NO_CURRENCY' }} - + {{ item.collateral.max_value | mcurrency: 'WEI' : 'NO_CURRENCY' }} RPL + + + {{ item.collateral.min_value | mcurrency: 'WEI' : 'RPL' : false | mcurrency: 'ETHER' : unit.pref.RPL }} - + {{ item.collateral.max_value | mcurrency: 'WEI' : 'RPL' : false | mcurrency: 'ETHER' : unit.pref.RPL }} + + + + + {{ nextRewardRound | date: 'MMM dd, h:mm a' }} + +
+
+
+
+
- - - - Rank - +
+ + Blocks {{ data.timeframeDisplay() }} + + + + + + Luck + + {{ data.summaryGroup()?.luck.proposal.percent | number: '1.0-1' }}% + - + + + +
- - +
+ + Sync Committees {{ data.timeframeDisplay() }} + - - {{ data.bestRank | percentageabs : data.bestTopPercentage : rankPercentMode : 'Top ' }} - - - - - -
-
-
- - - - {{ data.bestRank | percentageabs : data.bestTopPercentage : rankPercentMode : 'Top ' }} - - -
-
- - - Best Rank - - -
-
+ + + + Total Committees + + {{ data.syncCount() }} + + + Participation + + {{ data.syncEfficiency() | number: '1.0-1' }}% + + + + + Luck + + {{ data.summaryGroup()?.luck.sync.percent | number: '1.0-1' }}% + - + + + +
-
-
- - - - {{ data.worstRank | percentageabs : data.worstTopPercentage : rankPercentMode : 'Top ' }} - - -
-
- - - Worst Rank - - -
-
-
-
-
+ + General + - - - - - Effective Performance - - - {{ utilizationAvg }} % - + + + + + Effective Balance + + + + {{ data.overviewData()?.balances.effective || 0 | mcurrency: 'WEI' : unit.getNetworkDefaultCurrency('cons') }} + + - - - - Effective Balance - - - - {{ data.effectiveBalance | mcurrency : 'GWEI' : unit.getNetworkDefaultCurrency('cons') }} - - - - - - - Validator Index - - {{ data.foreignValidatorItem.data.validatorindex | number : '1.0' : 'en-US' }} - - - - - - Withdrawal Cred - - {{ data.foreignValidatorItem.data.withdrawalcredentials | slice : 0 : 4 }} + + + Staked Balance + + + {{ data.overviewData()?.balances.staked_eth || 0 | mcurrency: 'WEI' : unit.getNetworkDefaultCurrency('cons') }} - - - - Effective Balance - - {{ data.effectiveBalance | mcurrency : 'GWEI' : unit.getNetworkDefaultCurrency('cons') }} - - - - - {{ unit.getNetworkDefaultUnit('cons').display }} Price - - {{ unit.lastPrice.Cons | mcurrency : unit.getFiatCurrency('cons') : unit.getFiatCurrency('cons') }} - - - - - - - Updated - - - - {{ api.lastRefreshed | timeago }} - - - - - - - - View on {{ api.getHostName() }} - - -
-
- -
-
- + + + + + {{ unit.getNetworkDefaultUnit('cons').display }} Price + + {{ unit.lastPrice.Cons | mcurrency: unit.getFiatCurrency('cons') : unit.getFiatCurrency('cons') }} + + + + + + + Updated + + + + {{ api.lastRefreshed | timeago }} + + + + + + + + View on {{ api.getHostName() }} + + +
-
+ diff --git a/src/app/components/dashboard/dashboard.component.scss b/src/app/components/dashboard/dashboard.component.scss index 65cced08..5eca826c 100644 --- a/src/app/components/dashboard/dashboard.component.scss +++ b/src/app/components/dashboard/dashboard.component.scss @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -18,17 +17,10 @@ * // along with Beaconchain Dashboard. If not, see . */ -@import '../../../theme/variables.scss'; - +@use '../../../theme/variables.scss'; ion-segment-button { - --indicator-height: 0px !important; - text-transform: none !important; - --ripple-color: transparent !important; - //transition: color 0.15s ease; - font-family: 'Varela'; - font-size: 0.75em; --background-focused-opacity: 1; - opacity: 1 !important; + color: var(--ion-text-color-lighter); } ion-segment-button.md::part(native) { @@ -42,6 +34,7 @@ ion-segment { .segment-button-checked { color: var(--segment-primary) !important; font-weight: 600 !important; + opacity: 1 !important; } .segment-button-checked.md::part(native) { @@ -56,13 +49,6 @@ ion-segment { padding-bottom: 12px; } -.center { - width: 100%; - display: flex; - justify-content: center; - text-align: center; -} - .status { text-align: center; background-color: var(--ion-toolbar-background) !important; @@ -131,21 +117,11 @@ ion-segment { padding-bottom: 6px !important; } -ion-list-header { - padding-left: 0px; - text-align: center; -} -ion-list-header ion-label { - font-size: 0.9rem; - font-weight: 600 !important; - font-family: 'Varela'; - letter-spacing: 1.05px; -} - ion-item { - max-width: 92%; + //max-width: var(--ion-item-max-width); - margin: auto; + //margin: auto; + margin: var(--edge-padding); } .value { @@ -155,16 +131,11 @@ ion-item { } .chartcontainer { - padding-top: 20px; - width: 97%; + padding-top: 5px; + width: 98%; margin: auto; } -.loading-spinner { - margin-top: 55px; - margin-bottom: 10px; -} - .updates { padding-top: 0px; padding-bottom: 0px; @@ -179,34 +150,19 @@ ion-item { } .loading-container { - height: 100%; -} - -.grid-cell { - width: 50%; - float: left; - margin-bottom: 7px; - margin-top: 7px; -} - -.left { - text-align: start !important; -} - -.right { - text-align: end !important; + height: 100vh !important; + background-color: var(--ion-background-color); } .stat-title { - opacity: 0.85; -} - -.income-title { - opacity: 0.85; - font-size: 1em; - //color: var(--ion-text-color-lighter); + opacity: var(--default-secondary-transparency); + font-weight: var(--smaller-label-weight); } .grid { width: 100%; } + +ion-item ion-label { + margin-right: 0px; // fixes ios margin at the right side +} diff --git a/src/app/components/dashboard/dashboard.component.ts b/src/app/components/dashboard/dashboard.component.ts index 061b4ffc..3e6ee55d 100644 --- a/src/app/components/dashboard/dashboard.component.ts +++ b/src/app/components/dashboard/dashboard.component.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -18,91 +17,62 @@ * // along with Beaconchain Dashboard. If not, see . */ -import { Component, OnInit, Input, SimpleChange } from '@angular/core' -import { RewardType, UnitconvService } from '../../services/unitconv.service' -import { ApiService } from '../../services/api.service' -import { DashboardDataRequest, EpochResponse, SyncCommitteeResponse } from '../../requests/requests' -import * as HighCharts from 'highcharts' -import * as Highstock from 'highcharts/highstock' -import BigNumber from 'bignumber.js' -import { OverviewData, Rocketpool } from '../../controllers/OverviewController' -import { Release } from '../../utils/ClientUpdateUtils' -import ThemeUtils from 'src/app/utils/ThemeUtils' -import { highChartOptions } from 'src/app/utils/HighchartOptions' -import { StorageService } from 'src/app/services/storage.service' +import { Component, OnInit, Input, SimpleChange, signal, WritableSignal, computed, Signal, effect, Output, EventEmitter } from '@angular/core' +import { UnitconvService } from '@services/unitconv.service' +import { ApiService } from '@services/api.service' +import { OverviewData2 } from '../../controllers/OverviewController' +import { Release } from '@utils/ClientUpdateUtils' +import ThemeUtils from '@utils/ThemeUtils' +import { StorageService } from '@services/storage.service' import confetti from 'canvas-confetti' import { Browser } from '@capacitor/browser' import { ModalController, Platform } from '@ionic/angular' -import { SubscribePage } from 'src/app/pages/subscribe/subscribe.page' -import { MerchantUtils } from 'src/app/utils/MerchantUtils' -import { ValidatorUtils } from 'src/app/utils/ValidatorUtils' -import FirebaseUtils from 'src/app/utils/FirebaseUtils' -import { trigger, style, animate, transition } from '@angular/animations' +import { SubscribePage } from '@pages/subscribe/subscribe.page' +import { MerchantUtils } from '@utils/MerchantUtils' +import { ValidatorUtils } from '@utils/ValidatorUtils' +import FirebaseUtils from '@utils/FirebaseUtils' +import { endEpochSyncCommittee, slotToEpoch, startEpochSyncCommittee } from '@utils/MathUtils' +import { epochToTimestamp, getLocale } from '@utils/TimeUtils' +import { Period, setID } from '@requests/v2-dashboard' +import { getSuccessFailMode, Mode } from './success-fail-view/success-fail-view.component' +import { DashboardUtils } from '@utils/DashboardUtils' +import { formatAddress } from '@utils/Formatting' +import BigNumber from 'bignumber.js' +type ExtraTabs = 'chartIncome' | 'chartSummary' | 'rocketPool' +type RewardTabs = 'combined' | 'cons' | 'exec' @Component({ selector: 'app-validator-dashboard', templateUrl: './dashboard.component.html', styleUrls: ['./dashboard.component.scss'], - animations: [trigger('fadeIn', [transition(':enter', [style({ opacity: 0 }), animate('300ms 300ms', style({ opacity: 1 }))])])], + standalone: false, }) export class DashboardComponent implements OnInit { public classReference = UnitconvService - @Input() data?: OverviewData + @Input() data?: OverviewData2 @Input() updates?: Release[] @Input() currentY: number @Input() scrolling: boolean + @Input() online: boolean + @Output() fadeInCompleted = new EventEmitter() + @Output() changedGroup = new EventEmitter() beaconChainUrl: string = null - finalizationIssue = false - awaitGenesis = false - earlyGenesis = false - utilizationAvg = -1 - - chartData - chartDataProposals - chartError = false - - randomChartId - - rankPercentMode = false - selectedChart = 'chartIncome' - - showFirstProposalMsg = false - showMergeChecklist = false - firstCelebrate = true - - doneLoading = false - proposals: Proposals = { - good: 0, - bad: 0, - } - currentPackageMaxValidators = 100 + selectedExtraTab: WritableSignal = signal('chartIncome') + selectedRPNode: WritableSignal = signal(null) rplState = 'rpl' - rplDisplay - nextRewardRound = null - rplCommission = 0 - rplApr = '' - rplProjectedClaim = null + nextRewardRound: string = null - displaySmoothingPool: boolean - smoothingClaimed: BigNumber - smoothingUnclaimed: BigNumber - unclaimedRpl: BigNumber - totalRplEarned: BigNumber - hasNonSmoothingPoolAsWell: boolean + notificationPermissionPending = false - currentSyncCommitteeMessage: SyncCommitteeMessage = null - nextSyncCommitteeMessage: SyncCommitteeMessage = null + rewardTab: RewardTabs = 'combined' - notificationPermissionPending = false - depositCreditText = null - vacantMinipoolText = null - showWithdrawalInfo = false + successFailMode: WritableSignal = signal('percentage') - rewardTab: 'combined' | 'cons' | 'exec' = 'combined' + ignoreConfetti = false constructor( public unit: UnitconvService, @@ -110,285 +80,182 @@ export class DashboardComponent implements OnInit { public theme: ThemeUtils, private storage: StorageService, private modalController: ModalController, - private merchant: MerchantUtils, + public merchant: MerchantUtils, public validatorUtils: ValidatorUtils, private firebaseUtils: FirebaseUtils, - private platform: Platform + private platform: Platform, + private dashboardUtils: DashboardUtils ) { - this.randomChartId = getRandomInt(Number.MAX_SAFE_INTEGER) - this.updateMergeListDismissed() - } - - updateMergeListDismissed() { - this.storage.getBooleanSetting('merge_list_dismissed', false).then((result) => { - if (this.isAfterPotentialMergeTarget()) { - this.showMergeChecklist = false - } else { - this.showMergeChecklist = !result + effect(async () => { + if ((await this.showFirstProposalMsg()) && !this.ignoreConfetti) { + this.ignoreConfetti = true + setTimeout(() => { + confetti({ + particleCount: 30, + spread: 50, + origin: { y: 0.41 }, + }) + }, 800) } }) } - isAfterPotentialMergeTarget() { - const now = Date.now() - const target = 1663624800000 // target sept 20th to dismiss merge checklist - return now >= target - } + formatAddress = formatAddress - async ngOnChanges(event) { - if (event.data && event.data instanceof SimpleChange) { - if (event.data.currentValue) { - this.chartError = false - this.chartData = null - - if (this.platform.is('ios') || this.platform.is('android')) { - this.firebaseUtils.hasNotificationConsent().then(async (result) => { - const loggedIn = await this.storage.isLoggedIn() - if (!loggedIn) return - - this.notificationPermissionPending = !result - }) - } + groups = computed(() => { + return this.dashboardUtils.getGroupList(this.data?.overviewData()?.groups) + }) - if (this.balanceChart && this.proposalChart) { - this.balanceChart.destroy() - this.proposalChart.destroy() - this.randomChartId = getRandomInt(Number.MAX_SAFE_INTEGER) - } + selectedExtraTabTitle = computed(() => { + if (this.selectedExtraTab() == 'chartIncome') return 'Income' + if (this.selectedExtraTab() == 'chartSummary') return 'Efficiency' + return 'Income' + }) - setTimeout(() => { - this.drawBalanceChart() - this.drawProposalChart() - }, 500) - - this.beaconChainUrl = this.api.getBaseUrl() + selectedExtraTabTimeframe = computed(() => { + if (this.data && this.data.timeframeDisplay()) return this.data.timeframeDisplay() + return Period.AllTime + }) - await Promise.all([ - this.updateRplDisplay(), - this.updateNextRewardRound(), - this.updateRplCommission(), - this.updateRplApr(), - this.updateRplProjectedClaim(), - this.updateSmoothingPool(), - this.updateActiveSyncCommitteeMessage(this.data.currentSyncCommittee), - this.updateNextSyncCommitteeMessage(this.data.nextSyncCommittee), - this.updateDepositCreditText(), - this.updateVacantMinipoolText(), - this.updateWithdrawalInfo(), - ]) - - if (!this.data.foreignValidator) { - await Promise.all([this.checkForFinalization(), this.checkForGenesisOccurred()]) - } - - this.doneLoading = true - } + showFirstProposalMsg = computed(async () => { + if (!this.data || this.data.foreignValidator || !this.data.summary() || this.data.summary().length == 0) return + const foundAtLeasOne = this.data.summary()[0].proposals.success === 1 + const noPreviousFirstProposal = await this.storage.getBooleanSetting('first_proposal_executed', false) + if (foundAtLeasOne && !noPreviousFirstProposal && this.data?.timeframe() == Period.AllTime) { + return true } - } + }) + + finalizationIssue: Signal = computed(() => { + if (!this.data || !this.data.latestState()?.state) return false + const epochsToWaitBeforeFinalizationIssue = 4 // 2 normal delay + 2 extra + return ( + slotToEpoch(this.data.chainNetwork().id, this.data.latestState().state.finalized_epoch) - epochsToWaitBeforeFinalizationIssue > + this.data.latestState().state.finalized_epoch + ) + }) - updateWithdrawalInfo() { - this.storage.getBooleanSetting('withdrawal_info_dismissed', false).then((result) => { - this.showWithdrawalInfo = !this.data.withdrawalsEnabledForAll && !result - }) - } + awaitGenesis = computed(() => { + if (!this.data || !this.data.latestState()?.state) return false + const currentEpoch = slotToEpoch(this.data.chainNetwork().id, this.data.latestState().state.current_slot) + return currentEpoch == 0 && this.data.latestState().state.current_slot <= 0 + }) - updateDepositCreditText() { - if (this.data.rocketpool.depositCredit && this.data.rocketpool.depositCredit.gt(0)) { - this.depositCreditText = `You have ${this.unit.convertNonFiat( - this.data.rocketpool.depositCredit, - 'WEI', - 'ETHER', - true - )} in unused Rocketpool deposit credit.

You can use this credit to spin up more minipools. Be aware that you can not withdraw your deposit credit.` - } - } + earlyGenesis = computed(() => { + if (!this.data || !this.data.latestState()?.state) return false + const currentEpoch = slotToEpoch(this.data.chainNetwork().id, this.data.latestState().state.current_slot) + return !this.awaitGenesis() && !this.finalizationIssue() && currentEpoch <= 7 + }) - updateVacantMinipoolText() { - if (this.data.rocketpool.vacantPools && this.data.rocketpool.vacantPools > 0) { - this.vacantMinipoolText = `${this.data.rocketpool.vacantPools} of your ${ - this.data.rocketpool.vacantPools == 1 ? 'minipool is' : 'minipools are' - } - currently vacant. Head over to the validators tab to see which one has a vacant label.

- If you recently converted a validator to a minipool please make sure you did change the 0x0 withdrawal credentials to the new vacant minipool address (0x01) to fix this warning.

- If you already changed the withdrawal credentials this warning will disappear on it's own within 24h. - ` - } - } + currentSyncCommitteeMessage: Signal = computed(() => { + if (this.data && this.data.summaryGroup().sync_count.current_validators > 0 && this.data.latestState()?.state) { + const startEpoch = startEpochSyncCommittee(this.data.chainNetwork().id, this.data.latestState().state.current_slot) + const startTs = epochToTimestamp(this.data.chainNetwork().id, startEpoch) - epochToTimestamp(epoch: number) { - const network = this.api.getNetwork() - return (network.genesisTs + epoch * network.slotPerEpoch * network.slotsTime) * 1000 - } + const endEpoch = endEpochSyncCommittee(this.data.chainNetwork().id, this.data.latestState().state.current_slot) + const endTs = epochToTimestamp(this.data.chainNetwork().id, endEpoch) - updateActiveSyncCommitteeMessage(committee: SyncCommitteeResponse) { - if (committee) { - const endTs = this.epochToTimestamp(committee.end_epoch + 1) - const startTs = this.epochToTimestamp(committee.start_epoch) - this.currentSyncCommitteeMessage = { - title: 'Sync Committee', - text: `Your validator${committee.validators.length > 1 ? 's' : ''} ${committee.validators.toString()} ${ - committee.validators.length > 1 ? 'are' : 'is' - } currently part of the active sync committee. -

This duty started at epoch ${committee.start_epoch} at ${new Date(startTs).toLocaleString()} and - will end after epoch ${committee.end_epoch} at ${new Date(endTs).toLocaleString()}. -

You'll earn extra rewards during this period. - `, - } as SyncCommitteeMessage - } else { - this.currentSyncCommitteeMessage = null - } - } + const plural = this.data.summaryGroup().sync_count.current_validators > 1 + const options = this.syncDateFormatOptions() - updateNextSyncCommitteeMessage(committee: SyncCommitteeResponse) { - if (committee) { - const endTs = this.epochToTimestamp(committee.end_epoch + 1) - const startTs = this.epochToTimestamp(committee.start_epoch) - this.nextSyncCommitteeMessage = { - title: 'Sync Committee Soon', - text: `Your validator${committee.validators.length > 1 ? 's' : ''} ${committee.validators.toString()} ${ - committee.validators.length > 1 ? 'are' : 'is' - } part of the next sync committee. -

This duty starts at epoch ${committee.start_epoch} at ${new Date(startTs).toLocaleString()} and - will end after epoch ${committee.end_epoch} at ${new Date(endTs).toLocaleString()}. -

You'll earn extra rewards during this period. - `, + const opening = plural ? `${this.data.summaryGroup().sync_count.current_validators} of your validators` : 'Your validator' + return { + title: 'Sync Committee', + text: `${opening} ${plural ? 'are' : 'is'} currently part of the active sync committee. +

This duty started at ${new Date(startTs).toLocaleString(getLocale(), options)} (Epoch ${startEpoch}) and + will end at ${new Date(endTs).toLocaleString(getLocale(), options)} (Epoch ${endEpoch - 1}). +

You'll earn extra rewards during this period if you are online and attesting. + `, } as SyncCommitteeMessage - } else { - this.nextSyncCommitteeMessage = null } - } + return null + }) - updateSmoothingPool() { - try { - if (!this.validatorUtils.rocketpoolStats || !this.validatorUtils.rocketpoolStats.effective_rpl_staked) return - this.hasNonSmoothingPoolAsWell = this.data.rocketpool.hasNonSmoothingPoolAsWell - this.displaySmoothingPool = this.data.rocketpool.smoothingPool - this.smoothingClaimed = this.data.rocketpool.smoothingPoolClaimed - this.smoothingUnclaimed = this.data.rocketpool.smoothingPoolUnclaimed - this.unclaimedRpl = this.data.rocketpool.rplUnclaimed - this.totalRplEarned = this.data.rocketpool.totalClaims.plus(this.data.rocketpool.rplUnclaimed) - } catch (e) { - console.warn('cannot update smoothing pool', e) - } - } + nextSyncCommitteeMessage: Signal = computed(() => { + if (this.data && this.data.summaryGroup().sync_count.upcoming_validators > 0 && this.data.latestState()?.state) { + const startEpoch = endEpochSyncCommittee(this.data.chainNetwork().id, this.data.latestState().state.current_slot) // end of current is start of next + const startTs = epochToTimestamp(this.data.chainNetwork().id, startEpoch) - updateRplProjectedClaim() { - try { - if (!this.validatorUtils.rocketpoolStats || !this.validatorUtils.rocketpoolStats.effective_rpl_staked) return - if (this.data.rocketpool.currentRpl.isLessThanOrEqualTo(this.data.rocketpool.minRpl)) { - this.rplProjectedClaim = 0 - return - } + const endEpoch = endEpochSyncCommittee(this.data.chainNetwork().id, startEpoch * this.data.chainNetwork().slotPerEpoch) // end of next + const endTs = epochToTimestamp(this.data.chainNetwork().id, endEpoch) - const temp = this.getEffectiveRplStake(this.data.rocketpool) - .dividedBy(new BigNumber(this.validatorUtils.rocketpoolStats.effective_rpl_staked)) - .multipliedBy(new BigNumber(this.validatorUtils.rocketpoolStats.node_operator_rewards)) + const plural = this.data.summaryGroup().sync_count.upcoming_validators > 1 + const options = this.syncDateFormatOptions() - this.rplProjectedClaim = temp - if (temp.isLessThanOrEqualTo(new BigNumber('0'))) { - this.rplProjectedClaim = null - } - } catch (e) { - console.warn('cannot updateRplProjectedClaim', e) + const opening = plural ? `${this.data.summaryGroup().sync_count.current_validators} of your validators` : 'Your validator' + return { + title: 'Sync Committee Soon', + text: `${opening} ${plural ? 'are' : 'is'} part of the next sync committee. +

This duty starts at ${new Date(startTs).toLocaleString(getLocale(), options)} (Epoch ${startEpoch}) and + will end at ${new Date(endTs).toLocaleString(getLocale(), options)} (Epoch ${endEpoch - 1}). +

You'll earn extra rewards during this period if you are online and attesting. + `, + } as SyncCommitteeMessage } - } + return null + }) - getEffectiveRplStake(data: Rocketpool): BigNumber { - if (data.currentRpl.isGreaterThanOrEqualTo(data.maxRpl)) return data.maxRpl - if (data.currentRpl.isLessThanOrEqualTo(data.minRpl)) return data.minRpl - return data.currentRpl - } + async onGroupChanged(id: number) { + await this.storage.setDashboardGroupID(id) + this.data?.selectedGroupID.set(id) - updateRplApr() { - try { - if (!this.validatorUtils.rocketpoolStats || !this.validatorUtils.rocketpoolStats.claim_interval_time) return - const hoursToAdd = this.validatorUtils.rocketpoolStats.claim_interval_time.split(':')[0] - const hoursNumber = parseInt(hoursToAdd) - this.rplApr = new BigNumber(this.validatorUtils.rocketpoolStats.node_operator_rewards) - .dividedBy(new BigNumber(this.validatorUtils.rocketpoolStats.effective_rpl_staked)) - .dividedBy(new BigNumber(hoursNumber / 24)) - .multipliedBy(new BigNumber(36500)) - .decimalPlaces(2) - .toFixed() - } catch (e) { - console.warn('cannot updateRplApr', e) - } + this.changedGroup.emit() } - updateRplCommission() { - try { - if (!this.validatorUtils.rocketpoolStats || !this.validatorUtils.rocketpoolStats.current_node_fee) return - this.rplCommission = Math.round(this.validatorUtils.rocketpoolStats.current_node_fee * 10000) / 100 - } catch (e) { - console.warn('cannot updateRplCommission', e) + syncDateFormatOptions(): Intl.DateTimeFormatOptions { + return { + year: 'numeric', + month: '2-digit', + day: '2-digit', + hour: '2-digit', + minute: '2-digit', } } - updateNextRewardRound() { - try { - if (!this.validatorUtils.rocketpoolStats || !this.validatorUtils.rocketpoolStats.claim_interval_time) return - const hoursToAdd = this.validatorUtils.rocketpoolStats.claim_interval_time.split(':')[0] - this.nextRewardRound = this.validatorUtils.rocketpoolStats.claim_interval_time_start * 1000 + parseInt(hoursToAdd) * 60 * 60 * 1000 - } catch (e) { - console.warn('cannot updateNextRewardRound', e) + ngOnChanges(event: { data: { currentValue: unknown } }) { + if (event.data && event.data instanceof SimpleChange) { + if (event.data.currentValue) { + this.beaconChainUrl = this.api.getBaseUrl() + } + this.selectedRPNode.set(this.data?.rocketpool()?.[0]?.node?.hash) } } - ngOnInit() { - //this.doneLoading = false - this.storage.getBooleanSetting('rank_percent_mode', false).then((result) => (this.rankPercentMode = result)) - this.storage.getItem('rpl_pdisplay_mode').then((result) => (this.rplState = result ? result : 'rpl')) - highChartOptions(HighCharts, this.api.getHostName()) - highChartOptions(Highstock, this.api.getHostName()) - this.merchant.getCurrentPlanMaxValidator().then((result) => { - this.currentPackageMaxValidators = result + depositCreditText = computed(() => { + let depositCredit = new BigNumber(0) + this.data.rocketpool()?.forEach((item) => { + depositCredit = depositCredit.plus(new BigNumber(item.deposit_credit)) }) - } - - private checkForGenesisOccurred() { - if (!this.data || !this.data.currentEpoch) return - const currentEpoch = this.data.currentEpoch as EpochResponse - this.awaitGenesis = currentEpoch.epoch == 0 && currentEpoch.proposedblocks <= 1 - this.earlyGenesis = !this.awaitGenesis && !this.finalizationIssue && currentEpoch.epoch <= 7 - } - - async checkForFinalization() { - const cachedFinalizationIssue = (await this.storage.getObject('finalization_issues')) as FinalizationIssue - if (cachedFinalizationIssue) { - if (cachedFinalizationIssue.ts && cachedFinalizationIssue.ts + 4 * 60 * 60 * 1000 > Date.now()) { - console.log('returning cached finalization issue state', cachedFinalizationIssue) - this.finalizationIssue = cachedFinalizationIssue.value - return - } + if (depositCredit.gt(0)) { + return `You have ${this.unit.convertNonFiat( + depositCredit, + 'WEI', + 'ETHER', + true + )} in unused Rocketpool deposit credit.

You can use this credit to spin up more minipools. Be aware that you can not withdraw your deposit credit.` } + return null + }) - const olderResult = this.validatorUtils.getOlderEpoch() - if (!this.data || !this.data.currentEpoch || !olderResult) return - console.log('checkForFinalization', olderResult) - this.finalizationIssue = new BigNumber(olderResult.globalparticipationrate).isLessThan('0.664') && olderResult.epoch > 7 - this.storage.setObject('finalization_issues', { ts: Date.now(), value: this.finalizationIssue } as FinalizationIssue) - } - - async getChartData(data: 'allbalances' | 'proposals') { - if (!this.data || !this.data.lazyChartValidators) return null - const chartReq = new DashboardDataRequest(data, this.data.lazyChartValidators) - const response = await this.api.execute(chartReq).catch(() => { - return null + ngOnInit() { + getSuccessFailMode(this.storage).then((result) => { + this.successFailMode.set(result) }) - if (!response) { - this.chartError = true - return null + if (this.platform.is('ios') || this.platform.is('android')) { + this.firebaseUtils.hasNotificationConsent().then(async (result) => { + const loggedIn = await this.storage.isLoggedIn() + if (!loggedIn) return + + this.notificationPermissionPending = !result + }) } - return chartReq.parse(response) + this.storage.getItem('rpl_pdisplay_mode').then((result) => (this.rplState = result ? result : 'rpl')) } async upgrade() { const modal = await this.modalController.create({ component: SubscribePage, cssClass: 'my-custom-class', - componentProps: { - tab: 'whale', - }, }) return await modal.present() } @@ -397,506 +264,30 @@ export class DashboardComponent implements OnInit { if (this.rplState == 'rpl' && canPercent) { // next % this.rplState = '%' - this.updateRplDisplay() this.storage.setItem('rpl_pdisplay_mode', this.rplState) return } else if ((this.rplState == 'rpl' && !canPercent) || this.rplState == '%') { // next % this.rplState = 'conv' - this.updateRplDisplay() this.storage.setItem('rpl_pdisplay_mode', this.rplState) return } else { this.rplState = 'rpl' - this.updateRplDisplay() this.storage.setItem('rpl_pdisplay_mode', this.rplState) return } } - updateRplDisplay() { - if (this.rplState == '%') { - const rplPrice = this.unit.getRPLPrice() - const currentETH = this.data.rocketpool.currentRpl.multipliedBy(rplPrice) - const minETH = this.data.rocketpool.minRpl.multipliedBy(rplPrice).multipliedBy(10) // since collateral is 10% of borrowed eth, multiply by 10 to get to the borrowed eth amount - - this.rplDisplay = currentETH.dividedBy(minETH).multipliedBy(100).decimalPlaces(1).toNumber() - } else { - this.rplDisplay = this.data.rocketpool.currentRpl - } - } - - async drawProposalChart() { - this.chartDataProposals = await this.getChartData('proposals') - - if (!this.chartDataProposals || this.chartDataProposals.length < 1) { - this.chartDataProposals = false - return - } - - const proposed = [] - const missed = [] - const orphaned = [] - this.chartDataProposals.map((d) => { - if (d[1] == 1) proposed.push([d[0] * 1000, 1]) - else if (d[1] == 2) missed.push([d[0] * 1000, 1]) - else if (d[1] == 3) orphaned.push([d[0] * 1000, 1]) - }) - - this.proposals = { - good: proposed.length, - bad: missed.length + orphaned.length, - } - - this.checkForFirstProposal(proposed) - - this.createProposedChart(proposed, missed, orphaned) - } - - private async checkForFirstProposal(chartData) { - if (this.data.foreignValidator) return - const foundAtLeasOne = chartData.length >= 1 && chartData.length <= 2 - const noPreviousFirstProposal = await this.storage.getBooleanSetting('first_proposal_executed', false) - if (foundAtLeasOne && !noPreviousFirstProposal) { - this.showFirstProposalMsg = true - - if (this.firstCelebrate) { - setTimeout(() => { - confetti({ - particleCount: 30, - spread: 50, - origin: { y: 0.41 }, - }) - }, 800) - } - this.firstCelebrate = false - } - } - - async drawBalanceChart() { - this.chartData = await this.getChartData('allbalances') - - if (!this.chartData || this.chartData.length < 3) { - this.chartError = true - return - } - - this.chartError = false - - const setTimestampToMidnight = (ts: number): number => { - const d = new Date(ts) - d.setHours(0) - d.setMinutes(0) - d.setSeconds(0) - d.setMilliseconds(0) - return d.getTime() - } - - // force timestamp to be at 00:00AM for the day to keep columns centered on ticks - for (let i = 0; i < this.chartData.consensusChartData.length; i++) { - this.chartData.consensusChartData[i].x = setTimestampToMidnight(this.chartData.consensusChartData[i].x) - } - for (let i = 0; i < this.chartData.executionChartData.length; i++) { - this.chartData.executionChartData[i].x = setTimestampToMidnight(this.chartData.executionChartData[i].x) - } - - // accumulate all execution income entries per day into a single entry - for (let i = this.chartData.executionChartData.length - 1; i > 0; i--) { - if (this.chartData.executionChartData[i].x == this.chartData.executionChartData[i - 1].x) { - this.chartData.executionChartData[i - 1].y += this.chartData.executionChartData[i].y - this.chartData.executionChartData.splice(i, 1) - } - } - - this.createBalanceChart(this.chartData.consensusChartData, this.chartData.executionChartData) - } - - switchRank() { - this.rankPercentMode = !this.rankPercentMode - this.storage.setBooleanSetting('rank_percent_mode', this.rankPercentMode) - } - - private getChartToolTipCaption(timestamp: number, genesisTs: number, slotTime: number, slotsPerEpoch: number, dataGroupLength: number) { - const dateToEpoch = (ts: number): number => { - const slot = Math.floor((ts / 1000 - genesisTs) / slotTime) - const epoch = Math.floor(slot / slotsPerEpoch) - return Math.max(0, epoch) - } - - const startEpoch = dateToEpoch(timestamp) - const dateForNextDay = new Date(timestamp) - dateForNextDay.setDate(dateForNextDay.getDate() + dataGroupLength) - const endEpoch = dateToEpoch(dateForNextDay.getTime()) - 1 - const epochText = `(Epochs ${startEpoch} - ${endEpoch})
` - - if (dataGroupLength == 1) { - return `${new Date(timestamp).toLocaleDateString()} ${epochText}` - } else { - return `${new Date(timestamp).toLocaleDateString()} - ${new Date(dateForNextDay).toLocaleDateString()}
${epochText}` - } - } - - private proposalChart = null - createProposedChart(proposed, missed, orphaned) { - const network = this.api.getNetwork() - - this.proposalChart = Highstock.chart( - 'highchartsBlocks' + this.randomChartId, - { - accessibility: { - enabled: false, - }, - chart: { - type: 'column', - marginLeft: 0, - marginRight: 0, - spacingLeft: 0, - spacingRight: 0, - spacingTop: 12, - }, - legend: { - enabled: true, - }, - title: { - text: '', - }, - colors: ['var(--chart-default)', '#ff835c', '#e4a354', '#2b908f', '#f45b5b', '#91e8e1'], - xAxis: { - lineWidth: 0, - tickColor: '#e5e1e1', - type: 'datetime', - range: 31 * 24 * 60 * 60 * 1000, - }, - yAxis: [ - { - title: { - text: '', - }, - allowDecimals: false, - opposite: false, - labels: { - align: 'left', - x: 1, - y: -2, - }, - }, - ], - tooltip: { - style: { - color: 'var(--text-color)', - display: `inline-block`, - width: 250, - }, - shared: true, - formatter: (tooltip) => { - // date and epoch - let text = this.getChartToolTipCaption( - tooltip.chart.hoverPoints[0].x, - network.genesisTs, - network.slotsTime, - network.slotPerEpoch, - tooltip.chart.hoverPoints[0].dataGroup.length - ) - - // summary - for (let i = 0; i < tooltip.chart.hoverPoints.length; i++) { - text += ` ${tooltip.chart.hoverPoints[i].series.name}: ${tooltip.chart.hoverPoints[i].y}
` - } - - return text - }, - }, - plotOptions: { - series: { - dataGrouping: { - units: [ - ['day', [1, 2, 3]], - ['week', [1, 2]], - ['month', [1, 2, 3, 6]], - ], - forced: true, - enabled: true, - groupAll: true, - }, - }, - column: { - borderWidth: 0, - centerInCategory: true, - }, - }, - series: [ - { - name: 'Proposed', - color: 'var(--chart-default)', - data: proposed, - pointWidth: 5, - type: 'column', - }, - { - name: 'Missed', - color: '#ff835c', - data: missed, - pointWidth: 5, - type: 'column', - }, - { - name: 'Orphaned', - color: '#e4a354', - data: orphaned, - pointWidth: 5, - type: 'column', - }, - ], - rangeSelector: { - enabled: false, - }, - scrollbar: { - enabled: false, - }, - navigator: { - enabled: true, - }, - }, - null - ) - } - - private balanceChart = null - createBalanceChart(consensusIncome, executionIncome) { - executionIncome = executionIncome || [] - - const ticksDecimalPlaces = 3 - const network = this.api.getNetwork() - - const getValueString = (value: BigNumber, type: RewardType): string => { - let text - if (type == 'cons') { - text = `${value.toFixed(5)} ` + this.unit.getNetworkDefaultUnit(type).display - if (!this.unit.isDefaultCurrency(this.unit.pref.Cons)) { - text += ` (${this.unit.convertToPref(value, this.unit.getNetworkDefaultCurrency(type), type)})` - } - } else if (type == 'exec') { - // Gnosis: All values provided by the API are in the CL currency, including the el rewards - text = `${this.unit.convertCLtoEL(value).toFixed(5)} ` + this.unit.getNetworkDefaultUnit(type).display - if (!this.unit.isDefaultCurrency(this.unit.pref.Exec)) { - text += ` (${this.unit.convertToPref(value, this.unit.getNetworkDefaultCurrency('cons'), 'cons')})` - } - } - - return text - } - - this.balanceChart = Highstock.chart( - 'highcharts' + this.randomChartId, - { - accessibility: { - enabled: false, - }, - exporting: { - scale: 1, - }, - rangeSelector: { - enabled: false, - }, - scrollbar: { - enabled: false, - }, - chart: { - type: 'column', - marginLeft: 0, - marginRight: 0, - spacingLeft: 0, - spacingRight: 0, - spacingTop: 12, - }, - legend: { - enabled: true, - }, - title: { - text: '', //Balance History for all Validators - }, - xAxis: { - type: 'datetime', - range: 31 * 24 * 60 * 60 * 1000, - }, - tooltip: { - style: { - color: 'var(--text-color)', - display: `inline-block`, - width: 250, - }, - shared: true, - formatter: (tooltip) => { - // date and epoch - let text = this.getChartToolTipCaption( - tooltip.chart.hoverPoints[0].x, - network.genesisTs, - network.slotsTime, - network.slotPerEpoch, - tooltip.chart.hoverPoints[0].dataGroup.length - ) - - // income - // Gnosis: All values provided by the API are in the CL currency, including the el rewards which is why we can simply add them for total - let total = new BigNumber(0) - for (let i = 0; i < tooltip.chart.hoverPoints.length; i++) { - const type = tooltip.chart.hoverPoints[i].series.name == 'Execution' ? 'exec' : 'cons' - - const value = new BigNumber(tooltip.chart.hoverPoints[i].y) - text += ` ${ - tooltip.chart.hoverPoints[i].series.name - }: ${getValueString(value, type)}
` - - total = total.plus(value) - } - - // add total if hovered point contains rewards for both EL and CL - // only if both exec and cons currencies are the same - if (tooltip.chart.hoverPoints.length > 1) { - text += `Total: ${getValueString(total, 'cons')}` - } - - return text - }, - }, - navigator: { - enabled: true, - series: { - data: consensusIncome, - color: '#7cb5ec', - }, - }, - plotOptions: { - column: { - borderWidth: 0, - stacking: 'normal', - dataLabels: { - enabled: false, - }, - dataGrouping: { - forced: true, - enabled: true, - - units: [ - ['day', [1, 2, 3]], - ['week', [1, 2]], - ['month', [1, 2, 3, 6]], - ], - }, - }, - series: { - turboThreshold: 10000, - }, - }, - yAxis: [ - { - title: { - text: '', - }, - opposite: false, - tickPositioner: function () { - const precision = Math.pow(10, ticksDecimalPlaces) - // make sure that no bar reaches the top or bottom of the chart (looks nicer) - const padding = 1.15 - // make sure that the top and bottom tick are exactly at a position with [ticksDecimalPlaces] decimal places - const min = Math.round(this.chart.series[1].dataMin * padding * precision) / precision - - // series[1].dataMax contains the consensus reward only and is therefore always available (we use it as default) - // series[0].dataMax contains the highest visible bar that contains BOTH consensus AND execution reward - // => i.e. series[0].dataMax is undefined if no execution reward is shown - // keep in mind that the user can toggle series on/off (can be checked via the series' visible parameter) - let maxSeries = 1 - if ( - this.chart.series[0].visible && - this.chart.series[0].dataMax != undefined && - (this.chart.series[1].dataMax == undefined || - !this.chart.series[1].visible || - this.chart.series[0].dataMax > this.chart.series[1].dataMax) - ) { - // use series[0] to calculate max since it is available and series[1] is either unavailable/hidden or lower than series[0] - maxSeries = 0 - } - - const max = Math.round(this.chart.series[maxSeries].dataMax * padding * precision) / precision - - // only show 3 ticks if min < 0 && max > 0 - let positions - if (min < 0) { - if (max < 0) { - positions = [min, 0] - } else { - positions = [min, 0, max] - } - } else { - positions = [0, max] - } - - return positions - }, - labels: { - align: 'left', - x: 1, - y: -2, - formatter: function () { - if (this.value == 0) { - return '0' - } - return parseFloat(this.value.toString()).toFixed(ticksDecimalPlaces) - }, - }, - }, - ], - series: [ - { - name: 'Consensus', - data: consensusIncome, - index: 2, - type: 'column', - }, - { - name: 'Execution', - data: executionIncome, - index: 1, - type: 'column', - }, - ], - }, - null - ) - } - - onDismissed() { - this.updateMergeListDismissed() - } - async openBrowser() { await Browser.open({ url: this.getBrowserURL(), toolbarColor: '#2f2e42' }) } getBrowserURL(): string { - if (this.data.foreignValidator) { - return this.api.getBaseUrl() + '/validator/' + this.data.foreignValidatorItem.pubkey - } else { - return this.api.getBaseUrl() + '/dashboard?validators=' + this.data.lazyChartValidators - } + return setID(this.api.getBaseUrl() + '/dashboard/{id}', this.data.id) } } -function getRandomInt(max) { - return Math.floor(Math.random() * Math.floor(max)) -} - -interface Proposals { - good: number - bad: number -} - interface SyncCommitteeMessage { title: string text: string } - -interface FinalizationIssue { - ts: number - value: boolean -} diff --git a/src/app/components/dashboard/dashboard.module.ts b/src/app/components/dashboard/dashboard.module.ts index f46589db..6bf72f72 100644 --- a/src/app/components/dashboard/dashboard.module.ts +++ b/src/app/components/dashboard/dashboard.module.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -26,11 +25,21 @@ import { IonicModule } from '@ionic/angular' import { DashboardComponent } from './dashboard.component' import { PipesModule } from '../../pipes/pipes.module' -import { ClientupdateComponentModule } from '../../components/clientupdate/clientupdate.module' -import { MessageComponentModule } from '../../components/message/message.module' +import { MessageComponentModule } from '@components/message/message.module' import { TooltipModule } from 'ng2-tooltip-directive-major-angular-updates' import { AdComponentModule } from '../ad/ad.module' -import { PerformanceItemComponentModule } from '../dashboard/performance-item.module' +import { PerformanceItemComponentModule } from './performance-item/performance-item.module' +import { SuccessFailViewComponent } from './success-fail-view/success-fail-view.component' +import { GridCellLeftComponent } from './grid-cell-left/grid-cell-left.component' +import { GridCellRightComponent } from './grid-cell-right/grid-cell-right.component' +import { SummaryChartModule } from './summary-chart/summary-chart.module' +import { RewardChartModule } from './reward-chart/reward-chart.module' +import { FullPageLoadingComponent } from '../full-page-loading/full-page-loading.component' +import { FullPageOfflineComponent } from '../full-page-offline/full-page-offline.component' +import { FirebaseUtilsModule } from '@utils/Firebase.module' +import { GroupSelectorComponent } from './group-selector/group-selector.component' +import { SlotvizWidgetComponent } from '@components/slotviz-widget/slotviz-widget.component' +import { ClientupdateComponent } from '@components/clientupdate/clientupdate.component' @NgModule({ imports: [ @@ -38,11 +47,21 @@ import { PerformanceItemComponentModule } from '../dashboard/performance-item.mo FormsModule, IonicModule, PipesModule, - ClientupdateComponentModule, + ClientupdateComponent, MessageComponentModule, TooltipModule, AdComponentModule, PerformanceItemComponentModule, + SummaryChartModule, + SuccessFailViewComponent, + GridCellLeftComponent, + GridCellRightComponent, + RewardChartModule, + FullPageLoadingComponent, + FullPageOfflineComponent, + FirebaseUtilsModule, + GroupSelectorComponent, + SlotvizWidgetComponent, ], declarations: [DashboardComponent], exports: [DashboardComponent], diff --git a/src/app/components/dashboard/dashboard.spec.ts b/src/app/components/dashboard/dashboard.spec.ts deleted file mode 100644 index 7e8f9b86..00000000 --- a/src/app/components/dashboard/dashboard.spec.ts +++ /dev/null @@ -1,44 +0,0 @@ -/* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) - * // - * // This file is part of Beaconchain Dashboard. - * // - * // Beaconchain Dashboard is free software: you can redistribute it and/or modify - * // it under the terms of the GNU General Public License as published by - * // the Free Software Foundation, either version 3 of the License, or - * // (at your option) any later version. - * // - * // Beaconchain Dashboard is distributed in the hope that it will be useful, - * // but WITHOUT ANY WARRANTY; without even the implied warranty of - * // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * // GNU General Public License for more details. - * // - * // You should have received a copy of the GNU General Public License - * // along with Beaconchain Dashboard. If not, see . - */ - -import { async, ComponentFixture, TestBed } from '@angular/core/testing' -import { IonicModule } from '@ionic/angular' - -import { DashboardComponent } from './dashboard.component' - -describe('DashboardComponent', () => { - let component: DashboardComponent - let fixture: ComponentFixture - - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [DashboardComponent], - imports: [IonicModule.forRoot()], - }).compileComponents() - - fixture = TestBed.createComponent(DashboardComponent) - component = fixture.componentInstance - fixture.detectChanges() - })) - - it('should create', () => { - expect(component).toBeTruthy() - }) -}) diff --git a/src/app/components/dashboard/grid-cell-left/grid-cell-left.component.html b/src/app/components/dashboard/grid-cell-left/grid-cell-left.component.html new file mode 100644 index 00000000..04ab8d7c --- /dev/null +++ b/src/app/components/dashboard/grid-cell-left/grid-cell-left.component.html @@ -0,0 +1,14 @@ +
+
+ + + +
+
+ + {{ name }} + + {{ name }} + +
+
diff --git a/src/app/components/dashboard/grid-cell-left/grid-cell-left.component.scss b/src/app/components/dashboard/grid-cell-left/grid-cell-left.component.scss new file mode 100644 index 00000000..4f512952 --- /dev/null +++ b/src/app/components/dashboard/grid-cell-left/grid-cell-left.component.scss @@ -0,0 +1,45 @@ +// Copyright (C) 2024 bitfly explorer GmbH +// +// This file is part of Beaconchain Dashboard. +// +// Beaconchain Dashboard is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Beaconchain Dashboard is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Beaconchain Dashboard. If not, see . + +.grid-cell.left { + text-align: left; + /* Add more styling as needed */ +} + +.grid-cell.right { + text-align: right; + /* Add more styling as needed */ +} + +.grid-cell { + width: 50%; + float: left; + margin-bottom: 7px; + margin-top: 7px; +} + +.income-title { + opacity: var(--default-secondary-transparency); + font-size: var(--smaller-info-size); + //font-weight: var(--smaller-label-weight); + font-weight: bold; + //color: var(--ion-text-color-secondary) !important; +} + +.grid { + width: 100%; +} diff --git a/src/app/components/dashboard/grid-cell-left/grid-cell-left.component.ts b/src/app/components/dashboard/grid-cell-left/grid-cell-left.component.ts new file mode 100644 index 00000000..f745e650 --- /dev/null +++ b/src/app/components/dashboard/grid-cell-left/grid-cell-left.component.ts @@ -0,0 +1,22 @@ +import { CommonModule } from '@angular/common' +import { Component, EventEmitter, Input, Output } from '@angular/core' +import { IonicModule } from '@ionic/angular' +import { TooltipModule } from 'ng2-tooltip-directive-major-angular-updates' + +@Component({ + selector: 'app-grid-cell-left', + imports: [IonicModule, TooltipModule, CommonModule], + templateUrl: './grid-cell-left.component.html', + styleUrl: './grid-cell-left.component.scss', +}) +export class GridCellLeftComponent { + @Input() name: string = '' + @Input() tooltipText: string | null = null + + @Output() valueClick = new EventEmitter() + + onClick($event: { stopPropagation: () => void }) { + $event.stopPropagation() + this.valueClick.emit() + } +} diff --git a/src/app/components/dashboard/grid-cell-right/grid-cell-right.component.html b/src/app/components/dashboard/grid-cell-right/grid-cell-right.component.html new file mode 100644 index 00000000..49b791f8 --- /dev/null +++ b/src/app/components/dashboard/grid-cell-right/grid-cell-right.component.html @@ -0,0 +1,13 @@ +
+
+ + + +
+
+ + {{ name }} + {{ name }} + +
+
diff --git a/src/app/components/dashboard/grid-cell-right/grid-cell-right.component.ts b/src/app/components/dashboard/grid-cell-right/grid-cell-right.component.ts new file mode 100644 index 00000000..431d53fa --- /dev/null +++ b/src/app/components/dashboard/grid-cell-right/grid-cell-right.component.ts @@ -0,0 +1,22 @@ +import { CommonModule } from '@angular/common' +import { Component, EventEmitter, Input, Output } from '@angular/core' +import { IonicModule } from '@ionic/angular' +import { TooltipModule } from 'ng2-tooltip-directive-major-angular-updates' + +@Component({ + selector: 'app-grid-cell-right', + imports: [IonicModule, TooltipModule, CommonModule], + templateUrl: './grid-cell-right.component.html', + styleUrl: '../grid-cell-left/grid-cell-left.component.scss', +}) +export class GridCellRightComponent { + @Input() name: string = '' + @Input() tooltipText: string | null = null + + @Output() valueClick = new EventEmitter() + + onClick($event: { stopPropagation: () => void }) { + $event.stopPropagation() + this.valueClick.emit() + } +} diff --git a/src/app/components/dashboard/group-selector/group-selector.component.html b/src/app/components/dashboard/group-selector/group-selector.component.html new file mode 100644 index 00000000..21a202a4 --- /dev/null +++ b/src/app/components/dashboard/group-selector/group-selector.component.html @@ -0,0 +1,7 @@ + + Selected Group: + + All Groups + {{ item.name }} ({{ item.count }}) + + diff --git a/src/app/components/dashboard/group-selector/group-selector.component.scss b/src/app/components/dashboard/group-selector/group-selector.component.scss new file mode 100644 index 00000000..c4f99a9e --- /dev/null +++ b/src/app/components/dashboard/group-selector/group-selector.component.scss @@ -0,0 +1,34 @@ +// Copyright (C) 2024 bitfly explorer GmbH +// +// This file is part of Beaconchain Dashboard. +// +// Beaconchain Dashboard is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Beaconchain Dashboard is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Beaconchain Dashboard. If not, see . + +.group-selector { + --background-color: var(--ion-toolbar-background) !important; + --background: var(--ion-toolbar-background) !important; + margin: 0px !important; +} + +ion-select { + --placeholder-color: var(--x-toolbar-title-color); + color: var(--x-toolbar-title-color); +} + +.group-label { + color: var(--x-toolbar-title-color); + margin: var(--edge-padding); + margin-right: 5px !important; + font-weight: bold; +} diff --git a/src/app/components/dashboard/group-selector/group-selector.component.ts b/src/app/components/dashboard/group-selector/group-selector.component.ts new file mode 100644 index 00000000..6b240005 --- /dev/null +++ b/src/app/components/dashboard/group-selector/group-selector.component.ts @@ -0,0 +1,22 @@ +import { CommonModule } from '@angular/common' +import { Component, EventEmitter, Input, Output } from '@angular/core' +import { IonicModule } from '@ionic/angular' +import { GroupEntries } from '@utils/DashboardUtils' + +@Component({ + selector: 'app-group-selector', + imports: [CommonModule, IonicModule], + templateUrl: './group-selector.component.html', + styleUrl: './group-selector.component.scss', +}) +export class GroupSelectorComponent { + @Input() preSelectGroupID: number + @Input() groups: GroupEntries[] + + @Output() groupChanged = new EventEmitter() + + selectGroup(event: CustomEvent<{ value: number }>): void { + const selectedGroupID = event.detail.value + this.groupChanged.emit(selectedGroupID) + } +} diff --git a/src/app/components/dashboard/performance-item.component.html b/src/app/components/dashboard/performance-item.component.html deleted file mode 100644 index 0c3a4c22..00000000 --- a/src/app/components/dashboard/performance-item.component.html +++ /dev/null @@ -1,88 +0,0 @@ - - -
-
-
- - {{ performanceData.performance1d | mcurrency : currency : targetCurrency }} - -
-
- - Today - Today - -
-
- -
-
- - {{ performanceData.performance7d | mcurrency : currency : targetCurrency }} - -
-
- - Last 7d - Last 7d - -
-
- -
-
- - {{ performanceData.performance31d | mcurrency : currency : targetCurrency }} - -
-
- - Last 31d - Last 31d - -
-
- -
-
- - {{ performanceData.total | mcurrency : currency : targetCurrency }} - -
-
- - Total - Total - -
-
- -
-
- {{ performanceData.apr31d }} % -
-
- - APR 31d - APR 31d - -
-
-
diff --git a/src/app/components/dashboard/performance-item/performance-item.component.html b/src/app/components/dashboard/performance-item/performance-item.component.html new file mode 100644 index 00000000..ebc722ad --- /dev/null +++ b/src/app/components/dashboard/performance-item/performance-item.component.html @@ -0,0 +1,48 @@ + + +
+ + + {{ performanceData.performance1d | mcurrency: currency : targetCurrency }} + + + + + + {{ performanceData.performance7d | mcurrency: currency : targetCurrency }} + + + + + + {{ performanceData.performance30d | mcurrency: currency : targetCurrency }} + + + + + + {{ performanceData.total | mcurrency: currency : targetCurrency }} + + + + + {{ performanceData.apr30d | number: '1.0-2' }} % + +
diff --git a/src/app/components/dashboard/performance-item.component.scss b/src/app/components/dashboard/performance-item/performance-item.component.scss similarity index 75% rename from src/app/components/dashboard/performance-item.component.scss rename to src/app/components/dashboard/performance-item/performance-item.component.scss index 4efdfc96..05d2ae61 100644 --- a/src/app/components/dashboard/performance-item.component.scss +++ b/src/app/components/dashboard/performance-item/performance-item.component.scss @@ -1,5 +1,5 @@ /* - * // Copyright (C) 2020 - 2023 Bitfly GmbH + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -17,19 +17,4 @@ * // along with Beaconchain Dashboard. If not, see . */ -@import '../../../theme/variables.scss'; - -.grid-cell { - width: 50%; - float: left; - margin-bottom: 7px; - margin-top: 7px; -} - -.left { - text-align: start !important; -} - -.right { - text-align: end !important; -} +@use '../../../../theme/variables.scss'; diff --git a/src/app/components/dashboard/performance-item.component.ts b/src/app/components/dashboard/performance-item/performance-item.component.ts similarity index 84% rename from src/app/components/dashboard/performance-item.component.ts rename to src/app/components/dashboard/performance-item/performance-item.component.ts index e5c23282..b1dfc0da 100644 --- a/src/app/components/dashboard/performance-item.component.ts +++ b/src/app/components/dashboard/performance-item/performance-item.component.ts @@ -1,5 +1,5 @@ /* - * // Copyright (C) 2020 - 2023 Bitfly GmbH + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -18,13 +18,14 @@ */ import { Component, Input } from '@angular/core' -import { Performance } from 'src/app/controllers/OverviewController' -import { Currency, UnitconvService } from 'src/app/services/unitconv.service' +import { Performance } from '@controllers/OverviewController' +import { Currency, UnitconvService } from '@services/unitconv.service' @Component({ selector: 'app-performance-item', templateUrl: './performance-item.component.html', styleUrls: ['./performance-item.component.scss'], + standalone: false, }) export class PerformanceItemComponent { @Input() performanceData: Performance @@ -33,7 +34,7 @@ export class PerformanceItemComponent { @Input() currency: string @Input() todayTooltip: string @Input() last7DaysTooltip: string - @Input() last31DaysTooltip: string + @Input() last30DaysTooltip: string @Input() totalTooltip: string @Input() aprTooltip: string } diff --git a/src/app/components/dashboard/performance-item.module.ts b/src/app/components/dashboard/performance-item/performance-item.module.ts similarity index 79% rename from src/app/components/dashboard/performance-item.module.ts rename to src/app/components/dashboard/performance-item/performance-item.module.ts index 5f746400..f238fc90 100644 --- a/src/app/components/dashboard/performance-item.module.ts +++ b/src/app/components/dashboard/performance-item/performance-item.module.ts @@ -1,5 +1,5 @@ /* - * // Copyright (C) 2020 - 2023 Bitfly GmbH + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -24,11 +24,13 @@ import { FormsModule } from '@angular/forms' import { IonicModule } from '@ionic/angular' import { PerformanceItemComponent } from './performance-item.component' -import { PipesModule } from '../../pipes/pipes.module' +import { PipesModule } from '../../../pipes/pipes.module' import { TooltipModule } from 'ng2-tooltip-directive-major-angular-updates' +import { GridCellLeftComponent } from '../grid-cell-left/grid-cell-left.component' +import { GridCellRightComponent } from '../grid-cell-right/grid-cell-right.component' @NgModule({ - imports: [CommonModule, FormsModule, IonicModule, PipesModule, TooltipModule], + imports: [CommonModule, FormsModule, IonicModule, PipesModule, TooltipModule, GridCellLeftComponent, GridCellRightComponent], declarations: [PerformanceItemComponent], exports: [PerformanceItemComponent], }) diff --git a/src/app/components/dashboard/reward-chart/reward-chart.component.html b/src/app/components/dashboard/reward-chart/reward-chart.component.html new file mode 100644 index 00000000..ed0e9b32 --- /dev/null +++ b/src/app/components/dashboard/reward-chart/reward-chart.component.html @@ -0,0 +1,7 @@ +
+
+ +
+ +
+
diff --git a/src/app/pages/merge-checklist/merge-checklist.page.scss b/src/app/components/dashboard/reward-chart/reward-chart.component.scss similarity index 79% rename from src/app/pages/merge-checklist/merge-checklist.page.scss rename to src/app/components/dashboard/reward-chart/reward-chart.component.scss index a7424bb7..b5a317e3 100644 --- a/src/app/pages/merge-checklist/merge-checklist.page.scss +++ b/src/app/components/dashboard/reward-chart/reward-chart.component.scss @@ -1,4 +1,4 @@ -// Copyright (C) 2022 Bitfly GmbH +// Copyright (C) 2024 bitfly explorer GmbH // // This file is part of Beaconchain Dashboard. // @@ -13,9 +13,4 @@ // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License -// along with Beaconchain Dashboard. If not, see . - -.hint { - opacity: 0.65; - font-size: 0.8rem; -} +// along with Beaconchain Dashboard. If not, see . diff --git a/src/app/components/dashboard/reward-chart/reward-chart.component.ts b/src/app/components/dashboard/reward-chart/reward-chart.component.ts new file mode 100644 index 00000000..6cb4dd5a --- /dev/null +++ b/src/app/components/dashboard/reward-chart/reward-chart.component.ts @@ -0,0 +1,260 @@ +import { Component, computed, Input } from '@angular/core' +import { OverviewData2 } from '@controllers/OverviewController' +import { ChartSeries } from '@requests/types/common' +import { ApiService } from '@services/api.service' +import { epochToTimestamp, formatTsToAbsolute, formatTsToDateTime, getLocale } from '@utils/TimeUtils' +import { fontSize, getTooltipHeader } from '../summary-chart/summary-chart.component' +import BigNumber from 'bignumber.js' +import { getChartTextColor, getChartTooltipBackgroundColor, getRewardChartColors, getRewardsChartLineColor } from '@utils/ColorUtils' +import { Currency, UnitconvService } from '@services/unitconv.service' +import { Aggregation } from '@requests/v2-dashboard' +import { EChartsOption } from 'echarts' + +@Component({ + selector: 'app-reward-chart', + templateUrl: './reward-chart.component.html', + styleUrl: './reward-chart.component.scss', + standalone: false, +}) +export class RewardChartComponent { + @Input() data: OverviewData2 + + fontSize = '12px' + groupsEnabled = false + + constructor( + private api: ApiService, + private unit: UnitconvService + ) {} + + rewardChart = computed(() => { + return this.createRewardChart(this.series(), this.data.rewardChart()?.categories) + }) + + valueFormatter = (value: number) => { + return value.toFixed(3) + '' + } + + colors = computed(() => { + return { + background: getChartTooltipBackgroundColor(), + data: getRewardChartColors(), + label: getChartTextColor(), + line: getRewardsChartLineColor(), + } + }) + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + mapSeriesData = (data: RewardChartSeries, cur: Currency) => { + data.bigData.forEach((bigValue, index) => { + if (!bigValue.isZero()) { + const formatted = bigValue.dividedBy(1e18) //this.unit.convertNonFiat(bigValue, 'WEI', "ETH", true) + data.formatedData[index] = { + fullLabel: formatted.toFixed(9) + ' ETH', // todo gnosis + label: formatted.toFixed(5) + ' ETH', // todo gnosis + } as ExtendedLabel + const parsedValue = parseFloat(`${formatted.toFixed(9)}`) + if (!isNaN(parsedValue)) { + data.data[index] = parsedValue + } + } + }) + } + + series = computed(() => { + const list: RewardChartSeries[] = [] + if (!this.data || !this.data.rewardChart() || !this.data.rewardChart().series) { + return list + } + + const categoryCount = this.data.rewardChart()?.categories.length ?? 0 + const clSeries: RewardChartSeries = { + barMaxWidth: 33, + bigData: Array.from(Array(categoryCount)).map(() => new BigNumber('0')), + color: this.colors().data.cl, + data: Array.from(Array(categoryCount)).map(() => 0), + formatedData: Array.from(Array(categoryCount)).map(() => ({ label: `0 ${this.unit.pref.Cons.unit.display}` })), + groups: [], + id: 1, + name: 'Consensus', + property: 'cl', + stack: 'x', + type: 'bar', + } + const elSeries: RewardChartSeries = { + barMaxWidth: 33, + bigData: Array.from(Array(categoryCount)).map(() => new BigNumber('0')), + color: this.colors().data.el, + data: Array.from(Array(categoryCount)).map(() => 0), + formatedData: Array.from(Array(categoryCount)).map(() => ({ label: `0 ${this.unit.pref.Exec.unit.display}` })), + groups: [], + id: 2, + name: 'Execution', + property: 'el', + stack: 'x', + type: 'bar', + } + list.push(elSeries) + list.push(clSeries) + this.data.rewardChart().series.forEach((group) => { + let name + // if (!this.groupsEnabled) { + // name = $t('dashboard.validator.rewards.chart.rewards') + // } else { + // name = getGroupLabel($t, group.id, groups.value) + // } + const newData: RewardChartGroupData = { + bigData: [], + id: group.id, + name, + } + for (let i = 0; i < categoryCount; i++) { + const bigValue = group.data[i] ? new BigNumber(group.data[i]) : new BigNumber('0') + + if (!bigValue.isZero()) { + if (group.property === 'el') { + elSeries.bigData[i] = elSeries.bigData[i].plus(bigValue) + } else { + clSeries.bigData[i] = clSeries.bigData[i].plus(bigValue) + } + } + newData.bigData.push(bigValue) + } + + if (group.property === 'el') { + elSeries.groups.push(newData) + } else { + clSeries.groups.push(newData) + } + }) + + this.mapSeriesData(elSeries, this.unit.pref.Exec) + this.mapSeriesData(clSeries, this.unit.pref.Cons) + + return list + }) + + createRewardChart(series: RewardChartSeries[], categories: number[]) { + if (!this.data || !categories || !series) { + return + } + + const root = document.body + const chartDefaultColor = getComputedStyle(root).getPropertyValue('--chart-default').trim() + + return { + dataZoom: { + dataBackground: { + areaStyle: { color: this.colors().background }, + lineStyle: { color: this.colors().background }, + }, + left: '3%', // Match this with the grid's left margin + right: '3%', // Match this with the grid's right margin + end: 100, + start: 60, + type: 'slider', + }, + grid: { + bottom: 80, + containLabel: true, + left: '5%', + right: '5%', + top: 20, + }, + legend: { + bottom: 50, + orient: 'horizontal', + textStyle: { + // color: this.colors().label, + fontSize: fontSize, + //fontWeight: fontWeightMedium, + }, + type: 'scroll', + }, + series: series, + textStyle: { + // color: this.colors().label, + //fontFamily, + fontSize: fontSize, + //fontWeight: fontWeightLight, + }, + tooltip: { + borderColor: this.colors().background, + formatter: (params) => { + if (Array.isArray(params)) { + console.log('params', params) + const startEpoch = parseInt(params[0].name) + return ( + getTooltipHeader( + epochToTimestamp(this.data.chainNetwork().id, startEpoch) / 1000, + this.data.chainNetwork().id, + Aggregation.Hourly, + (val) => formatTsToDateTime(val, getLocale()) + ) + + '
' + + params.map((d) => ` ${d.seriesName}: ${(d.value as number).toFixed(5)} ETH `).join('
') + // todo gnosis + ) + } + }, + order: 'seriesAsc', + confine: true, + padding: 0, + trigger: 'axis', + triggerOn: 'click', + }, + color: [chartDefaultColor, '#ff835c', '#e4a354', '#2b908f', '#f45b5b', '#91e8e1'], + xAxis: { + axisLabel: { + fontSize: fontSize, + //fontWeight: fontWeightMedium, + formatter: (value: number) => { + const date = formatTsToAbsolute(epochToTimestamp(this.data.chainNetwork().id, value) / 1000, getLocale(), false) + if (date === undefined) { + return '' + } + + return `${date}\nEpoch ${value}` + }, + lineHeight: 20, + }, + data: categories, + type: 'category', + }, + yAxis: { + axisLabel: { + fontSize: fontSize, + //fontWeight: fontWeightMedium, + formatter: this.valueFormatter, + padding: [0, 10, 0, 0], + }, + silent: true, + // splitLine: { lineStyle: { color: this.colors().line } }, + type: 'value', + }, + } as EChartsOption + } +} + +interface RewardChartGroupData { + bigData: BigNumber[] + id: number + name: string +} + +interface RewardChartSeries extends ChartSeries { + barMaxWidth: number + bigData: BigNumber[] + color: string + formatedData: ExtendedLabel[] + groups: RewardChartGroupData[] + name: string + stack: 'x' + type: 'bar' +} + +export type ExtendedLabel = { + fullLabel?: string + label: NumberOrString +} +export type NumberOrString = number | string diff --git a/src/app/components/dashboard/reward-chart/reward-chart.module.ts b/src/app/components/dashboard/reward-chart/reward-chart.module.ts new file mode 100644 index 00000000..8de5acfb --- /dev/null +++ b/src/app/components/dashboard/reward-chart/reward-chart.module.ts @@ -0,0 +1,12 @@ +import { NgModule } from '@angular/core' +import { CommonModule } from '@angular/common' +import { NgxEchartsModule } from 'ngx-echarts' +import { IonicModule } from '@ionic/angular' +import { RewardChartComponent } from './reward-chart.component' + +@NgModule({ + imports: [CommonModule, NgxEchartsModule, IonicModule], + declarations: [RewardChartComponent], + exports: [RewardChartComponent], +}) +export class RewardChartModule {} diff --git a/src/app/components/dashboard/success-fail-view/success-fail-view.component.html b/src/app/components/dashboard/success-fail-view/success-fail-view.component.html new file mode 100644 index 00000000..ef094909 --- /dev/null +++ b/src/app/components/dashboard/success-fail-view/success-fail-view.component.html @@ -0,0 +1,12 @@ + + + {{ name }} + + + + {{ this.data.success }} / + {{ this.data.failed }} + + {{ this.percent() | number: '1.0-2' }}% + + diff --git a/src/app/components/dashboard/success-fail-view/success-fail-view.component.scss b/src/app/components/dashboard/success-fail-view/success-fail-view.component.scss new file mode 100644 index 00000000..89287885 --- /dev/null +++ b/src/app/components/dashboard/success-fail-view/success-fail-view.component.scss @@ -0,0 +1,50 @@ +/** + * Copyright (C) 2024 bitfly explorer GmbH + * + * This file is part of Beaconchain Dashboard. + * + * Beaconchain Dashboard is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Beaconchain Dashboard is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Beaconchain Dashboard. If not, see . + */ + +@use '../../../../theme/variables.scss'; + +.ok-proposals { + color: var(--ion-color-success); +} + +.err-proposals { + color: var(--ion-color-danger); +} + +ion-item { + // max-width: var(--ion-item-max-width); + + // margin: auto; + margin: var(--edge-padding); +} + +.value { + text-align: end; + font-weight: bold !important; + font-size: 1.1em !important; +} + +.stat-title { + opacity: var(--default-secondary-transparency); + font-weight: var(--smaller-label-weight); +} + +ion-item ion-label { + margin-right: 0px; // fixes ios margin at the right side +} diff --git a/src/app/components/dashboard/success-fail-view/success-fail-view.component.ts b/src/app/components/dashboard/success-fail-view/success-fail-view.component.ts new file mode 100644 index 00000000..6d4c7bd8 --- /dev/null +++ b/src/app/components/dashboard/success-fail-view/success-fail-view.component.ts @@ -0,0 +1,49 @@ +import { CommonModule } from '@angular/common' +import { Component, computed, Input, WritableSignal } from '@angular/core' +import { IonLabel, IonItem } from '@ionic/angular/standalone' +import { PipesModule } from '@pipes/pipes.module' +import { StorageService } from '@services/storage.service' + +@Component({ + selector: 'app-success-fail-view', + imports: [IonItem, IonLabel, CommonModule, PipesModule], + templateUrl: './success-fail-view.component.html', + styleUrl: './success-fail-view.component.scss', +}) +export class SuccessFailViewComponent { + @Input() name: string + @Input() data: SuccessFailData + @Input() mode: WritableSignal + + constructor(private storage: StorageService) {} + + percent = computed(() => { + const total = this.data.success + this.data.failed + if (total === 0) return 0 + return (this.data.success / total) * 100 + }) + + switchMode() { + if (this.mode() === 'absolute') { + this.mode.set('percentage') + } else { + this.mode.set('absolute') + } + setSuccessFailMode(this.storage, this.mode()) + } +} + +export async function getSuccessFailMode(storage: StorageService): Promise { + return (await storage.getBooleanSetting('success_fail_mode_perc', true)) ? 'percentage' : 'absolute' +} + +export async function setSuccessFailMode(storage: StorageService, mode: Mode): Promise { + await storage.setBooleanSetting('success_fail_mode_perc', mode === 'percentage') +} + +export interface SuccessFailData { + success: number + failed: number +} + +export type Mode = 'absolute' | 'percentage' diff --git a/src/app/components/dashboard/summary-chart/summary-chart.component.html b/src/app/components/dashboard/summary-chart/summary-chart.component.html new file mode 100644 index 00000000..3c4aea79 --- /dev/null +++ b/src/app/components/dashboard/summary-chart/summary-chart.component.html @@ -0,0 +1,24 @@ +
+
+
+ + + {{ chip.name }} + +
+ +
+ +
+
diff --git a/src/app/components/dashboard/summary-chart/summary-chart.component.scss b/src/app/components/dashboard/summary-chart/summary-chart.component.scss new file mode 100644 index 00000000..7446af32 --- /dev/null +++ b/src/app/components/dashboard/summary-chart/summary-chart.component.scss @@ -0,0 +1,27 @@ +/** + * Copyright (C) 2024 bitfly explorer GmbH + * + * This file is part of Beaconchain Dashboard. + * + * Beaconchain Dashboard is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Beaconchain Dashboard is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Beaconchain Dashboard. If not, see . + */ + +@use '../../../../theme/variables.scss'; + +.custom-chip-disabled { + opacity: 0.4; +} +ion-chip { + height: 18px; +} diff --git a/src/app/components/dashboard/summary-chart/summary-chart.component.ts b/src/app/components/dashboard/summary-chart/summary-chart.component.ts new file mode 100644 index 00000000..b02291c1 --- /dev/null +++ b/src/app/components/dashboard/summary-chart/summary-chart.component.ts @@ -0,0 +1,695 @@ +import { Component, computed, Input, OnInit } from '@angular/core' +import { Toast } from '@capacitor/toast' +import { OverviewData2, OverviewProvider } from '@controllers/OverviewController' +import { ChartData } from '@requests/types/common' +import { Aggregation, V2DashboardSummaryChart } from '@requests/v2-dashboard' +import { AlertService } from '@services/alert.service' +import { getChartTextColor, getChartTooltipBackgroundColor, getSummaryChartGroupColors } from '@utils/ColorUtils' +import { MerchantUtils } from '@utils/MerchantUtils' +import { + formatGoTimestamp, + formatTsToDateTime, + formatTsToTime, + getEndTs, + getLocale, + ONE_DAY, + ONE_HOUR, + ONE_WEEK, + slotToSecondsTimestamp, + timestampToEpoch, +} from '@utils/TimeUtils' +import { get } from 'lodash-es' +import { ECharts, EChartsOption } from 'echarts' +import { StorageService } from '@services/storage.service' + +const currentZoom = { + end: 100, + start: 80, +} +const MAX_DATA_POINTS = 199 + +const bounceTime = 450 + +@Component({ + selector: 'app-summary-chart', + templateUrl: './summary-chart.component.html', + styleUrl: './summary-chart.component.scss', + standalone: false, +}) +export class SummaryChartComponent implements OnInit { + @Input() data: OverviewData2 + + chips: ChipsOptions[] = null + + timeFrames: { from?: number; to?: number; lastUpdate?: number } = {} + + chartInstance: ECharts = null + + selectedAggregation: Aggregation = Aggregation.Hourly + + constructor( + private merchant: MerchantUtils, + private alert: AlertService, + private storage: StorageService, + private overviewProvider: OverviewProvider + ) {} + + ngOnInit() { + this.merchant.getUserInfo(false).then(() => { + this.initChips() + }) + } + + onChartInit(ec: ECharts) { + this.chartInstance = ec + this.initLoad() + } + + async initLoad() { + console.log('INIT LOAD') + this.validateDataZoom(true, true, true) + const options = Object.assign({}, this.data.summaryChartOptions()) + if (options) { + options.aggregation = await this.storage.getDashboardSummaryAggregation() + options.force = true + options.endTime = this.timeFrames.to + options.startTime = this.timeFrames.from + } else { + console.warn('No options found') + } + + await this.overviewProvider.setSummaryChartOptions(this.data, options) + //this.validateDataZoom(undefined, true, true) + // this.overviewProvider.setSummaryChartOptions(this.data, { + // aggregation: await this.storage.getDashboardSummaryAggregation(), + // startTime: null, + // endTime: null, + // force: false, + // } as SummaryChartOptions) + } + + initChips() { + const temp = [ + { + name: 'Epoch', + value: Aggregation.Epoch, + disabled: false, + }, + { + name: 'Hourly', + value: Aggregation.Hourly, + disabled: false, + }, + { + name: 'Daily', + value: Aggregation.Daily, + disabled: false, + }, + { + name: 'Weekly', + value: Aggregation.Weekly, + disabled: false, + }, + ] + + this.chips = temp.map((item) => { + item.disabled = this.merchant.userAllowedChartAggregations().filter((a) => a === item.value).length === 0 + + // handle special case where user has select a premium aggregator but does not extend premium after it expired + // reset to default (hourly) + if (item.value === this.data.summaryChartOptions().aggregation && item.disabled) { + this.changeAggregation(temp[1]) // hourly + } + + return item + }) + } + + changeAggregation(chip: ChipsOptions) { + if (chip.disabled) { + Toast.show({ + text: 'This feature is available with a premium subscription', + duration: 'short', + }) + return + } + + this.storage.setDashboardSummaryAggregation(chip.value) + + // const tsData = this.getTimestamps(chip.value, true) + // if (!this.data) { + // return + // } + + const options = Object.assign({}, this.data.summaryChartOptions()) + if (options) { + options.aggregation = chip.value + options.force = true + } else { + console.warn('No options found') + } + this.data.summaryChartOptionsInternal.set(options) + this.changeZoom(true) + + // + // if (options) { + // options.aggregation = chip.value + // options.force = true + // options.endTime = Math.floor(Date.now() / 1000) // tsData.newTimeFrames.to + // options.startTime = null //tsData.newTimeFrames.from + // } else { + // console.warn('No options found') + // } + + // await this.overviewProvider.setSummaryChartOptions(this.data, options) + //this.validateDataZoom(undefined, true, true) + + //this.data. = chip.value + } + + summaryChart = computed(() => { + const temp = this.createSummaryChart(this.data.summaryChart(), this.categories()) + //this.validateDataZoom(undefined, undefined, true) + //this.initZoom() + return temp + }) + + categories = computed(() => { + if (!this.data || !this.data.latestState() || !this.data.summaryChartOptions()) { + return [] + } + // charts have 5 slots delay + if (this.data.latestState().state.current_slot <= 5 || !this.data.summaryChartOptions().aggregation) { + return [] + } + const maxSeconds = this.data.overviewData().chart_history_seconds?.[this.data.summaryChartOptions().aggregation] ?? 0 + if (!maxSeconds) { + return [] + } + const list: number[] = [] + let latestTs = slotToSecondsTimestamp(this.data.chainNetwork().id, this.data.latestState().state.current_slot - 5) || 0 + console.log('latestTs', latestTs, this.data.chainNetwork().id, this.data.latestState()) + + let step = 0 + switch (this.data.summaryChartOptions().aggregation) { + case Aggregation.Epoch: + step = this.data.chainNetwork().slotsTime * this.data.chainNetwork().slotPerEpoch + break + case Aggregation.Daily: + step = ONE_DAY + break + case Aggregation.Hourly: + step = ONE_HOUR + break + case Aggregation.Weekly: + step = ONE_WEEK + break + } + if (!step) { + return [] + } + const minTs = Math.max(slotToSecondsTimestamp(this.data.chainNetwork().id, 0) || 0, latestTs - maxSeconds) + while (latestTs >= minTs) { + list.splice(0, 0, latestTs) + + latestTs -= step + } + console.log('latestTS', latestTs, maxSeconds, minTs) + + return list + }) + + rawDataToSeries(data: ChartData) { + if (!data || !data.series) { + return [] + } + const newSeries: SeriesObject[] = [] + data.series.forEach((element) => { + let name: string + if (element.id === V2DashboardSummaryChart.SUMMARY_CHART_GROUP_TOTAL) { + name = 'Total' + } else if (element.id === V2DashboardSummaryChart.SUMMARY_CHART_GROUP_NETWORK_AVERAGE) { + name = 'Network Average' + } + //else { + // name = getGroupLabel($t, element.id, groups.value, allGroups) + // } + const newObj: SeriesObject = { + data: element.data, + type: 'line', + smooth: false, + symbol: 'none', + name, + } + newSeries.push(newObj) + }) + return newSeries + } + + createSummaryChart(data: ChartData, categories: number[]) { + // if (!data || !categories || data.series.length < 1) { + // return + // } + + const root = document.body + const chartDefaultColor = getComputedStyle(root).getPropertyValue('--chart-default').trim() + + const newSeries: SeriesObject[] = this.rawDataToSeries(data) + const dataCategories = data ? (data.categories ?? []) : [] + + return { + grid: { + containLabel: true, + top: 0, + left: '3%', + right: '3%', + //bottom: 35, + }, + xAxis: [ + { + // xAxis of the chart + type: 'category', + data: dataCategories, + boundaryGap: false, + axisLabel: { + fontSize: fontSize, + lineHeight: 20, + formatter: (value: string) => { + return formatTimestamp(value, this.data.chainNetwork().id, this.data.summaryChartOptions().aggregation) + }, + }, + }, + { + // xAxis of the time frame selection + type: 'category', + data: categories, + show: false, + boundaryGap: false, + }, + ], + series: newSeries, + yAxis: { + nameLocation: 'center', + nameTextStyle: { + padding: [0, 0, 30, 0], + }, + type: 'value', + minInterval: 10, + maxInterval: 20, + min: (range: { min: number }) => (range.min >= 0 ? Math.max(0, 10 * Math.ceil(range.min / 10 - 1)) : 10 * Math.ceil(range.min / 10 - 1)), + silent: true, + axisLabel: { + formatter: '{value} %', + fontSize: fontSize, + }, + splitLine: { + lineStyle: { + //color: colors.value.label + }, + }, + }, + textStyle: { + //fontFamily, + fontSize: fontSize, + //fontWeight: fontWeightLight, + //color: colors.value.label + }, + color: [chartDefaultColor, '#ff835c', '#e4a354', '#2b908f', '#f45b5b', '#91e8e1'], + legend: { + type: 'scroll', + orient: 'horizontal', + bottom: 40, + textStyle: { + //color: colors.value.label, + fontSize: fontSize, + //fontWeight: fontWeightMedium + }, + }, + tooltip: { + order: 'seriesAsc', + trigger: 'axis', + padding: 3, + confine: true, + formatter: (params: { color: string; seriesName: string; value: number; axisValue: string }[]) => { + if (Array.isArray(params)) { + const ts = parseInt(params[0].axisValue) + return ( + getTooltipHeader(ts, this.data.chainNetwork().id, this.data.summaryChartOptions().aggregation, (val) => + formatTsToDateTime(val, getLocale()) + ) + + '
' + + params.map((d) => ` ${d.seriesName}: ${d.value.toFixed(2)} % `).join('
') + ) + } + }, + }, + dataZoom: { + type: 'slider', + ...currentZoom, + labelFormatter: (_value: number, valueStr: string) => { + return this.formatToDateOrEpoch(valueStr) + }, + xAxisIndex: [1], + bottom: 10, + left: '3%', // Match this with the grid's left margin + right: '3%', // Match this with the grid's right margin + dataBackground: { + areaStyle: { color: this.colors().background }, + lineStyle: { color: this.colors().background }, + }, + }, + } as unknown as EChartsOption + } + + colors = computed(() => { + return { + background: getChartTooltipBackgroundColor(), + groups: getSummaryChartGroupColors('light'), // todo + label: getChartTextColor(), + } + }) + + async ionViewWillEnter() { + if (this.data.id != (await this.storage.getDashboardID())) { + this.changeZoom(true) + return + } + } + + formatToDateOrEpoch = (value: string) => { + if (this.data.summaryChartOptions().aggregation === 'epoch') { + return formatTSToEpoch(value + '', this.data.chainNetwork().id) + } + return formatTSToDate(value + '') + } + + async loadData(startTime: number, endTime: number) { + if (!this.data || (!startTime && !endTime)) { + return + } + + const loading = await this.alert.presentLoading('Loading...') + loading.present() + + console.log('load data', startTime, endTime) + try { + const options = Object.assign({}, this.data.summaryChartOptions()) + options.startTime = startTime + options.endTime = endTime + options.force = true + await this.overviewProvider.setSummaryChartOptions(this.data, options) + loading.dismiss() + } catch (e) { + loading.dismiss() + console.log('err', e) + // TODO: Maybe we want to show an error here (either a toast or inline centred in the chart space) + } + } + + private preventOnZoomHandling = false + onDataZoom() { + if (this.preventOnZoomHandling) { + this.preventOnZoomHandling = false + return + } + //this.updateTimestamp() + this.validateDataZoom() + } + + // get the current dataZoom settings in the chart + getDataZoomValues = () => { + const chartOptions = this.chartInstance.getOption() + const start: number = get(chartOptions, 'dataZoom[0].start', 80) as number + const end: number = get(chartOptions, 'dataZoom[0].end', 100) as number + return { + end, + start, + } + } + + // get the from to values for the selected zoom settings + getZoomTimestamps = () => { + if (!this.data.summaryChartOptions()) return undefined + const max = this.categories().length - 1 + if (max <= 0) { + return + } + const zoomValues = this.getDataZoomValues() + const toIndex = Math.floor((max / 100) * zoomValues.end) + const fromIndex = Math.floor((max / 100) * zoomValues.start) + return { + ...zoomValues, + fromIndex, + fromTs: this.categories()[fromIndex], + toIndex, + toTs: this.categories()[toIndex], + } + } + + maxDataPoints(aggregation: Aggregation) { + switch (aggregation) { + case Aggregation.Epoch: + return Math.floor( + this.merchant.userInfo().premium_perks.chart_history_seconds.epoch / + (this.data.chainNetwork().slotsTime * this.data.chainNetwork().slotPerEpoch) + ) + case Aggregation.Daily: + return Math.floor(this.merchant.userInfo().premium_perks.chart_history_seconds.daily / ONE_DAY) + case Aggregation.Hourly: + return Math.floor(this.merchant.userInfo().premium_perks.chart_history_seconds.hourly / ONE_HOUR) + case Aggregation.Weekly: + return Math.floor(this.merchant.userInfo().premium_perks.chart_history_seconds.weekly / ONE_WEEK) + } + return 199 + } + + getDefaultTargetPoints(aggregation: Aggregation) { + switch (aggregation) { + case Aggregation.Epoch: + return 12 + case Aggregation.Daily: + return 7 + case Aggregation.Weekly: + return 8 + } + return 6 + } + + getTimestamps(aggregation: Aggregation, categoryChanged: boolean) { + if (!this.chartInstance) { + return + } + const timestamps = this.getZoomTimestamps() + if (!timestamps) { + return + } + + const firstTime = categoryChanged //!this.data.summaryChartOptions.value.endTime + + const max = this.categories().length - 1 + + const useDefault = categoryChanged + let dataPointsChanged = false + if (useDefault) { + dataPointsChanged = true + let targetPoints = this.getDefaultTargetPoints(aggregation) + // for dashboards with a large amount of time frames we show at least 3% + targetPoints = Math.max(targetPoints, Math.ceil(max * 0.03)) + timestamps.toIndex = firstTime ? max : Math.max(Math.ceil((max / 100) * timestamps.end), targetPoints) + timestamps.fromIndex = timestamps.toIndex - targetPoints + console.log('fresh timestamps', aggregation, timestamps) + } else if (timestamps.toIndex - timestamps.fromIndex > MAX_DATA_POINTS) { + console.log('adjusting zoom', timestamps, currentZoom) + dataPointsChanged = true + if (timestamps.start !== currentZoom.start) { + timestamps.toIndex = Math.min(timestamps.fromIndex + MAX_DATA_POINTS, max) + } else { + timestamps.fromIndex = Math.max(0, timestamps.toIndex - MAX_DATA_POINTS) + } + } else { + let minDataPoints = 3 + if (aggregation === 'epoch') { + minDataPoints = 6 + } + if (timestamps.toIndex - timestamps.fromIndex < minDataPoints) { + dataPointsChanged = true + if (timestamps.start !== currentZoom.start) { + timestamps.toIndex = Math.min(timestamps.fromIndex + minDataPoints, max) + timestamps.fromIndex = timestamps.toIndex - minDataPoints + } else { + timestamps.fromIndex = Math.max(timestamps.toIndex - minDataPoints, 0) + timestamps.toIndex = timestamps.fromIndex + minDataPoints + } + } + } + + if (dataPointsChanged) { + timestamps.end = (timestamps.toIndex * 100) / max + timestamps.toTs = this.categories()[timestamps.toIndex] + timestamps.start = (timestamps.fromIndex * 100) / max + timestamps.fromTs = this.categories()[timestamps.fromIndex] + } + + let fromTs: number | undefined = timestamps.fromTs + let toTs: number | undefined = timestamps.toTs + const bufferSteps = aggregation === Aggregation.Epoch ? 0 : 5 + // if we are on the far left/right we omit the from/to timestamp + // to prevent webservice errors if we get slight over the limit + // when we omit one of the time stamps the backend will use the max secons of the dashboard settings + if (timestamps.fromIndex <= bufferSteps) { + fromTs = undefined + } else if (timestamps.toIndex >= max - bufferSteps) { + toTs = undefined + } + const newTimeFrames = { + from: fromTs, + to: toTs, + lastUpdate: Date.now(), + } + + return { + timestamps: timestamps, + newTimeFrames: newTimeFrames, + } + } + + // validate and adjust zoom settings + async validateDataZoom(instant?: boolean, categoryChanged?: boolean, doNotLoad: boolean = false) { + const { timestamps, newTimeFrames } = this.getTimestamps(this.data.summaryChartOptions().aggregation, categoryChanged) + + // when the timeframes of the slider change we bounce the new timeframe for the chart + if (this.data.summaryChartOptions().endTime !== newTimeFrames.to || this.data.summaryChartOptions().startTime !== newTimeFrames.from) { + if (instant) { + this.timeFrames = newTimeFrames + if (!doNotLoad) { + if (this.timeFrames.lastUpdate + bounceTime <= Date.now()) { + await this.loadData(this.timeFrames.from, this.timeFrames.to) + console.log('CHART DATA UPDATE', newTimeFrames) + } + } + } else { + this.timeFrames = newTimeFrames + if (!doNotLoad) { + await debounce(() => { + if (this.timeFrames.lastUpdate + bounceTime <= Date.now()) { + console.log('CHART DATA UPDATE', newTimeFrames) + return this.loadData(this.timeFrames.from, this.timeFrames.to) + } + }, bounceTime) + } + } + } + + // if we had to fix the slider ranges we need to update the zoom settings + if (timestamps.start !== currentZoom.start || timestamps.end !== currentZoom.end) { + currentZoom.end = timestamps.end + currentZoom.start = timestamps.start + this.changeZoom() + } + } + + changeZoom(triggerZoomHandling = false) { + if (!triggerZoomHandling) { + this.preventOnZoomHandling = true + } + + this.chartInstance.setOption({ + dataZoom: { + ...((get(this.chartInstance, 'xAxis[1]') as object) || {}), + ...currentZoom, + }, + }) + if (get(this.chartInstance.getOption(), 'dataZoom[0]')) { + this.chartInstance.dispatchAction({ + type: 'dataZoom', + ...currentZoom, + }) + } + } + + // initZoom() { + // if (!this.chartInstance) { + // return + // } + // const timestamps = this.getZoomTimestamps() + // if (!timestamps) { + // return + // } + // currentZoom.end = timestamps.end + // currentZoom.start = timestamps.start + // this.chartInstance.setOption({ + // dataZoom: { + // ...(get(this.chartInstance, 'xAxis[1]') || {}), + // ...currentZoom, + // }, + // }) + // if (get(this.chartInstance.getOption(), 'dataZoom[0]')) { + // this.chartInstance.dispatchAction({ + // type: 'dataZoom', + // ...currentZoom, + // }) + // } + // } +} + +function debounce(callback: () => Promise, wait: number): Promise { + return new Promise((resolve) => + setTimeout(async () => { + await callback() + resolve() + }, wait) + ) +} + +export const fontSize = '12px' + +export function getTooltipHeader(ts: number, chainID: number, aggregationValue: string, timeFormat: (number: number) => string): string { + let endDateFormatted = '' + let endEpochFormatted = '' + if (aggregationValue != 'epoch') { + endDateFormatted = ' - ' + timeFormat(getEndTs(aggregationValue, ts)) + endEpochFormatted = ' - ' + timestampToEpoch(chainID, getEndTs(aggregationValue, ts) * 1000) + } + return ( + '' + + timeFormat(ts) + + endDateFormatted + + '
Epoch ' + + timestampToEpoch(chainID, ts * 1000) + + endEpochFormatted + + '
' + ) +} + +export function formatTSToDate(value: string) { + return formatGoTimestamp(Number(value), undefined, 'absolute', 'narrow', getLocale(), false) +} +export function formatTSToEpoch(value: string, chainID: number) { + return `Epoch ${timestampToEpoch(chainID, parseInt(value) * 1000)}` +} + +export function formatTimestamp(value: string, chainID: number, aggregationValue: string) { + const date = formatTSToDate(value) + switch (aggregationValue) { + case 'epoch': + return `${date}\n${timestampToEpoch(chainID, parseInt(value) * 1000)}` + case 'hourly': + return `${date}\n${formatTsToTime(Number(value), getLocale())}` + default: + return date + } +} + +interface SeriesObject { + data: number[] + type: string + smooth: boolean + symbol: string + name: string +} + +interface ChipsOptions { + name: string + value: Aggregation + disabled: boolean +} diff --git a/src/app/components/dashboard/summary-chart/summary-chart.module.ts b/src/app/components/dashboard/summary-chart/summary-chart.module.ts new file mode 100644 index 00000000..b1771767 --- /dev/null +++ b/src/app/components/dashboard/summary-chart/summary-chart.module.ts @@ -0,0 +1,12 @@ +import { NgModule } from '@angular/core' +import { CommonModule } from '@angular/common' +import { NgxEchartsModule } from 'ngx-echarts' +import { SummaryChartComponent } from './summary-chart.component' +import { IonicModule } from '@ionic/angular' + +@NgModule({ + imports: [CommonModule, NgxEchartsModule, IonicModule], + declarations: [SummaryChartComponent], + exports: [SummaryChartComponent], +}) +export class SummaryChartModule {} diff --git a/src/app/components/full-page-loading/full-page-loading.component.html b/src/app/components/full-page-loading/full-page-loading.component.html new file mode 100644 index 00000000..dd7aa30c --- /dev/null +++ b/src/app/components/full-page-loading/full-page-loading.component.html @@ -0,0 +1,19 @@ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+ +
diff --git a/src/app/components/full-page-loading/full-page-loading.component.scss b/src/app/components/full-page-loading/full-page-loading.component.scss new file mode 100644 index 00000000..bbc860b4 --- /dev/null +++ b/src/app/components/full-page-loading/full-page-loading.component.scss @@ -0,0 +1,115 @@ +/** + * Copyright (C) 2024 bitfly explorer GmbH + * + * This file is part of Beaconchain Dashboard. + * + * Beaconchain Dashboard is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Beaconchain Dashboard is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Beaconchain Dashboard. If not, see . + */ + +.content { + display: block; + height: 100%; + position: relative; +} + +.container { + background-color: var(--ion-background-color); + height: 100vh; +} + +.center { + width: 100%; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + background-color: var(--ion-background-color); + display: flex; + align-items: center; + justify-content: center; +} + +.lds-grid, +.lds-grid div { + box-sizing: border-box; + opacity: var(--loading-opacity); +} +.lds-grid { + display: inline-block; + position: relative; + width: 40px; + height: 40px; +} +.lds-grid div { + position: absolute; + width: 8px; + height: 8px; + border-radius: 50%; + background: currentColor; + animation: lds-grid 1.2s linear infinite; +} +.lds-grid div:nth-child(1) { + top: 4px; + left: 4px; + animation-delay: 0s; +} +.lds-grid div:nth-child(2) { + top: 4px; + left: 16px; + animation-delay: -0.4s; +} +.lds-grid div:nth-child(3) { + top: 4px; + left: 28px; + animation-delay: -0.8s; +} +.lds-grid div:nth-child(4) { + top: 16px; + left: 4px; + animation-delay: -0.4s; +} +.lds-grid div:nth-child(5) { + top: 16px; + left: 16px; + animation-delay: -0.8s; +} +.lds-grid div:nth-child(6) { + top: 16px; + left: 28px; + animation-delay: -1.2s; +} +.lds-grid div:nth-child(7) { + top: 28px; + left: 4px; + animation-delay: -0.8s; +} +.lds-grid div:nth-child(8) { + top: 28px; + left: 16px; + animation-delay: -1.2s; +} +.lds-grid div:nth-child(9) { + top: 28px; + left: 28px; + animation-delay: -1.6s; +} +@keyframes lds-grid { + 0%, + 100% { + opacity: 1; + } + 50% { + opacity: 0.5; + } +} diff --git a/src/app/components/full-page-loading/full-page-loading.component.spec.ts b/src/app/components/full-page-loading/full-page-loading.component.spec.ts new file mode 100644 index 00000000..93586cca --- /dev/null +++ b/src/app/components/full-page-loading/full-page-loading.component.spec.ts @@ -0,0 +1,94 @@ +/// +import { ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing' +import { FullPageLoadingComponent } from './full-page-loading.component' +import { NoopAnimationsModule } from '@angular/platform-browser/animations' + +describe('FullPageLoadingComponent', () => { + let component: FullPageLoadingComponent + let fixture: ComponentFixture + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [FullPageLoadingComponent, NoopAnimationsModule], + }).compileComponents() + + fixture = TestBed.createComponent(FullPageLoadingComponent) + component = fixture.componentInstance + }) + + it('should not show loading immediately when loading is true and then show it after SKIP_LOADING_IF_FASTER_THAN ms', fakeAsync(() => { + // Instead of calling fixture.detectChanges(), call ngOnChanges() manually + component.loading = true + component.ngOnChanges() // simulate the one-time change + + // Immediately after, reset() was called so showLoading remains false. + expect(component.showLoading).toBe(false) + + // Advance time past SKIP_LOADING_IF_FASTER_THAN (here using 35ms as a buffer). + tick(35) + // The setTimeout callback should now have run and, since loading is still true, + // set showLoading to true (it also calls cdr.detectChanges(), so we don't trigger extra change detection). + expect(component.showLoading).toBe(true) + })) + + it('should skip showing the loading screen if loading becomes false quickly', fakeAsync(() => { + // Start with loading true and call ngOnChanges once. + component.loading = true + component.ngOnChanges() + tick(20) + + // Now simulate that loading becomes false quickly. + component.loading = false + // Call ngOnChanges again to simulate the input change. + component.ngOnChanges() + + // Advance time to flush the pending timeout. + tick(31) + // In the "else" branch of ngOnChanges, loadingDoneStartPreRender() is called, + // which sets showContent to true and ensures showLoading stays false. + expect(component.showLoading).toBe(false) + expect(component.showContent).toBe(true) + + // Because the real animation callbacks aren’t triggered in test mode (using NoopAnimationsModule), + // manually simulate the animation finish. + component.onLoadingAnimationDone() + tick(component.renderWait) + expect(component.fadeInComplete).toBe('done') + })) + + it('should emit fadeInCompleted event after loading animation is done', fakeAsync(() => { + const fadeInSpy = vi.spyOn(component.fadeInCompleted, 'emit') + + // For immediate loading completion, set loading to false and call ngOnChanges. + component.loading = false + component.ngOnChanges() + + tick(31) + // Manually simulate the animation callback. + component.onLoadingAnimationDone() + tick(component.renderWait) + + expect(fadeInSpy).toHaveBeenCalled() + })) + + it('should reset the component state when reset() is called', () => { + // Set some non-default state. + component.showContent = true + component.fadeInComplete = 'done' + component.showLoading = true + + // Call reset(). + component.reset() + + // Verify that state is reset to its initial values. + expect(component.showContent).toBe(false) + expect(component.fadeInComplete).toBe('wait') + expect(component.showLoading).toBe(false) + }) + + it('onLoadingAnimationStart should mark that loading animation has started', () => { + component.onLoadingAnimationStart() + const loadingAnimationStarted = (component as any).loadingAnimationStarted + expect(loadingAnimationStarted).toBe(true) + }) +}) diff --git a/src/app/components/full-page-loading/full-page-loading.component.ts b/src/app/components/full-page-loading/full-page-loading.component.ts new file mode 100644 index 00000000..89ce0a86 --- /dev/null +++ b/src/app/components/full-page-loading/full-page-loading.component.ts @@ -0,0 +1,128 @@ +import { animate, state, style, transition, trigger } from '@angular/animations' +import { CommonModule } from '@angular/common' +import { Component, Input, ChangeDetectorRef, OnChanges, Output, EventEmitter } from '@angular/core' + +const SKIP_LOADING_IF_FASTER_THAN = 30 //ms + +@Component({ + selector: 'app-full-page-loading', + imports: [CommonModule], + standalone: true, + templateUrl: './full-page-loading.component.html', + styleUrls: ['./full-page-loading.component.scss'], + animations: [ + trigger('fadeIn', [ + state('wait', style({ opacity: 0 })), + state('fading', style({ opacity: 1 })), + state('done', style({ opacity: 1 })), + transition('wait => fading', animate('250ms ease-in')), + ]), + trigger('out', [transition(':leave', [style({ opacity: 1 }), animate('0.2s ease-in', style({ opacity: 0 }))])]), + ], +}) +export class FullPageLoadingComponent implements OnChanges { + @Input() fixInfiniteScroll: boolean = false + @Input() loading: boolean // the real loading state + showLoading = false // the fake loading state, is only shown if loading is still true after SKIP_LOADING_IF_FASTER_THAN + + // Wait ms before triggering fade in, this is so view can pre render in opacity state preventing flicker + // some big components like dashboard need more time to render, consider increasing this value on a per component basis + @Input() renderWait: number = 40 + + @Output() fadeInCompleted = new EventEmitter() + + showContent = false + fadeInComplete: 'wait' | 'done' | 'fading' = 'wait' + + private startRenderTime: number + + constructor(private cdr: ChangeDetectorRef) {} + + ngOnChanges() { + if (this.loading) { + //console.log('fpl ngOnChanges loading=true', this.loadingAnimationStarted) + this.reset() + + /* + * We do not immediately show loader but only if after SKIP_LOADING_IF_FASTER_THAN millisecons loading is still true + * The idea is to not show the loading screen if it loads faster than 50ms, for example requests are cached + */ + setTimeout(() => { + if (this.loading) { + // still loading, show loader + this.showLoading = true + this.cdr.detectChanges() + } else { + this.loadingDoneStartPreRender() + this.onLoadingAnimationDone() // just skip to done if all is available from cache, no animation + } + }, SKIP_LOADING_IF_FASTER_THAN) + } else { + this.loadingDoneStartPreRender() + + //console.log('fpl ngOnChanges loading=false', this.loadingAnimationStarted) + + // if loading has not been set to true after 30ms and loading animation has not started, the view probably already has data from cache and can be rendered immediately + // this fixes some views returning an empty screen if loading is initialized with false and loading=true is never set (e.g. cached data) + setTimeout(() => { + if (!this.loading && !this.loadingAnimationStarted) { + //console.log('fpl fix', this.loadingAnimationStarted) + this.onLoadingAnimationDone() + } + }, 30) + } + } + + loadingDoneStartPreRender() { + this.showLoading = false + + // start rendering content (while hidden) + this.showContent = true + this.startRenderTime = Date.now() + } + + /** + * Reset the component to initial state, useful for pull to refresh + */ + reset() { + this.showContent = false + this.fadeInComplete = 'wait' + this.showLoading = false + } + + private loadingAnimationStarted = false + onLoadingAnimationStart() { + this.loadingAnimationStarted = true + } + + // Called after showLoading animation is faded out, we may display the content now after waiting the render wait + onLoadingAnimationDone() { + if (!this.loading) { + // If the time it took to render up to now is bigger than renderWait, display immediately else wait the difference + const diff = Date.now() - this.startRenderTime + + this.mayRenderWait(() => { + this.fadeInComplete = 'done' + this.fadeInCompleted.emit() + this.cdr.detectChanges() + }, diff) + } + } + + /** + * + * @param callback Execute immediately or wait for render depending on when render started + * and if it is past the renderWait time + * @param diff Difference between now and the start of the render + */ + mayRenderWait(callback: () => void, diff: number) { + if (diff > SKIP_LOADING_IF_FASTER_THAN) { + callback() + } else { + // wait for view to render before fading in + setTimeout(() => { + callback() + }, this.renderWait - diff) + } + } +} diff --git a/src/app/components/full-page-offline/full-page-offline.component.html b/src/app/components/full-page-offline/full-page-offline.component.html new file mode 100644 index 00000000..0600df33 --- /dev/null +++ b/src/app/components/full-page-offline/full-page-offline.component.html @@ -0,0 +1,18 @@ +
+
+
+
+ +
+
+

No Connection

+ Please check your internet connection. +
+ Retry +
+
+
+ +
+ +
diff --git a/src/app/components/full-page-offline/full-page-offline.component.scss b/src/app/components/full-page-offline/full-page-offline.component.scss new file mode 100644 index 00000000..0b84cea3 --- /dev/null +++ b/src/app/components/full-page-offline/full-page-offline.component.scss @@ -0,0 +1,55 @@ +/** + * Copyright (C) 2024 bitfly explorer GmbH + * + * This file is part of Beaconchain Dashboard. + * + * Beaconchain Dashboard is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Beaconchain Dashboard is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Beaconchain Dashboard. If not, see . + */ + +.content { + display: block; + height: 100%; + position: relative; +} + +.container { + background-color: var(--ion-background-color); + height: 100vh; +} + +.center { + width: 100%; + // display: flex; + // justify-content: center; + // text-align: center; + //padding-top: 42.5vh; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + background-color: var(--ion-background-color); + display: flex; + align-items: center; + justify-content: center; +} + +ion-icon { + font-size: 4rem; +} + +.link { + color: var(--ion-color-primary); + font-weight: bold; + font-size: var(--smaller-info-size); +} diff --git a/src/app/components/full-page-offline/full-page-offline.component.ts b/src/app/components/full-page-offline/full-page-offline.component.ts new file mode 100644 index 00000000..00a0a60d --- /dev/null +++ b/src/app/components/full-page-offline/full-page-offline.component.ts @@ -0,0 +1,27 @@ +import { CommonModule } from '@angular/common' +import { Component, EventEmitter, Input, Output } from '@angular/core' +import { IonicModule } from '@ionic/angular' + +const MAX_WAIT_BEFORE_RETRY = 90 * 1000 // ms + +@Component({ + selector: 'app-full-page-offline', + imports: [IonicModule, CommonModule], + standalone: true, + templateUrl: './full-page-offline.component.html', + styleUrl: './full-page-offline.component.scss', +}) +export class FullPageOfflineComponent { + @Input() online: boolean + @Input() fixInfiniteScroll: boolean = false + @Output() retry = new EventEmitter() + + private lastRetryClick = new Date().getTime() + private waitBeforeRetry = 500 // ms + onRetryClick() { + if (new Date().getTime() - this.lastRetryClick < this.waitBeforeRetry) return + this.waitBeforeRetry *= 6 + if (this.waitBeforeRetry > MAX_WAIT_BEFORE_RETRY) this.waitBeforeRetry = MAX_WAIT_BEFORE_RETRY + this.retry.emit() + } +} diff --git a/src/app/components/help/help.component.html b/src/app/components/help/help.component.html index baba21c9..93ab60d3 100644 --- a/src/app/components/help/help.component.html +++ b/src/app/components/help/help.component.html @@ -1,5 +1,5 @@ + + + + + + + + + +
+
+ +
+
diff --git a/src/app/components/slotviz-widget/slotviz-widget.component.scss b/src/app/components/slotviz-widget/slotviz-widget.component.scss new file mode 100644 index 00000000..7c6715f3 --- /dev/null +++ b/src/app/components/slotviz-widget/slotviz-widget.component.scss @@ -0,0 +1,71 @@ +/** + * Copyright (C) 2025 bitfly explorer GmbH + * + * This file is part of Beaconchain Dashboard. + * + * Beaconchain Dashboard is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Beaconchain Dashboard is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Beaconchain Dashboard. If not, see . + */ + +@use '../../../theme/variables.scss'; + +.inner { + padding-top: 5px; + padding-bottom: 5px; +} + +.background { + background-color: var(--ion-toolbar-background); +} + +ion-item { + --background-color: var(--ion-toolbar-background) !important; + --background: var(--ion-toolbar-background) !important; +} + +ion-label { + color: var(--x-toolbar-title-color) !important; +} +ion-icon { + color: var(--x-toolbar-title-color) !important; + + margin: 8px 0px; +} + +.unknown { + opacity: 0.5; + animation: var(--blink-animation); +} + +.danger { + opacity: 0.9; + color: var(--ion-color-danger) !important; +} + +.warning { + opacity: 0.9; + color: var(--ion-color-warning) !important; +} + +.success { + opacity: 0.9; + color: var(--ion-color-success) !important; +} + +#previous { + font-size: 1em; +} + +.next { + font-size: 1.5em; +} diff --git a/src/app/components/slotviz-widget/slotviz-widget.component.ts b/src/app/components/slotviz-widget/slotviz-widget.component.ts new file mode 100644 index 00000000..d5d3fa7c --- /dev/null +++ b/src/app/components/slotviz-widget/slotviz-widget.component.ts @@ -0,0 +1,147 @@ +import { CommonModule } from '@angular/common' +import { Component, computed, effect, Input, signal, WritableSignal } from '@angular/core' +import { SlotVizProvider } from '@controllers/SlotVizController' +import { IonicModule, ModalController } from '@ionic/angular' +import { PipesModule } from '@pipes/pipes.module' +import { trigger, state, style, transition, animate } from '@angular/animations' +import { dashboardID } from '@requests/v2-dashboard' +import { SlotvizComponent } from '@pages/slotviz/slotviz.component' + +@Component({ + selector: 'app-slotviz-widget', + imports: [CommonModule, IonicModule, PipesModule], + templateUrl: './slotviz-widget.component.html', + styleUrls: ['./slotviz-widget.component.scss'], + animations: [ + trigger('iconAnimation', [ + state( + 'initial', + style({ + transform: 'translateX(0)', + fontSize: '1.5em', + opacity: 0, + }) + ), + state( + 'moved', + style({ + transform: 'translateX(-25px)', + fontSize: '1em', + opacity: 0.7, + }) + ), + transition('initial => moved', [style({ opacity: 1 }), animate('0.3s ease')]), + ]), + trigger('newIconAnimation', [ + transition(':enter', [style({ opacity: 0, transform: 'scale(0.5)' }), animate('0.2s ease', style({ opacity: 1, transform: 'scale(1)' }))]), + ]), + ], +}) +export class SlotvizWidgetComponent { + @Input() dashboardID: dashboardID + @Input() groupID: number + + nextIconState: 'initial' | 'moved' = 'initial' + previousIconHidden = false + movedIcon: WritableSignal = signal(null) + isNewIconVisible = false + + constructor( + public slotViz: SlotVizProvider, + private modalCtrl: ModalController + ) { + effect(() => { + this.slotViz.nextDutyTs() + this.triggerAnimation() + }) + } + + ngOnInit() { + this.slotViz.start(this.dashboardID, this.groupID) + } + + ngOnChange() { + this.slotViz.changeDashboard(this.dashboardID) + this.slotViz.changeGroupID(this.groupID) + } + + previousIcon = computed(() => { + const prev = this.slotViz.previousDuty() + if (prev == null) return 'help-outline' + if (prev.proposal) return 'cube-outline' + if (prev.sync) return 'sync-outline' + if (prev.attestations) return 'document-text-outline' + + return 'help-outline' + }) + + previousIconColor = computed(() => { + const prev = this.slotViz.previousDuty() + if (prev == null) return 'unknown' + if (prev.attestations) { + if ( + prev.attestations.failed && + prev.attestations.success && + prev.attestations.failed.total_count > 0 && + prev.attestations.success.total_count > 0 + ) + return 'warning' + if (prev.attestations.failed && prev.attestations.failed.total_count > 0) return 'danger' + if (prev.attestations.success && prev.attestations.success.total_count > 0) return 'success' + } else if (prev.proposal) { + if (prev.status == 'missed' || prev.status == 'orphaned') return 'danger' + } else if (prev.sync) { + if (prev.sync.failed && prev.attestations.success && prev.sync.failed.total_count > 0 && prev.attestations.success.total_count > 0) + return 'warning' + if (prev.sync.failed && prev.sync.failed.total_count > 0) return 'danger' + if (prev.attestations.success && prev.sync.success.total_count > 0) return 'success' + } + + return 'unknown' + }) + + nextIcon = computed(() => { + const next = this.slotViz.nextDuty() + if (next == null) return 'help-outline' + if (next.proposal) return 'cube-outline' + if (next.sync) return 'sync-outline' + if (next.attestations) return 'document-text-outline' + + return 'help-outline' + }) + + animationBlocked = false + triggerAnimation() { + if (this.animationBlocked) return + this.animationBlocked = true + + console.log('animation triggered') + this.nextIconState = 'moved' + this.previousIconHidden = true + this.isNewIconVisible = true + + setTimeout(() => { + this.previousIconHidden = false + this.isNewIconVisible = false + this.resetAnimation() + this.animationBlocked = false + }, 300) + } + + resetAnimation() { + this.nextIconState = 'initial' + } + + async openSlotViz() { + const modal = await this.modalCtrl.create({ + component: SlotvizComponent, + componentProps: { + dashboardID: this.dashboardID, + groupID: this.groupID, + }, + }) + modal.present() + + await modal.onWillDismiss() + } +} diff --git a/src/app/components/validator/validator.component.html b/src/app/components/validator/validator.component.html index 3e37e9ab..feb6f611 100644 --- a/src/app/components/validator/validator.component.html +++ b/src/app/components/validator/validator.component.html @@ -1,5 +1,5 @@ -
+
- - {{ data.pubkey | slice : 0 : 5 }} + + {{ validator.public_key | slice: 0 : 7 }}
-
- {{ name }} - {{ balance | mcurrency : 'GWEI' : unit.pref.Cons }} - - - {{ validator.attrEffectiveness && validator.attrEffectiveness != -1 ? 'Eff.:' + validator.attrEffectiveness + '%' : '' }} - | Share: - - {{ validator.share | percent : '1.0-1' }} - , RPL: {{ validator.rplshare | percent : '1.0-1' }} - - - - {{ state }} - Rocketpool {{ validator.rocketpool.node_deposit_balance | mcurrency : 'WEI' : 'ETHER' : false }} - Vacant - Sync - - - +
+ + {{ name }} + +
+ +
+
+ Balance: {{ validator.balance | mcurrency: 'WEI' : unit.pref.Cons }} + Efficiency: {{ efficiency | number: '1.0-2' }}% +
+
+ {{ state }}
- - -
+
diff --git a/src/app/components/validator/validator.component.scss b/src/app/components/validator/validator.component.scss index 75e5aa12..097d5bba 100644 --- a/src/app/components/validator/validator.component.scss +++ b/src/app/components/validator/validator.component.scss @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -18,55 +17,15 @@ * // along with Beaconchain Dashboard. If not, see . */ -@import '../../../theme/variables.scss'; +@use '../../../theme/variables.scss'; -.blockie { - position: absolute; - top: 20px; - left: 22px; - border-radius: 20%; - height: 59px; - width: 56px; - image-rendering: pixelated; -} - -.container { -} - -.pubkey { - top: 83px; - text-align: center; - padding-top: 74px; - width: 66px; - font-size: 0.79rem; -} - -.bookmarked { - color: var(--ion-color-primary); -} - -.inner { +.infi-item-middle-container { + margin-right: 15px; } ion-item { background: var(--ion-card-background); -} - -ion-icon { - position: absolute !important; - top: 2px; - right: 20px; - margin-top: 0px !important; - padding-top: 0px !important; - margin-bottom: 29px; - height: 56px; -} - -.info { - margin-top: 15px; - margin-left: 0px; - margin-right: 45px; - margin-bottom: 15px; + margin: auto; } .balance { @@ -78,11 +37,6 @@ ion-icon { font-weight: bold; } -.smaller-info { - font-size: 0.8rem; - color: var(--ion-text-color-secondary); -} - .online { --color: #ffffff; color: #ffffff; @@ -127,8 +81,44 @@ ion-icon { ion-badge { margin: 0 4px; + + font-size: 0.7rem; +} + +.status-container { + height: 76px; + margin-right: 2px; + margin-left: 0px; } .onlinestate { - margin-right: 4px; + padding-left: 5px; + padding-right: 5px; + padding-bottom: 3px; + padding-top: 5px; + margin: 0; +} + +.labels { + font-size: 0.65rem; + vertical-align: top; + margin-right: 3px; +} + +ion-icon { + font-size: 0.65rem; + color: var(--ion-color-sync-icon-small); + position: absolute; + top: 3px; +} + +.sync-active { + -webkit-animation: spin 6s linear infinite; + -moz-animation: spin 6s linear infinite; + animation: spin 6s linear infinite; +} + +.sync-container { + height: 14px; + display: inline-block; } diff --git a/src/app/components/validator/validator.component.spec.ts b/src/app/components/validator/validator.component.spec.ts deleted file mode 100644 index c9f2f0b8..00000000 --- a/src/app/components/validator/validator.component.spec.ts +++ /dev/null @@ -1,50 +0,0 @@ -/* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) - * // - * // This file is part of Beaconchain Dashboard. - * // - * // Beaconchain Dashboard is free software: you can redistribute it and/or modify - * // it under the terms of the GNU General Public License as published by - * // the Free Software Foundation, either version 3 of the License, or - * // (at your option) any later version. - * // - * // Beaconchain Dashboard is distributed in the hope that it will be useful, - * // but WITHOUT ANY WARRANTY; without even the implied warranty of - * // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * // GNU General Public License for more details. - * // - * // You should have received a copy of the GNU General Public License - * // along with Beaconchain Dashboard. If not, see . - */ - -import { async, ComponentFixture, TestBed } from '@angular/core/testing' -import { IonicModule } from '@ionic/angular' -import { AlertService } from 'src/app/services/alert.service' -import { UnitconvService } from 'src/app/services/unitconv.service' -import { ValidatorUtils } from 'src/app/utils/ValidatorUtils' - -import { ValidatorComponent } from './validator.component' -import { PipesModule } from '../../pipes/pipes.module' - -describe('ValidatorComponent', () => { - let component: ValidatorComponent - let fixture: ComponentFixture - - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [ValidatorComponent], - imports: [IonicModule.forRoot(), PipesModule], - providers: [{ provide: UnitconvService }, { provide: AlertService }, { provide: ValidatorUtils }], - }).compileComponents() - - fixture = TestBed.createComponent(ValidatorComponent) - component = fixture.componentInstance - - fixture.detectChanges() - })) - - it('should create', () => { - expect(component).toBeTruthy() - }) -}) diff --git a/src/app/components/validator/validator.component.ts b/src/app/components/validator/validator.component.ts index 6fe2c1ee..b59b945b 100644 --- a/src/app/components/validator/validator.component.ts +++ b/src/app/components/validator/validator.component.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -18,126 +17,111 @@ * // along with Beaconchain Dashboard. If not, see . */ -import { Component, OnInit, Input } from '@angular/core' -import { ValidatorResponse } from 'src/app/requests/requests' +import { Component, Input } from '@angular/core' import * as blockies from 'ethereum-blockies' -import { ValidatorUtils, getDisplayName, Validator, ValidatorState } from 'src/app/utils/ValidatorUtils' -import { UnitconvService } from '../../services/unitconv.service' -import { AlertService } from 'src/app/services/alert.service' -import BigNumber from 'bignumber.js' -import OverviewController from 'src/app/controllers/OverviewController' +import { getDisplayName, ValidatorState } from '@utils/ValidatorUtils' +import { UnitconvService } from '@services/unitconv.service' +import { MobileValidatorDashboardValidatorsTableRow } from '@requests/types/mobile' +type SyncState = 'none' | 'current' | 'next' @Component({ selector: 'app-validator', templateUrl: './validator.component.html', styleUrls: ['./validator.component.scss'], + standalone: false, }) -export class ValidatorComponent implements OnInit { - fadeIn = 'fade-in' +export class ValidatorComponent { + @Input() validator: MobileValidatorDashboardValidatorsTableRow + @Input() first: boolean + @Input() last: boolean + @Input() selected: boolean - @Input() validator: Validator - - data: ValidatorResponse name: string imgData: string - tagged: boolean - state: string stateCss: string + labels: string + efficiency: number + sync: SyncState = 'none' - balance = null - - overviewController = new OverviewController() - - constructor(private validatorUtils: ValidatorUtils, public unit: UnitconvService, private alerts: AlertService) {} - - async ngOnChanges() { - this.data = this.validator.data - this.balance = this.calculateBalanceShare(this.validator) + constructor(public unit: UnitconvService) {} + ngOnChanges() { this.name = getDisplayName(this.validator) this.imgData = this.getBlockies() - this.tagged = !!(await this.validatorUtils.getValidatorLocal(this.validator.pubkey)) this.state = this.interpretState(this.validator) this.stateCss = this.interpretStateCss(this.validator) + this.labels = this.getLabels(this.validator) + this.efficiency = this.validator.efficiency + this.sync = this.getSyncState(this.validator) } - setInput(validator: Validator) { - this.validator = validator - this.data = validator.data - this.balance = this.calculateBalanceShare(this.validator) - } - - calculateBalanceShare(validator) { - return this.overviewController.sumBigIntBalanceRP([validator], (cur) => new BigNumber(cur.data.balance)) - } - - ngOnInit() { - setTimeout(() => { - this.fadeIn = null - }, 500) - } - - tag(event) { - event.stopPropagation() - this.validatorUtils.convertToValidatorModelAndSaveValidatorLocal(false, this.data) - this.tagged = true - } - - untag(event) { - event.stopPropagation() - - this.alerts.confirmDialog('Remove validator', 'Do you want to remove this validator?', 'Delete', () => { - this.confirmUntag() - }) + private getBlockies() { + // TODO: figure out why the first blockie image is always black + blockies.create({ seed: this.validator.index + '' }).toDataURL() + const dataurl = blockies.create({ seed: this.validator.index + '', size: 8, scale: 7 }).toDataURL() + return dataurl } - private confirmUntag() { - this.validatorUtils.deleteValidatorLocal(this.data, false) - this.tagged = false + getSyncState(item: MobileValidatorDashboardValidatorsTableRow): SyncState { + if (item.is_in_next_sync_committee) { + return 'next' + } + if (item.is_in_sync_committee) { + return 'current' + } + return 'none' } - private getBlockies() { - // TODO: figure out why the first blockie image is always black - blockies.create({ seed: this.data.pubkey }).toDataURL() - const dataurl = blockies.create({ seed: this.data.pubkey, size: 8, scale: 7 }).toDataURL() - return dataurl + getLabels(item: MobileValidatorDashboardValidatorsTableRow) { + if (item.rocket_pool) { + return 'RP' + } + return '' } - interpretState(item: Validator) { - switch (item.state) { - case ValidatorState.ACTIVE: + interpretState(item: MobileValidatorDashboardValidatorsTableRow) { + switch (item.status) { + case ValidatorState.ACTIVE_ONLINE: return 'Active' - case ValidatorState.OFFLINE: + case ValidatorState.ACTIVE_OFFLINE: return 'Offline' case ValidatorState.SLASHED: return 'Slashed' case ValidatorState.EXITED: return 'Exited' - case ValidatorState.WAITING: + case ValidatorState.PENDING: return 'Waiting for Activation' - case ValidatorState.ELIGABLE: + case ValidatorState.DEPOSITED: return 'Waiting for deposit processing' + case ValidatorState.EXITING_ONLINE: + return 'Exiting (Active)' + case ValidatorState.EXITING_OFFLINE: + return 'Exiting (Offline)' + case ValidatorState.SLASHING_ONLINE: + return 'Slashing (Active)' + case ValidatorState.SLASHING_OFFLINE: + return 'Slashing (Offline)' default: return 'Unknown' } } - interpretStateCss(item: Validator) { - switch (item.state) { - case ValidatorState.ACTIVE: + interpretStateCss(item: MobileValidatorDashboardValidatorsTableRow) { + switch (item.status) { + case ValidatorState.ACTIVE_ONLINE || ValidatorState.EXITING_ONLINE || ValidatorState.SLASHING_ONLINE: return 'online' - case ValidatorState.OFFLINE: + case ValidatorState.ACTIVE_OFFLINE || ValidatorState.EXITING_OFFLINE || ValidatorState.SLASHING_OFFLINE: return 'offline' case ValidatorState.SLASHED: return 'slashed' case ValidatorState.EXITED: return 'exited' - case ValidatorState.WAITING: + case ValidatorState.DEPOSITED: return 'waiting' - case ValidatorState.ELIGABLE: + case ValidatorState.PENDING: return 'waiting' default: return '' diff --git a/src/app/components/validator/validator.module.ts b/src/app/components/validator/validator.module.ts index b48fe130..2dcdd9e4 100644 --- a/src/app/components/validator/validator.module.ts +++ b/src/app/components/validator/validator.module.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // diff --git a/src/app/controllers/MachineController.ts b/src/app/controllers/MachineController.ts index bb4bfaa3..d83b8e01 100644 --- a/src/app/controllers/MachineController.ts +++ b/src/app/controllers/MachineController.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -19,14 +18,16 @@ */ import { Options } from 'highcharts' -import { HDD_THRESHOLD, RAM_THRESHOLD, StorageService } from '../services/storage.service' +import { HDD_THRESHOLD, RAM_THRESHOLD, StorageService } from '@services/storage.service' +import { MachineMetricNode, MachineMetricSystem, MachineMetricValidator } from '@requests/types/machine_metrics' +import { environment } from 'src/environments/environment' const OFFLINE_THRESHOLD = 8 * 60 * 1000 export interface MachineChartData { Data: Highcharts.SeriesAreaOptions[] Config: MachineChartConfig - Error: string + Error?: string | undefined } export default class MachineController { @@ -34,7 +35,7 @@ export default class MachineController { selectionTimeFrame = 180 - public addBytesConfig(perS = false) { + public addBytesConfig(perS = false): MachineChartConfig { return { config: { tooltip: { @@ -59,7 +60,7 @@ export default class MachineController { labels: { x: -5, formatter: function () { - return bytes(this.value, true, this.isFirst, 0) + (perS ? '/s' : '') + return bytes(parseInt(this.value.toString()), true, this.isFirst, 0) + (perS ? '/s' : '') }, }, }, @@ -75,14 +76,18 @@ export default class MachineController { color: 'var(--text-color)', fontWeight: 'bold', }, + // @ts-expect-error: noImplicitThis disabled for this line pointFormatter: function () { + // @ts-expect-error: noImplicitThis disabled for this line return '\u25CF ' + this.series.name + ': ' + this.y.toFixed(0) + postFix + '' }, }, yAxis: { labels: { x: -5, + // @ts-expect-error: noImplicitThis disabled for this line formatter: function () { + // @ts-expect-error: noImplicitThis disabled for this line return this.value }, }, @@ -94,33 +99,33 @@ export default class MachineController { public doMemoryCharts(current: ProcessedStats): MachineChartData { const chartData = [] - if (current && current.system) { + if (current && current.system_metrics) { chartData.push({ name: 'Memory: System', color: '#7cb5ec', - data: this.timeAxisChanges(current.system, (value) => { + data: this.timeAxisChanges(current.system_metrics, (value) => { return value.memory_node_bytes_total }), pointWidth: 25, }) } - if (current && current.node) { + if (current && current.node_metrics) { chartData.push({ name: 'Memory: Beaconnode', color: '#Dcb5ec', - data: this.timeAxisChanges(current.node, (value) => { + data: this.timeAxisChanges(current.node_metrics, (value) => { return value.memory_process_bytes }), pointWidth: 25, }) } - if (current && current.validator) { + if (current && current.validator_metrics) { chartData.push({ name: 'Memory: Validator', color: '#3FF5ec', - data: this.timeAxisChanges(current.validator, (value) => { + data: this.timeAxisChanges(current.validator_metrics, (value) => { return value.memory_process_bytes }), pointWidth: 25, @@ -130,26 +135,26 @@ export default class MachineController { return { Data: chartData, Config: this.addBytesConfig(), - } as MachineChartData + } as unknown as MachineChartData } public doCPUCharts(current: ProcessedStats): MachineChartData { - const chartData = [] + const chartData: { name: string; color: string; data: unknown[][]; pointWidth: number }[] = [] - if (!current) return { Data: chartData } as MachineChartData - if (!current.system) return { Error: 'system_missing' } as MachineChartData + if (!current) return { Data: chartData } as unknown as MachineChartData + if (!current.system_metrics) return { Error: 'system_missing' } as MachineChartData const cpuSystemTotal = this.timeAxisChanges( - current.system, + current.system_metrics, (value) => { return value.cpu_node_system_seconds_total }, true ) - if (current && current.validator) { + if (current && current.validator_metrics) { const cpuValidator = this.timeAxisChanges( - current.validator, + current.validator_metrics, (value) => { return value.cpu_process_seconds_total }, @@ -163,9 +168,9 @@ export default class MachineController { }) } - if (current && current.node) { + if (current && current.node_metrics) { const cpuNode = this.timeAxisChanges( - current.node, + current.node_metrics, (value) => { return value.cpu_process_seconds_total }, @@ -202,18 +207,18 @@ export default class MachineController { }, } as Options, }, - } as MachineChartData + } as unknown as MachineChartData } public doSyncCharts(current: ProcessedStats): MachineChartData { const chartData = [] - if (current && current.node) { + if (current && current.node_metrics) { chartData.push({ name: 'Exec Connected', color: '#3335FF', data: this.timeAxisChanges( - current.node, + current.node_metrics, (value) => { return value.sync_eth1_connected ? 1.2 : 0 }, @@ -223,12 +228,12 @@ export default class MachineController { }) } - if (current && current.node) { + if (current && current.node_metrics) { chartData.push({ name: 'Cons Synced', color: '#3FF5ec', data: this.timeAxisChanges( - current.node, + current.node_metrics, (value) => { return value.sync_eth2_synced ? 1.3 : 0 }, @@ -263,11 +268,11 @@ export default class MachineController { }, } as Options, }, - } as MachineChartData + } as unknown as MachineChartData } isBuggyPrysmVersion(data: ProcessedStats): boolean { - return data.client == 'prysm' && (!data.system || data.system.length <= 2 || data.system[0].cpu_cores == 0) + return data.client == 'prysm' && (!data.system_metrics || data.system_metrics.length <= 2 || data.system_metrics[0].cpu_cores == 0) } async getAnyAttention(data: ProcessedStats) { @@ -279,8 +284,8 @@ export default class MachineController { } protected async getDiskAttention(data: ProcessedStats): Promise { - if (!data || !data.system) return null - const freePercentage = this.getLastFrom(data.system, (array) => array.disk_node_bytes_free / array.disk_node_bytes_total) + if (!data || !data.system_metrics) return null + const freePercentage = this.getLastFrom(data.system_metrics, (array) => array.disk_node_bytes_free / array.disk_node_bytes_total) const threshold = 100 - ((await this.store.getSetting(HDD_THRESHOLD, 90)) as number) console.log('HDD threshold', threshold) @@ -292,11 +297,11 @@ export default class MachineController { } protected async getMemoryAttention(data: ProcessedStats): Promise { - if (!data || !data.system) return null + if (!data || !data.system_metrics) return null const usagePercentage = 1 - this.getLastFrom( - data.system, + data.system_metrics, (array) => (array.memory_node_bytes_free + array.memory_node_bytes_buffers + array.memory_node_bytes_cached) / array.memory_node_bytes_total ) const threshold = (await this.store.getSetting(RAM_THRESHOLD, 80)) as number @@ -322,16 +327,16 @@ export default class MachineController { } protected getSyncAttention(data: ProcessedStats): string { - const synced = this.getLastFrom(data.node, (array) => array.sync_eth2_synced) - const eth1Connected = this.getLastFrom(data.node, (array) => array.sync_eth1_connected) + const synced = this.getLastFrom(data.node_metrics, (array) => array.sync_eth2_synced) + const eth1Connected = this.getLastFrom(data.node_metrics, (array) => array.sync_eth1_connected) - if (!data.node) { + if (!data.node_metrics) { return "No beaconnode data found. If you wish to track this data, make sure to configure metric tracking on your beaconnode machine too. Learn more here." } else if (!eth1Connected) { return 'No execution client connection, make sure you have configured an execution endpoint and it is currently active and synced.' } else if (!synced) { return 'Your beaconnode is currently syncing. It might take some time to get fully synced.' - } else if (!data.validator) { + } else if (!data.validator_metrics) { return "No validator data found. If you wish to track this data, make sure to configure metric tracking on your validator machine too. Learn more here." } return null @@ -365,7 +370,7 @@ export default class MachineController { return Math.round((erg / (depth - 1)) * 100) / 100 } - protected getAvgRelativeFrom(data1LastN: number[], data2LastN: number[], callback: (val1, val2) => number) { + protected getAvgRelativeFrom(data1LastN: number[], data2LastN: number[], callback: (val1: number, val2: number) => number) { if (!data1LastN || !data2LastN) return null const length = Math.min(data1LastN.length, data2LastN.length) @@ -388,11 +393,11 @@ export default class MachineController { // --- Data helper functions --- - getTimeDiff(dataSet: StatsBase[], startIndex, endIndex) { - return Math.abs(dataSet[startIndex].timestamp - dataSet[endIndex].timestamp) + getTimeDiff(dataSet: number[][], startIndex: number, endIndex: number) { + return Math.abs(dataSet[startIndex][0] - dataSet[endIndex][0]) } - getGapSize(dataSet: StatsBase[]) { + getGapSize(dataSet: number[][]) { if (!dataSet || dataSet.length == 0) return 60000 let temp = this.getTimeDiff(dataSet, dataSet.length - 2, dataSet.length - 1) @@ -404,12 +409,12 @@ export default class MachineController { return temp } - normalizeTimeframeNumber(dataSet: StatsBase[]): number { + normalizeTimeframeNumber(dataSet: number[][]): number { const gapSize = Math.round(this.getGapSize(dataSet) / 1000) return gapSize } - timeAxisRelative(max: StatsBase[], current: number[], inverted = false, rounding = 10) { + timeAxisRelative(max: number[][], current: number[][], inverted = false, rounding = 10) { const result = [] const gapSize = this.normalizeTimeframeNumber(max) @@ -443,8 +448,8 @@ export default class MachineController { return result } - public timeAxisChanges(data: T[], delegateValue: (value: T, timeDiff?) => number, accumilative = false) { - let result = [] + public timeAxisChanges(data: T[], delegateValue: (value: T, timeDiff?: unknown) => number, accumilative = false) { + let result: number[][] = [] let summedUp = -1 let lastValue = 0 let lastTimestamp = -1 @@ -493,37 +498,38 @@ export default class MachineController { return array } - public combineByMachineName(validator: Map, node: Map, system: Map) { + public async combineByMachineName(validator: Map, node: Map, system: Map) { const allKeys = this.findAllKeys(validator, node, system) + const debugShowOldMachines = await this.store.getBooleanSetting('debug_show_old_machines', false) - const result: ProcessedStats[] = [] - for (const key in allKeys) { - const sortedVal = this.sortData(validator.get(key)) as StatsValidator[] - const sortedNode = this.sortData(node.get(key)) as StatsNode[] - const sortedSystem = this.sortData(system.get(key)) as StatsSystem[] + const result: Map = new Map() + for (const key of allKeys) { + const sortedVal = this.sortData(validator.get(key)) + const sortedNode = this.sortData(node.get(key)) + const sortedSystem = this.sortData(system.get(key)) const unixTime = this.findAnyData(sortedVal, sortedNode, sortedSystem, (value) => { return value.timestamp }) // do not display machines that have not been online for more than 4 days - if (unixTime && Date.now() - unixTime > 96 * 60 * 60 * 1000) { + if (!debugShowOldMachines && !environment.mock_combine_machines && unixTime && Date.now() - unixTime > 96 * 60 * 60 * 1000) { continue } - result[key] = { - validator: sortedVal, - node: sortedNode, - system: sortedSystem, + result.set(key, { + validator_metrics: sortedVal, + node_metrics: sortedNode, + system_metrics: sortedSystem, client: this.findAnyData(sortedVal, sortedNode, sortedSystem, (value) => { - return value.client_name + return (value as ProcessBase).client_name }), clientVersion: this.findAnyData(sortedVal, sortedNode, sortedSystem, (value) => { - return value.client_version + return (value as ProcessBase).client_version }), formattedDate: unixTime ? new Date(unixTime) : null, status: 'ONLINE', - } + }) } return result @@ -538,7 +544,12 @@ export default class MachineController { }) } - public findAnyData(validator: StatsValidator[], node: StatsNode[], system: StatsSystem[], dataCallback: (value) => V) { + public findAnyData( + validator: StatsValidator[], + node: StatsNode[], + system: StatsSystem[], + dataCallback: (value: StatsValidator | StatsNode | StatsSystem) => V + ) { const result1 = this.findAnyDataIn(validator, dataCallback) const result3 = this.findAnyDataIn(node, dataCallback) const result4 = this.findAnyDataIn(system, dataCallback) @@ -548,38 +559,37 @@ export default class MachineController { public findAnyDataIn(current: T[], dataCallback: (value: T) => V) { if (!current || current.length <= 0) return null const result = dataCallback(current[current.length - 1]) - if (result && result != '') { + if (result) { return result } return null } - public findAllKeys(validator: Map, node: Map, system: Map) { - const result = [] + public findAllKeys(validator: Map, node: Map, system: Map): string[] { + const set = new Set() for (const key of validator.keys()) { - result[key] = true + set.add(key) } for (const key of node.keys()) { - result[key] = true + set.add(key) } for (const key of system.keys()) { - result[key] = true + set.add(key) } - return result + return Array.from(set) } - public filterMachines(data: Type[]): Map { - const result = new Map() - for (let i = 0; i < data.length; i++) { - let array = result.get(data[i].machine) - if (array == null) { - array = [] + public filterMachines(data: T[]): Map { + return data.reduce((result, current) => { + if (environment.mock_combine_machines) { + current.machine = 'test' } - array.push(data[i]) - result.set(data[i].machine, array) - } - return result + const existingArray = result.get(current.machine) || [] + existingArray.push(current) + result.set(current.machine, existingArray) + return result + }, new Map()) } public hashCode(string: string) { @@ -595,10 +605,10 @@ export default class MachineController { export const bytes = (function () { const s = ['b', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB'], - tempLabel = [] - let count + tempLabel: number[] = [] + let count: number - return function (byteData, label, isFirst, precision = 3) { + return function (byteData: number, label: unknown, isFirst: unknown, precision = 3) { let e, value if (byteData == 0) return 0 @@ -606,7 +616,7 @@ export const bytes = (function () { if (isFirst) count = 0 e = Math.floor(Math.log(byteData) / Math.log(1024)) - value = (byteData / Math.pow(1024, Math.floor(e))).toFixed(precision) + value = parseInt((byteData / Math.pow(1024, Math.floor(e))).toFixed(precision)) tempLabel[count] = value if (count > 0 && Math.abs(tempLabel[count - 1] - tempLabel[count]) < 0.0001) @@ -632,57 +642,26 @@ export interface ProcessedStats extends StatsResponse { } export interface StatsBase { - machine: string - timestamp: number - row: number + machine?: string + timestamp?: number + //row: number } export interface ProcessBase extends StatsBase { - client_name: string - client_version: string - cpu_process_seconds_total: number - memory_process_bytes: number + client_name?: string + client_version?: string + cpu_process_seconds_total?: number + memory_process_bytes?: number } export interface StatsResponse { - validator: StatsValidator[] - node: StatsNode[] - system: StatsSystem[] + validator_metrics: StatsValidator[] + node_metrics: StatsNode[] + system_metrics: StatsSystem[] } -export interface StatsValidator extends ProcessBase { - validator_active: number - validator_total: number -} +export interface StatsValidator extends MachineMetricValidator, ProcessBase {} -export interface StatsNode extends ProcessBase { - disk_beaconchain_bytes_total: number - network_libp2p_bytes_total_receive: number - network_libp2p_bytes_total_transmit: number - network_peers_connected: number - sync_eth1_connected: boolean - sync_eth2_synced: boolean - sync_beacon_head_slot: number -} +export interface StatsNode extends MachineMetricNode, ProcessBase {} -export interface StatsSystem extends StatsBase { - cpu_cores: number - cpu_node_idle_seconds_total: number - cpu_node_iowait_seconds_total: number - cpu_node_system_seconds_total: number - cpu_node_user_seconds_total: number - cpu_threads: number - disk_node_bytes_free: number - disk_node_bytes_total: number - disk_node_io_seconds: number - disk_node_reads_total: number - disk_node_writes_total: number - memory_node_bytes_buffers: number - memory_node_bytes_cached: number - memory_node_bytes_free: number - memory_node_bytes_total: number - misc_node_boot_ts_seconds: number - misc_os: string - network_node_bytes_total_receive: number - network_node_bytes_total_transmit: number -} +export interface StatsSystem extends MachineMetricSystem, StatsBase {} diff --git a/src/app/controllers/OverviewController.ts b/src/app/controllers/OverviewController.ts index f128edca..8f9753e1 100644 --- a/src/app/controllers/OverviewController.ts +++ b/src/app/controllers/OverviewController.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -18,59 +17,316 @@ * // along with Beaconchain Dashboard. If not, see . */ -import { EpochResponse, ProposalLuckResponse, SyncCommitteeResponse, ValidatorResponse } from '../requests/requests' -import { sumBigInt, findHighest, findLowest } from '../utils/MathUtils' import BigNumber from 'bignumber.js' -import { getValidatorQueryString, ValidatorState, Validator } from '../utils/ValidatorUtils' -import { formatDate } from '@angular/common' -import { SyncCommitteesStatistics, SyncCommitteesStatisticsResponse } from '../requests/requests' -import { UnitconvService } from '../services/unitconv.service' -import { ApiNetwork } from '../models/StorageTypes' - -export type OverviewData = { - overallBalance: BigNumber - validatorCount: number - requiredValidatorsForOKState: number - exitedValidatorsCount: number - activeValidatorCount: number - consensusPerformance: Performance - executionPerformance: Performance - combinedPerformance: Performance - slashedCount: number - awaitingActivationCount: number - activationeligibilityCount: number - bestRank: number - worstRank: number - bestTopPercentage: number - worstTopPercentage: number - displayAttrEffectiveness: boolean - attrEffectiveness: number - proposalLuckResponse: ProposalLuckResponse - dashboardState: DashboardStatus - lazyLoadChart: boolean - lazyChartValidators: string - foreignValidator: boolean - foreignValidatorItem?: Validator - foreignValidatorWithdrawalCredsAre0x01: boolean - effectiveBalance: BigNumber - currentEpoch: EpochResponse - rocketpool: Rocketpool - currentSyncCommittee: SyncCommitteeResponse - nextSyncCommittee: SyncCommitteeResponse - syncCommitteesStats: SyncCommitteesStatistics - proposalLuck: ProposalLuckResponse - withdrawalsEnabledForAll: boolean +import { + Aggregation, + dashboardID, + EfficiencyType, + Period, + V2DashboardOverview, + V2DashboardRewardChart, + V2DashboardRocketPool, + V2DashboardSummaryChart, + V2DashboardSummaryGroupTable, + V2DashboardSummaryTable, + V2GetValidatorStatusOfGroup, +} from '@requests/v2-dashboard' +import { ApiService, LatestStateWithTime } from '@services/api.service' +import { + VDBGroupSummaryData, + VDBOverviewData, + VDBOverviewValidators, + VDBRocketPoolTableRow, + VDBSummaryTableRow, + VDBSummaryValidatorsData, +} from '@requests/types/validator_dashboard' +import { computed, Injectable, signal, Signal, WritableSignal } from '@angular/core' +import { ChartData } from '@requests/types/common' +import { ChainNetwork, findChainNetworkById } from '@utils/NetworkData' +import { sumBigInt } from '@utils/MathUtils' +import { UnitconvService } from '@services/unitconv.service' +export interface SummaryChartOptions { + aggregation: Aggregation + startTime: number + endTime: number + force: boolean +} + +@Injectable({ providedIn: 'root' }) +export class OverviewProvider { + constructor( + private api: ApiService, + private unit: UnitconvService + ) {} + + clearRequestCache(data: OverviewData2) { + if (!data) return + return this.api.clearAllAssociatedCacheKeys(data.associatedCacheKey) + } + + async setSummaryChartOptions(data: OverviewData2, options: SummaryChartOptions, force: boolean = false) { + data.summaryChartOptionsInternal.set(options) + const aggregation = options.aggregation + + let startTime = options.startTime + if (startTime == null) { + startTime = Date.now() / 1000 - 12 * 60 * 60 + if (aggregation == Aggregation.Epoch) { + startTime = Date.now() / 1000 - 8 * 60 * 60 + } else if (aggregation == Aggregation.Daily) { + startTime = Date.now() / 1000 - 21 * 24 * 60 * 60 + } else if (aggregation == Aggregation.Weekly) { + startTime = Date.now() / 1000 - 8 * 7 * 24 * 60 * 60 + } + } + + const request = new V2DashboardSummaryChart(data.id, EfficiencyType.All, aggregation, startTime, options.endTime) + .withAllowedCacheResponse(!force) + .withCustomCacheKey('summary-chart-initial-' + aggregation + data.id) + if (options.force) { + request.withAllowedCacheResponse(false) + } + const result = await this.api.set(request, data.summaryChart, data.associatedCacheKey) + if (result.error) { + console.error('Error fetching summary chart', result.error) + } + } + + async setGroup(data: OverviewData2, groupID: number, force: boolean = false) { + if (groupID == -1) { + data.groupValidatorStatus.set(null) + return + } + const result = await this.api.set( + new V2GetValidatorStatusOfGroup(data.id, groupID, Period.AllTime).withAllowedCacheResponse(!force), + data.groupValidatorStatus, + data.associatedCacheKey + ) + if (result.error) { + console.error('Error fetching group dashboard status', result.error) + } + } + + async setTimeframe(data: OverviewData2, timeframe: Period, groupID: number, force: boolean = false) { + data.timeframeInternal.set(timeframe) + const period = timeframe + + return Promise.all([ + this.api.set(new V2DashboardSummaryTable(data.id, period, null).withAllowedCacheResponse(!force), data.summary, data.associatedCacheKey), + this.api.set( + new V2DashboardSummaryGroupTable(data.id, groupID, period, null).withAllowedCacheResponse(!force), + data.summaryGroup, + data.associatedCacheKey + ), + ]) + } + + async create( + id: dashboardID, + timeframe: Period, + groupID: number, + summaryChartOptions: SummaryChartOptions, + associatedCacheKey: string = null + ): Promise { + if (!id) return null + + const temp = new OverviewData2(id, associatedCacheKey, this.unit) + + const overview = this.api.set(new V2DashboardOverview(id), temp.overviewData, associatedCacheKey) + this.setTimeframe(temp, timeframe, groupID, false) + + this.api.set(new V2DashboardRocketPool(id), temp.rocketpool, associatedCacheKey) + this.api.set(new V2DashboardRewardChart(id).withCustomCacheKey('reward-chart-initial-' + id), temp.rewardChart, associatedCacheKey) + + this.api.getLatestState().then((latestState) => { + temp.latestState.set(latestState) + }) + + temp.summaryChartOptionsInternal.set(summaryChartOptions) + + //this.setSummaryChartOptions(temp, summaryChartOptions) // Summary Chart handles its own fetch logic, so below is not necessary + + // wait after all requests are made + const overviewResult = await overview + if (overviewResult.error) { + throw overviewResult.error + } + + return temp + } +} + +function getPeriodDisplayable(period: Period): string { + if (period == Period.AllTime) return 'All' + if (period == Period.Last1h) return '1h' + if (period == Period.Last24h) return '24h' + if (period == Period.Last7d) return '7d' + if (period == Period.Last30d) return '30d' +} +export class OverviewData2 { + associatedCacheKey: string = null + + loading: WritableSignal = signal(false) + id: dashboardID + + overviewData: WritableSignal = signal(null) + summary: WritableSignal = signal(null) + summaryGroup: WritableSignal = signal(null) + latestState: WritableSignal = signal(null) + rocketpool: WritableSignal = signal(null) + summaryChart: WritableSignal> = signal(null) + rewardChart: WritableSignal> = signal(null) + groupValidatorStatus: WritableSignal = signal(null) + + timeframeInternal: WritableSignal = signal(null) + timeframe = computed(() => this.timeframeInternal()) + timeframeDisplay = computed(() => getPeriodDisplayable(this.timeframe())) + + selectedGroupID: WritableSignal = signal(-1) + summaryCurrentGroup = computed(() => { + // todo: efficiency should be provided by summaryGroup + if (!this.summary()) return null + return this.summary().find((group) => group.group_id == this.selectedGroupID()) + }) + + summaryChartOptionsInternal: WritableSignal = signal(null) + summaryChartOptions = computed(() => this.summaryChartOptionsInternal()) + + foreignValidator: boolean = false + unit: UnitconvService + + chainNetwork: Signal = computed(() => { + if (!this.overviewData()) return findChainNetworkById(1) + return findChainNetworkById(this.overviewData().network) + }) + + constructor(id: dashboardID, associatedCacheKey: string, unit: UnitconvService) { + this.id = id + this.associatedCacheKey = associatedCacheKey + this.unit = unit + } + + isEmpty = computed(() => { + return this.validatorCount() == 0 + }) + + validatorCount: Signal = computed(() => { + if (!this.overviewData()) return 0 + // if group is selected, just return count for that group + if (this.groupValidatorStatus()) { + return this.groupValidatorStatus().reduce((acc, group) => acc + group.validators.length, 0) + } + + return getValidatorCount(this.overviewData()) + }) + + dashboardState: Signal = computed(() => { + let validators = this.overviewData()?.validators + // if group is selected, calculate validator states of that group + if (this.groupValidatorStatus()) { + validators = { + online: this.groupValidatorStatus().find((item) => item.category == 'online')?.validators.length, + offline: this.groupValidatorStatus().find((item) => item.category == 'offline')?.validators.length, + slashed: this.groupValidatorStatus().find((item) => item.category == 'slashed')?.validators.length, + exited: this.groupValidatorStatus().find((item) => item.category == 'exited')?.validators.length, + pending: this.groupValidatorStatus().find((item) => item.category == 'pending')?.validators.length, + } as VDBOverviewValidators + } + + return getDashboardState(validators, this.validatorCount(), this.foreignValidator) + }) + + consensusPerformance: Signal = computed(() => { + return getConsensusPerformance(this.overviewData()) + }) + + executionPerformance: Signal = computed(() => { + return getExecutionPerformance(this.overviewData()) + }) + + combinedPerformance: Signal = computed(() => { + return getCombinedPerformance(this.consensusPerformance(), this.executionPerformance(), this.unit) + }) + + showSyncStats: Signal = computed(() => { + if (this.summaryGroup() == null) return false + return ( + this.summaryGroup().sync_count.current_validators > 0 || + this.summaryGroup().sync_count.past_periods > 0 || + this.summaryGroup().sync_count.upcoming_validators > 0 + ) + }) + + syncEfficiency: Signal = computed(() => { + if (this.summaryGroup() == null) return 0 + const total = this.summaryGroup().sync.status_count.success + this.summaryGroup().sync.status_count.failed + if (total == 0) return 0 + return (this.summaryGroup().sync.status_count.success * 100) / total + }) + + syncCount: Signal = computed(() => { + if (this.summaryGroup() == null) return 0 + return this.summaryGroup().sync_count.past_periods + this.summaryGroup().sync_count.current_validators > 0 ? 1 : 0 + }) + + isReadyToDisplay: Signal = computed(() => { + return this.overviewData() != null && this.summary() != null && this.summaryGroup() != null + }) + + rpTotalRPLClaimed: Signal = computed(() => { + if (this.rocketpool() == null) return new BigNumber(0) + const claimed = sumBigInt(this.rocketpool(), (rp) => new BigNumber(rp.rpl_claimed)) + const unclaimed = sumBigInt(this.rocketpool(), (rp) => new BigNumber(rp.rpl_unclaimed)) + + return claimed.plus(unclaimed) + }) + + avgNetworkEfficiency: Signal = computed(() => { + if (this.summary() == null) return 0 + return this.summary()[0].average_network_efficiency + }) + + getTotalMissedRewards: Signal = computed(() => { + if (this.summaryGroup() == null) return new BigNumber(0) + return new BigNumber(this.summaryGroup().missed_rewards.attestations) + .plus(new BigNumber(this.summaryGroup().missed_rewards.proposer_rewards.cl)) + .plus(new BigNumber(this.summaryGroup().missed_rewards.proposer_rewards.el)) + .plus(new BigNumber(this.summaryGroup().missed_rewards.sync)) + }) + + totalSmoothingPool: Signal = computed(() => { + if (this.rocketpool() == null) return new BigNumber(0) + const claimed = sumBigInt(this.rocketpool(), (rp) => new BigNumber(rp.smoothingpool_claimed)) + const unclaimed = sumBigInt(this.rocketpool(), (rp) => new BigNumber(rp.smoothingpool_unclaimed)) + return claimed.plus(unclaimed) + }) + + totalRPL: Signal = computed(() => { + if (this.rocketpool() == null) return new BigNumber(0) + const claimed = sumBigInt(this.rocketpool(), (rp) => new BigNumber(rp.rpl_claimed)) + const unclaimed = sumBigInt(this.rocketpool(), (rp) => new BigNumber(rp.rpl_unclaimed)) + return claimed.plus(unclaimed) + }) +} + +export function getValidatorCount(overviewData: VDBOverviewData): number { + return ( + overviewData.validators.exited + + overviewData.validators.offline + + overviewData.validators.online + + overviewData.validators.slashed + + overviewData.validators.pending + ) } export type Performance = { performance1d: BigNumber - performance31d: BigNumber + performance30d: BigNumber performance7d: BigNumber - performance365d: BigNumber total: BigNumber apr7d: number - apr31d: number - apr365d: number + apr30d: number + aprTotal: number } export type Rocketpool = { @@ -123,813 +379,216 @@ export type Description = { extendedDescriptionPre: string } -const VALIDATOR_32ETH = new BigNumber(32000000000) - -export default class OverviewController { - constructor(private refreshCallback: () => void = null, private userMaxValidators = 280, private unit: UnitconvService = null) {} - - public processDashboard( - validators: Validator[], - currentEpoch: EpochResponse, - syncCommitteesStatsResponse = null, - proposalLuckResponse: ProposalLuckResponse = null, - network: ApiNetwork - ) { - return this.process(validators, currentEpoch, false, syncCommitteesStatsResponse, proposalLuckResponse, network) +// VDBSummaryValidators just 3 states? +function getDashboardState(validators: VDBOverviewValidators, validatorCount: number, foreignValidator: boolean): DashboardStatus { + if (!validators) return null + // create status object with some default values + const dashboardStatus: DashboardStatus = { + state: StateType.none, + title: `${validators.online} / ${validatorCount}`, + iconCss: 'ok', + icon: 'checkmark-circle-outline', + description: [], + extendedDescription: '', + extendedDescriptionPre: '', } - public processDetail(validators: Validator[], currentEpoch: EpochResponse, network: ApiNetwork) { - return this.process(validators, currentEpoch, true, null, null, network) - } - - private process( - validators: Validator[], - currentEpoch: EpochResponse, - foreignValidator = false, - syncCommitteesStatsResponse = null, - proposalLuckResponse: ProposalLuckResponse = null, - network: ApiNetwork - ): OverviewData { - if (!validators || validators.length <= 0 || currentEpoch == null) return null - - const effectiveBalance = sumBigInt(validators, (cur) => cur.data.effectivebalance) - const validatorDepositActive = sumBigInt(validators, (cur) => { - if (cur.data.activationepoch <= currentEpoch.epoch) { - if (!cur.rocketpool || !cur.rocketpool.node_address) return VALIDATOR_32ETH.multipliedBy(new BigNumber(cur.share == null ? 1 : cur.share)) - - let nodeDeposit - if (cur.rocketpool.node_deposit_balance) { - nodeDeposit = new BigNumber(cur.rocketpool.node_deposit_balance.toString()).dividedBy(new BigNumber(1e9)) - } else { - nodeDeposit = VALIDATOR_32ETH.dividedBy(new BigNumber(2)) - } - return nodeDeposit.multipliedBy(new BigNumber(cur.share == null ? 1 : cur.share)) - } else { - return new BigNumber(0) - } - }) - - const overallBalance = this.sumBigIntBalanceRP(validators, (cur) => new BigNumber(cur.data.balance)) - const validatorCount = validators.length - const activeValidators = this.getActiveValidators(validators) - const offlineValidators = this.getOfflineValidators(validators) - - const consensusPerf = this.getConsensusPerformance(validators, validatorDepositActive) - - const executionPerf = this.getExecutionPerformance(validators, validatorDepositActive) - - const smoothingPoolClaimed = this.sumRocketpoolSmoothingBigIntPerNodeAddress( - true, - validators, - (cur) => cur.rocketpool.claimed_smoothing_pool, - (cur) => cur.execshare - ).dividedBy(new BigNumber('1e9')) - - const smoothingPoolUnclaimed = this.sumRocketpoolSmoothingBigIntPerNodeAddress( - true, - validators, - (cur) => cur.rocketpool.unclaimed_smoothing_pool, - (cur) => cur.execshare - ).dividedBy(new BigNumber('1e9')) - - const combinedPerf = { - performance1d: consensusPerf.performance1d.plus(this.unit.convertELtoCL(executionPerf.performance1d)), - performance31d: consensusPerf.performance31d.plus(this.unit.convertELtoCL(executionPerf.performance31d)), - performance7d: consensusPerf.performance7d.plus(this.unit.convertELtoCL(executionPerf.performance7d)), - performance365d: consensusPerf.performance365d.plus(this.unit.convertELtoCL(executionPerf.performance365d)), - apr31d: this.getAPRFrom(31, validatorDepositActive, this.unit.convertELtoCL(executionPerf.performance31d).plus(consensusPerf.performance31d)), - apr7d: this.getAPRFrom(7, validatorDepositActive, this.unit.convertELtoCL(executionPerf.performance7d).plus(consensusPerf.performance7d)), - apr365d: this.getAPRFrom( - 365, - validatorDepositActive, - this.unit.convertELtoCL(executionPerf.performance365d).plus(consensusPerf.performance365d) - ), - total: consensusPerf.total.plus(this.unit.convertELtoCL(executionPerf.total)).plus(smoothingPoolClaimed).plus(smoothingPoolUnclaimed), - } as Performance - - let attrEffectiveness = 0 - let displayAttrEffectiveness = false - if (activeValidators.length > 0) { - displayAttrEffectiveness = true - - attrEffectiveness = sumBigInt(activeValidators, (cur) => - cur.attrEffectiveness ? new BigNumber(cur.attrEffectiveness.toString()) : new BigNumber(0) - ) - .dividedBy(activeValidators.length) - .decimalPlaces(1) - .toNumber() - - const attrChecked = Math.min(Math.max(attrEffectiveness, 0), 100) - if (attrEffectiveness != attrChecked) { - console.warn(`Effectiveness out of range: ${attrEffectiveness} (displaying "NaN")`) - attrEffectiveness = -1 // display "NaN" if something went wrong - } - } - - let bestRank = 0 - let bestTopPercentage = 0 - let worstRank = 0 - let worstTopPercentage = 0 - const rankRelevantValidators = activeValidators.concat(offlineValidators) - if (rankRelevantValidators.length > 0) { - bestRank = findLowest(rankRelevantValidators, (cur) => cur.data.rank7d) - bestTopPercentage = findLowest(rankRelevantValidators, (cur) => cur.data.rankpercentage) - worstRank = findHighest(rankRelevantValidators, (cur) => cur.data.rank7d) - worstTopPercentage = findHighest(rankRelevantValidators, (cur) => cur.data.rankpercentage) - } - - const rocketpoolValiCount = sumBigInt(validators, (cur) => (cur.rocketpool ? new BigNumber(1) : new BigNumber(0))) - const feeSum = sumBigInt(validators, (cur) => - cur.rocketpool ? new BigNumber(cur.rocketpool.minipool_node_fee).multipliedBy('100') : new BigNumber('0') - ) - let feeAvg = 0 - if (feeSum.decimalPlaces(3).toNumber() != 0) { - feeAvg = feeSum.dividedBy(rocketpoolValiCount).decimalPlaces(1).toNumber() - } + //// + // Attention: The order of all the updateStateX functions matters! + // The first one that matches will set the icon and its css as well as, if only one state matches, the extendedDescription - const currentSync = validators.find((cur) => !!cur.currentSyncCommittee) - const nextSync = validators.find((cur) => !!cur.nextSyncCommittee) + // handle slashed validators + updateStateSlashed(dashboardStatus, validators.slashed, validatorCount, foreignValidator) - let foreignWCAre0x01 = false - if (foreignValidator) { - foreignWCAre0x01 = validators[0].data.withdrawalcredentials.startsWith('0x01') - } + // handle offline validators + updateStateOffline(dashboardStatus, validatorCount, validators.offline, foreignValidator) - return { - overallBalance: overallBalance, - validatorCount: validatorCount, - bestRank: bestRank, - bestTopPercentage: bestTopPercentage, - worstRank: worstRank, - worstTopPercentage: worstTopPercentage, - attrEffectiveness: attrEffectiveness, - displayAttrEffectiveness: displayAttrEffectiveness, - consensusPerformance: consensusPerf, - executionPerformance: executionPerf, - combinedPerformance: combinedPerf, - dashboardState: this.getDashboardState(validators, currentEpoch, foreignValidator, network), - lazyLoadChart: true, - lazyChartValidators: getValidatorQueryString(validators, 2000, this.userMaxValidators - 1), - foreignValidator: foreignValidator, - foreignValidatorItem: foreignValidator ? validators[0] : null, - foreignValidatorWithdrawalCredsAre0x01: foreignWCAre0x01, - effectiveBalance: effectiveBalance, - currentEpoch: currentEpoch, - currentSyncCommittee: currentSync ? currentSync.currentSyncCommittee : null, - nextSyncCommittee: nextSync ? nextSync.nextSyncCommittee : null, - syncCommitteesStats: this.calculateSyncCommitteeStats(syncCommitteesStatsResponse, network), - proposalLuckResponse: proposalLuckResponse, - withdrawalsEnabledForAll: - validators.filter((cur) => (cur.data.withdrawalcredentials.startsWith('0x01') ? true : false)).length == validatorCount, - rocketpool: { - minRpl: this.sumRocketpoolBigIntPerNodeAddress( - true, - validators, - (cur) => cur.rocketpool.node_min_rpl_stake, - (cur) => cur.rplshare - ), - maxRpl: this.sumRocketpoolBigIntPerNodeAddress( - true, - validators, - (cur) => cur.rocketpool.node_max_rpl_stake, - (cur) => cur.rplshare - ), - currentRpl: this.sumRocketpoolBigIntPerNodeAddress( - true, - validators, - (cur) => cur.rocketpool.node_rpl_stake, - (cur) => cur.rplshare - ), - totalClaims: this.sumRocketpoolBigIntPerNodeAddress( - true, - validators, - (cur) => cur.rocketpool.rpl_cumulative_rewards, - (cur) => cur.rplshare - ), - fee: feeAvg, - status: foreignValidator && validators[0].rocketpool ? validators[0].rocketpool.minipool_status : null, - depositType: foreignValidator && validators[0].rocketpool ? validators[0].rocketpool.minipool_deposit_type : null, - smoothingPoolClaimed: smoothingPoolClaimed, - smoothingPoolUnclaimed: smoothingPoolUnclaimed, - rplUnclaimed: this.sumRocketpoolBigIntPerNodeAddress( - true, - validators, - (cur) => cur.rocketpool.unclaimed_rpl_rewards, - (cur) => cur.rplshare - ), - smoothingPool: validators.find((cur) => (cur.rocketpool ? cur.rocketpool.smoothing_pool_opted_in == true : false)) != null ? true : false, - hasNonSmoothingPoolAsWell: - validators.find((cur) => (cur.rocketpool ? cur.rocketpool.smoothing_pool_opted_in == false : true)) != null ? true : false, - cheatingStatus: this.getRocketpoolCheatingStatus(validators), - depositCredit: this.sumRocketpoolBigIntPerNodeAddress( - false, - validators, - (cur) => (cur.rocketpool.node_deposit_credit ? cur.rocketpool.node_deposit_credit.toString() : '0'), - () => 1 - ), - vacantPools: validators.filter((cur) => cur.rocketpool && cur.rocketpool.is_vacant).length, - }, - } as OverviewData + // handle awaiting activation validators + if (validators.pending > 0) { + updateStateAwaiting(dashboardStatus, validators.pending, validatorCount, foreignValidator) } - private getExecutionPerformance(validators: Validator[], validatorDepositActive: BigNumber) { - const performance1d = this.sumBigIntPerformanceRP(validators, (cur) => - this.sumExcludeSmoothingPool(cur, (fieldCur) => fieldCur.execution.performance1d.toString()).multipliedBy( - new BigNumber(cur.execshare == null ? 1 : cur.execshare) - ) - ) - const performance31d = this.sumBigIntPerformanceRP(validators, (cur) => - this.sumExcludeSmoothingPool(cur, (fieldCur) => fieldCur.execution.performance31d.toString()).multipliedBy( - new BigNumber(cur.execshare == null ? 1 : cur.execshare) - ) - ) - const performance7d = this.sumBigIntPerformanceRP(validators, (cur) => - this.sumExcludeSmoothingPool(cur, (fieldCur) => fieldCur.execution.performance7d.toString()).multipliedBy( - new BigNumber(cur.execshare == null ? 1 : cur.execshare) - ) - ) - const performance365d = this.sumBigIntPerformanceRP(validators, (cur) => - this.sumExcludeSmoothingPool(cur, (fieldCur) => fieldCur.execution.performance365d.toString()).multipliedBy( - new BigNumber(cur.execshare == null ? 1 : cur.execshare) - ) - ) - const total = this.sumBigIntPerformanceRP(validators, (cur) => - this.sumExcludeSmoothingPool(cur, (fieldCur) => fieldCur.execution.performanceTotal.toString()).multipliedBy( - new BigNumber(cur.execshare == null ? 1 : cur.execshare) - ) - ) + // handle exited validators + updateExitedState(dashboardStatus, validators.exited, validatorCount, foreignValidator) - return { - performance1d: performance1d, - performance31d: performance31d, - performance7d: performance7d, - performance365d: performance365d, - apr31d: this.getAPRFrom(31, validatorDepositActive, performance31d), - apr7d: this.getAPRFrom(7, validatorDepositActive, performance7d), - apr365d: this.getAPRFrom(365, validatorDepositActive, performance365d), - total: total, - } - } + // handle ok state, always call last + updateStateOk(dashboardStatus, validators.online, validatorCount, foreignValidator) - private sumExcludeSmoothingPool(cur: Validator, field: (cur: Validator) => string) { - // Exclude rocketpool minipool from execution rewards collection - if (!cur.rocketpool || !cur.rocketpool.smoothing_pool_opted_in) { - return cur.execution ? new BigNumber(field(cur)).dividedBy(new BigNumber('1e9')) : new BigNumber(0) - } - return new BigNumber(0) + if (dashboardStatus.state == StateType.mixed) { + // remove extended description if more than one state is shown + dashboardStatus.extendedDescription = '' + dashboardStatus.extendedDescriptionPre = '' } - private getConsensusPerformance(validators: Validator[], validatorDepositActive: BigNumber): Performance { - const performance1d = this.sumBigIntPerformanceRP(validators, (cur) => - new BigNumber(cur.data.performance1d).multipliedBy(new BigNumber(cur.share == null ? 1 : cur.share)) - ) - const performance31d = this.sumBigIntPerformanceRP(validators, (cur) => - new BigNumber(cur.data.performance31d).multipliedBy(new BigNumber(cur.share == null ? 1 : cur.share)) - ) - const performance7d = this.sumBigIntPerformanceRP(validators, (cur) => - new BigNumber(cur.data.performance7d).multipliedBy(new BigNumber(cur.share == null ? 1 : cur.share)) - ) - const performance365d = this.sumBigIntPerformanceRP(validators, (cur) => - new BigNumber(cur.data.performance365d).multipliedBy(new BigNumber(cur.share == null ? 1 : cur.share)) - ) - const total = this.sumBigIntPerformanceRP(validators, (cur) => { - if (cur.data.performancetotal !== undefined) { - return new BigNumber(cur.data.performancetotal).multipliedBy(new BigNumber(cur.share == null ? 1 : cur.share)) - } else { - return new BigNumber(0) - } - }) - - return { - performance1d: performance1d, - performance31d: performance31d, - performance7d: performance7d, - performance365d: performance365d, - apr31d: this.getAPRFrom(31, validatorDepositActive, performance31d), - apr7d: this.getAPRFrom(7, validatorDepositActive, performance7d), - apr365d: this.getAPRFrom(365, validatorDepositActive, performance365d), - total: total, - } - } - - private getRocketpoolCheatingStatus(validators: Validator[]): RocketpoolCheatingStatus { - let strikes = 0 - let penalties = 0 - - validators.forEach((cur) => { - if (cur.rocketpool && cur.rocketpool.node_address) { - const penalty_count = cur.rocketpool.penalty_count - if (penalty_count >= 3) { - penalties += penalty_count - } else { - strikes += penalty_count - } - } - }) - - return { - strikes: strikes, - penalties: penalties, - } - } - - public sumBigIntBalanceRP(validators: Validator[], field: (cur: Validator) => BigNumber): BigNumber { - return sumBigInt(validators, (cur) => { - const fieldVal = field(cur) - if (!cur.rocketpool) return fieldVal.multipliedBy(new BigNumber(cur.share == null ? 1 : cur.share)) - if (!cur.rocketpool.node_address) { - return fieldVal.multipliedBy(new BigNumber(cur.share == null ? 1 : cur.share)) - } - - let nodeDeposit - if (cur.rocketpool.node_deposit_balance) { - nodeDeposit = new BigNumber(cur.rocketpool.node_deposit_balance.toString()).dividedBy(new BigNumber(1e9)) - } else { - nodeDeposit = VALIDATOR_32ETH.dividedBy(new BigNumber(2)) - } - - const rewards = new BigNumber(fieldVal.toString()).minus(VALIDATOR_32ETH) - - const nodeShare = nodeDeposit.dividedBy(VALIDATOR_32ETH).toNumber() - const rewardNode = new BigNumber(rewards).multipliedBy(new BigNumber(nodeShare)) - const rewardNodeFromPool = new BigNumber(rewards) - .multipliedBy(new BigNumber(1 - nodeShare)) - .multipliedBy(new BigNumber(cur.rocketpool.minipool_node_fee.toString())) - - // if negative, rocketpool reimburses the rETH holder by taking it from the node operator - let wholeBalance - if (rewards.isNegative()) { - wholeBalance = nodeDeposit.plus(rewards) - // if less than what the user deposited upfront, he lost everything and we put the balance to 0 - // the validator can leak below that of course, but that's now at the expense of the rETH holders - if (wholeBalance.isNegative()) { - wholeBalance = new BigNumber(0) - } - } else { - wholeBalance = nodeDeposit.plus(rewardNode).plus(rewardNodeFromPool) - } - - return wholeBalance.multipliedBy(new BigNumber(cur.share == null ? 1 : cur.share)) - }) - } - - private sumBigIntPerformanceRP(validators: Validator[], field: (cur: Validator) => BigNumber): BigNumber { - return sumBigInt(validators, (cur) => { - if (!cur.rocketpool) return field(cur) - if (!cur.rocketpool.node_address) return field(cur) - - let fieldResolved = field(cur) - if (fieldResolved.s == null && fieldResolved.e == null) { - fieldResolved = new BigNumber(0) - } - - let nodeDeposit - if (cur.rocketpool.node_deposit_balance) { - nodeDeposit = new BigNumber(cur.rocketpool.node_deposit_balance.toString()).dividedBy(new BigNumber(1e9)) - } else { - nodeDeposit = VALIDATOR_32ETH.dividedBy(new BigNumber(2)) - } - - const rewards = new BigNumber(fieldResolved.toString()) - - const nodeShare = nodeDeposit.dividedBy(VALIDATOR_32ETH).toNumber() - - const rewardNode = new BigNumber(rewards).multipliedBy(new BigNumber(nodeShare)) - const rewardNodeFromPool = new BigNumber(rewards) - .multipliedBy(new BigNumber(1 - nodeShare)) - .multipliedBy(new BigNumber(cur.rocketpool.minipool_node_fee.toString())) - - // if negative, rocketpool reimburses the rETH holder by taking it from the node operator - let resultReward - if (rewards.isNegative()) { - resultReward = rewards - const negativeDepositBalance = nodeDeposit.multipliedBy(-1) - if (resultReward.isLessThan(negativeDepositBalance)) { - resultReward = negativeDepositBalance - } - } else { - resultReward = rewardNode.plus(rewardNodeFromPool) - } + return dashboardStatus +} - return resultReward - }) - } +function descriptionSwitch(myText: string, foreignText: string, foreignValidator: boolean) { + return foreignValidator ? foreignText : myText +} - private sumRocketpoolBigIntPerNodeAddress( - applyShare: boolean, - validators: Validator[], - field: (cur: Validator) => string, - share: (cur: Validator) => number - ): BigNumber { - const nodesAdded = new Set() - return sumBigInt(validators, (cur) => { - if (!cur.rocketpool) return new BigNumber(0) - if (!cur.rocketpool.node_address) return new BigNumber(0) - if (nodesAdded.has(cur.rocketpool.node_address)) return new BigNumber(0) - nodesAdded.add(cur.rocketpool.node_address) - const temp = new BigNumber(field(cur).toString()) - if (applyShare) { - return temp.multipliedBy(share(cur) == null ? 1 : share(cur)) - } - return temp - }) +function singularPluralSwitch(totalValidatorCount: number, validatorCount: number, verbSingular: string, verbPlural: string): string { + if (totalValidatorCount != validatorCount && validatorCount == 1) { + return ` ${verbSingular}` + } else { + return ` ${verbPlural}` } +} - private sumRocketpoolSmoothingBigIntPerNodeAddress( - applyShare: boolean, - validators: Validator[], - field: (cur: Validator) => string, - share: (cur: Validator) => number - ): BigNumber { - const totalMinipoolFeeForNodeCache = new Map() - - return sumBigInt(validators, (cur) => { - if (!cur.rocketpool) return new BigNumber(0) - if (!cur.rocketpool.node_address) return new BigNumber(0) - - if (!totalMinipoolFeeForNodeCache.has(cur.rocketpool.node_address)) { - const totalMinipoolFeeForNode = validators - .filter((item) => { - if (!item.rocketpool) return false - if (!item.rocketpool.node_address) return false - return item.rocketpool.node_address == cur.rocketpool.node_address - }) - .reduce((accumulator, currentValue) => accumulator + parseFloat(currentValue.rocketpool.minipool_node_fee.toString()), 0) - totalMinipoolFeeForNodeCache.set(cur.rocketpool.node_address, totalMinipoolFeeForNode) - } - - const nodeFeeShare = - parseFloat(cur.rocketpool.minipool_node_fee.toString()) / (totalMinipoolFeeForNodeCache.get(cur.rocketpool.node_address) || 1) - let temp = new BigNumber(field(cur).toString()) - temp = temp.multipliedBy(nodeFeeShare) - if (applyShare) { - return temp.multipliedBy(share(cur) == null ? 1 : share(cur)) - } - return temp - }) +function updateStateSlashed(dashboardStatus: DashboardStatus, slashedCount: number, validatorCount: number, foreignValidator: boolean) { + if (slashedCount == 0) { + return } - private getAPRFrom(days: number, validatorDepositActive: BigNumber, performance: BigNumber): number { - return new BigNumber(performance.toString()) - .multipliedBy(36500 / days) - .dividedBy(validatorDepositActive) - .decimalPlaces(1) - .toNumber() + if (dashboardStatus.state == StateType.none) { + dashboardStatus.icon = 'alert-circle-outline' + dashboardStatus.iconCss = 'err' + dashboardStatus.state = StateType.slashed + } else { + dashboardStatus.state = StateType.mixed } - private getDashboardState(validators: Validator[], currentEpoch: EpochResponse, foreignValidator, network: ApiNetwork): DashboardStatus { - // collect data - const validatorCount = validators.length - const activeValidators = this.getActiveValidators(validators) - const activeValidatorCount = activeValidators.length - const slashedValidators = this.getSlashedValidators(validators) - const slashedCount = slashedValidators.length - const exitedValidators = this.getExitedValidators(validators) - const exitedValidatorsCount = exitedValidators.length - const awaitingActivation = this.getWaitingForActivationValidators(validators) - const awaitingCount = awaitingActivation.length - const activationEligibility = this.getEligableValidators(validators) - const eligibilityCount = activationEligibility.length - - // create status object with some default values - const dashboardStatus: DashboardStatus = { - state: StateType.none, - title: `${activeValidatorCount} / ${validatorCount}`, - iconCss: 'ok', - icon: 'checkmark-circle-outline', - description: [], - extendedDescription: '', - extendedDescriptionPre: '', - } - - //// - // Attention: The order of all the updateStateX functions matters! - // The first one that matches will set the icon and its css as well as, if only one state matches, the extendedDescription - - // handle slashed validators - this.updateStateSlashed(dashboardStatus, slashedCount, validatorCount, foreignValidator, slashedValidators[0]?.data, currentEpoch, network) - - // handle offline validators - const offlineCount = validatorCount - activeValidatorCount - exitedValidatorsCount - slashedCount - awaitingCount - eligibilityCount - this.updateStateOffline(dashboardStatus, validatorCount, offlineCount, foreignValidator) - - // handle awaiting activation validators - if (awaitingCount > 0) { - this.updateStateAwaiting(dashboardStatus, awaitingCount, validatorCount, foreignValidator, awaitingActivation[0].data, currentEpoch, network) - } - - // handle eligable validators - if (eligibilityCount > 0) { - this.updateStateEligibility( - dashboardStatus, - eligibilityCount, - validatorCount, - foreignValidator, - activationEligibility[0].data, - currentEpoch, - network - ) - } - - // handle exited validators - this.updateExitedState(dashboardStatus, exitedValidatorsCount, validatorCount, foreignValidator) - - // handle ok state, always call last - this.updateStateOk(dashboardStatus, activeValidatorCount, validatorCount, foreignValidator, activeValidators[0]?.data, currentEpoch, network) - - if (dashboardStatus.state == StateType.mixed) { - // remove extended description if more than one state is shown - dashboardStatus.extendedDescription = '' - dashboardStatus.extendedDescriptionPre = '' - } + const pre = validatorCount == slashedCount ? 'All' : `${slashedCount}` + const helpingVerb = singularPluralSwitch(validatorCount, slashedCount, 'was', 'were') + dashboardStatus.description.push({ + text: descriptionSwitch(pre + ' of your validators' + helpingVerb + ' slashed', 'This validator was slashed', foreignValidator), + highlight: true, + }) +} - return dashboardStatus +function updateStateAwaiting(dashboardStatus: DashboardStatus, awaitingCount: number, validatorCount: number, foreignValidator: boolean) { + if (awaitingCount == 0) { + return } - private descriptionSwitch(myText, foreignText, foreignValidator) { - return foreignValidator ? foreignText : myText + if (dashboardStatus.state == StateType.none) { + dashboardStatus.icon = 'timer-outline' + dashboardStatus.iconCss = 'waiting' + dashboardStatus.state = StateType.activation } - private getExitingDescription(validatorResp: ValidatorResponse, currentEpoch: EpochResponse, network: ApiNetwork): Description { - if (!validatorResp.exitepoch) return { extendedDescriptionPre: null, extendedDescription: null } - - const exitDiff = validatorResp.exitepoch - currentEpoch.epoch - const isExiting = exitDiff >= 0 && exitDiff < 6480 // ~ 1 month - const exitingDate = isExiting ? this.getEpochDate(validatorResp.exitepoch, currentEpoch, network) : null + const pre = validatorCount == awaitingCount ? 'All' : `${awaitingCount}` + const helpingVerb = singularPluralSwitch(validatorCount, awaitingCount, 'is', 'are') + dashboardStatus.description.push({ + text: descriptionSwitch( + pre + ' of your validators' + helpingVerb + ' waiting for activation', + 'This validator is waiting for activation', + foreignValidator + ), + highlight: true, + }) +} - return { - extendedDescriptionPre: isExiting ? 'Exiting on ' : null, - extendedDescription: exitingDate, - } +function updateExitedState(dashboardStatus: DashboardStatus, exitedCount: number, validatorCount: number, foreignValidator: boolean) { + if (exitedCount == 0) { + return } - private singularPluralSwitch(totalValidatorCount: number, validatorCount: number, verbSingular: string, verbPlural: string): string { - if (totalValidatorCount != validatorCount && validatorCount == 1) { - return ` ${verbSingular}` - } else { - return ` ${verbPlural}` - } + const allValidatorsExited = validatorCount == exitedCount + if (dashboardStatus.state == StateType.none && allValidatorsExited) { + dashboardStatus.icon = descriptionSwitch('ribbon-outline', 'home-outline', foreignValidator) + dashboardStatus.iconCss = 'ok' + dashboardStatus.state = StateType.exited + dashboardStatus.extendedDescription = descriptionSwitch('Thank you for your service', null, foreignValidator) + } else { + dashboardStatus.state = StateType.mixed } - private updateStateSlashed( - dashboardStatus: DashboardStatus, - slashedCount: number, - validatorCount: number, - foreignValidator: boolean, - validatorResp: ValidatorResponse, - currentEpoch: EpochResponse, - network: ApiNetwork - ) { - if (slashedCount == 0) { - return - } - - if (dashboardStatus.state == StateType.none) { - dashboardStatus.icon = 'alert-circle-outline' - dashboardStatus.iconCss = 'err' - const exitingDescription = this.getExitingDescription(validatorResp, currentEpoch, network) - dashboardStatus.extendedDescriptionPre = exitingDescription.extendedDescriptionPre - dashboardStatus.extendedDescription = exitingDescription.extendedDescription - dashboardStatus.state = StateType.slashed - } else { - dashboardStatus.state = StateType.mixed - } + const pre = allValidatorsExited ? 'All' : `${exitedCount}` + const helpingVerb = singularPluralSwitch(validatorCount, exitedCount, 'has', 'have') + // exit message is only highlighted if it is about foreign validators or if all validators are exited + const highlight = foreignValidator || allValidatorsExited + dashboardStatus.description.push({ + text: descriptionSwitch(pre + ' of your validators' + helpingVerb + ' exited', 'This validator has exited', foreignValidator), + highlight: highlight, + }) +} - const pre = validatorCount == slashedCount ? 'All' : `${slashedCount}` - const helpingVerb = this.singularPluralSwitch(validatorCount, slashedCount, 'was', 'were') - dashboardStatus.description.push({ - text: this.descriptionSwitch(pre + ' of your validators' + helpingVerb + ' slashed', 'This validator was slashed', foreignValidator), - highlight: true, - }) +function updateStateOffline(dashboardStatus: DashboardStatus, validatorCount: number, offlineCount: number, foreignValidator: boolean) { + if (offlineCount == 0) { + return } - private updateStateAwaiting( - dashboardStatus: DashboardStatus, - awaitingCount: number, - validatorCount: number, - foreignValidator: boolean, - awaitingActivation: ValidatorResponse, - currentEpoch: EpochResponse, - network: ApiNetwork - ) { - if (awaitingCount == 0) { - return - } - - if (dashboardStatus.state == StateType.none) { - const estEta = this.getEpochDate(awaitingActivation.activationeligibilityepoch, currentEpoch, network) - - dashboardStatus.icon = 'timer-outline' - dashboardStatus.iconCss = 'waiting' - dashboardStatus.state = StateType.activation - dashboardStatus.extendedDescriptionPre = estEta ? 'Estimated on ' : null - dashboardStatus.extendedDescription = estEta ? estEta : null - } - - const pre = validatorCount == awaitingCount ? 'All' : `${awaitingCount}` - const helpingVerb = this.singularPluralSwitch(validatorCount, awaitingCount, 'is', 'are') - dashboardStatus.description.push({ - text: this.descriptionSwitch( - pre + ' of your validators' + helpingVerb + ' waiting for activation', - 'This validator is waiting for activation', - foreignValidator - ), - highlight: true, - }) + if (dashboardStatus.state == StateType.none) { + dashboardStatus.icon = 'alert-circle-outline' + dashboardStatus.iconCss = 'warn' + dashboardStatus.state = StateType.offline + } else { + dashboardStatus.state = StateType.mixed } - private updateStateEligibility( - dashboardStatus: DashboardStatus, - eligibilityCount: number, - validatorCount: number, - foreignValidator: boolean, - eligbleState: ValidatorResponse, - currentEpoch: EpochResponse, - network: ApiNetwork - ) { - if (eligibilityCount == 0) { - return - } - - const estEta = this.getEpochDate(eligbleState.activationeligibilityepoch, currentEpoch, network) - - if (dashboardStatus.state == StateType.none) { - dashboardStatus.icon = 'timer-outline' - dashboardStatus.iconCss = 'waiting' - dashboardStatus.state = StateType.eligibility - dashboardStatus.extendedDescriptionPre = estEta ? 'Estimated on ' : null - dashboardStatus.extendedDescription = estEta ? estEta : null - } - - const pre = validatorCount == eligibilityCount ? 'All' : `${eligibilityCount}` - const helpingVerb = this.singularPluralSwitch(validatorCount, eligibilityCount, 'is', 'are') - dashboardStatus.description.push({ - text: this.descriptionSwitch( - pre + " of your validators' deposits" + helpingVerb + ' being processed', - "This validator's deposit is being processed", - foreignValidator - ), - highlight: true, - }) - } - - private updateExitedState(dashboardStatus: DashboardStatus, exitedCount: number, validatorCount: number, foreignValidator: boolean) { - if (exitedCount == 0) { - return - } - - const allValidatorsExited = validatorCount == exitedCount - if (dashboardStatus.state == StateType.none && allValidatorsExited) { - dashboardStatus.icon = this.descriptionSwitch('ribbon-outline', 'home-outline', foreignValidator) - dashboardStatus.iconCss = 'ok' - dashboardStatus.state = StateType.exited - dashboardStatus.extendedDescription = this.descriptionSwitch('Thank you for your service', null, foreignValidator) - } else { - dashboardStatus.state = StateType.mixed - } + const pre = validatorCount == offlineCount ? 'All' : `${offlineCount}` + const helpingVerb = singularPluralSwitch(validatorCount, offlineCount, 'is', 'are') + dashboardStatus.description.push({ + text: descriptionSwitch(pre + ' of your validators' + helpingVerb + ' offline', 'This validator is offline', foreignValidator), + highlight: true, + }) +} - const pre = allValidatorsExited ? 'All' : `${exitedCount}` - const helpingVerb = this.singularPluralSwitch(validatorCount, exitedCount, 'has', 'have') - // exit message is only highlighted if it is about foreign validators or if all validators are exited - const highlight = foreignValidator || allValidatorsExited - dashboardStatus.description.push({ - text: this.descriptionSwitch(pre + ' of your validators' + helpingVerb + ' exited', 'This validator has exited', foreignValidator), - highlight: highlight, - }) +function updateStateOk(dashboardStatus: DashboardStatus, activeCount: number, validatorCount: number, foreignValidator: boolean) { + if (dashboardStatus.state != StateType.mixed && dashboardStatus.state != StateType.none) { + return } - private updateStateOffline(dashboardStatus: DashboardStatus, validatorCount: number, offlineCount: number, foreignValidator: boolean) { - if (offlineCount == 0) { - return - } - - if (dashboardStatus.state == StateType.none) { - dashboardStatus.icon = 'alert-circle-outline' - dashboardStatus.iconCss = 'warn' - dashboardStatus.state = StateType.offline - } else { - dashboardStatus.state = StateType.mixed - } - - const pre = validatorCount == offlineCount ? 'All' : `${offlineCount}` - const helpingVerb = this.singularPluralSwitch(validatorCount, offlineCount, 'is', 'are') + if (dashboardStatus.state == StateType.none) { + const pre = validatorCount == activeCount ? 'All' : `${activeCount}` + const helpingVerb = singularPluralSwitch(validatorCount, activeCount, 'is', 'are') dashboardStatus.description.push({ - text: this.descriptionSwitch(pre + ' of your validators' + helpingVerb + ' offline', 'This validator is offline', foreignValidator), + text: descriptionSwitch(pre + ' of your validators ' + helpingVerb + ' active', 'This validator is active', foreignValidator), highlight: true, }) - } - - private updateStateOk( - dashboardStatus: DashboardStatus, - activeCount: number, - validatorCount: number, - foreignValidator: boolean, - validatorResp: ValidatorResponse, - currentEpoch: EpochResponse, - network: ApiNetwork - ) { - if (dashboardStatus.state != StateType.mixed && dashboardStatus.state != StateType.none) { - return - } - if (dashboardStatus.state == StateType.none) { - const pre = validatorCount == activeCount ? 'All' : `${activeCount}` - const helpingVerb = this.singularPluralSwitch(validatorCount, activeCount, 'is', 'are') - dashboardStatus.description.push({ - text: this.descriptionSwitch(pre + ' of your validators ' + helpingVerb + ' active', 'This validator is active', foreignValidator), - highlight: true, - }) - - const exitingDescription = this.getExitingDescription(validatorResp, currentEpoch, network) - dashboardStatus.extendedDescriptionPre = exitingDescription.extendedDescriptionPre - dashboardStatus.extendedDescription = exitingDescription.extendedDescription - dashboardStatus.state = StateType.online - } - } - - private getEpochDate(activationEpoch: number, currentEpoch: EpochResponse, network: ApiNetwork) { - try { - const diff = activationEpoch - currentEpoch.epoch - if (diff <= 0) { - if (this.refreshCallback) this.refreshCallback() - return null - } - - const date = new Date(currentEpoch.lastCachedTimestamp) - - const inEpochOffset = (network.slotPerEpoch - currentEpoch.scheduledblocks) * network.slotsTime - - date.setSeconds(diff * 6.4 * 60 - inEpochOffset) - - const timeString = formatDate(date, 'medium', 'en-US') - return timeString - } catch (e) { - console.warn('could not get activation time', e) - return null - } - } - - private getActiveValidators(validators: Validator[]) { - return validators.filter((item) => { - return item.state == ValidatorState.ACTIVE - }) - } - - private getOfflineValidators(validators: Validator[]) { - return validators.filter((item) => { - return item.state == ValidatorState.OFFLINE - }) - } - - private getSlashedValidators(validators: Validator[]) { - return validators.filter((item) => { - return item.state == ValidatorState.SLASHED - }) + dashboardStatus.state = StateType.online } +} - private getExitedValidators(validators: Validator[]) { - return validators.filter((item) => { - return item.state == ValidatorState.EXITED - }) +function emptyPerformance(): Performance { + return { + performance1d: new BigNumber(0), + performance30d: new BigNumber(0), + performance7d: new BigNumber(0), + total: new BigNumber(0), + apr7d: 0, + apr30d: 0, + aprTotal: 0, } +} - private getWaitingForActivationValidators(validators: Validator[]) { - return validators.filter((item) => { - return item.state == ValidatorState.WAITING - }) +function getExecutionPerformance(overviewData: VDBOverviewData): Performance { + if (!overviewData) return emptyPerformance() + return { + performance1d: new BigNumber(overviewData.rewards.last_24h.el), + performance30d: new BigNumber(overviewData.rewards.last_30d.el), + performance7d: new BigNumber(overviewData.rewards.last_7d.el), + total: new BigNumber(overviewData.rewards.all_time.el), + apr30d: overviewData.apr.last_30d.el, + apr7d: overviewData.apr.last_7d.el, + aprTotal: overviewData.apr.all_time.el, } +} - private getEligableValidators(validators: Validator[]) { - return validators.filter((item) => { - return item.state == ValidatorState.ELIGABLE - }) +function getConsensusPerformance(overviewData: VDBOverviewData): Performance { + if (!overviewData) return emptyPerformance() + return { + performance1d: new BigNumber(overviewData.rewards.last_24h.cl), + performance30d: new BigNumber(overviewData.rewards.last_30d.cl), + performance7d: new BigNumber(overviewData.rewards.last_7d.cl), + total: new BigNumber(overviewData.rewards.all_time.cl), + apr30d: overviewData.apr.last_30d.cl, + apr7d: overviewData.apr.last_7d.cl, + aprTotal: overviewData.apr.all_time.cl, } +} - private calculateSyncCommitteeStats(stats: SyncCommitteesStatisticsResponse, network: ApiNetwork): SyncCommitteesStatistics { - if (stats) { - // if no slots where expected yet, don't show any statistic as either no validator is subscribed or they have not been active in the selected timeframe - if (stats.expectedSlots > 0) { - const slotsTotal = stats.participatedSlots + stats.missedSlots - const slotsPerSyncPeriod = network.slotPerEpoch * network.epochsPerSyncPeriod - const r: SyncCommitteesStatistics = { - committeesParticipated: Math.ceil(slotsTotal / network.slotPerEpoch / network.epochsPerSyncPeriod), - committeesExpected: Math.round((stats.expectedSlots * 100) / network.slotPerEpoch / network.epochsPerSyncPeriod) / 100, - slotsPerSyncCommittee: slotsPerSyncPeriod, - slotsLeftInSyncCommittee: slotsPerSyncPeriod - stats.scheduledSlots, - slotsParticipated: stats.participatedSlots, - slotsMissed: stats.missedSlots, - slotsScheduled: stats.scheduledSlots, - efficiency: 0, - luck: (slotsTotal * 100) / stats.expectedSlots, - } - if (slotsTotal > 0) { - r.efficiency = Math.round(((stats.participatedSlots * 100) / slotsTotal) * 100) / 100 - } - - return r - } - } - return null +function getCombinedPerformance(cons: Performance, exec: Performance, unit: UnitconvService): Performance { + return { + performance1d: cons.performance1d.plus(unit.convertELtoCL(exec.performance1d)), + performance30d: cons.performance30d.plus(unit.convertELtoCL(exec.performance30d)), + performance7d: cons.performance7d.plus(unit.convertELtoCL(exec.performance7d)), + total: cons.total.plus(unit.convertELtoCL(exec.total)), + apr30d: cons.apr30d + exec.apr30d, + apr7d: cons.apr7d + exec.apr7d, + aprTotal: cons.aprTotal + exec.aprTotal, } } diff --git a/src/app/controllers/SlotVizController.ts b/src/app/controllers/SlotVizController.ts new file mode 100644 index 00000000..52200c44 --- /dev/null +++ b/src/app/controllers/SlotVizController.ts @@ -0,0 +1,185 @@ +// Copyright (C) 2025 bitfly explorer GmbH +// +// This file is part of Beaconchain Dashboard. +// +// Beaconchain Dashboard is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Beaconchain Dashboard is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Beaconchain Dashboard. If not, see . + +import { computed, Injectable, NgZone, Signal, signal, WritableSignal } from '@angular/core' +import { LatestStateData } from '@requests/types/latest_state' +import { SlotVizEpoch, VDBSlotVizSlot } from '@requests/types/slot_viz' +import { dashboardID, V2SlotViz } from '@requests/v2-dashboard' +import { ApiService } from '@services/api.service' +import { ChainNetwork, findChainNetworkById } from '@utils/NetworkData' +import { slotToSecondsTimestamp, timestampToSlot, timeUntilNextSlot } from '@utils/TimeUtils' + +export type FilterType = 'block' | 'attestation' | 'sync' | 'slash' + +@Injectable({ providedIn: 'root' }) +export class SlotVizProvider { + private dashboardID: dashboardID + private groupID: number = -1 + + private running: boolean = false + + private intervalId: ReturnType | null = null + private timerSignal = signal(0) + + private currentChainConfig: ChainNetwork + + private latestState: WritableSignal = signal(null) + public slotViz: WritableSignal = signal(null) + + slots = computed(() => { + if (this.slotViz() == null) return [] + return this.slotViz() + .flatMap((item) => item.slots) + .sort((a, b) => a.slot - b.slot) + }) + + previousDuties: Signal = computed(() => { + // give me all slots before current one where validator has a duty + const duties = this.slots() + .filter((slot) => this.slotHasDuty(slot) && slot.slot <= this.currentSlot()) + .sort((a, b) => b.slot - a.slot) + if (duties.length == 0) return [] + return duties + }) + + previousDuty: Signal = computed(() => { + this.currentSlot() + const duties = this.previousDuties() + + if (duties.length == 0) return null + return duties[0] + }) + + nextDuties: Signal = computed(() => { + // give me all slots after current one where validator has a duty + const duties = this.slots() + .filter((slot) => slot.slot > this.currentSlot() && this.slotHasDuty(slot)) + .sort((a, b) => a.slot - b.slot) + if (duties.length == 0) return [] + return duties + }) + + nextDuty: Signal = computed(() => { + this.currentSlot() + if (this.nextDuties().length == 0) return null + return this.nextDuties()[0] + + // let i = 0 + // while (i < this.nextDuties().length && this.slotTime(this.nextDuties()[i].slot) <= Date.now()) { + // i++ + // } + // return i < this.nextDuties().length ? this.nextDuties()[i] : null + }) + + currentSlot: Signal = computed(() => { + this.timerSignal() + const slot = timestampToSlot(this.api.networkConfig.supportedChainIds, Date.now()) + console.log('slotviz current slot') + return slot + }) + + currentEpoch: Signal = computed(() => { + return Math.floor(this.currentSlot() / findChainNetworkById(this.api.networkConfig.supportedChainIds).slotPerEpoch) + }) + + nextDutyTs: Signal = computed(() => { + if (this.slots().length == 0) return 0 + if (this.nextDuty() == null) return this.slotTime(this.slots()[this.slots().length - 1].slot) + return this.slotTime(this.nextDuty().slot) + }) + + private slotHasDuty(slot: VDBSlotVizSlot) { + return slot.attestations || slot.proposal || slot.sync + } + + constructor( + private api: ApiService, + private zone: NgZone + ) {} + + start(id: dashboardID, groupID: number) { + console.log('slotviz slot viz start') + this.dashboardID = id + this.groupID = groupID + + if (this.running) return + this.running = true + + this.startTimer() + this.serviceLoop() + } + + stop() { + this.running = false + if (this.intervalId) { + clearInterval(this.intervalId) + } + } + + private slotTime(slot: number) { + return slotToSecondsTimestamp(this.api.networkConfig.supportedChainIds, slot) * 1000 + } + + private serviceLoop() { + if (!this.running) return + + this.update() + this.currentChainConfig = findChainNetworkById(this.api.getNetwork().supportedChainIds) + setTimeout(() => this.serviceLoop(), this.currentChainConfig.slotsTime * 1000) + } + + private async update() { + const result = await Promise.all([ + // this.api.set(new V2LatestState().withAllowedCacheResponse(false), this.latestState), + this.api.set(new V2SlotViz(this.dashboardID, this.groupID).withAllowedCacheResponse(false), this.slotViz), + ]) + if (result[0].error) { + // || result[1].error + console.error('Error updating SlotVizProvider', result) + } + } + + changeDashboard(id: dashboardID) { + this.dashboardID = id + this.zone.run(() => { + this.timerSignal.set(Date.now()) + }) + } + + changeGroupID(groupID: number) { + this.groupID = groupID + this.zone.run(() => { + this.timerSignal.set(Date.now()) + }) + } + + private startTimer() { + const buffer = 0 + const wait = timeUntilNextSlot(this.api.networkConfig.supportedChainIds, Date.now()) + buffer + // start interval with start of next slot + setTimeout(() => { + this.zone.run(() => { + this.timerSignal.set(Date.now()) + }) + this.startTimer() + }, wait) + } + + ngOnDestroy() { + this.stop() + } +} diff --git a/src/app/directive/press.directive.ts b/src/app/directive/press.directive.ts new file mode 100644 index 00000000..d6db3bb4 --- /dev/null +++ b/src/app/directive/press.directive.ts @@ -0,0 +1,63 @@ +import { Directive, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core' +import { GestureController, Gesture, GestureDetail } from '@ionic/angular' + +@Directive({ + // Using the attribute name "press" so you can declare (press)="doAction()" + selector: '[press]', + standalone: true, +}) +export class PressDirective implements OnInit, OnDestroy { + /** + * Output event that fires when a long press is detected. + * You can bind to it as (press)="doAction()". + */ + @Output() press = new EventEmitter() + + /** + * How long (in ms) the user must press before it’s considered a long press. + * Default is 500ms. + */ + @Input() pressDuration = 300 + + private gesture: Gesture + private pressTimeout: any + + constructor( + private elementRef: ElementRef, + private gestureCtrl: GestureController + ) {} + + ngOnInit(): void { + this.gesture = this.gestureCtrl.create({ + el: this.elementRef.nativeElement, + gestureName: 'long-press', + threshold: 0, + onStart: (ev: GestureDetail) => this.startPressTimer(ev), + // Cancel the timer on end or if the pointer moves out + onEnd: () => this.cancelPressTimer(), + onMove: () => this.cancelPressTimer(), + }) + this.gesture.enable(true) + } + + private startPressTimer(ev: GestureDetail): void { + this.cancelPressTimer() // Ensure no previous timer is running + this.pressTimeout = setTimeout(() => { + // When the timer fires, emit the event + this.press.emit(ev) + }, this.pressDuration) + } + + private cancelPressTimer(): void { + if (this.pressTimeout) { + clearTimeout(this.pressTimeout) + this.pressTimeout = null + } + } + + ngOnDestroy(): void { + if (this.gesture) { + this.gesture.destroy() + } + } +} diff --git a/src/app/modals/dashboard-and-group-select/dashboard-and-group-select.component.html b/src/app/modals/dashboard-and-group-select/dashboard-and-group-select.component.html new file mode 100644 index 00000000..9d867390 --- /dev/null +++ b/src/app/modals/dashboard-and-group-select/dashboard-and-group-select.component.html @@ -0,0 +1,104 @@ + + + + + + Manage + + + My Dashboards + {{ dashboards() ? sortedValidatorDashboards().length : '-' }} / {{ maxAllowedDashboards() }} + + + + + + + + {{ + item.text + }} + + + + + + + + + + +
+ + + + New: Your Dashboards + + + You may have more than one dashboard. Each dashboard is associated with a network, like Ethereum or Gnosis. The new groups feature allows + you to further organize a dashboard. + +
+ +
+ + + + Sign in to beaconcha.in + + + Get free notifications about your validators, manage or share your dashboards and stay in sync from web or app. + +
+ +
+ + + + Get more with Premium + + + Premium lets you track more validators, access more dashboards and groups, extended history timeframes and much more. + +
+ + + +
+ +

No Dashboards

+
+ Do you want to create a new one? +
+ Create Dashboard +
+ +
+ + Old App Dashboards + + +
+
+
+
diff --git a/src/app/modals/dashboard-and-group-select/dashboard-and-group-select.component.scss b/src/app/modals/dashboard-and-group-select/dashboard-and-group-select.component.scss new file mode 100644 index 00000000..28380a95 --- /dev/null +++ b/src/app/modals/dashboard-and-group-select/dashboard-and-group-select.component.scss @@ -0,0 +1,101 @@ +// Copyright (C) 2024 bitfly explorer GmbH +// +// This file is part of Beaconchain Dashboard. +// +// Beaconchain Dashboard is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Beaconchain Dashboard is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Beaconchain Dashboard. If not, see . + +ion-list-header { + padding-top: 5px; +} + +.top-bar { + padding-bottom: 0px !important; + margin-bottom: 0px !important; +} + +.hint { + display: inline-block; + color: var(--ion-text-color-secondary); + + margin: var(--edge-padding-left-plus-15px); + font-size: var(--smaller-info-size); + font-weight: var(--smaller-label-weight); + line-height: 1.25em !important; + margin-bottom: 10px; + margin-right: 45px; +} + +.premium { + padding-bottom: 0px !important; + height: 38px; +} + +.prem-icon { + padding: 0px; + margin-right: 10px; + margin-top: 3px; + font-size: 18px; +} + +.prem-title { + padding-top: 0px; + margin-top: 0px; +} + +.ios .prem-title { + padding-top: 5px; +} + +.prem-x { + padding: 0px 0px 8px 8px; + margin: 1px; + font-size: 19px; + padding-bottom: 11px; +} + +.message { + margin-top: 10px; + margin-bottom: 10px; +} + +.ios .message ion-list { + padding: 4px 0px; +} + +.nothingfound ion-icon { + width: 100%; + display: flex; + justify-content: center; + text-align: center; + padding-bottom: 12px; + font-size: 55px; + color: var(--ion-text-color-lighter); +} + +.nothingfound { + text-align: center; + padding: 50px; + + padding-top: 45px; + color: var(--ion-text-color-lighter); + background-color: var(--background-color); +} + +.nothingfound ion-label { +} + +.link { + color: var(--ion-color-primary); + font-weight: bold; +} diff --git a/src/app/modals/dashboard-and-group-select/dashboard-and-group-select.component.ts b/src/app/modals/dashboard-and-group-select/dashboard-and-group-select.component.ts new file mode 100644 index 00000000..70e57cf7 --- /dev/null +++ b/src/app/modals/dashboard-and-group-select/dashboard-and-group-select.component.ts @@ -0,0 +1,524 @@ +import { Component, computed, effect, Input, OnInit, signal, WritableSignal } from '@angular/core' +import { AlertController, IonicModule, ModalController } from '@ionic/angular' +import { UserDashboardsData, ValidatorDashboard } from '@requests/types/dashboard' +import { V2MyDashboards } from '@requests/v2-user' +import { ApiService, capitalize } from '@services/api.service' +import { DashboardItemComponent, LegacyAdd } from '@components/dashboard-item/dashboard-item.component' +import { CommonModule } from '@angular/common' +import { dashboardID, V2CreateDashboard, V2DashboardOverview } from '@requests/v2-dashboard' +import { AlertService, DASHBOARD_SELECTOR } from '@services/alert.service' +import { Toast } from '@capacitor/toast' +import { MerchantUtils } from '@utils/MerchantUtils' +import { StorageService } from '@services/storage.service' +import { DashboardUtils } from '@utils/DashboardUtils' +import { OAuthUtils } from '@utils/OAuthUtils' +import { SubscribePage } from '@pages/subscribe/subscribe.page' +import { FullPageLoadingComponent } from '@components/full-page-loading/full-page-loading.component' +import { CHAIN_NETWORKS, findChainNetworkById, findChainNetworkByName } from '@utils/NetworkData' +import { fromEvent, Subscription } from 'rxjs' +import { FullPageOfflineComponent } from '@components/full-page-offline/full-page-offline.component' +import { OfflineComponentModule } from '@components/offline/offline.module' +import { ValidatorUtils } from '@utils/ValidatorUtils' +import { getValidatorCount } from '@controllers/OverviewController' +import { APIUnauthorizedError } from '@requests/requests' +import { SHOW_TESTNETS_CONFIG } from 'src/app/tabs/tab-preferences/tab-preferences.page' +import { UserInfo } from '@requests/types/user' + +const DASHBOARD_INFO_DISMISS_KEY = 'dashboard_info_dismissed' +const ASSOCIATED_CACHE_KEY = 'manage_dashboards' + +interface DashboardAddButton { + network: number + text: string +} +@Component({ + selector: 'app-dashboard-and-group-select', + imports: [CommonModule, IonicModule, DashboardItemComponent, FullPageLoadingComponent, FullPageOfflineComponent, OfflineComponentModule], + templateUrl: './dashboard-and-group-select.component.html', + styleUrl: './dashboard-and-group-select.component.scss', +}) +export class DashboardAndGroupSelectComponent implements OnInit { + @Input() dashboardChangedCallback: () => void + + name: string + + dashboards: WritableSignal = signal(null) + defaultDashboard: WritableSignal = signal(null) + + dashboardIDWhenEntered: dashboardID = null + + isLoggedIn = true + infoDismissed = true + + dashboardAddButtons: DashboardAddButton[] = [] + + private backbuttonSubscription: Subscription + + online: boolean = true + + legacyDashboard: ValidatorDashboard[] = [] + + initLoading: boolean = true + + constructor( + private modalCtrl: ModalController, + private api: ApiService, + private alertController: AlertController, + private alert: AlertService, + protected merchant: MerchantUtils, + private storage: StorageService, + private dashboardUtils: DashboardUtils, + private oauth: OAuthUtils, + private validatorUtils: ValidatorUtils + ) { + this.storage.getDashboardID().then((id) => { + this.defaultDashboard.set(id) + this.dashboardIDWhenEntered = id + }) + effect(() => { + if (this.defaultDashboard()) { + this.storage.setDashboardID(this.defaultDashboard()) + this.dashboardUtils.dashboardAwareListener.notifyAll() + } + }) + const event = fromEvent(document, 'backbutton') + this.backbuttonSubscription = event.subscribe(() => { + this.cancel() + }) + } + + async ngOnInit() { + this.infoDismissed = await this.storage.getBooleanSetting(DASHBOARD_INFO_DISMISS_KEY, false) + this.setup() + } + + maxAllowedDashboards = computed(() => { + return this.calculateMaxAllowedDashboards(this.merchant.userInfo()) + }) + + calculateMaxAllowedDashboards(userInfo: UserInfo) { + if (!userInfo) return 1 + return userInfo.premium_perks.validator_dashboards + } + + sortedValidatorDashboards = computed(() => { + return ( + this.dashboards()?.validator_dashboards?.sort((a, b) => { + return a.id - b.id + }) || [] + ) + }) + + async getLegacyDashboard() { + const push = (dashboard: ValidatorDashboard) => { + if (dashboard) this.legacyDashboard.push(dashboard) + } + + this.legacyDashboard = [] + push(await this.getLegacyDashboardForNetwork('main')) + push(await this.getLegacyDashboardForNetwork('gnosis')) + push(await this.getLegacyDashboardForNetwork('holesky')) + push(await this.getLegacyDashboardForNetwork('sepolia')) + } + + async getLegacyDashboardForNetwork(network: string) { + const localValidators = await this.validatorUtils.getMyLocalValidators(network) + if (!localValidators || localValidators.length <= 0) { + return + } + + // special case for network key difference between v1 and v2 + if (network == 'main') { + network = 'ethereum' + } + + return { + id: -1 - findChainNetworkByName(network).id, + name: 'Legacy Dashboard', + network: findChainNetworkByName(network).id, + is_archived: false, + validator_count: localValidators.length, + group_count: 1, + } as ValidatorDashboard + } + + async initNetworks() { + this.dashboardAddButtons = [] + + CHAIN_NETWORKS.forEach((network) => { + if (!network.testnet) { + this.dashboardAddButtons.push({ + network: network.id, + text: `Add on ${capitalize(network.name)}`, + }) + } + }) + + if (await this.storage.getBooleanSetting(SHOW_TESTNETS_CONFIG, false)) { + CHAIN_NETWORKS.forEach((network) => { + if (network.testnet) { + this.dashboardAddButtons.push({ + network: network.id, + text: `Add on ${capitalize(network.name)} (Test)`, + }) + } + }) + } + } + + async setup() { + this.online = true + await this.initNetworks() + + this.getLegacyDashboard() + + this.isLoggedIn = await this.storage.isLoggedIn() + // @deprecated - remove in v2 + if (!this.isLoggedIn) { + this.dashboards.set({ + validator_dashboards: [ + { + id: null, + name: 'Default', + network: this.api.networkConfig.supportedChainIds, + is_archived: false, + validator_count: await this.dashboardUtils.getLocalValidatorCount(), + group_count: 1, + }, + ], + } as UserDashboardsData) + this.initLoading = false + return + } + + const result = await this.api.getAllUserDashboards(ASSOCIATED_CACHE_KEY) + console.log('all dashboards', result) + if (result.error) { + console.warn('dashboards can not be loaded', result.error) + + this.dashboardUtils.defaultDashboardErrorHandler(result.error) + if (!(result.error instanceof APIUnauthorizedError)) { + this.online = false + } + this.initLoading = false + return + } else { + this.dashboards.set(result.data) + } + + // Convenience: If user already has a testnet dashboard, allow them to create dashboards on testnets too + if (this.hasTestnetDashboard(result.data.validator_dashboards)) { + await this.storage.setBooleanSetting(SHOW_TESTNETS_CONFIG, true) + this.initNetworks() + } + + this.merchant.getUserInfo(false) + this.initLoading = false + } + + hasTestnetDashboard(data: ValidatorDashboard[]) { + let has = false + data.forEach((dashboard) => { + CHAIN_NETWORKS.forEach((network) => { + if (network.testnet) { + if (dashboard.network == network.id && network.testnet) { + has = true + } + } + }) + }) + return has + } + + async addDashboard(network: number, onSuccessCallback: (id: dashboardID) => void = null) { + if (!this.isLoggedIn) { + this.alert.showInfo('Login required', 'You must be logged in to your beaconcha.in account to create or manage dashboards.') + return + } + + const networkName = findChainNetworkById(network).name + + const networkPerks = await this.merchant.getUserInfoOnNetwork(network, false) + if (networkPerks.error) { + this.alert.showError('Error', 'Could not load network config, please try again later.', DASHBOARD_SELECTOR) + return + } + + const validatorCountOnNetwork = this.sortedValidatorDashboards().filter((d) => d.network == network).length + if (validatorCountOnNetwork >= this.merchant.highestPackageDashboardsAllowed()) { + this.alert.showInfo( + 'Maximum dashboards reached', + 'You reached the highest possible number of dashboards we currently support on that network.

If you feel like you need more, let us know!' + ) + return + } + + if (validatorCountOnNetwork >= this.calculateMaxAllowedDashboards(networkPerks.data)) { + this.alert.showInfo( + 'Upgrade to premium', + 'You have reached the maximum number of dashboards allowed for your plan on that network.

You can create more dashboards by upgrading to a premium plan.' + ) + return + } + + const alert = await this.alertController.create({ + cssClass: 'my-custom-class', + header: 'New ' + capitalize(networkName) + ' Dashboard', + inputs: [ + { + name: 'newName', + type: 'text', + placeholder: 'Dashboard name', + }, + ], + buttons: [ + { + text: 'Cancel', + role: 'cancel', + cssClass: 'secondary', + handler: () => { + return + }, + }, + { + text: 'Create', + handler: async (alertData) => { + if (alertData.newName.length < 1) { + Toast.show({ + text: 'Please enter a name', + }) + return false + } + + const loading = await this.alert.presentLoading('Applying changes...') + loading.present() + + const result = await this.api.executeOnChainID(new V2CreateDashboard(alertData.newName, network), null, network) + if (result.error) { + Toast.show({ + text: 'Error creating dashboard, please try again later', + }) + } else { + if (onSuccessCallback) { + loading.dismiss() + onSuccessCallback(result.data.id) + return + } + Toast.show({ + text: 'Dashboard created', + }) + this.doRefresh() + } + + loading.dismiss() + }, + }, + ], + }) + + await alert.present() + } + + async cancel() { + const setDefault = (id: dashboardID) => { + this.defaultDashboard.set(id) + if (this.dashboardChangedCallback) { + this.dashboardChangedCallback() + } + } + + // When the current default dashboard has been deleted, we must either pick another or create a new one + if (this.isLoggedIn && this.sortedValidatorDashboards().find((item) => item.id == this.defaultDashboard()) == null) { + // if there's at least one other, pick the first + if (this.sortedValidatorDashboards().length >= 1) { + setDefault(this.sortedValidatorDashboards()[0].id) + } else { + // else we must create one + const result = await this.api.execute(new V2CreateDashboard('Default Dashboard', this.api.networkConfig.supportedChainIds)) + if (result.error) { + Toast.show({ + text: 'Error creating dashboard, please try again later', + }) + } + this.api.clearSpecificCache(new V2MyDashboards()) + setDefault(result.data.id) + } + } else if (this.defaultDashboard() != this.dashboardIDWhenEntered) { + if (this.dashboardChangedCallback) { + this.dashboardChangedCallback() + } + } + return this.modalCtrl.dismiss(null, 'cancel') + } + + legacyAddToDashboard(legacyAddData: LegacyAdd) { + if (!this.isLoggedIn) { + this.alert.showInfo('Login required', 'You must be logged in to your beaconcha.in account to add validators to your dashboard.') + return + } + + const index = legacyAddData.indices + + const add = (id: dashboardID) => { + this.alert.confirmDialog( + 'Migrate from Legacy Dashboard', + `Do you want to add ${index.length} validator${index.length > 1 ? 's' : ''} from your legacy dashboard to your new dashboard "${this.dashboards()?.validator_dashboards?.find((d) => d.id == id)?.name}"?`, + 'OK', + async () => { + let loading = await this.alert.presentLoading('Loading...') + loading.present() + const result = await this.api.execute(new V2DashboardOverview(id), ASSOCIATED_CACHE_KEY) + if (result.error) { + Toast.show({ + text: 'Can not add validators right now, please try again later', + }) + loading.dismiss() + return + } + loading.dismiss() + + const validatorCount = getValidatorCount(result.data) + + if (validatorCount + index.length > this.merchant.getCurrentPlanMaxValidator()) { + Toast.show({ + text: 'You dashboard is full or does not fit all legacy validators', + }) + loading.dismiss() + return + } + + const allGroups = result.data.groups.map((g) => { + return { + name: 'group', + label: g.name + ' (' + g.count + ')', + value: g.id, + type: 'radio', + disabled: g.count + index.length >= this.merchant.getCurrentPlanMaxValidator(), + } + }) + + this.alert.showSelect('Add to Group', allGroups, async (groupID: number) => { + loading = await this.alert.presentLoading('Migrating...') + loading.present() + const ok = await this.dashboardUtils.addValidators(index, groupID, id) + if (!ok) { + Toast.show({ + text: 'Can not add validators right now, please try again later', + }) + loading.dismiss() + return + } + + await this.doRefresh() + this.dashboardUtils.dashboardAwareListener.notifyAll() + loading.dismiss() + this.dashboardChangedCallback() + Toast.show({ + text: 'Validators added to group', + }) + }) + } + ) + } + + const allDashboardOptions = () => { + const result = this.dashboards().validator_dashboards.map((d) => { + return { + name: 'dashboard', + label: d.name, + value: d.id, + type: 'radio', + checked: d.id == this.defaultDashboard(), + } + }) + + result.push({ + name: 'dashboard', + label: 'Create new dashboard', + value: -1, + type: 'radio', + checked: false, + }) + return result + } + + this.alert.showSelectWithCancel('Select Dashboard', allDashboardOptions(), async (selectedDashboardID: dashboardID) => { + const checkNetwork = (id: dashboardID) => { + const formatNetwork = (network: string) => { + if (network == 'main') return 'Ethereum' + return capitalize(network) + } + + const targetNetwork = findChainNetworkById( + this.dashboards()?.validator_dashboards?.find((d) => d.id == selectedDashboardID).network + ).legacyKey + if (legacyAddData.network != targetNetwork) { + const originName = formatNetwork(legacyAddData.network) + const targetName = formatNetwork(targetNetwork) + + this.alert.confirmDialog( + 'Network mismatch', + `This legacy dashboard is from the network "${originName}" but your target dashboard is from the network "${targetName}".

Do you want to add them anyway?`, + 'OK (NOT RECOMMENDED)', + () => { + add(id) + }, + 'error-btn' + ) + } else { + add(id) + } + } + + if (selectedDashboardID == -1) { + await this.addDashboard(this.dashboardAddButtons[0].network, (id: dashboardID) => { + checkNetwork(id) + }) + } else { + checkNetwork(selectedDashboardID) + } + }) + } + + defaultDashboardData = computed(() => { + return this.dashboards()?.validator_dashboards?.find((d) => d.id == this.defaultDashboard()) + }) + + /** + * Call when you need to clear the API request cache for all calls this view made. + * Note: when making calls in this view, always use the ASSOCIATED_CACHE_KEY + * @returns promise void + */ + clearRequestCache() { + return this.api.clearAllAssociatedCacheKeys(ASSOCIATED_CACHE_KEY) + } + + async doRefresh() { + await this.clearRequestCache() + return this.setup() + } + + async signIn() { + const success = await this.oauth.login() + if (success) { + this.setup() + } + } + + async sellUp() { + const modal = await this.modalCtrl.create({ + component: SubscribePage, + cssClass: 'my-custom-class', + }) + return await modal.present() + } + + dismissInfo() { + this.storage.setBooleanSetting(DASHBOARD_INFO_DISMISS_KEY, true) + this.infoDismissed = true + } + + ngOnDestroy() { + this.backbuttonSubscription.unsubscribe() + } +} diff --git a/src/app/models/StorageTypes.ts b/src/app/models/StorageTypes.ts index be7660c4..8508b675 100644 --- a/src/app/models/StorageTypes.ts +++ b/src/app/models/StorageTypes.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -18,12 +17,17 @@ * // along with Beaconchain Dashboard. If not, see . */ +/**@deprecated */ export interface AuthUser { accessToken: string refreshToken: string expiresIn: number } +export interface AuthUserv2 { + Session: string +} + export interface ApiNetwork { key: string protocol: string @@ -33,13 +37,9 @@ export interface ApiNetwork { version: string onlyDebug: boolean active: boolean - genesisTs: number - elCurrency: NetworkMainCurrency - clCurrency: NetworkMainCurrency - slotPerEpoch: number - slotsTime: number - epochsPerSyncPeriod: number + supportedChainIds: number name: string + v2NetworkConfigKey?: string } export class NetworkMainCurrency { diff --git a/src/app/pages/block-detail/block-detail.module.ts b/src/app/pages/block-detail/block-detail.module.ts index 2ae1c57d..532f018d 100644 --- a/src/app/pages/block-detail/block-detail.module.ts +++ b/src/app/pages/block-detail/block-detail.module.ts @@ -7,10 +7,12 @@ import { IonicModule } from '@ionic/angular' import { BlockDetailPageRoutingModule } from './block-detail-routing.module' import { BlockDetailPage } from './block-detail.page' -import { PipesModule } from 'src/app/pipes/pipes.module' +import { PipesModule } from '@pipes/pipes.module' +import { FullPageLoadingComponent } from '@components/full-page-loading/full-page-loading.component' +import { FullPageOfflineComponent } from '@components/full-page-offline/full-page-offline.component' @NgModule({ - imports: [CommonModule, FormsModule, IonicModule, BlockDetailPageRoutingModule, PipesModule], + imports: [CommonModule, FormsModule, IonicModule, BlockDetailPageRoutingModule, PipesModule, FullPageLoadingComponent, FullPageOfflineComponent], declarations: [BlockDetailPage], }) export class BlockDetailPageModule {} diff --git a/src/app/pages/block-detail/block-detail.page.html b/src/app/pages/block-detail/block-detail.page.html index 012c47da..f6cff50e 100644 --- a/src/app/pages/block-detail/block-detail.page.html +++ b/src/app/pages/block-detail/block-detail.page.html @@ -1,12 +1,13 @@ - - + + - #{{ block.blockNumber }} + Block {{ block.block }} + Slot {{ block.slot }} @@ -30,7 +31,7 @@
- {{ feeRecipient }} + {{ feeRecipient || "no recipient" }} {{ nameResolved }} @@ -39,127 +40,186 @@
- - General - - - - - Proposer - {{ block.posConsensus.proposerIndex }} - - - - Producer Reward - - {{ block.producerReward | mcurrency: "WEI":unit.pref.Exec }} - - - - - Burned - {{ burned | mcurrency: "WEI":unit.pref.Exec }} - - - - Base Fee - {{ baseFee }} - - - - Gas Used - - {{ this.block.gasUsed }} - {{ gasUsedPercent }} % - - - - - Gas Limit - {{ this.block.gasLimit }} - - - - Time - {{ timestamp | date:'MMM d, yy, h:mm' }} - - - - - Consensus - - - - - Epoch - {{ block.posConsensus.epoch }} - - - - Slot - {{ block.posConsensus.slot }} - - - - Finalized - - - - - - - - - MEV - - - - - Relay - {{ block.relay.tag }} - - - - - Content - - - - - TX Count - {{ block.txCount }} - - - - Internal Count - {{ block.internalTxCount }} - - - - Ommer Count - {{ block.uncleCount }} - - - - - Links - - - - - - - View Block - - - - - - - View Fee Recipient - - - - -
+
+ + +
+ + Proposer Rewards + + + + Execution + + {{ block.reward?.el || 0 | mcurrency: "WEI":unit.pref.Exec }} + + + + + Consensus + + {{ block.reward?.cl || 0 | mcurrency: "WEI":unit.pref.Exec }} + + + + + + General + + + + + Status + {{ block.status }} + + + + Proposer + {{ block.proposer }} + + + + + + + Base Fee + {{ v1Overview()?.baseFee }} + + + + Gas Used + + {{ this.v1Overview()?.gasUsed }} + {{ gasUsedPercent() }} % + + + + + Gas Limit + {{ this.v1Overview()?.gasLimit }} + + + + + Time + {{ timestamp | date:'MMM d, yy, h:mm' }} + + + + + Consensus + + + + + Epoch + + {{ v1Overview()?.posConsensus?.epoch || block.slot / getChainNetwork().slotPerEpoch | number: '1.0-0'}} + + + + + + Slot + {{ block.slot | number: '1.0-0' }} + + + + + + + + + Content + + + + + TX Count + {{v1Overview()?.txCount }} + + + + Internal Count + {{ v1Overview()?.internalTxCount }} + + + + + + + Graffiti + + + + + {{ block.graffiti }} + + + + + Links + + + + + + + View Block + + + + + + + View Fee Recipient + + + + +
+
+
+
+
diff --git a/src/app/pages/block-detail/block-detail.page.scss b/src/app/pages/block-detail/block-detail.page.scss index 3d38137a..359b8db9 100644 --- a/src/app/pages/block-detail/block-detail.page.scss +++ b/src/app/pages/block-detail/block-detail.page.scss @@ -1,4 +1,4 @@ -// Copyright (C) 2022 Bitfly GmbH +// Copyright (C) 2022 bitfly explorer GmbH // // This file is part of Beaconchain Dashboard. // @@ -15,7 +15,7 @@ // You should have received a copy of the GNU General Public License // along with Beaconchain Dashboard. If not, see . -@import '../../../theme/variables.scss'; +@use '../../../theme/variables.scss'; // Makes the iOS top bounce in our primary color // and the bottom bounce in main themes color @@ -48,19 +48,10 @@ ion-refresher-content { margin: 0 10px; } -ion-segment-button { - --indicator-height: 0px !important; - text-transform: none !important; - --ripple-color: transparent !important; - //transition: color 0.15s ease; - font-size: 1.05em !important; - letter-spacing: normal !important; - opacity: 1 !important; -} - .segment-button-checked { color: var(--segment-primary) !important; font-weight: 600 !important; + opacity: 1 !important; } .status ion-icon { @@ -150,9 +141,10 @@ ion-list { } ion-item { - max-width: 92%; + // max-width: var(--ion-item-max-width); - margin: auto; + // margin: auto; + margin: var(--edge-padding); } .value { @@ -208,15 +200,30 @@ ion-item { } .stat-title { - opacity: 0.85; -} - -.income-title { - opacity: 0.85; - font-size: 1em; - //color: var(--ion-text-color-lighter); + opacity: var(--default-secondary-transparency); + font-weight: var(--smaller-label-weight); } .grid { width: 100%; } + +.proposed { +} + +.orphaned { + color: var(--ion-color-warning); +} + +ion-badge { + padding: 4px 5px 2px 5px; + margin: 5px; +} + +.missed { + color: var(--ion-color-danger); +} + +.scheduled { + color: var(--ion-color-secondary); +} diff --git a/src/app/pages/block-detail/block-detail.page.spec.ts b/src/app/pages/block-detail/block-detail.page.spec.ts deleted file mode 100644 index c9ff0de4..00000000 --- a/src/app/pages/block-detail/block-detail.page.spec.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing' -import { IonicModule } from '@ionic/angular' - -import { BlockDetailPage } from './block-detail.page' - -describe('BlockDetailPage', () => { - let component: BlockDetailPage - let fixture: ComponentFixture - - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [BlockDetailPage], - imports: [IonicModule.forRoot()], - }).compileComponents() - - fixture = TestBed.createComponent(BlockDetailPage) - component = fixture.componentInstance - fixture.detectChanges() - })) - - it('should create', () => { - expect(component).toBeTruthy() - }) -}) diff --git a/src/app/pages/block-detail/block-detail.page.ts b/src/app/pages/block-detail/block-detail.page.ts index 59511df1..6c6bf19d 100644 --- a/src/app/pages/block-detail/block-detail.page.ts +++ b/src/app/pages/block-detail/block-detail.page.ts @@ -1,61 +1,132 @@ -import { Component, OnInit, Input } from '@angular/core' -import { BlockResponse } from 'src/app/requests/requests' -import { BlockUtils, ETHPOOL, ROCKETPOOL_SMOOTHING_POOL } from 'src/app/utils/BlockUtils' +import { Component, OnInit, Input, WritableSignal, signal, computed } from '@angular/core' +import { ETHPOOL, ROCKETPOOL_SMOOTHING_POOL } from '@utils/BlockUtils' import * as blockies from 'ethereum-blockies' import BigNumber from 'bignumber.js' -import { UnitconvService } from 'src/app/services/unitconv.service' +import { UnitconvService } from '@services/unitconv.service' import { ModalController } from '@ionic/angular' import { Browser } from '@capacitor/browser' -import { ApiService } from 'src/app/services/api.service' +import { ApiService } from '@services/api.service' +import { VDBBlocksTableRow } from '@requests/types/validator_dashboard' +import { slotToSecondsTimestamp } from '@utils/TimeUtils' +import { Toast } from '@capacitor/toast' +import { findChainNetworkById } from '@utils/NetworkData' +import { V1BlockResponse, V1BlocksOverview } from '@requests/requests' @Component({ selector: 'app-block-detail', templateUrl: './block-detail.page.html', styleUrls: ['./block-detail.page.scss'], + standalone: false, }) export class BlockDetailPage implements OnInit { - @Input() block: BlockResponse - imgData = null - timestamp = 0 - producerReward = new BigNumber(0) - feeRecipient = '' - baseFee = '' - gasUsedPercent = '' - burned = new BigNumber(0) - currentY = 0 - scrolling = false + @Input() block: VDBBlocksTableRow + + imgData: string = null + timestamp = 0 + producerReward = new BigNumber(0) + feeRecipient: string = null + showGasUsedPercent = true nameResolved = '' - constructor(private blockUtils: BlockUtils, public unit: UnitconvService, private modalCtrl: ModalController, private api: ApiService) {} + // overview: WritableSignal = signal(null) // v2 + v1Overview: WritableSignal = signal(null) + + gasUsedPercent = computed(() => { + return ((this.v1Overview().gasUsed * 100) / this.v1Overview().gasLimit).toFixed(1) + //v2: return ((parseInt(this.overview().gas_usage) * 100) / this.overview().gas_limit.value).toFixed(1) + }) + + chainID = 0 + + online: boolean = true + initialLoading: boolean = true + + constructor( + public unit: UnitconvService, + private modalCtrl: ModalController, + protected api: ApiService + ) {} async ngOnInit() { + this.online = true + this.chainID = await this.api.getCurrentDashboardChainID() + this.getOverviewv1() this.imgData = this.getBlockies() - this.timestamp = this.block.timestamp * 1000 - this.producerReward = await this.blockUtils.getBlockRewardWithShare(this.block) - this.feeRecipient = this.block.feeRecipient - if (this.block.relay) { - this.feeRecipient = this.block.relay.producerFeeRecipient + this.timestamp = slotToSecondsTimestamp(this.chainID, this.block.slot) * 1000 + if (this.block.reward) { + this.producerReward = new BigNumber(this.block.reward.el).plus(new BigNumber(this.block.reward.cl)) } - this.baseFee = new BigNumber(this.block.baseFee).dividedBy(1e9).toFixed(1) + ' Gwei' - this.gasUsedPercent = ((this.block.gasUsed * 100) / this.block.gasLimit).toFixed(1) - this.burned = new BigNumber(this.block.gasUsed).multipliedBy(new BigNumber(this.block.baseFee)) + this.nameResolved = null - if (this.feeRecipient.toLocaleLowerCase() == ROCKETPOOL_SMOOTHING_POOL) { + this.feeRecipient = this.block.reward_recipient?.hash + if (this.block.reward_recipient?.ens != null) { + this.nameResolved = this.block.reward_recipient?.ens + } + if (this.block.reward_recipient?.hash?.toLocaleLowerCase() == ROCKETPOOL_SMOOTHING_POOL) { this.nameResolved = 'Went to Rocketpool Smoothing-Pool' - } else if (this.feeRecipient.toLocaleLowerCase() == ETHPOOL) { + } else if (this.block.reward_recipient?.hash?.toLocaleLowerCase() == ETHPOOL) { this.nameResolved = 'Distributed via ethpool.eth' } + + if (this.block.status == 'missed') { + this.feeRecipient = 'This block was missed' + } else if (this.block.status == 'orphaned') { + this.feeRecipient = 'This block was orphaned' + } else if (this.block.status == 'scheduled') { + this.feeRecipient = 'This block is scheduled' + } + } + + getChainNetwork() { + return findChainNetworkById(this.chainID) + } + + // v2 + // async getOverview() { + // if (!this.block.block) { + // this.initialLoading = false + // return + // } + // const result = await this.api.set(new V2BlockOverview(this.chainID, this.block.block), this.overview) + // if (result.error) { + // Toast.show({ + // text: 'Failed to fetch block overview', + // duration: 'long', + // }) + // this.online = false + // console.error(result.error) + // } + // this.initialLoading = false + // } + + async getOverviewv1() { + if (!this.block.block) { + this.initialLoading = false + return + } + const result = await this.api.execute(new V1BlocksOverview(this.block.block)) + console.log('v1 block result', result) + if (result.error) { + Toast.show({ + text: 'Failed to fetch block overview', + duration: 'long', + }) + this.online = false + console.error(result.error) + } + this.v1Overview.set(result.data[0]) + this.initialLoading = false } closeModal() { this.modalCtrl.dismiss() } - onScroll($event) { + onScroll($event: { detail: { currentY: number } }) { this.currentY = $event.detail.currentY } @@ -69,8 +140,8 @@ export class BlockDetailPage implements OnInit { private getBlockies() { // TODO: figure out why the first blockie image is always black - blockies.create({ seed: this.block.blockHash }).toDataURL() - const dataurl = blockies.create({ seed: this.block.blockHash, size: 8, scale: 7 }).toDataURL() + blockies.create({ seed: this.block.slot.toString() }).toDataURL() + const dataurl = blockies.create({ seed: this.block.slot.toString(), size: 8, scale: 7 }).toDataURL() return dataurl } @@ -79,13 +150,15 @@ export class BlockDetailPage implements OnInit { } async openBlock() { + // todo new url await Browser.open({ - url: this.api.getBaseUrl() + '/block/' + this.block.blockNumber, + url: this.api.getBaseUrl() + '/block/' + this.block.slot, toolbarColor: '#2f2e42', }) } async openFeeRecipient() { + // todo new url await Browser.open({ url: this.api.getBaseUrl() + '/address/' + this.feeRecipient, toolbarColor: '#2f2e42', diff --git a/src/app/pages/clients/clients.module.ts b/src/app/pages/clients/clients.module.ts index 0bf7042f..b645a6d3 100644 --- a/src/app/pages/clients/clients.module.ts +++ b/src/app/pages/clients/clients.module.ts @@ -7,9 +7,11 @@ import { IonicModule } from '@ionic/angular' import { ClientsPageRoutingModule } from './clients-routing.module' import { ClientsPage } from './clients.page' +import { FullPageLoadingComponent } from '@components/full-page-loading/full-page-loading.component' +import { FullPageOfflineComponent } from '@components/full-page-offline/full-page-offline.component' @NgModule({ - imports: [CommonModule, FormsModule, IonicModule, ClientsPageRoutingModule], + imports: [CommonModule, FormsModule, IonicModule, ClientsPageRoutingModule, FullPageLoadingComponent, FullPageOfflineComponent], declarations: [ClientsPage], }) export class ClientsPageModule {} diff --git a/src/app/pages/clients/clients.page.html b/src/app/pages/clients/clients.page.html index 8b8cf092..51263a41 100644 --- a/src/app/pages/clients/clients.page.html +++ b/src/app/pages/clients/clients.page.html @@ -1,152 +1,48 @@ - - + + - Excecution Clients + Excecution - Consensus Clients + Consensus + + + Other - - Show me updates for - - - + + + + Show me updates for + + - + Besu - - - - Erigon - - - - Geth - - - - Nethermind - - - - - - - - Lighthouse - - - - Lodestar - - - - - Nimbus - - - - Prysm - - - - Teku{{client.name}} - - -
+ +
+ +
diff --git a/src/app/pages/clients/clients.page.spec.ts b/src/app/pages/clients/clients.page.spec.ts deleted file mode 100644 index 3009ee86..00000000 --- a/src/app/pages/clients/clients.page.spec.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing' -import { IonicModule } from '@ionic/angular' - -import { ClientsPage } from './clients.page' - -describe('ClientsPage', () => { - let component: ClientsPage - let fixture: ComponentFixture - - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [ClientsPage], - imports: [IonicModule.forRoot()], - }).compileComponents() - - fixture = TestBed.createComponent(ClientsPage) - component = fixture.componentInstance - fixture.detectChanges() - })) - - it('should create', () => { - expect(component).toBeTruthy() - }) -}) diff --git a/src/app/pages/clients/clients.page.ts b/src/app/pages/clients/clients.page.ts index 407e3abc..7120dca3 100644 --- a/src/app/pages/clients/clients.page.ts +++ b/src/app/pages/clients/clients.page.ts @@ -1,59 +1,76 @@ -import { Component, OnInit, Input } from '@angular/core' +import { Component, Input, WritableSignal, signal, SimpleChanges } from '@angular/core' import { ModalController } from '@ionic/angular' -import ClientUpdateUtils from '../../utils/ClientUpdateUtils' -import { NotificationBase } from '../../tab-preferences/notification-base' -import { SyncService } from '../../services/sync.service' - +import ClientUpdateUtils, { ClientInfo, Clients } from '@utils/ClientUpdateUtils' +import { NotificationBase } from '../../tabs/tab-preferences/notification-base' +import { StorageService } from '@services/storage.service' @Component({ selector: 'app-clients', templateUrl: './clients.page.html', styleUrls: ['./clients.page.scss'], + standalone: false, }) -export class ClientsPage implements OnInit { +export class ClientsPage { @Input() clientIdentifier = '' + loading: WritableSignal = signal(false) + online: WritableSignal = signal(true) + + clients: ClientInfo[] = null + constructor( private modalCtrl: ModalController, private updateUtils: ClientUpdateUtils, - private sync: SyncService, - public notificationBase: NotificationBase + public notificationBase: NotificationBase, + private storage: StorageService ) {} - ngOnInit() { - this.updateUtils.getClient('LIGHTHOUSE').then((result) => { - this.notificationBase.setClientToggleState('LIGHTHOUSE', result && result != 'null') - }) - this.updateUtils.getClient('LODESTAR').then((result) => { - this.notificationBase.setClientToggleState('LODESTAR', result && result != 'null') - }) - this.updateUtils.getClient('PRYSM').then((result) => { - this.notificationBase.setClientToggleState('PRYSM', result && result != 'null') - }) - this.updateUtils.getClient('NIMBUS').then((result) => { - this.notificationBase.setClientToggleState('NIMBUS', result && result != 'null') - }) - this.updateUtils.getClient('TEKU').then((result) => { - this.notificationBase.setClientToggleState('TEKU', result && result != 'null') - }) - this.updateUtils.getClient('BESU').then((result) => { - this.notificationBase.setClientToggleState('BESU', result && result != 'null') - }) - this.updateUtils.getClient('ERIGON').then((result) => { - this.notificationBase.setClientToggleState('ERIGON', result && result != 'null') - }) - this.updateUtils.getClient('GETH').then((result) => { - this.notificationBase.setClientToggleState('GETH', result && result != 'null') - }) - this.updateUtils.getClient('NETHERMIND').then((result) => { - this.notificationBase.setClientToggleState('NETHERMIND', result && result != 'null') - }) + ngOnChanges(changes: SimpleChanges) { + if (changes.clientIdentifier && !changes.clientIdentifier.firstChange) { + this.init() // Refresh data based on new identifier + } + } + + async doRefresh(force: boolean = false) { + if (!(await this.storage.isLoggedIn())) return + this.loading.set(true) + const result = await this.notificationBase.updateClientsFromRemote(force) + if (result.error) { + this.online.set(false) + } + this.loading.set(false) + } + + getClientListFilter() { + if (this.clientIdentifier == 'eth1Clients') { + return 'exec' + } + if (this.clientIdentifier == 'eth2Clients') { + return 'cons' + } + return '3rdparty' + } + + async init() { + this.clients = Clients.filter((client) => client.type == this.getClientListFilter()) + await this.doRefresh() + + for (const client of this.clients) { + this.updateUtils.getClient(client.key).then((result) => { + this.notificationBase.setClientToggleState(client.key, result && result != 'null') + }) + } this.notificationBase.disableToggleLock() } + ionViewWillEnter() { + this.init() + } + closeModal() { if (this.notificationBase.settingsChanged) { - this.sync.syncAllSettings(true) + //this.sync.syncAllSettings(true) + // todo save } this.modalCtrl.dismiss() } diff --git a/src/app/pages/dev/dev.page.html b/src/app/pages/dev/dev.page.html index 6cafa30f..ad739b06 100644 --- a/src/app/pages/dev/dev.page.html +++ b/src/app/pages/dev/dev.page.html @@ -1,5 +1,5 @@ - + @@ -8,17 +8,46 @@ + + v2 + + - + - Force sync + Use v2 api - + - Clear sync queue + Migrate to v2 + + + + Local Bundle Update + + + Reset Bundle to Buildin + + + + + Register Push + + + + + Sync Client Updates + + + + + General + + + Make dev mode permanent @@ -34,14 +63,21 @@ Set "Last Closed" to 0 for all clients + + + Show old machines + + Use real package standard - plankton - Goldfish - Whale + guppy + Dolphin + Orca @@ -49,9 +85,14 @@ Auth User - + - Manually edit access token + Manually edit v2 session + + + + + Manually edit access token (depr) @@ -78,6 +119,11 @@ Toggle init + + + Toast test + + Toggle test @@ -107,44 +153,57 @@ Firebase - - - Update firebase token - + + + + Update firebase token + - - - Notification Consent - + + + Notification Consent + - - - Reset saved firebase token - + + + Reset saved firebase token + - -

Notification Consent: {{ notificationConsent }}

-
+ +

Notification Consent: {{ notificationConsent }}

+
- -

{{ firebaseToken }}

-
+ +

Firebase Token: {{ firebaseToken }}

+
+ + +

Session (v2): {{ session }}

+
+ + +

Device ID: {{ deviceID }}

+
+ + +

Bundle Code: {{ bundleCode }}

+
+
Logs - - - Current - - - - Current - 1 - - - - Current - 2 - + + + + + Current + + + + Current - 1 + +
diff --git a/src/app/pages/dev/dev.page.scss b/src/app/pages/dev/dev.page.scss index 3568d60c..f406c0fb 100644 --- a/src/app/pages/dev/dev.page.scss +++ b/src/app/pages/dev/dev.page.scss @@ -1,4 +1,4 @@ -// Copyright (C) 2021 Bitfly GmbH +// Copyright (C) 2021 bitfly explorer GmbH // // This file is part of Beaconchain Dashboard. // diff --git a/src/app/pages/dev/dev.page.spec.ts b/src/app/pages/dev/dev.page.spec.ts deleted file mode 100644 index dbd8a227..00000000 --- a/src/app/pages/dev/dev.page.spec.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing' -import { IonicModule } from '@ionic/angular' - -import { DevPage } from './dev.page' - -describe('DevPage', () => { - let component: DevPage - let fixture: ComponentFixture - - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [DevPage], - imports: [IonicModule.forRoot()], - }).compileComponents() - - fixture = TestBed.createComponent(DevPage) - component = fixture.componentInstance - fixture.detectChanges() - })) - - it('should create', () => { - expect(component).toBeTruthy() - }) -}) diff --git a/src/app/pages/dev/dev.page.ts b/src/app/pages/dev/dev.page.ts index 68d2f767..811ddb8a 100644 --- a/src/app/pages/dev/dev.page.ts +++ b/src/app/pages/dev/dev.page.ts @@ -1,20 +1,29 @@ import { Component, OnInit } from '@angular/core' -import { DEBUG_SETTING_OVERRIDE_PACKAGE } from 'src/app/services/storage.service' -import { CURRENT_TOKENKEY } from 'src/app/utils/FirebaseUtils' -import { Tab3Page } from 'src/app/tab-preferences/tab-preferences.page' +import { DEBUG_SETTING_OVERRIDE_PACKAGE } from '@services/storage.service' +import { CURRENT_TOKENKEY, pushLastTokenUpstream } from '@utils/FirebaseUtils' +import { Tab3Page } from 'src/app/tabs/tab-preferences/tab-preferences.page' import { Toast } from '@capacitor/toast' -import { Clients } from '../../utils/ClientUpdateUtils' -import { DevModeEnabled } from 'src/app/services/storage.service' +import { Clients } from '@utils/ClientUpdateUtils' +import { DevModeEnabled } from '@services/storage.service' +import { V2RegisterPushNotificationToken } from '@requests/v2-user' +import { CapacitorUpdater } from '@capgo/capacitor-updater' +import versionInfo from '../../../version.json' @Component({ selector: 'app-dev', templateUrl: './dev.page.html', styleUrls: ['./dev.page.scss'], + standalone: false, }) export class DevPage extends Tab3Page implements OnInit { packageOverride = 'default' firebaseToken = '' notificationConsent = false + deviceID = '' + usev2api = false + showOldMachines = false + bundleCode = '' + session: string ngOnInit() { this.notificationBase.disableToggleLock() @@ -26,7 +35,39 @@ export class DevPage extends Tab3Page implements OnInit { this.firebaseToken = result }) + this.storage.getAuthUserv2().then((result) => { + this.session = result.Session + }) + + this.storage.getDeviceID().then((result) => { + this.deviceID = result + }) + + this.storage.isV2().then((result) => { + this.usev2api = result + }) + this.firebaseUtils.hasNotificationConsent().then((result) => (this.notificationConsent = result)) + + this.storage.getAuthUserv2().then((result) => { + console.log('v2 auth', result) + }) + + this.storage.getBooleanSetting('debug_show_old_machines', false).then((result) => { + this.showOldMachines = result + }) + + this.bundleCode = versionInfo.buildNumber + ' - ' + versionInfo.formattedVersion + } + + changeOldMachines() { + this.storage.setBooleanSetting('debug_show_old_machines', this.showOldMachines) + } + + toastTest() { + Toast.show({ + text: 'Test toast', + }) } // --- Development methods --- @@ -61,19 +102,8 @@ export class DevPage extends Tab3Page implements OnInit { this.updateUtils.checkAllUpdates() } - clearSyncQueue() { - this.sync.developDeleteQueue() - Toast.show({ - text: 'Queue cleared', - }) - } - - forceSync() { - this.sync.fullSync() - } - updateFirebaseToken() { - this.firebaseUtils.pushLastTokenUpstream(true) + pushLastTokenUpstream(this.storage, this.api, true) } permanentDevMode() { @@ -132,6 +162,7 @@ export class DevPage extends Tab3Page implements OnInit { }) } + // @deprecated replaced by changeSession async changeAccessToken() { const alert = await this.alertController.create({ cssClass: 'my-custom-class', @@ -178,8 +209,47 @@ export class DevPage extends Tab3Page implements OnInit { await alert.present() } + async changeSession() { + const alert = await this.alertController.create({ + cssClass: 'my-custom-class', + header: 'Session ID', + inputs: [ + { + name: 'session', + type: 'text', + placeholder: 'Session ID', + }, + ], + buttons: [ + { + text: 'Cancel', + role: 'cancel', + cssClass: 'secondary', + handler: () => { + return + }, + }, + { + text: 'Ok', + handler: async (alertData) => { + await this.storage.setAuthUserv2({ + Session: alertData.session, + }) + this.api.invalidateAllCache() + await this.oauth.postLogin() + this.dashboardUtils.dashboardAwareListener.notifyAll() + alert.dismiss() + }, + }, + ], + }) + + await alert.present() + } + async restoreAuthUser() { await this.storage.restoreAuthUser() + await this.oauth.postLogin() this.alerts.confirmDialog('Success', 'Restart app with restored user?', 'OK', () => { this.restartApp() }) @@ -196,4 +266,74 @@ export class DevPage extends Tab3Page implements OnInit { openLogSession(offset: number) { this.storage.openLogSession(this.modalController, offset) } + + async migrateV2() { + await this.storage.setDashboardID(null) + await this.validatorUtils.debugSetMyLocalValidators('holesky', [99, 98, 97, 96, 95]) + + await this.storage.setBooleanSetting('migration_completed', false) // reset + await this.v2migrator.switchToV2(false) + + this.merchant.restartApp() + //this.v2migrator.migrate() + } + + async localBundleUpdate() { + const bundleURL = await this.storage.getItem('dev_bundle_url') + const alert = await this.alertController.create({ + cssClass: 'my-custom-class', + header: 'Bundle URL', + message: 'This way of updating is insecure as it bypasses HTTPS. Proceed if you know what you are doing. Stay safe.', + inputs: [ + { + name: 'url', + type: 'text', + placeholder: 'Bundle URL', + value: bundleURL, + }, + ], + buttons: [ + { + text: 'Cancel', + role: 'cancel', + cssClass: 'secondary', + handler: () => { + return + }, + }, + { + text: 'Ok', + handler: async (alertData) => { + await this.storage.setItem('dev_bundle_url', alertData.url) + await this.appUpdater.updateBundle(alertData.url, true) + }, + }, + ], + }) + + await alert.present() + } + + changeToV2Api() { + console.log('use v2 api', this.usev2api) + this.v2migrator.switchToV2(this.usev2api) + } + + syncClients() { + this.notificationBase.syncClientUpdates() + } + + async registerV2Push() { + //const lastToken = await this.storage.getItem('last_firebase_token') + const deviceID = await this.storage.getDeviceID() + const result = this.api.execute(new V2RegisterPushNotificationToken('hallo', deviceID)) + console.log('v2 register push', result) + } + + resetBundleToBuildIn() { + CapacitorUpdater.reset({ + // back to native bundle + toLastSuccessful: false, + }) + } } diff --git a/src/app/pages/helppage/helppage-routing.module.ts b/src/app/pages/helppage/helppage-routing.module.ts index eb8a8cda..154f12e7 100644 --- a/src/app/pages/helppage/helppage-routing.module.ts +++ b/src/app/pages/helppage/helppage-routing.module.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // diff --git a/src/app/pages/helppage/helppage.module.ts b/src/app/pages/helppage/helppage.module.ts index 54e14534..2383c345 100644 --- a/src/app/pages/helppage/helppage.module.ts +++ b/src/app/pages/helppage/helppage.module.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -27,7 +26,7 @@ import { IonicModule } from '@ionic/angular' import { HelppagePageRoutingModule } from './helppage-routing.module' import { HelppagePage } from './helppage.page' -import { HelpComponentModule } from '../../components/help/help.module' +import { HelpComponentModule } from '@components/help/help.module' @NgModule({ imports: [CommonModule, FormsModule, IonicModule, HelppagePageRoutingModule, HelpComponentModule], diff --git a/src/app/pages/helppage/helppage.page.html b/src/app/pages/helppage/helppage.page.html index ee25882d..38c3b26b 100644 --- a/src/app/pages/helppage/helppage.page.html +++ b/src/app/pages/helppage/helppage.page.html @@ -1,5 +1,5 @@ - - + + @@ -30,5 +30,5 @@ - + diff --git a/src/app/pages/helppage/helppage.page.scss b/src/app/pages/helppage/helppage.page.scss index bd24986e..1e60fed5 100644 --- a/src/app/pages/helppage/helppage.page.scss +++ b/src/app/pages/helppage/helppage.page.scss @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // diff --git a/src/app/pages/helppage/helppage.page.spec.ts b/src/app/pages/helppage/helppage.page.spec.ts deleted file mode 100644 index 09316852..00000000 --- a/src/app/pages/helppage/helppage.page.spec.ts +++ /dev/null @@ -1,44 +0,0 @@ -/* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) - * // - * // This file is part of Beaconchain Dashboard. - * // - * // Beaconchain Dashboard is free software: you can redistribute it and/or modify - * // it under the terms of the GNU General Public License as published by - * // the Free Software Foundation, either version 3 of the License, or - * // (at your option) any later version. - * // - * // Beaconchain Dashboard is distributed in the hope that it will be useful, - * // but WITHOUT ANY WARRANTY; without even the implied warranty of - * // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * // GNU General Public License for more details. - * // - * // You should have received a copy of the GNU General Public License - * // along with Beaconchain Dashboard. If not, see . - */ - -import { async, ComponentFixture, TestBed } from '@angular/core/testing' -import { IonicModule } from '@ionic/angular' - -import { HelppagePage } from './helppage.page' - -describe('HelppagePage', () => { - let component: HelppagePage - let fixture: ComponentFixture - - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [HelppagePage], - imports: [IonicModule.forRoot()], - }).compileComponents() - - fixture = TestBed.createComponent(HelppagePage) - component = fixture.componentInstance - fixture.detectChanges() - })) - - it('should create', () => { - expect(component).toBeTruthy() - }) -}) diff --git a/src/app/pages/helppage/helppage.page.ts b/src/app/pages/helppage/helppage.page.ts index 309441b5..38155e98 100644 --- a/src/app/pages/helppage/helppage.page.ts +++ b/src/app/pages/helppage/helppage.page.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -26,6 +25,7 @@ import { fromEvent, Subscription } from 'rxjs' selector: 'app-helppage', templateUrl: './helppage.page.html', styleUrls: ['./helppage.page.scss'], + standalone: false, }) export class HelppagePage implements OnInit { private backbuttonSubscription: Subscription diff --git a/src/app/pages/licences/licences-routing.module.ts b/src/app/pages/licences/licences-routing.module.ts index 812c6ccf..22005bc3 100644 --- a/src/app/pages/licences/licences-routing.module.ts +++ b/src/app/pages/licences/licences-routing.module.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // diff --git a/src/app/pages/licences/licences.module.ts b/src/app/pages/licences/licences.module.ts index d860cb62..efea8692 100644 --- a/src/app/pages/licences/licences.module.ts +++ b/src/app/pages/licences/licences.module.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // diff --git a/src/app/pages/licences/licences.page.html b/src/app/pages/licences/licences.page.html index 219b55be..4fced668 100644 --- a/src/app/pages/licences/licences.page.html +++ b/src/app/pages/licences/licences.page.html @@ -1,5 +1,5 @@ - - + + @@ -31,7 +31,7 @@
-@square/okhttp
+@square/okhttp
 Copyright 2019 Square, Inc.
 
 Licensed under the Apache License, Version 2.0 (the "License");
@@ -47,7 +47,7 @@
 limitations under the License.
 
 
-@google/gson
+@google/gson
 Copyright 2008 Google Inc.
 
 Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/src/app/pages/licences/licences.page.scss b/src/app/pages/licences/licences.page.scss
index d166ad1d..7332585f 100644
--- a/src/app/pages/licences/licences.page.scss
+++ b/src/app/pages/licences/licences.page.scss
@@ -1,6 +1,5 @@
 /* 
- *  // Copyright (C) 2020 - 2021 Bitfly GmbH
- *  // Manuel Caspari (manuel@bitfly.at)
+ *  // Copyright (C) 2020 - 2024 bitfly explorer GmbH
  *  // 
  *  // This file is part of Beaconchain Dashboard.
  *  // 
@@ -18,7 +17,7 @@
  *  // along with Beaconchain Dashboard.  If not, see .
  */
 
-@import '../../../theme/variables.scss';
+@use '../../../theme/variables.scss';
 
 ion-buttons {
 	--color: #fff;
diff --git a/src/app/pages/licences/licences.page.spec.ts b/src/app/pages/licences/licences.page.spec.ts
deleted file mode 100644
index 1b7051ae..00000000
--- a/src/app/pages/licences/licences.page.spec.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- *  // Copyright (C) 2020 - 2021 Bitfly GmbH
- *  // Manuel Caspari (manuel@bitfly.at)
- *  //
- *  // This file is part of Beaconchain Dashboard.
- *  //
- *  // Beaconchain Dashboard is free software: you can redistribute it and/or modify
- *  // it under the terms of the GNU General Public License as published by
- *  // the Free Software Foundation, either version 3 of the License, or
- *  // (at your option) any later version.
- *  //
- *  // Beaconchain Dashboard is distributed in the hope that it will be useful,
- *  // but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  // GNU General Public License for more details.
- *  //
- *  // You should have received a copy of the GNU General Public License
- *  // along with Beaconchain Dashboard.  If not, see .
- */
-
-import { async, ComponentFixture, TestBed } from '@angular/core/testing'
-import { IonicModule } from '@ionic/angular'
-
-import { LicencesPage } from './licences.page'
-
-describe('LicencesPage', () => {
-	let component: LicencesPage
-	let fixture: ComponentFixture
-
-	beforeEach(async(() => {
-		TestBed.configureTestingModule({
-			declarations: [LicencesPage],
-			imports: [IonicModule.forRoot()],
-		}).compileComponents()
-
-		fixture = TestBed.createComponent(LicencesPage)
-		component = fixture.componentInstance
-		fixture.detectChanges()
-	}))
-
-	it('should create', () => {
-		expect(component).toBeTruthy()
-	})
-})
diff --git a/src/app/pages/licences/licences.page.ts b/src/app/pages/licences/licences.page.ts
index a535469a..1424f5c8 100644
--- a/src/app/pages/licences/licences.page.ts
+++ b/src/app/pages/licences/licences.page.ts
@@ -1,6 +1,5 @@
 /*
- *  // Copyright (C) 2020 - 2021 Bitfly GmbH
- *  // Manuel Caspari (manuel@bitfly.at)
+ *  // Copyright (C) 2020 - 2024 bitfly explorer GmbH
  *  //
  *  // This file is part of Beaconchain Dashboard.
  *  //
@@ -26,6 +25,7 @@ import { fromEvent, Subscription } from 'rxjs'
 	selector: 'app-licences',
 	templateUrl: './licences.page.html',
 	styleUrls: ['./licences.page.scss'],
+	standalone: false,
 })
 export class LicencesPage implements OnInit {
 	private backbuttonSubscription: Subscription
@@ -39,7 +39,7 @@ export class LicencesPage implements OnInit {
 		})
 	}
 
-	populatePre(url) {
+	populatePre(url: string) {
 		const xhr = new XMLHttpRequest()
 		xhr.onload = function () {
 			document.getElementById('contents').textContent += this.responseText
diff --git a/src/app/pages/logview/logview.page.html b/src/app/pages/logview/logview.page.html
index 84e93e1f..a9c5fa15 100644
--- a/src/app/pages/logview/logview.page.html
+++ b/src/app/pages/logview/logview.page.html
@@ -1,12 +1,12 @@
 
-	
-		
+	
+		
 			
 				
 			
 		
 		Logview
-		
+		
 			
 				
 			
diff --git a/src/app/pages/logview/logview.page.spec.ts b/src/app/pages/logview/logview.page.spec.ts
deleted file mode 100644
index 48864a57..00000000
--- a/src/app/pages/logview/logview.page.spec.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'
-import { IonicModule } from '@ionic/angular'
-
-import { LogviewPage } from './logview.page'
-
-describe('LogviewPage', () => {
-	let component: LogviewPage
-	let fixture: ComponentFixture
-
-	beforeEach(waitForAsync(() => {
-		TestBed.configureTestingModule({
-			declarations: [LogviewPage],
-			imports: [IonicModule.forRoot()],
-		}).compileComponents()
-
-		fixture = TestBed.createComponent(LogviewPage)
-		component = fixture.componentInstance
-		fixture.detectChanges()
-	}))
-
-	it('should create', () => {
-		expect(component).toBeTruthy()
-	})
-})
diff --git a/src/app/pages/logview/logview.page.ts b/src/app/pages/logview/logview.page.ts
index 17202100..ec57805b 100644
--- a/src/app/pages/logview/logview.page.ts
+++ b/src/app/pages/logview/logview.page.ts
@@ -7,6 +7,7 @@ import { Clipboard } from '@capacitor/clipboard'
 	selector: 'app-logview',
 	templateUrl: './logview.page.html',
 	styleUrls: ['./logview.page.scss'],
+	standalone: false,
 })
 export class LogviewPage implements OnInit {
 	@Input() logs: [LogEntry] = [{ text: '', extra: '' }]
@@ -23,7 +24,7 @@ export class LogviewPage implements OnInit {
 		this.modalCtrl.dismiss()
 	}
 
-	formatLog(log) {
+	formatLog(log: string) {
 		if (log.startsWith('[ERROR]')) return 'error'
 		else if (log.startsWith(': Error:')) return 'error'
 		else if (log.startsWith('[WARN]')) return 'warn'
@@ -32,7 +33,7 @@ export class LogviewPage implements OnInit {
 		return ''
 	}
 
-	openExtra(index) {
+	openExtra(index: number) {
 		this.open[index] = !this.open[index]
 	}
 
diff --git a/src/app/pages/machine-detail/machine-detail.module.ts b/src/app/pages/machine-detail/machine-detail.module.ts
index ee4e5ec4..83af3dee 100644
--- a/src/app/pages/machine-detail/machine-detail.module.ts
+++ b/src/app/pages/machine-detail/machine-detail.module.ts
@@ -9,8 +9,8 @@ import { MachineDetailPageRoutingModule } from './machine-detail-routing.module'
 import { MachineDetailPage } from './machine-detail.page'
 import { TooltipModule } from 'ng2-tooltip-directive-major-angular-updates'
 import { PipesModule } from '../../pipes/pipes.module'
-import { MachineChartComponentModule } from 'src/app/components/machinechart/machinechart.module'
-import { MessageComponentModule } from 'src/app/components/message/message.module'
+import { MachineChartComponentModule } from '@components/machinechart/machinechart.module'
+import { MessageComponentModule } from '@components/message/message.module'
 
 @NgModule({
 	imports: [
diff --git a/src/app/pages/machine-detail/machine-detail.page.html b/src/app/pages/machine-detail/machine-detail.page.html
index 07050f96..c5ab6f6c 100644
--- a/src/app/pages/machine-detail/machine-detail.page.html
+++ b/src/app/pages/machine-detail/machine-detail.page.html
@@ -1,6 +1,6 @@
 
-	
-		
+	
+		
 			
 				
 			
@@ -44,13 +44,18 @@
 			[hidden]="selectedTab != 'cpu'"
 			title="CPU Processes"
 			[key]="key"
-			priority="true"
+			[priority]="true"
 			[chartData]="data | delegate: cpuDelegate"
 			[subtitleLeft]="cpuProcessLabelNode"
 			[subtitleRight]="cpuProcessLabelVal">
 		
 
-		
+		
 		
 
 		
diff --git a/src/app/pages/machine-detail/machine-detail.page.scss b/src/app/pages/machine-detail/machine-detail.page.scss index f61ffee2..fb53e90d 100644 --- a/src/app/pages/machine-detail/machine-detail.page.scss +++ b/src/app/pages/machine-detail/machine-detail.page.scss @@ -1,16 +1,4 @@ -@import '../../../theme/variables.scss'; - -ion-segment-button { - color: var(--x-toolbar-title-color); - - font-family: 'Varela'; - font-size: 0.75em; - --indicator-height: 0px !important; - text-transform: none !important; - --ripple-color: transparent !important; - //transition: color 0.15s ease; - opacity: 0.65; -} +@use '../../../theme/variables.scss'; ion-segment { background-color: var(--ion-toolbar-background); @@ -56,3 +44,11 @@ ion-segment { .alert-text { color: var(--ion-text-color) !important; } + +ion-card-title { + font-size: 1.1rem; +} + +ion-card-content { + font-size: var(--smaller-info-size); +} diff --git a/src/app/pages/machine-detail/machine-detail.page.spec.ts b/src/app/pages/machine-detail/machine-detail.page.spec.ts deleted file mode 100644 index 8f8dbd21..00000000 --- a/src/app/pages/machine-detail/machine-detail.page.spec.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing' -import { IonicModule } from '@ionic/angular' - -import { MachineDetailPage } from './machine-detail.page' - -describe('MachineDetailPage', () => { - let component: MachineDetailPage - let fixture: ComponentFixture - - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [MachineDetailPage], - imports: [IonicModule.forRoot()], - }).compileComponents() - - fixture = TestBed.createComponent(MachineDetailPage) - component = fixture.componentInstance - fixture.detectChanges() - })) - - it('should create', () => { - expect(component).toBeTruthy() - }) -}) diff --git a/src/app/pages/machine-detail/machine-detail.page.ts b/src/app/pages/machine-detail/machine-detail.page.ts index 124677cb..d66f19ca 100644 --- a/src/app/pages/machine-detail/machine-detail.page.ts +++ b/src/app/pages/machine-detail/machine-detail.page.ts @@ -2,13 +2,14 @@ import { Component, OnInit, Input } from '@angular/core' import { ModalController } from '@ionic/angular' import { Options } from 'highcharts' import { fromEvent, Subscription } from 'rxjs' -import { StorageService } from 'src/app/services/storage.service' +import { StorageService } from '@services/storage.service' import MachineController, { ProcessedStats, bytes, MachineChartData } from '../../controllers/MachineController' @Component({ selector: 'app-machine-detail', templateUrl: './machine-detail.page.html', styleUrls: ['./machine-detail.page.scss'], + standalone: false, }) export class MachineDetailPage extends MachineController implements OnInit { @Input() key: string @@ -77,9 +78,9 @@ export class MachineDetailPage extends MachineController implements OnInit { diskUsageLabelReads = '' diskUsageLabelWrites = '' - syncAttention = null - diskAttention = null - memoryAttention = null + syncAttention: string = null + diskAttention: string = null + memoryAttention: string = null syncLabelState = '' syncLabelEth1Connected = '' @@ -89,7 +90,10 @@ export class MachineDetailPage extends MachineController implements OnInit { private backbuttonSubscription: Subscription - constructor(private modalCtrl: ModalController, storage: StorageService) { + constructor( + private modalCtrl: ModalController, + storage: StorageService + ) { super(storage) } @@ -101,39 +105,39 @@ export class MachineDetailPage extends MachineController implements OnInit { }) if (this.data) { - this.magicGapNumber = this.normalizeTimeframeNumber(this.data.system) - this.os = this.formatOS(this.getLastFrom(this.data.system, (array) => array.misc_os)) - this.uptime = this.getLastFrom(this.data.system, (array) => array.misc_node_boot_ts_seconds) * 1000 - this.threadCount = this.getLastFrom(this.data.system, (array) => array.cpu_threads) - this.coreCount = this.getLastFrom(this.data.system, (array) => array.cpu_cores) + this.magicGapNumber = this.normalizeTimeframeNumber(this.data.system_metrics.map((value) => [value.timestamp, 0])) + this.os = this.formatOS(this.getLastFrom(this.data.system_metrics, (array) => array.misc_os)) + this.uptime = this.getLastFrom(this.data.system_metrics, (array) => array.misc_node_boot_ts_seconds) * 1000 + this.threadCount = this.getLastFrom(this.data.system_metrics, (array) => array.cpu_threads) + this.coreCount = this.getLastFrom(this.data.system_metrics, (array) => array.cpu_cores) - this.headslot = this.getLastFrom(this.data.node, (array) => array.sync_beacon_head_slot) + this.headslot = this.getLastFrom(this.data.node_metrics, (array) => array.sync_beacon_head_slot) - const synced = this.getLastFrom(this.data.node, (array) => array.sync_eth2_synced) + const synced = this.getLastFrom(this.data.node_metrics, (array) => array.sync_eth2_synced) this.stateSynced = synced ? 'Synced' : 'Syncing' - this.validatorLabelActive = 'Active: ' + this.getLastFrom(this.data.validator, (array) => array.validator_active) - this.validatorLabelTotal = 'Total: ' + this.getLastFrom(this.data.validator, (array) => array.validator_total) + this.validatorLabelActive = 'Active: ' + this.getLastFrom(this.data.validator_metrics, (array) => array.validator_active) + this.validatorLabelTotal = 'Total: ' + this.getLastFrom(this.data.validator_metrics, (array) => array.validator_total) - const lastFreeBytes = this.getLastFrom(this.data.system, (array) => array.disk_node_bytes_free) - const totalBytes = this.getLastFrom(this.data.system, (array) => array.disk_node_bytes_total) + const lastFreeBytes = this.getLastFrom(this.data.system_metrics, (array) => array.disk_node_bytes_free) + const totalBytes = this.getLastFrom(this.data.system_metrics, (array) => array.disk_node_bytes_total) const percent = Math.round((lastFreeBytes * 1000) / totalBytes) / 10 this.diskLabel = 'Free: ' + bytes(lastFreeBytes, true, true, 1) + ' - ' + percent + '%' this.beaconchainLabel = 'Size: ' + bytes( - this.getLastFrom(this.data.node, (array) => array.disk_beaconchain_bytes_total), + this.getLastFrom(this.data.node_metrics, (array) => array.disk_beaconchain_bytes_total), true, true, 3 ) - this.peerLabel = 'Peers: ' + this.getLastFrom(this.data.node, (array) => array.network_peers_connected) + this.peerLabel = 'Peers: ' + this.getLastFrom(this.data.node_metrics, (array) => array.network_peers_connected) this.networkLabelRx = 'Receive: ' + bytes( - this.getAvgFrom(this.data.system, (array) => array.network_node_bytes_total_receive / this.magicGapNumber, true), + this.getAvgFrom(this.data.system_metrics, (array) => array.network_node_bytes_total_receive / this.magicGapNumber, true), true, true, 2 @@ -142,7 +146,7 @@ export class MachineDetailPage extends MachineController implements OnInit { this.networkLabelTx = 'Transmit: ' + bytes( - this.getAvgFrom(this.data.system, (array) => array.network_node_bytes_total_transmit / this.magicGapNumber, true), + this.getAvgFrom(this.data.system_metrics, (array) => array.network_node_bytes_total_transmit / this.magicGapNumber, true), true, true, 2 @@ -150,16 +154,16 @@ export class MachineDetailPage extends MachineController implements OnInit { '/s' const lastMemAv = this.getLastFrom( - this.data.system, + this.data.system_metrics, (array) => array.memory_node_bytes_free + array.memory_node_bytes_buffers + array.memory_node_bytes_cached ) - const lastMemTotal = this.getLastFrom(this.data.system, (array) => array.memory_node_bytes_total) + const lastMemTotal = this.getLastFrom(this.data.system_metrics, (array) => array.memory_node_bytes_total) const percentMem = Math.round(1000 - (lastMemAv * 1000) / lastMemTotal) / 10 this.memoryLabelFree = 'Used: ' + bytes(lastMemTotal - lastMemAv, true, true, 1) + ' - ' + percentMem + '%' this.memoryLabelTotal = 'Total: ' + bytes( - this.getLastFrom(this.data.system, (array) => array.memory_node_bytes_total), + this.getLastFrom(this.data.system_metrics, (array) => array.memory_node_bytes_total), true, true, 1 @@ -168,7 +172,7 @@ export class MachineDetailPage extends MachineController implements OnInit { this.memoryProcessLabelNode = 'Node: ' + bytes( - this.getLastFrom(this.data.node, (array) => array.memory_process_bytes), + this.getLastFrom(this.data.node_metrics, (array) => array.memory_process_bytes), true, true, 2 @@ -176,7 +180,7 @@ export class MachineDetailPage extends MachineController implements OnInit { this.memoryProcessLabelVal = 'Validator: ' + bytes( - this.getLastFrom(this.data.validator, (array) => array.memory_process_bytes), + this.getLastFrom(this.data.validator_metrics, (array) => array.memory_process_bytes), true, true, 2 @@ -186,8 +190,8 @@ export class MachineDetailPage extends MachineController implements OnInit { 'Node: ' + ( this.getAvgRelativeFrom( - this.getLastN(this.data.node, (array) => array.cpu_process_seconds_total, true), - this.getLastN(this.data.system, (array) => array.cpu_node_system_seconds_total, true), + this.getLastN(this.data.node_metrics, (array) => array.cpu_process_seconds_total, true), + this.getLastN(this.data.system_metrics, (array) => array.cpu_node_system_seconds_total, true), (val1, val2) => { return val1 / val2 } @@ -199,8 +203,8 @@ export class MachineDetailPage extends MachineController implements OnInit { 'Validator: ' + ( this.getAvgRelativeFrom( - this.getLastN(this.data.validator, (array) => array.cpu_process_seconds_total, true, 180), - this.getLastN(this.data.system, (array) => array.cpu_node_system_seconds_total, true, 180), + this.getLastN(this.data.validator_metrics, (array) => array.cpu_process_seconds_total, true, 180), + this.getLastN(this.data.system_metrics, (array) => array.cpu_node_system_seconds_total, true, 180), (val1, val2) => { return val1 / val2 } @@ -213,8 +217,8 @@ export class MachineDetailPage extends MachineController implements OnInit { ( 100.0 - this.getAvgRelativeFrom( - this.getLastN(this.data.system, (array) => array.cpu_node_idle_seconds_total, true), - this.getLastN(this.data.system, (array) => array.cpu_node_system_seconds_total, true), + this.getLastN(this.data.system_metrics, (array) => array.cpu_node_idle_seconds_total, true), + this.getLastN(this.data.system_metrics, (array) => array.cpu_node_system_seconds_total, true), (val1, val2) => { return val1 / val2 } @@ -224,14 +228,18 @@ export class MachineDetailPage extends MachineController implements OnInit { '%' this.diskUsageLabelReads = - 'Reads: ' + Math.round(this.getAvgFrom(this.data.system, (array) => array.disk_node_reads_total / this.magicGapNumber, true)) + ' iops' + 'Reads: ' + + Math.round(this.getAvgFrom(this.data.system_metrics, (array) => array.disk_node_reads_total / this.magicGapNumber, true)) + + ' iops' this.diskUsageLabelWrites = - 'Writes: ' + Math.round(this.getAvgFrom(this.data.system, (array) => array.disk_node_writes_total / this.magicGapNumber, true)) + ' iops' + 'Writes: ' + + Math.round(this.getAvgFrom(this.data.system_metrics, (array) => array.disk_node_writes_total / this.magicGapNumber, true)) + + ' iops' - const eth1Connected = this.getLastFrom(this.data.node, (array) => array.sync_eth1_connected) + const eth1Connected = this.getLastFrom(this.data.node_metrics, (array) => array.sync_eth1_connected) this.syncLabelEth1Connected = eth1Connected ? 'Exec Connected' : 'Exec Offline' - const fullySynced = this.getLastFrom(this.data.node, (array) => array.sync_eth2_synced) + const fullySynced = this.getLastFrom(this.data.node_metrics, (array) => array.sync_eth2_synced) this.syncLabelState = fullySynced ? 'Synced' : 'Syncing...' this.syncAttention = this.getSyncAttention(this.data) @@ -274,11 +282,11 @@ export class MachineDetailPage extends MachineController implements OnInit { public doBeaconchainSizeChart(current: ProcessedStats): MachineChartData { const chartData = [] - if (current && current.node) { + if (current && current.node_metrics) { chartData.push({ name: 'Beaconchain Size', color: '#7cb5ec', - data: this.timeAxisChanges(current.node, (value) => { + data: this.timeAxisChanges(current.node_metrics, (value) => { return value.disk_beaconchain_bytes_total }), pointWidth: 25, @@ -288,18 +296,18 @@ export class MachineDetailPage extends MachineController implements OnInit { return { Data: chartData, Config: this.addBytesConfig(), - } as MachineChartData + } as unknown as MachineChartData } public doPeerCharts(current: ProcessedStats): MachineChartData { const chartData = [] - if (current && current.node) { + if (current && current.node_metrics) { chartData.push({ name: 'Connected Peers', color: '#7cb5ec', data: this.timeAxisChanges( - current.node, + current.node_metrics, (value) => { return value.network_peers_connected }, @@ -312,18 +320,18 @@ export class MachineDetailPage extends MachineController implements OnInit { return { Data: chartData, Config: this.addAbsoluteConfig(), - } as MachineChartData + } as unknown as MachineChartData } public doDiskCharts(current: ProcessedStats): MachineChartData { - const chartData = [] + const chartData: { name: string; color: string; data: unknown[]; pointWidth: number }[] = [] - if (!current) return { Data: chartData } as MachineChartData - if (!current.system) return { Error: 'system_missing' } as MachineChartData + if (!current) return { Data: chartData } as unknown as MachineChartData + if (!current.system_metrics) return { Error: 'system_missing' } as MachineChartData - if (current && current.system) { + if (current && current.system_metrics) { const data = this.timeAxisChanges( - current.system, + current.system_metrics, (value) => { return value.disk_node_bytes_free }, @@ -341,18 +349,18 @@ export class MachineDetailPage extends MachineController implements OnInit { return { Data: chartData, Config: this.addBytesConfig(), - } as MachineChartData + } as unknown as MachineChartData } public doValidatorChart(current: ProcessedStats): MachineChartData { const chartData = [] - if (current && current.validator) { + if (current && current.validator_metrics) { chartData.push({ name: 'Total', color: '#7cb5ec', data: this.timeAxisChanges( - current.validator, + current.validator_metrics, (value) => { return value.validator_total }, @@ -364,7 +372,7 @@ export class MachineDetailPage extends MachineController implements OnInit { name: 'Active', color: '#Dcb5ec', data: this.timeAxisChanges( - current.validator, + current.validator_metrics, (value) => { return value.validator_active }, @@ -388,21 +396,21 @@ export class MachineDetailPage extends MachineController implements OnInit { Data: chartData, Config: mergedConfig, Error: undefined, - } as MachineChartData + } as unknown as MachineChartData } public doDiskIoUsageCharts(current: ProcessedStats): MachineChartData { - const chartData = [] + const chartData: { name: string; color: string; data: unknown[]; pointWidth: number }[] = [] - if (!current) return { Data: chartData } as MachineChartData - if (!current.system) return { Error: 'system_missing' } as MachineChartData + if (!current) return { Data: chartData } as unknown as MachineChartData + if (!current.system_metrics) return { Error: 'system_missing' } as MachineChartData - if (current && current.system) { + if (current && current.system_metrics) { chartData.push({ name: 'Reads', color: '#Dcb5ec', data: this.timeAxisChanges( - current.system, + current.system_metrics, (value) => { return value.disk_node_reads_total / this.magicGapNumber }, @@ -414,7 +422,7 @@ export class MachineDetailPage extends MachineController implements OnInit { name: 'Writes', color: '#7cb5ec', data: this.timeAxisChanges( - current.system, + current.system_metrics, (value) => { return value.disk_node_writes_total / this.magicGapNumber }, @@ -427,22 +435,22 @@ export class MachineDetailPage extends MachineController implements OnInit { return { Data: chartData, Config: this.addAbsoluteConfig(' iops'), - } as MachineChartData + } as unknown as MachineChartData } public doNetworkCharts(current: ProcessedStats): MachineChartData { - const chartData = [] + const chartData: { name: string; color: string; data: unknown[]; pointWidth: number }[] = [] - if (!current) return { Data: chartData } as MachineChartData - if (!current.system) return { Error: 'system_missing' } as MachineChartData + if (!current) return { Data: chartData } as unknown as MachineChartData + if (!current.system_metrics) return { Error: 'system_missing' } as MachineChartData - if (current && current.system) { - console.log('system', current.system) + if (current && current.system_metrics) { + console.log('system', current.system_metrics) chartData.push({ name: 'Receive', color: '#7cb5ec', data: this.timeAxisChanges( - current.system, + current.system_metrics, (value) => { return value.network_node_bytes_total_receive / this.magicGapNumber }, @@ -454,7 +462,7 @@ export class MachineDetailPage extends MachineController implements OnInit { name: 'Transmit', color: '#Dcb5ec', data: this.timeAxisChanges( - current.system, + current.system_metrics, (value) => { return value.network_node_bytes_total_transmit / this.magicGapNumber }, @@ -467,45 +475,45 @@ export class MachineDetailPage extends MachineController implements OnInit { return { Data: chartData, Config: this.addBytesConfig(true), - } as MachineChartData + } as unknown as MachineChartData } public doCPUSystemCharts(current: ProcessedStats): MachineChartData { - const chartData = [] + const chartData: { name: string; color: string; data: unknown[][]; pointWidth: number }[] = [] - if (!current) return { Data: chartData } as MachineChartData - if (!current.system) return { Error: 'system_missing' } as MachineChartData + if (!current) return { Data: chartData } as unknown as MachineChartData + if (!current.system_metrics) return { Error: 'system_missing' } as MachineChartData const cpuSystemTotal = this.timeAxisChanges( - current.system, + current.system_metrics, (value) => { return value.cpu_node_system_seconds_total }, true ) const idle = this.timeAxisChanges( - current.system, + current.system_metrics, (value) => { return value.cpu_node_idle_seconds_total }, true ) const user = this.timeAxisChanges( - current.system, + current.system_metrics, (value) => { return value.cpu_node_user_seconds_total }, true ) const io = this.timeAxisChanges( - current.system, + current.system_metrics, (value) => { return value.cpu_node_iowait_seconds_total }, true ) - if (current && current.system) { + if (current && current.system_metrics) { chartData.push({ name: 'Total Usage', color: '#7cb5ec', @@ -557,20 +565,20 @@ export class MachineDetailPage extends MachineController implements OnInit { }, } as Options, }, - } as MachineChartData + } as unknown as MachineChartData } public doMemorySystemCharts(current: ProcessedStats): MachineChartData { - const chartData = [] + const chartData: { name: string; color: string; data: unknown[]; pointWidth: number }[] = [] - if (!current) return { Data: chartData } as MachineChartData - if (!current.system) return { Error: 'system_missing' } as MachineChartData + if (!current) return { Data: chartData } as unknown as MachineChartData + if (!current.system_metrics) return { Error: 'system_missing' } as MachineChartData - if (current && current.system) { + if (current && current.system_metrics) { chartData.push({ name: 'Total', color: '#7cb5ec', - data: this.timeAxisChanges(current.system, (value) => { + data: this.timeAxisChanges(current.system_metrics, (value) => { return value.memory_node_bytes_total }), pointWidth: 25, @@ -579,7 +587,7 @@ export class MachineDetailPage extends MachineController implements OnInit { chartData.push({ name: 'Cached', color: '#3335FF', - data: this.timeAxisChanges(current.system, (value) => { + data: this.timeAxisChanges(current.system_metrics, (value) => { return value.memory_node_bytes_cached }), pointWidth: 25, @@ -587,7 +595,7 @@ export class MachineDetailPage extends MachineController implements OnInit { chartData.push({ name: 'Buffer', color: '#3FF5ec', - data: this.timeAxisChanges(current.system, (value) => { + data: this.timeAxisChanges(current.system_metrics, (value) => { return value.memory_node_bytes_buffers }), pointWidth: 25, @@ -595,7 +603,7 @@ export class MachineDetailPage extends MachineController implements OnInit { chartData.push({ name: 'Free', color: '#Dcb5ec', - data: this.timeAxisChanges(current.system, (value) => { + data: this.timeAxisChanges(current.system_metrics, (value) => { return value.memory_node_bytes_free }), pointWidth: 25, @@ -605,7 +613,7 @@ export class MachineDetailPage extends MachineController implements OnInit { return { Data: chartData, Config: this.addBytesConfig(), - } as MachineChartData + } as unknown as MachineChartData } getDiskFullTimeEstimate(data: number[][]): number { diff --git a/src/app/pages/machines/machines.module.ts b/src/app/pages/machines/machines.module.ts deleted file mode 100644 index 6c585f3c..00000000 --- a/src/app/pages/machines/machines.module.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { NgModule } from '@angular/core' -import { CommonModule } from '@angular/common' -import { FormsModule } from '@angular/forms' - -import { IonicModule } from '@ionic/angular' - -import { MachinesPageRoutingModule } from './machines-routing.module' -import { MachinesPage } from './machines.page' -import { MachineChartComponentModule } from 'src/app/components/machinechart/machinechart.module' -import { PipesModule } from 'src/app/pipes/pipes.module' -import { AdComponentModule } from 'src/app/components/ad/ad.module' - -@NgModule({ - imports: [CommonModule, FormsModule, IonicModule, MachinesPageRoutingModule, MachineChartComponentModule, PipesModule, AdComponentModule], - declarations: [MachinesPage], -}) -export class MachinesPageModule {} diff --git a/src/app/pages/machines/machines.page.html b/src/app/pages/machines/machines.page.html deleted file mode 100644 index eb0800db..00000000 --- a/src/app/pages/machines/machines.page.html +++ /dev/null @@ -1,113 +0,0 @@ - - - Monitoring - - - - CPU - - - Memory - - - Sync - - - - - - - - - - - Last {{ this.selectedTimeFrame }} - - - -
- - - - - Attention - - - - - - You may be using an old monitoring endpoint on your machine. Click here for more info on how to migrate to continue using this - feature. - - - -
- -
- -
- - - - - - - - -
-
- -
-
-
- Machine Monitoring

- - Monitor your {{ api.getNetwork().name }} staking machines on the go. -

- Login - Setup Monitoring -
-
- -
-
- -
-
- -
-
diff --git a/src/app/pages/machines/machines.page.spec.ts b/src/app/pages/machines/machines.page.spec.ts deleted file mode 100644 index da768d92..00000000 --- a/src/app/pages/machines/machines.page.spec.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing' -import { IonicModule } from '@ionic/angular' - -import { MachinesPage } from './machines.page' - -describe('MachinesPage', () => { - let component: MachinesPage - let fixture: ComponentFixture - - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [MachinesPage], - imports: [IonicModule.forRoot()], - }).compileComponents() - - fixture = TestBed.createComponent(MachinesPage) - component = fixture.componentInstance - fixture.detectChanges() - })) - - it('should create', () => { - expect(component).toBeTruthy() - }) -}) diff --git a/src/app/pages/merge-checklist/merge-checklist-routing.module.ts b/src/app/pages/merge-checklist/merge-checklist-routing.module.ts deleted file mode 100644 index f26bcb6e..00000000 --- a/src/app/pages/merge-checklist/merge-checklist-routing.module.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { NgModule } from '@angular/core' -import { Routes, RouterModule } from '@angular/router' - -import { MergeChecklistPage } from './merge-checklist.page' - -const routes: Routes = [ - { - path: '', - component: MergeChecklistPage, - }, -] - -@NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule], -}) -export class MergeChecklistPageRoutingModule {} diff --git a/src/app/pages/merge-checklist/merge-checklist.module.ts b/src/app/pages/merge-checklist/merge-checklist.module.ts deleted file mode 100644 index bfe2661d..00000000 --- a/src/app/pages/merge-checklist/merge-checklist.module.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { NgModule } from '@angular/core' -import { CommonModule } from '@angular/common' -import { FormsModule } from '@angular/forms' - -import { IonicModule } from '@ionic/angular' - -import { MergeChecklistPageRoutingModule } from './merge-checklist-routing.module' - -import { MergeChecklistPage } from './merge-checklist.page' - -@NgModule({ - imports: [CommonModule, FormsModule, IonicModule, MergeChecklistPageRoutingModule], - declarations: [MergeChecklistPage], -}) -export class MergeChecklistPageModule {} diff --git a/src/app/pages/merge-checklist/merge-checklist.page.html b/src/app/pages/merge-checklist/merge-checklist.page.html deleted file mode 100644 index c1c284cf..00000000 --- a/src/app/pages/merge-checklist/merge-checklist.page.html +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - - - Merge Checklist - - - - - - - - - - - - - {{entry.val}} - {{entry.timing}} - - - - - - Optional - - - - - {{entry.val}} - - - - - Guides & Help - - - - - - Launchpad Merge Readiness - - - - - CoinCashew Merge Checklist - - - - - Install Execution Client - - - - - MEV Boost - - - - - Reddit ethstaker - - -
-
diff --git a/src/app/pages/merge-checklist/merge-checklist.page.spec.ts b/src/app/pages/merge-checklist/merge-checklist.page.spec.ts deleted file mode 100644 index 568fec1f..00000000 --- a/src/app/pages/merge-checklist/merge-checklist.page.spec.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing' -import { IonicModule } from '@ionic/angular' - -import { MergeChecklistPage } from './merge-checklist.page' - -describe('MergeChecklistPage', () => { - let component: MergeChecklistPage - let fixture: ComponentFixture - - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [MergeChecklistPage], - imports: [IonicModule.forRoot()], - }).compileComponents() - - fixture = TestBed.createComponent(MergeChecklistPage) - component = fixture.componentInstance - fixture.detectChanges() - })) - - it('should create', () => { - expect(component).toBeTruthy() - }) -}) diff --git a/src/app/pages/merge-checklist/merge-checklist.page.ts b/src/app/pages/merge-checklist/merge-checklist.page.ts deleted file mode 100644 index 96d82b2c..00000000 --- a/src/app/pages/merge-checklist/merge-checklist.page.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { Component, Input } from '@angular/core' -import { Browser } from '@capacitor/browser' -import { StorageService } from 'src/app/services/storage.service' -import { AlertService } from 'src/app/services/alert.service' -import { ModalController } from '@ionic/angular' - -@Component({ - selector: 'app-merge-checklist', - templateUrl: './merge-checklist.page.html', - styleUrls: ['./merge-checklist.page.scss'], -}) -export class MergeChecklistPage { - @Input() fromSettings = false - - public todo = [ - { val: 'Run your own execution client', isChecked: false, key: 'cl_own_client', timing: 'Timing: Do this now' }, - { val: 'Update execution & consensus client', isChecked: false, key: 'cl_update', timing: 'Timing: Do this after TTD client releases' }, - { val: 'JWT authentication for Engine API', isChecked: false, key: 'cl_auth', timing: 'Timing: Do this after TTD client releases' }, - { val: 'Set fee recipient address', isChecked: false, key: 'cl_fee_recipient', timing: 'Timing: Do this after TTD client releases' }, - { - val: 'Remove external execution client fallbacks like Infura.', - isChecked: false, - key: 'cl_no_ext_fallbacks', - timing: 'Timing: Do this after TTD client releases', - }, - ] - - public optional = [ - { val: 'Prune execution client', isChecked: false, key: 'cl_prune' }, - { val: 'Setup MEV Boost', isChecked: false, key: 'cl_mevboost' }, - ] - - constructor(private modalCtrl: ModalController, private storage: StorageService, private alerts: AlertService) { - this.loadCheckedState(this.todo) - this.loadCheckedState(this.optional) - } - - async loadCheckedState(array) { - for (let i = 0; i < array.length; i++) { - array[i].isChecked = await this.getChecked(array[i]) - } - } - - closeModal() { - this.modalCtrl.dismiss() - } - - async openBrowser(link) { - await Browser.open({ url: link, toolbarColor: '#2f2e42' }) - } - - async getChecked(entry) { - return await this.storage.getBooleanSetting(entry.key, false) - } - - change(entry) { - if (!entry || !entry.detail) return - this.storage.setBooleanSetting(entry.detail.value.key, entry.detail.value.isChecked) - } - - dismissChecklist() { - this.alerts.confirmDialog( - 'Hide Checklist', - 'You are about to hide the checklist from your dashboard. You can still find it in the settings page.', - 'OK', - () => { - this.storage.setBooleanSetting('merge_list_dismissed', true) - this.closeModal() - } - ) - } -} diff --git a/src/app/pages/notification-detail/accordion-indexslot/accordion-indexslot.component.html b/src/app/pages/notification-detail/accordion-indexslot/accordion-indexslot.component.html new file mode 100644 index 00000000..34a33b13 --- /dev/null +++ b/src/app/pages/notification-detail/accordion-indexslot/accordion-indexslot.component.html @@ -0,0 +1,24 @@ + + + + {{ name }} ({{ data.length }}) + + +
+
+ + +
+ {{ CAP_MAX_SHOW }} of {{ this.data.length }}
+ Show me all +
+
+
diff --git a/src/app/pages/notification-detail/accordion-indexslot/accordion-indexslot.component.scss b/src/app/pages/notification-detail/accordion-indexslot/accordion-indexslot.component.scss new file mode 100644 index 00000000..9fa0e947 --- /dev/null +++ b/src/app/pages/notification-detail/accordion-indexslot/accordion-indexslot.component.scss @@ -0,0 +1,40 @@ +// Copyright (C) 2024 bitfly explorer GmbH +// +// This file is part of Beaconchain Dashboard. +// +// Beaconchain Dashboard is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Beaconchain Dashboard is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Beaconchain Dashboard. If not, see . + +@use '../../../../theme/variables.scss'; + +.content { + background: var(--ion-card-background); +} + +// ion-label { +// color: var(--x-toolbar-title-color) !important; +// } +ion-icon { + // color: var(--x-toolbar-title-color) !important; + + margin: 8px 0px; + margin-right: 20px; +} + +.accordion-header { + padding: 0 5px; +} + +.background { + background-color: var(--ion-item-background); +} diff --git a/src/app/pages/notification-detail/accordion-indexslot/accordion-indexslot.component.ts b/src/app/pages/notification-detail/accordion-indexslot/accordion-indexslot.component.ts new file mode 100644 index 00000000..95b0eae7 --- /dev/null +++ b/src/app/pages/notification-detail/accordion-indexslot/accordion-indexslot.component.ts @@ -0,0 +1,158 @@ +import { Component, Input } from '@angular/core' +import { NotificationValidator } from '../notification-item/notification-item.component' +import { Address, IndexBlocks, IndexEpoch, IndexSlots } from '@requests/types/common' +import { IonicModule } from '@ionic/angular' +import { CommonModule } from '@angular/common' +import { NotificationEventValidatorBackOnline, NotificationEventWithdrawal } from '@requests/types/notifications' +import { MoreComponent } from '../more/more.component' +import { ModalController } from '@ionic/angular' +import BigNumber from 'bignumber.js' +import { ApiService } from '@services/api.service' + +export type DataTypes = IndexEpoch | IndexSlots | IndexBlocks | NotificationEventValidatorBackOnline | NotificationEventWithdrawal | Address | number + +const CAP = 7 // Millers Law + +@Component({ + selector: 'app-accordion-indexslot', + imports: [IonicModule, CommonModule, NotificationValidator], + standalone: true, + templateUrl: './accordion-indexslot.component.html', + styleUrl: './accordion-indexslot.component.scss', +}) +export class AccordionIndexslotComponent { + @Input() name: string + @Input() data: DataTypes[] + @Input() extraName: string + @Input() key: string + @Input() icon: string + + CAP_MAX_SHOW = 3 // could be variable in the future, like if it's just one category show more. But 3 is fine for now + + ac = new ArrayComputer() + + constructor( + private modalCtrl: ModalController, + private api: ApiService + ) {} + + isDataCapped = () => { + return this.data.length > CAP + } + + dataCapped = () => { + if (this.isDataCapped()) return this.data.slice(0, this.CAP_MAX_SHOW) + return this.data + } + + async showAll() { + const modal = await this.modalCtrl.create({ + component: MoreComponent, + componentProps: { + title: this.name, + data: this.data, + extraName: this.extraName, + }, + }) + modal.present() + + await modal.onWillDismiss() + } + + getExternalLink = (data: DataTypes) => { + return getExternalLink(data, this.api) + } + getTitlePrefix = getTitlePrefix + getImageSeed = getImageSeed + getTitle = getTitle + getExtra = getExtra +} + +/** + * Utility class to handle caching of array computed values + */ +export class ArrayComputer { + private cache = new Map() + + arrayComputed(data: DataTypes, computeFn: (data: DataTypes) => T): T { + const key = JSON.stringify({ data, fn: computeFn.toString() }) + + if (!this.cache.has(key)) { + const result = computeFn(data) + this.cache.set(key, result) + } + return this.cache.get(key) as T + } +} + +export function getExternalLink(data: DataTypes, api: ApiService) { + if (typeof data === 'number') { + return api.getBaseUrl() + '/validator/' + data + } else if ('index' in data) { + return api.getBaseUrl() + '/validator/' + data.index + } else if ('hash' in data) { + return api.getBaseUrl() + '/address/' + data.hash + } + return null +} + +export function getTitlePrefix(data: DataTypes) { + if (typeof data === 'number' || 'index' in data) { + return 'Validator' + } else if ('hash' in data) { + return '' + } + return '' +} + +export function getImageSeed(data: DataTypes) { + if (typeof data === 'number') { + return data + '' + } else if ('index' in data) { + return data.index + '' + } else if ('hash' in data) { + return data.hash + } +} + +export function getTitle(data: DataTypes, searchString: string = null) { + let result = '' + if (typeof data === 'number') { + result = data + '' + } else if ('index' in data) { + result = data.index + '' + } else if ('hash' in data) { + result = data.hash.substring(0, 8) + '...' + data.hash.substring(data.hash.length - 8) + } + + return highlightSearchPart(result, searchString) +} + +export function getExtra(data: DataTypes, searchString: string = null) { + let result = '' + if (typeof data === 'number') { + result = '' + } else if ('epoch' in data) { + result = data.epoch + '' + } else if ('slots' in data) { + result = data.slots + '' + } else if ('blocks' in data) { + result = data.blocks + '' + } else if ('epoch_count' in data) { + result = data.epoch_count + '' + } else if ('amount' in data) { + result = new BigNumber(data.amount).dividedBy(1e18).decimalPlaces(5) + ' ETH' // todo gnosis + } + + return highlightSearchPart(result, searchString) +} + +function highlightSearchPart(text: string, searchString: string) { + // highlight searchString in text with tags + if (!searchString) return text + const index = text.toLowerCase().indexOf(searchString.toLowerCase()) + if (index === -1) return text + const before = text.substring(0, index) + const after = text.substring(index + searchString.length) + return before + '' + text.substring(index, index + searchString.length) + '' + after +} diff --git a/src/app/pages/notification-detail/more/more.component.html b/src/app/pages/notification-detail/more/more.component.html new file mode 100644 index 00000000..390719f2 --- /dev/null +++ b/src/app/pages/notification-detail/more/more.component.html @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + Notification + + + + + + + + + + + {{ title }} + + +
+ +
+
+
diff --git a/src/app/pages/notification-detail/more/more.component.scss b/src/app/pages/notification-detail/more/more.component.scss new file mode 100644 index 00000000..80c1190c --- /dev/null +++ b/src/app/pages/notification-detail/more/more.component.scss @@ -0,0 +1,60 @@ +// Copyright (C) 2024 bitfly explorer GmbH +// +// This file is part of Beaconchain Dashboard. +// +// Beaconchain Dashboard is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Beaconchain Dashboard is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Beaconchain Dashboard. If not, see . + +@use '../../../../theme/variables.scss'; + +cdk-virtual-scroll-viewport { + margin-left: 0px; + margin-right: 0px; + padding-left: 0px; + padding-right: 0px; + width: 100%; + height: 100%; +} + +ion-searchbar { + --background: var(--ion-toolbar-background); + --box-shadow: var(--ion-toolbar-background); + --color: var(--x-toolbar-title-color); + --clear-button-color: var(--x-toolbar-title-color); + --cancel-button-color: var(--x-toolbar-title-color); + --icon-color: var(--x-toolbar-title-color); + --placeholder-color: var(--x-toolbar-title-color); + --placeholder-opacity: 0.8; + width: 100%; + margin: var(--edge-padding); +} + +@media (min-width: 360px) { + ion-searchbar { + padding-right: 30px !important; + } +} + +@media (min-width: 480px) { + ion-searchbar { + padding-right: 50px !important; + } +} + +.toolbar-btn::part(native) { + --ion-color-contrast: var(--x-toolbar-title-color); + --color: var(--x-toolbar-title-color); + color: var(--x-toolbar-title-color); + background: transparent !important; + --background: transparent !important; +} diff --git a/src/app/pages/notification-detail/more/more.component.ts b/src/app/pages/notification-detail/more/more.component.ts new file mode 100644 index 00000000..707a846b --- /dev/null +++ b/src/app/pages/notification-detail/more/more.component.ts @@ -0,0 +1,206 @@ +import { Component, Input, ViewChild } from '@angular/core' +import { InfiniteScrollDataSource, loadMoreType } from '@utils/InfiniteScrollDataSource' +import { + ArrayComputer, + DataTypes, + getExternalLink, + getExtra, + getImageSeed, + getTitle, + getTitlePrefix, +} from '../accordion-indexslot/accordion-indexslot.component' +import { IonicModule, ModalController, SearchbarCustomEvent } from '@ionic/angular' +import { CommonModule } from '@angular/common' +import { NotificationValidator } from '../notification-item/notification-item.component' +import { ScrollingModule } from '@angular/cdk/scrolling' +import { IonSearchbar } from '@ionic/angular/standalone' +import { AlertService } from '@services/alert.service' +import { ApiService } from '@services/api.service' + +const PAGE_SIZE = 25 + +type Sort = 'index:asc' | 'index:desc' | 'extra:asc' | 'extra:desc' + +@Component({ + selector: 'app-more', + imports: [CommonModule, IonicModule, NotificationValidator, ScrollingModule], + templateUrl: './more.component.html', + styleUrl: './more.component.scss', +}) +export class MoreComponent { + @Input() title: string + @Input() data: DataTypes[] + @Input() extraName: string + + filteredData: DataTypes[] + + dataSource: InfiniteScrollDataSource + + loadMore: boolean + + sort: Sort = 'index:asc' + + @ViewChild('searchbarRef', { static: true }) searchbarRef: IonSearchbar + + ac = new ArrayComputer() + + constructor( + private modalCtrl: ModalController, + private alerts: AlertService, + private api: ApiService + ) {} + + ngOnInit() { + this.dataSource = new InfiniteScrollDataSource(PAGE_SIZE, this.getDefaultDataRetriever()) + } + + async ionViewDidEnter() { + this.filteredData = this.data + await this.dataSource.reset() + } + + selectSort() { + const options = [ + { + name: 'sort', + label: 'Index Ascending', + value: 'index:asc' as Sort, + type: 'radio', + checked: this.sort == 'index:asc', + }, + { + name: 'sort', + label: 'Index Descending', + value: 'index:desc' as Sort, + type: 'radio', + checked: this.sort == 'index:desc', + }, + ] + + if (this.extraName) { + options.push({ + name: 'sort', + label: this.extraName + ' Ascending', + value: 'extra:asc' as Sort, + type: 'radio', + checked: this.sort == 'extra:asc', + }) + options.push({ + name: 'sort', + label: this.extraName + ' Descending', + value: 'extra:desc' as Sort, + type: 'radio', + checked: this.sort == 'extra:desc', + }) + } + + this.alerts.showSelect('Sort by', options, (data) => { + if (data) { + if (data != this.sort) { + this.sort = data as Sort + this.doSort(this.sort) + } + } + }) + } + + getSortFunction(sort: Sort) { + // prefer number sort if it is a number, otherwise use string sort + function compareNumberOrString(a: string, b: string) { + if (!isNaN(Number(a)) && !isNaN(Number(b))) { + return Number(a) - Number(b) + } else { + return a.localeCompare(b) + } + } + + switch (sort) { + case 'index:asc': + return (a: DataTypes, b: DataTypes) => { + return compareNumberOrString(getTitle(a), getTitle(b)) + } + case 'index:desc': + return (a: DataTypes, b: DataTypes) => { + return compareNumberOrString(getTitle(b), getTitle(a)) + } + case 'extra:asc': + return (a: DataTypes, b: DataTypes) => { + return compareNumberOrString(getExtra(a), getExtra(b)) + } + case 'extra:desc': + return (a: DataTypes, b: DataTypes) => { + return compareNumberOrString(getExtra(b), getExtra(a)) + } + default: + throw new Error(`Unsupported sort type: ${sort}`) + } + } + + async doSort(sort: Sort) { + try { + const sortFn = this.getSortFunction(sort) + this.filteredData.sort((a, b) => { + return sortFn(a, b) + }) + await this.dataSource.reset() + } catch (e) { + console.error(e) + } + } + + cancelSearch() { + this.filteredData = this.data + this.doSort(this.sort) + } + + searchEvent(event: SearchbarCustomEvent) { + this.filteredData = this.data.filter((item) => { + return ( + getTitle(item).toLowerCase().includes(event.detail.value.toLowerCase()) || + getExtra(item).toLowerCase().includes(event.detail.value.toLowerCase()) + ) + }) + this.dataSource.reset() + } + + private getDefaultDataRetriever(): loadMoreType { + return (cursor) => { + return new Promise((resolve) => { + let offset = parseInt(cursor) + if (isNaN(offset)) { + offset = 0 + } + + const subset = this.filteredData.slice(offset, offset + PAGE_SIZE) + const nextOffset = offset + subset.length + if (nextOffset < this.filteredData.length) { + resolve({ + data: subset, + next_cursor: nextOffset + '', + }) + } else { + resolve({ + data: subset, + next_cursor: null, + }) + } + }) + } + } + + closeModal() { + this.modalCtrl.dismiss() + } + + getExternalLink = (data: DataTypes) => { + return getExternalLink(data, this.api) + } + getTitlePrefix = getTitlePrefix + getImageSeed = getImageSeed + getTitle = (data: DataTypes) => { + return getTitle(data, this.searchbarRef.value) + } + getExtra = (data: DataTypes) => { + return getExtra(data, this.searchbarRef.value) + } +} diff --git a/src/app/pages/notification-detail/notification-detail.component.html b/src/app/pages/notification-detail/notification-detail.component.html new file mode 100644 index 00000000..f7164adb --- /dev/null +++ b/src/app/pages/notification-detail/notification-detail.component.html @@ -0,0 +1,153 @@ + + + + + + + + + Notification + + + + + + + + + + + + +
+
+ +
+
+ +
+ +
+ + Your Dashboard
{{ data()?.dashboard_name }} in Group + {{ data()?.group_name }} +
+ +
+
+ + {{ timestamp | date: locale() }} + + Epoch {{ epoch }} + +
+
+
+
+
+
+ +
+
+ + + + Group Efficiency below {{ groupEfficiency().efficiency | number: '1.0-2' }}% + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
diff --git a/src/app/pages/notification-detail/notification-detail.component.scss b/src/app/pages/notification-detail/notification-detail.component.scss new file mode 100644 index 00000000..c3de28eb --- /dev/null +++ b/src/app/pages/notification-detail/notification-detail.component.scss @@ -0,0 +1,63 @@ +/** + * Copyright (C) 2024 bitfly explorer GmbH + * + * This file is part of Beaconchain Dashboard. + * + * Beaconchain Dashboard is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Beaconchain Dashboard is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Beaconchain Dashboard. If not, see . + */ + +@use '../../../theme/variables.scss'; + +.status ion-icon { + width: 100%; + display: flex; + justify-content: center; + text-align: center; + padding-bottom: 12px; +} + +.status { + text-align: center; + background-color: var(--ion-toolbar-background) !important; + background-image: var(--status-bg-image); + padding-bottom: 0px; +} + +.status-icon { + margin-top: 7px; + font-size: 69px; + color: var(--x-toolbar-title-color); +} + +.status-text { + margin: 0 35px; +} + +.container { + background-color: var(--ion-background-color); +} + +.white { + color: var(--x-toolbar-title-color); + padding: 0px; + margin: 0px; +} + +.inner { + margin: var(--edge-padding); +} + +.background { + background-color: var(--ion-item-background); +} diff --git a/src/app/pages/notification-detail/notification-detail.component.ts b/src/app/pages/notification-detail/notification-detail.component.ts new file mode 100644 index 00000000..5765ec14 --- /dev/null +++ b/src/app/pages/notification-detail/notification-detail.component.ts @@ -0,0 +1,152 @@ +import { Component, computed, effect, Input, Signal, signal, ViewChild, WritableSignal } from '@angular/core' +import { NotificationValidatorDashboardDetail } from '@requests/types/notifications' +import { V2NotificationDetails } from '@requests/v2-notifications' +import { ApiService } from '@services/api.service' + +import { IonAccordionGroup, IonicModule, ModalController } from '@ionic/angular' +import { fromEvent, Subscription } from 'rxjs' +import { FullPageLoadingComponent } from '@components/full-page-loading/full-page-loading.component' +import { FullPageOfflineComponent } from '@components/full-page-offline/full-page-offline.component' +import { CommonModule } from '@angular/common' +import { AccordionIndexslotComponent } from './accordion-indexslot/accordion-indexslot.component' +import { PipesModule } from '@pipes/pipes.module' +import { epochToTimestamp, shortTimeFormatLocale } from '@utils/TimeUtils' +import { APIUnauthorizedError } from '@requests/requests' + +@Component({ + selector: 'app-notification-detail', + imports: [IonicModule, PipesModule, FullPageLoadingComponent, FullPageOfflineComponent, CommonModule, AccordionIndexslotComponent], + standalone: true, + templateUrl: './notification-detail.component.html', + styleUrl: './notification-detail.component.scss', +}) +export class NotificationDetailComponent { + @ViewChild('accordionGroup', { static: true }) accordionGroup: IonAccordionGroup + + @Input() dashboardID: number + @Input() groupID: number + @Input() epoch: number + @Input() chainID: number = 1 // todo + + currentY: number + data: WritableSignal = signal(null) + initialLoading: boolean = true + online: boolean = true + timestamp = 0 + dateState: 'ts' | 'epoch' = 'ts' + state = signal<'expanded' | 'collapsed'>('collapsed') + fadeInCompleted: boolean = false + + private backbuttonSubscription: Subscription + + constructor( + private api: ApiService, + private modalCtrl: ModalController + ) { + effect(() => { + const openAccordions = this.defaultOpenAccordions() + if (openAccordions.length > 0) { + queueMicrotask(() => this.state.set('expanded')) + } else { + queueMicrotask(() => this.state.set('collapsed')) + } + }) + } + + ionViewWillEnter() { + const event = fromEvent(document, 'backbutton') + this.backbuttonSubscription = event.subscribe(() => { + this.modalCtrl.dismiss() + }) + this.update() + } + + ngAfterViewInit() { + if (!this.accordionGroup) { + console.error('accordionGroup is not initialized.') + } + } + + defaultOpenAccordions = computed(() => { + if (this.data() === null) return [] + + const wouldOpenCount = Object.keys(this.data()).reduce((count, key) => { + const value = this.data()[key as keyof NotificationValidatorDashboardDetail] + if (Array.isArray(value) && value.length > 0) { + count++ + } + return count + }, 0) + + return Object.keys(this.data()).filter((key) => { + const value = this.data()[key as keyof NotificationValidatorDashboardDetail] + return Array.isArray(value) && value.length > 0 && wouldOpenCount <= 1 + }) + }) + + groupEfficiency: Signal = computed(() => { + if (this.data()?.group_efficiency_below) { + return { efficiency: this.data().group_efficiency_below } as GroupEfficiency + } + return null + }) + + async update() { + const result = await this.api.set(new V2NotificationDetails(this.dashboardID, this.groupID, this.epoch), this.data) + if (result.error) { + console.error('Failed to get notification details', result.error) + if (!(result.error instanceof APIUnauthorizedError)) { + this.online = false + } + this.initialLoading = false + } + //this.data().slashed = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17] + // this.data().validator_offline = Array.from({ length: 100 }, (_, i) => i + 1) + // this.data().withdrawal = [{ index: 1, amount: '1000', address: { hash: '', is_contract: false } }] + // this.data().max_collateral_reached = [{ hash: '0x1231231231231231231231231232', is_contract: false }] + this.initialLoading = false + this.accordionChange() + this.timestamp = epochToTimestamp(this.chainID, this.epoch) + } + + collapse = () => { + if (this.state() == 'collapsed') { + this.accordionGroup.value = Object.keys(this.data()).filter((key) => { + const value = this.data()[key as keyof NotificationValidatorDashboardDetail] + return Array.isArray(value) && value.length > 0 + }) + } else { + this.accordionGroup.value = [] + } + this.accordionChange() + } + + accordionChange = () => { + if (!this.accordionGroup || !this.accordionGroup.value) { + return + } + this.state.set(this.accordionGroup.value.length === 0 ? 'collapsed' : 'expanded') + } + + toggleDateState() { + this.dateState = this.dateState === 'ts' ? 'epoch' : 'ts' + } + + ngOnDestroy() { + this.backbuttonSubscription.unsubscribe() + } + + closeModal() { + this.modalCtrl.dismiss() + } + + onScroll($event: { detail: { currentY: number } }) { + this.currentY = $event.detail.currentY + } + + locale = shortTimeFormatLocale +} + +interface GroupEfficiency { + efficiency: number +} diff --git a/src/app/pages/notification-detail/notification-item/notification-item.component.html b/src/app/pages/notification-detail/notification-item/notification-item.component.html new file mode 100644 index 00000000..4af87e9e --- /dev/null +++ b/src/app/pages/notification-detail/notification-item/notification-item.component.html @@ -0,0 +1,21 @@ +
+
+ +
+ +
+ +
+ {{ titlePrefix }} + + {{ extraName }}: + +
+ +
+ +
+
+
+
+
diff --git a/src/app/pages/notification-detail/notification-item/notification-item.component.scss b/src/app/pages/notification-detail/notification-item/notification-item.component.scss new file mode 100644 index 00000000..afe7a6ee --- /dev/null +++ b/src/app/pages/notification-detail/notification-item/notification-item.component.scss @@ -0,0 +1,82 @@ +/** + * Copyright (C) 2024 bitfly explorer GmbH + * + * This file is part of Beaconchain Dashboard. + * + * Beaconchain Dashboard is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Beaconchain Dashboard is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Beaconchain Dashboard. If not, see . + */ + +@use '../../../../theme/variables.scss'; + +.infi-item-middle-container { + margin-right: 15px; +} + +ion-item { + background: var(--ion-card-background); + margin: auto; +} + +ion-icon { + position: absolute !important; + top: 5px; + margin-top: 0px !important; + padding-top: 0px !important; + margin-bottom: 29px; +} + +.title { + font-size: 16px; + font-weight: bold; +} + +.balance { + font-weight: bold; +} + +.status-container { + margin-left: 0px; + margin-right: 25px; +} + +.onlinestate { + padding-left: 5px; + padding-right: 5px; + padding-bottom: 3px; + padding-top: 5px; + margin: 0; +} + +.start { + width: 50px; +} + +.inner { + padding-top: 2px; +} + +.blockie { + margin-top: 5px; + left: 16px; + margin-left: 5px; + border-radius: 20%; + height: 40px; + width: 40px; + image-rendering: pixelated; +} + +.opacity-icon { + color: var(--ion-tab-button-color); + opacity: 0.95; +} diff --git a/src/app/pages/notification-detail/notification-item/notification-item.component.ts b/src/app/pages/notification-detail/notification-item/notification-item.component.ts new file mode 100644 index 00000000..15b48171 --- /dev/null +++ b/src/app/pages/notification-detail/notification-item/notification-item.component.ts @@ -0,0 +1,42 @@ +import { CommonModule } from '@angular/common' +import { Component, Input } from '@angular/core' +import { Browser } from '@capacitor/browser' +import { IonicModule } from '@ionic/angular' +import * as blockies from 'ethereum-blockies' + +@Component({ + selector: 'app-notification-item', + imports: [IonicModule, CommonModule], + standalone: true, + templateUrl: './notification-item.component.html', + styleUrl: './notification-item.component.scss', +}) +export class NotificationValidator { + @Input() title: number | string + @Input() extra: string // optional + @Input() extraName: string + @Input() imgSeed: string + @Input() titlePrefix: string + @Input() first: boolean + @Input() last: boolean + @Input() externalLink?: string + + imgData: string + + constructor() {} + + ngOnChanges() { + this.imgData = this.getBlockies() + } + + private getBlockies() { + // TODO: figure out why the first blockie image is always black + blockies.create({ seed: this.imgSeed + '' }).toDataURL() + const dataurl = blockies.create({ seed: this.imgSeed + '', size: 8, scale: 7 }).toDataURL() + return dataurl + } + + openExternalLink() { + Browser.open({ url: this.externalLink, toolbarColor: '#2f2e42' }) + } +} diff --git a/src/app/pages/notification-history/base-history-item/base-history-item.component.html b/src/app/pages/notification-history/base-history-item/base-history-item.component.html new file mode 100644 index 00000000..49bd3b59 --- /dev/null +++ b/src/app/pages/notification-history/base-history-item/base-history-item.component.html @@ -0,0 +1,22 @@ +
+
+ +
+
+
{{ day }}
+
{{ month }}
+
+
+ +
+ {{ title }} + +
+ +
+ {{ time }} +
+
+
+
+
diff --git a/src/app/pages/notification-history/base-history-item/base-history-item.component.scss b/src/app/pages/notification-history/base-history-item/base-history-item.component.scss new file mode 100644 index 00000000..88f709a9 --- /dev/null +++ b/src/app/pages/notification-history/base-history-item/base-history-item.component.scss @@ -0,0 +1,70 @@ +// Copyright (C) 2024 bitfly explorer GmbH +// +// This file is part of Beaconchain Dashboard. +// +// Beaconchain Dashboard is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Beaconchain Dashboard is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Beaconchain Dashboard. If not, see . +@use '../../../../theme/variables.scss'; + +ion-item { + background: var(--ion-card-background); + margin: auto; +} + +ion-icon { + position: absolute !important; + top: 5px; + margin-top: 0px !important; + padding-top: 0px !important; + margin-bottom: 29px; +} + +.title { + font-size: 16px; + font-weight: bold; +} + +.date-container { + width: 40px; + text-align: center; +} + +.status-container { + font-size: var(--smaller-info-size); +} + +.inner { + padding-top: 2px; +} + +ion-item { + display: flex; + align-items: stretch; /* Ensures all children have the same height */ +} + +.start, +.status-container { + display: flex; + align-items: flex-start; /* Align content to the top */ + justify-content: flex-start; /* Align content to the top vertically */ + flex-direction: column; /* Stack child elements vertically if needed */ +} + +.date-container, +.status-container { + align-self: flex-start; /* Overrides any default centering */ +} + +.infi-item-middle-container { + flex: 1; /* Allows the middle container to expand and fill available space */ +} diff --git a/src/app/pages/notification-history/base-history-item/base-history-item.component.ts b/src/app/pages/notification-history/base-history-item/base-history-item.component.ts new file mode 100644 index 00000000..3c81e464 --- /dev/null +++ b/src/app/pages/notification-history/base-history-item/base-history-item.component.ts @@ -0,0 +1,52 @@ +import { CommonModule } from '@angular/common' +import { Component, Input } from '@angular/core' +import { IonicModule } from '@ionic/angular' +import { HistoryDataTypes } from '../validator-history-item/validator-history-item.component' +import { epochToTimestamp, formatMonthShort, getLocale } from '@utils/TimeUtils' + +@Component({ + selector: 'app-base-history-item', + imports: [CommonModule, IonicModule], + templateUrl: './base-history-item.component.html', + styleUrl: './base-history-item.component.scss', +}) +export class BaseHistoryItemComponent { + @Input() data: HistoryDataTypes + @Input() first: boolean + @Input() last: boolean + @Input() title: string + + ts: number + day: number + month: string + time: string + + ngOnChanges() { + this.ts = getTs(this.data) + this.day = getDay(this.data) + this.month = getMonth(this.data) + this.time = getTime(this.data) + } +} + +export function getTs(data: HistoryDataTypes): number { + if (!data) return 0 + if ('dashboard_id' in data) { + // todo can be cleaned up once api returns timestamp for dashboard as well + return epochToTimestamp(data.chain_id, data.epoch) + } else { + return data.timestamp * 1000 + } +} + +export function getDay(data: HistoryDataTypes): number { + return new Date(getTs(data)).getDate() +} + +function getMonth(data: HistoryDataTypes): string { + return formatMonthShort(new Date(getTs(data)).getMonth()) +} + +function getTime(data: HistoryDataTypes): string { + return new Date(getTs(data)).toLocaleTimeString(getLocale(), { hour: '2-digit', minute: '2-digit' }) +} diff --git a/src/app/pages/notification-history/client-history-item/client-history-item.component.html b/src/app/pages/notification-history/client-history-item/client-history-item.component.html new file mode 100644 index 00000000..ba426649 --- /dev/null +++ b/src/app/pages/notification-history/client-history-item/client-history-item.component.html @@ -0,0 +1,6 @@ + + New version {{ data.version }} + + diff --git a/src/app/pages/notification-history/client-history-item/client-history-item.component.scss b/src/app/pages/notification-history/client-history-item/client-history-item.component.scss new file mode 100644 index 00000000..e4df5922 --- /dev/null +++ b/src/app/pages/notification-history/client-history-item/client-history-item.component.scss @@ -0,0 +1,18 @@ +// Copyright (C) 2024 bitfly explorer GmbH +// +// This file is part of Beaconchain Dashboard. +// +// Beaconchain Dashboard is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Beaconchain Dashboard is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Beaconchain Dashboard. If not, see . + +@use '../../../../theme/variables.scss'; diff --git a/src/app/pages/notification-history/client-history-item/client-history-item.component.ts b/src/app/pages/notification-history/client-history-item/client-history-item.component.ts new file mode 100644 index 00000000..5f9be500 --- /dev/null +++ b/src/app/pages/notification-history/client-history-item/client-history-item.component.ts @@ -0,0 +1,25 @@ +import { Component, Input } from '@angular/core' +import { CommonModule } from '@angular/common' +import { IonicModule } from '@ionic/angular' +import { NotificationClientsTableRow } from '@requests/types/notifications' +import { BaseHistoryItemComponent } from '../base-history-item/base-history-item.component' +import { Toast } from '@capacitor/toast' +@Component({ + selector: 'app-client-history-item', + imports: [CommonModule, IonicModule, BaseHistoryItemComponent], + templateUrl: './client-history-item.component.html', + styleUrl: './client-history-item.component.scss', +}) +export class ClientHistoryItemComponent { + @Input() data: NotificationClientsTableRow + @Input() first: boolean + @Input() last: boolean + + open() { + Toast.show({ + text: 'Coming soon', // todo wait for api to return this + }) + return + //Browser.open({ url: this.data.url, toolbarColor: '#2f2e42' }) + } +} diff --git a/src/app/pages/notification-history/machine-history-item/machine-history-item.component.html b/src/app/pages/notification-history/machine-history-item/machine-history-item.component.html new file mode 100644 index 00000000..c625b7eb --- /dev/null +++ b/src/app/pages/notification-history/machine-history-item/machine-history-item.component.html @@ -0,0 +1,7 @@ + + {{ data.machine_name }} + {{ preExtra }} {{ extra }}% + diff --git a/src/app/pages/notification-history/machine-history-item/machine-history-item.component.scss b/src/app/pages/notification-history/machine-history-item/machine-history-item.component.scss new file mode 100644 index 00000000..e4df5922 --- /dev/null +++ b/src/app/pages/notification-history/machine-history-item/machine-history-item.component.scss @@ -0,0 +1,18 @@ +// Copyright (C) 2024 bitfly explorer GmbH +// +// This file is part of Beaconchain Dashboard. +// +// Beaconchain Dashboard is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Beaconchain Dashboard is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Beaconchain Dashboard. If not, see . + +@use '../../../../theme/variables.scss'; diff --git a/src/app/pages/notification-history/machine-history-item/machine-history-item.component.ts b/src/app/pages/notification-history/machine-history-item/machine-history-item.component.ts new file mode 100644 index 00000000..5ff2433f --- /dev/null +++ b/src/app/pages/notification-history/machine-history-item/machine-history-item.component.ts @@ -0,0 +1,63 @@ +import { Component, Input } from '@angular/core' +import { BaseHistoryItemComponent } from '../base-history-item/base-history-item.component' +import { CommonModule } from '@angular/common' +import { IonicModule } from '@ionic/angular' +import { NotificationMachinesTableRow } from '@requests/types/notifications' + +@Component({ + selector: 'app-machine-history-item', + imports: [CommonModule, IonicModule, BaseHistoryItemComponent], + templateUrl: './machine-history-item.component.html', + styleUrl: './machine-history-item.component.scss', +}) +export class MachineHistoryItemComponent { + @Input() data: NotificationMachinesTableRow + @Input() first: boolean + @Input() last: boolean + + title: string + extra: number + preExtra: string + + ngOnChanges() { + this.title = formatMachineHistoryType(this.data.event_type) + this.extra = this.getExtra() + this.preExtra = this.getPreExtra() + } + + private getExtra() { + return this.data.threshold + } + + private getPreExtra() { + switch (this.data.event_type) { + case 'offline': + return '' + case 'storage': + return 'Usage above' + case 'cpu': + return 'Usage above' + case 'memory': + return 'Usage above' + default: + return 'Unknown' + } + } +} + +export function formatMachineHistoryType(eventType: string): string { + switch (eventType) { + case 'offline': + return 'Machine Offline' + case 'storage': + return 'Storage Warning' + case 'cpu': + return 'CPU Warning' + case 'memory': + return 'Memory Warning' + default: + return null + } + + return null +} diff --git a/src/app/pages/notification-history/network-history-item/network-history-item.component.html b/src/app/pages/notification-history/network-history-item/network-history-item.component.html new file mode 100644 index 00000000..459ac1a4 --- /dev/null +++ b/src/app/pages/notification-history/network-history-item/network-history-item.component.html @@ -0,0 +1,6 @@ + + {{ extra }} + On {{ network }} network + diff --git a/src/app/pages/notification-history/network-history-item/network-history-item.component.scss b/src/app/pages/notification-history/network-history-item/network-history-item.component.scss new file mode 100644 index 00000000..c14ebfb3 --- /dev/null +++ b/src/app/pages/notification-history/network-history-item/network-history-item.component.scss @@ -0,0 +1,20 @@ +/** + * Copyright (C) 2024 bitfly explorer GmbH + * + * This file is part of Beaconchain Dashboard. + * + * Beaconchain Dashboard is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Beaconchain Dashboard is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Beaconchain Dashboard. If not, see . + */ + +@use '../../../../theme/variables.scss'; diff --git a/src/app/pages/notification-history/network-history-item/network-history-item.component.ts b/src/app/pages/notification-history/network-history-item/network-history-item.component.ts new file mode 100644 index 00000000..437c14be --- /dev/null +++ b/src/app/pages/notification-history/network-history-item/network-history-item.component.ts @@ -0,0 +1,56 @@ +import { CommonModule } from '@angular/common' +import { Component, Input } from '@angular/core' +import { IonicModule } from '@ionic/angular' +import { NotificationNetworksTableRow } from '@requests/types/notifications' +import { BaseHistoryItemComponent } from '../base-history-item/base-history-item.component' +import { findChainNetworkById } from '@utils/NetworkData' +import { capitalize } from '@services/api.service' + +@Component({ + selector: 'app-network-history-item', + imports: [CommonModule, IonicModule, BaseHistoryItemComponent], + templateUrl: './network-history-item.component.html', + styleUrl: './network-history-item.component.scss', +}) +export class NetworkHistoryItemComponent { + @Input() data: NotificationNetworksTableRow + @Input() first: boolean + @Input() last: boolean + title: string + extra: string + network: string + + ngOnChanges() { + this.title = formatNetworkHistoryType(this.data.event_type) + this.extra = this.getExtra() + this.network = capitalize(findChainNetworkById(this.data.chain_id).name) + } + + private getExtra() { + switch (this.data.event_type) { + case 'new_reward_round': + return '' + case 'gas_above': + return this.data.threshold + case 'gas_below': + return this.data.threshold + case 'participation_rate': + return this.data.threshold + } + } +} + +export function formatNetworkHistoryType(eventType: string): string { + switch (eventType) { + case 'new_reward_round': + return 'New Reward Round' + case 'gas_above': + return 'Gas Above' + case 'gas_below': + return 'Gas Below' + case 'participation_rate': + return 'Participation Rate' + } + + return null +} diff --git a/src/app/pages/notifications/notifications-routing.module.ts b/src/app/pages/notification-history/notification-history-routing.module.ts similarity index 57% rename from src/app/pages/notifications/notifications-routing.module.ts rename to src/app/pages/notification-history/notification-history-routing.module.ts index bf9522d5..ffb19388 100644 --- a/src/app/pages/notifications/notifications-routing.module.ts +++ b/src/app/pages/notification-history/notification-history-routing.module.ts @@ -1,12 +1,11 @@ import { NgModule } from '@angular/core' import { Routes, RouterModule } from '@angular/router' - -import { NotificationsPage } from './notifications.page' +import { NoticationHistoryComponent } from './notification-history.component' const routes: Routes = [ { path: '', - component: NotificationsPage, + component: NoticationHistoryComponent, }, ] @@ -14,4 +13,4 @@ const routes: Routes = [ imports: [RouterModule.forChild(routes)], exports: [RouterModule], }) -export class NotificationsPageRoutingModule {} +export class NotificationHistoryPageRoutingModule {} diff --git a/src/app/pages/notification-history/notification-history.component.html b/src/app/pages/notification-history/notification-history.component.html new file mode 100644 index 00000000..ce6adc79 --- /dev/null +++ b/src/app/pages/notification-history/notification-history.component.html @@ -0,0 +1,75 @@ + + + + + + + History + + + + {{ item.title }} + + + + + + + + + +
+ +

No Notifications

+ Any notifications you receive will show up in this history. +
+ +
+ {{ visibleMonth }} + +
+ + +
+ + + + + + + + +
+
+
+
+
+
+
diff --git a/src/app/pages/notification-history/notification-history.component.scss b/src/app/pages/notification-history/notification-history.component.scss new file mode 100644 index 00000000..fd6779b9 --- /dev/null +++ b/src/app/pages/notification-history/notification-history.component.scss @@ -0,0 +1,88 @@ +// Copyright (C) 2024 bitfly explorer GmbH +// +// This file is part of Beaconchain Dashboard. +// +// Beaconchain Dashboard is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Beaconchain Dashboard is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Beaconchain Dashboard. If not, see . + +@use '../../../theme/variables.scss'; + +cdk-virtual-scroll-viewport { + margin-left: 0px; + margin-right: 0px; + padding-left: 0px; + padding-right: 0px; + width: 100%; + height: 100%; +} + +.next-block-hint { + position: relative; /* Allows positioning of the icon absolutely within this container */ + display: flex; + align-items: center; /* Center items vertically */ + justify-content: center; /* Center the label within the full width */ + font-weight: 400; + margin: 6px; + text-align: center; +} + +.hint-label { + flex: none; /* Prevent the label from stretching */ + text-align: center; +} + +.hint-icon { + position: absolute; /* Position the icon absolutely */ + right: 0px; /* Align it to the right side of the container */ + margin: var(--edge-padding-left-plus-15px); + font-size: 1.3rem; +} + +.opacity-icon { + color: var(--ion-tab-button-color); + opacity: 0.95; +} + +.nothingfound ion-icon { + width: 100%; + display: flex; + justify-content: center; + text-align: center; + padding-bottom: 12px; + font-size: 55px; + color: var(--ion-text-color-lighter); +} + +.nothingfound { + text-align: center; + padding: 50px; + + padding-top: 45px; + color: var(--ion-text-color-lighter); + background-color: var(--background-color); +} + +.nothingfound ion-label { + margin-left: 6%; + margin-right: 6%; +} + +.segment-button-checked { + //color: var(--segment-primary) !important; + font-weight: 600 !important; + opacity: 1; +} + +.segment-button-checked.md::part(native) { + opacity: 1 !important; +} diff --git a/src/app/pages/notification-history/notification-history.component.ts b/src/app/pages/notification-history/notification-history.component.ts new file mode 100644 index 00000000..b55891db --- /dev/null +++ b/src/app/pages/notification-history/notification-history.component.ts @@ -0,0 +1,237 @@ +import { ScrollingModule } from '@angular/cdk/scrolling' +import { CommonModule } from '@angular/common' +import { Component, signal, WritableSignal } from '@angular/core' +import { Toast } from '@capacitor/toast' +import { IonicModule } from '@ionic/angular' +import { APIRequest, APIUnauthorizedError } from '@requests/requests' +import { + NotificationClientsTableRow, + NotificationDashboardsTableRow, + NotificationMachinesTableRow, + NotificationNetworksTableRow, +} from '@requests/types/notifications' +import { V2NotificationsClients, V2NotificationsDashboard, V2NotificationsMachines, V2NotificationsNetworks } from '@requests/v2-notifications' +import { ApiService } from '@services/api.service' +import { InfiniteScrollDataSource, loadMoreType } from '@utils/InfiniteScrollDataSource' +import { eventTypeBadge, HistoryDataTypes, NotificationHistoryItemComponent } from './validator-history-item/validator-history-item.component' +import { formatMonthLong } from '@utils/TimeUtils' +import { AlertService } from '@services/alert.service' +import { FullPageLoadingComponent } from '@components/full-page-loading/full-page-loading.component' +import { FullPageOfflineComponent } from '@components/full-page-offline/full-page-offline.component' +import { FormsModule } from '@angular/forms' +import { getDay, getTs } from './base-history-item/base-history-item.component' +import { formatNetworkHistoryType, NetworkHistoryItemComponent } from './network-history-item/network-history-item.component' +import { formatMachineHistoryType, MachineHistoryItemComponent } from './machine-history-item/machine-history-item.component' +import { ClientHistoryItemComponent } from './client-history-item/client-history-item.component' + +const PAGE_SIZE = 25 +const ASSOCIATED_CACHE_KEY = 'notification-history' + +type Tab = 'validator-dashboard' | 'network' | 'machines' | 'eth-clients' + +@Component({ + selector: 'app-notification-history', + imports: [ + CommonModule, + IonicModule, + FormsModule, + ScrollingModule, + NotificationHistoryItemComponent, + FullPageLoadingComponent, + FullPageOfflineComponent, + NetworkHistoryItemComponent, + MachineHistoryItemComponent, + ClientHistoryItemComponent, + ], + templateUrl: './notification-history.component.html', + styleUrl: './notification-history.component.scss', +}) +export class NoticationHistoryComponent { + tabs = [ + { title: 'Dashboard', key: 'validator-dashboard' as Tab }, + { title: 'Network', key: 'network' as Tab }, + { title: 'Machines', key: 'machines' as Tab }, + { title: 'Updates', key: 'eth-clients' as Tab }, + ] + + dataSources: Map>> = new Map() + loadMore: boolean = true + online: boolean = true + initialLoadings: Map> = new Map() + + visibleMonth: string = '' + filter: string = '' + currentScrollIndex: number = 0 + + selectedTab: Tab = 'validator-dashboard' + + constructor( + private api: ApiService, + private alerts: AlertService + ) { + this.tabs.forEach((tab) => { + this.dataSources.set(tab.key, signal(undefined)) + this.initialLoadings.set(tab.key, signal(true)) + }) + } + + async ionViewWillEnter() { + await this.update() + this.onScrolledIndexChange(0) + } + + tabChange() { + this.ionViewWillEnter() + } + + async update() { + let dataRetriever: InfiniteScrollDataSource + switch (this.selectedTab) { + case 'validator-dashboard': + dataRetriever = new InfiniteScrollDataSource( + PAGE_SIZE, + this.getDefaultDataRetriever(V2NotificationsDashboard) + ) + break + case 'machines': + dataRetriever = new InfiniteScrollDataSource(PAGE_SIZE, this.getDefaultDataRetriever(V2NotificationsMachines)) + break + case 'network': + dataRetriever = new InfiniteScrollDataSource(PAGE_SIZE, this.getDefaultDataRetriever(V2NotificationsNetworks)) + break + case 'eth-clients': + dataRetriever = new InfiniteScrollDataSource(PAGE_SIZE, this.getDefaultDataRetriever(V2NotificationsClients)) + break + } + + this.dataSources.get(this.selectedTab).set(dataRetriever) + console.log('dataSources', this.selectedTab, this.dataSources, dataRetriever) + await dataRetriever.reset() + } + + private getDefaultDataRetriever APIRequest, E>(constructor: T): loadMoreType { + return async (cursor) => { + this.loadMore = !!cursor + const result = await this.api.execute(new constructor(cursor, PAGE_SIZE), ASSOCIATED_CACHE_KEY) + if (result.error) { + Toast.show({ + text: 'Could not load blocks', + duration: 'long', + }) + if (!(result.error instanceof APIUnauthorizedError)) { + // todo change to just if timeout? + this.online = false + } + this.initialLoadings.get(this.selectedTab).set(false) + + console.error('Could not load history', result.error) + return { + data: undefined, + next_cursor: null, + } + } + this.loadMore = false + this.initialLoadings.get(this.selectedTab).set(false) + + return { + data: result.data as E[], + next_cursor: result.paging?.next_cursor, + } + } + } + + onScrolledIndexChange(index: number): void { + this.currentScrollIndex = index + const itemsArray = this.dataSources.get(this.selectedTab)()?.getItems() + const item = itemsArray?.[this.currentScrollIndex] + if (!item) return + + // if last item in infinite scroller is also on the same day as the current one, display a "+" sign + // to indicate that there might be even more entries if the user scrolls down + let more = '' + const lastItemIsAlsoOnSameDay = isSameDay(new Date(getTs(itemsArray[itemsArray.length - 1])), new Date(getTs(item))) + if (lastItemIsAlsoOnSameDay && !this.dataSources.get(this.selectedTab)().hasReachedEnd()) { + more = '+' + } + + const countSameDayNotifications = this.getSameDayItems(item).length + this.visibleMonth = getDay(item) + ' ' + getMonth(item) + ' (' + countSameDayNotifications + more + ')' + } + + getSameDayItems(firstItem: HistoryDataTypes) { + return this.dataSources + .get(this.selectedTab)() + .getItems() + ?.filter((notification) => isSameDay(new Date(getTs(notification)), new Date(getTs(firstItem)))) + } + + async showDayDetails() { + const item = this.dataSources.get(this.selectedTab)().getItems()[this.currentScrollIndex] + const eventsOnSameDay = countEventTypes(this.getSameDayItems(item)) + + let alertText = ` +
+ ${getDay(item)} ${getMonth(item)} ${getYear(item)}
+ ` + + eventsOnSameDay.forEach((event) => { + const badge = eventTypeBadge(event.eventType) + // badge is just for validator dashboard history, otherwise use format methods below + if (badge.short) { + alertText += ` + ${event.count}x ${badge.short} Alert${event.count > 1 ? 's' : ''}
+ ` + } else { + const formattedText = formatMachineHistoryType(event.eventType) || formatNetworkHistoryType(event.eventType) || event.eventType + alertText += ` + ${event.count}x ${formattedText}
+ ` + } + }) + + alertText += `
` + + await this.alerts.showInfo('Day Summary', alertText) + } +} + +function getMonth(data: HistoryDataTypes): string { + return formatMonthLong(new Date(getTs(data)).getMonth()) +} + +function getYear(data: HistoryDataTypes): number { + return new Date(getTs(data)).getUTCFullYear() +} + +function isSameDay(date1: Date, date2: Date) { + return date1.getFullYear() === date2.getFullYear() && date1.getMonth() === date2.getMonth() && date1.getDate() === date2.getDate() +} + +export interface EventCount { + eventType: string + count: number +} + +function countEventTypes(rows: HistoryDataTypes[]) { + // Use a Map to store event type counts + const eventTypeCounts = new Map() + + // Iterate over each row in the input array + rows.forEach((row) => { + if ('event_types' in row) { + row.event_types.forEach((eventType) => { + // Increment count for each event type + eventTypeCounts.set(eventType.toString(), (eventTypeCounts.get(eventType.toString()) || 0) + 1) + }) + } else if ('event_type' in row) { + // Increment count for each event type + eventTypeCounts.set(row.event_type.toString(), (eventTypeCounts.get(row.event_type.toString()) || 0) + 1) + } else if ('client_name' in row) { + // Increment count for each event type + eventTypeCounts.set(row.client_name.toString(), (eventTypeCounts.get(row.client_name.toString()) || 0) + 1) + } + }) + + // Convert Map to an array of objects + return Array.from(eventTypeCounts, ([eventType, count]) => ({ eventType, count }) as EventCount) +} diff --git a/src/app/pages/notification-history/validator-history-item/validator-history-item.component.html b/src/app/pages/notification-history/validator-history-item/validator-history-item.component.html new file mode 100644 index 00000000..bcee8852 --- /dev/null +++ b/src/app/pages/notification-history/validator-history-item/validator-history-item.component.html @@ -0,0 +1,11 @@ + + In Group {{ data.group_name }} + Affecting {{ data.entity_count }} {{ data.entity_count > 1 ? 'Validators' : 'Validator' }} + + + {{ item.short }} + + + diff --git a/src/app/pages/notification-history/validator-history-item/validator-history-item.component.scss b/src/app/pages/notification-history/validator-history-item/validator-history-item.component.scss new file mode 100644 index 00000000..5a380979 --- /dev/null +++ b/src/app/pages/notification-history/validator-history-item/validator-history-item.component.scss @@ -0,0 +1,28 @@ +/** + * Copyright (C) 2024 bitfly explorer GmbH + * + * This file is part of Beaconchain Dashboard. + * + * Beaconchain Dashboard is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Beaconchain Dashboard is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Beaconchain Dashboard. If not, see . + */ + +@use '../../../../theme/variables.scss'; + +ion-badge { + --padding-end: 8px; + --padding-start: 8px; + --padding-top: 5px; + --padding-bottom: 4px; + min-width: 36px; +} diff --git a/src/app/pages/notification-history/validator-history-item/validator-history-item.component.ts b/src/app/pages/notification-history/validator-history-item/validator-history-item.component.ts new file mode 100644 index 00000000..eb96bde4 --- /dev/null +++ b/src/app/pages/notification-history/validator-history-item/validator-history-item.component.ts @@ -0,0 +1,95 @@ +import { Component, Input } from '@angular/core' +import { + NotificationClientsTableRow, + NotificationDashboardsTableRow, + NotificationMachinesTableRow, + NotificationNetworksTableRow, +} from '@requests/types/notifications' +import { NotificationDetailComponent } from '../../notification-detail/notification-detail.component' +import { IonicModule, ModalController } from '@ionic/angular' +import { CommonModule } from '@angular/common' +import { BaseHistoryItemComponent } from '../base-history-item/base-history-item.component' + +interface EventType { + eventType: string + short: string + color: string +} + +export type HistoryDataTypes = + | NotificationDashboardsTableRow + | NotificationMachinesTableRow + | NotificationNetworksTableRow + | NotificationClientsTableRow + +@Component({ + selector: 'app-validator-history-item', + imports: [CommonModule, IonicModule, BaseHistoryItemComponent], + templateUrl: './validator-history-item.component.html', + styleUrl: './validator-history-item.component.scss', +}) +export class NotificationHistoryItemComponent { + @Input() data: NotificationDashboardsTableRow + @Input() first: boolean + @Input() last: boolean + eventTypeBadge: EventType[] + + constructor(private modalCtrl: ModalController) {} + + ngOnChanges() { + this.eventTypeBadge = this.getEventTypeBadge() + } + + getEventTypeBadge = (): EventType[] => { + if (!this.data) return [] + const result = this.data.event_types.map((eventType) => { + return eventTypeBadge(eventType) + }) + return result + } + + async open() { + const modal = await this.modalCtrl.create({ + component: NotificationDetailComponent, + componentProps: { + dashboardID: this.data.dashboard_id, + groupID: this.data.group_id, + epoch: this.data.epoch, + }, + }) + modal.present() + + await modal.onWillDismiss() + } +} + +export function eventTypeBadge(eventType: string): EventType { + switch (eventType) { + case 'group_efficiency_below': + return { eventType: eventType.toString(), short: 'Efficiency', color: 'secondary' } + case 'validator_offline': + return { eventType: eventType.toString(), short: 'Offline', color: 'danger' } + case 'proposal_missed': + return { eventType: eventType.toString(), short: 'Block Missed', color: 'danger' } + case 'proposal_success': + return { eventType: eventType.toString(), short: 'Block Proposed', color: 'secondary' } + case 'proposal_upcoming': + return { eventType: eventType.toString(), short: 'Block Upcoming', color: 'secondary' } + case 'attestation_missed': + return { eventType: eventType.toString(), short: 'Att. Missed', color: 'danger' } + case 'max_collateral': + return { eventType: eventType.toString(), short: 'Max Coll.', color: 'secondary' } + case 'min_collateral': + return { eventType: eventType.toString(), short: 'Min Coll.', color: 'secondary' } + case 'sync': + return { eventType: eventType.toString(), short: 'Sync', color: 'secondary' } + case 'withdrawal': + return { eventType: eventType.toString(), short: 'Withdrawal', color: 'secondary' } + case 'validator_got_slashed': + return { eventType: eventType.toString(), short: 'Slashed', color: 'danger' } + case 'validator_online': + return { eventType: eventType.toString(), short: 'Online', color: 'danger' } + default: + return { eventType: eventType.toString(), short: null, color: 'primary' } + } +} diff --git a/src/app/pages/notifications/notifications.module.ts b/src/app/pages/notifications/notifications.module.ts deleted file mode 100644 index 3a991bf1..00000000 --- a/src/app/pages/notifications/notifications.module.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { NgModule } from '@angular/core' -import { CommonModule } from '@angular/common' -import { FormsModule } from '@angular/forms' - -import { IonicModule } from '@ionic/angular' - -import { NotificationsPageRoutingModule } from './notifications-routing.module' - -import { NotificationsPage } from './notifications.page' - -@NgModule({ - imports: [CommonModule, FormsModule, IonicModule, NotificationsPageRoutingModule], - declarations: [NotificationsPage], -}) -export class NotificationsPageModule {} diff --git a/src/app/pages/notifications/notifications.page.html b/src/app/pages/notifications/notifications.page.html deleted file mode 100644 index 1e16da12..00000000 --- a/src/app/pages/notifications/notifications.page.html +++ /dev/null @@ -1,446 +0,0 @@ - - - - - - Notifications - - - - -
- Note: You are using the No-Google version of this app. Push notifications will not work, but you can configure webhook - notifications on {{ api.getHostName() }} directly or by clicking here. -
- - - General - General » {{ network }} - - - - - - Notifications - - - - - Validators - - - - - - - - Validator Slashed ({{ getCount('validator_got_slashed') }}) - - - - - Submitted Proposals ({{ getCount('validator_proposal_submitted') }}) - - - - - Missed Proposals ({{ getCount('validator_proposal_missed') }}) - - - - - Missed Attestations ({{ getCount('validator_attestation_missed') }}) - - - - - Sync Committee Duty ({{ getCount('validator_synccommittee_soon') }}) - - - - - - Validator Offline ({{ getCount('validator_is_offline') }}) - - - - - Validator Withdrawals ({{ getCount('validator_withdrawal') }}) - - - - ETH Client Updates - - - - - - Client Updates - - - - - Monitoring - - - - - - Machine Offline - - -
- - Not supported - - - - Does not work with at least one of your machines. Prysm is currently not supported. - -
- - - - Storage Usage - - - - - - - - ≥ {{ storageThreshold }} % - - - - - - CPU Usage - - - - - - - - - ≥ {{ cpuThreshold }} % - - - - - - Memory Usage - - - - - - - - - ≥ {{ memoryThreshold }} % - -
- - - Rocketpool Network - - - - - - New Reward Round - - - - - Rocketpool Node - - - -
- -
- Note: You have not added any Rocketpool validators. Add at least one to enable these settings. -
-
-
- - - - - Max Collateral - - - - - - - - - - ≥ {{ maxCollateralThreshold/10 + 140}} % - ≤ {{ maxCollateralThreshold*-1/10 + 140}} % - - - - - - Min Collateral - - - - - - - ≤ {{ minCollateralThreshold/10 + 10 }} % - -
- -
-
diff --git a/src/app/pages/notifications/notifications.page.scss b/src/app/pages/notifications/notifications.page.scss deleted file mode 100644 index 95602f0f..00000000 --- a/src/app/pages/notifications/notifications.page.scss +++ /dev/null @@ -1,35 +0,0 @@ -@import '../../../theme/variables.scss'; - -.range { - margin-left: 50px !important; -} - -.range-locked { - padding-left: 1px !important; - margin-left: 0px !important; -} - -.pseudo-disabled { - opacity: 0.3 !important; -} - -ion-note { - color: var(--text-color); - font-size: 15px; - font-weight: bold; -} - -.active-count { - font-size: 0.85rem; - opacity: 0.8; -} - -.notificationnote { - margin: 14px; - opacity: 0.9; - font-size: 0.95em; -} - -.notificationnote strong { - color: var(--ion-color-primary); -} diff --git a/src/app/pages/notifications/notifications.page.spec.ts b/src/app/pages/notifications/notifications.page.spec.ts deleted file mode 100644 index da8b3a14..00000000 --- a/src/app/pages/notifications/notifications.page.spec.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing' -import { IonicModule } from '@ionic/angular' - -import { NotificationsPage } from './notifications.page' - -describe('NotificationsPage', () => { - let component: NotificationsPage - let fixture: ComponentFixture - - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [NotificationsPage], - imports: [IonicModule.forRoot()], - }).compileComponents() - - fixture = TestBed.createComponent(NotificationsPage) - component = fixture.componentInstance - fixture.detectChanges() - })) - - it('should create', () => { - expect(component).toBeTruthy() - }) -}) diff --git a/src/app/pages/notifications/notifications.page.ts b/src/app/pages/notifications/notifications.page.ts deleted file mode 100644 index b0329c7a..00000000 --- a/src/app/pages/notifications/notifications.page.ts +++ /dev/null @@ -1,174 +0,0 @@ -import { Component, OnInit } from '@angular/core' -import { Router } from '@angular/router' -import { ModalController, Platform } from '@ionic/angular' -import { AlertService } from 'src/app/services/alert.service' -import { ApiService } from 'src/app/services/api.service' -import { CPU_THRESHOLD, HDD_THRESHOLD, RAM_THRESHOLD, StorageService } from 'src/app/services/storage.service' -import { SyncService } from 'src/app/services/sync.service' -import { NotificationBase } from 'src/app/tab-preferences/notification-base' -import ClientUpdateUtils from 'src/app/utils/ClientUpdateUtils' -import FirebaseUtils from 'src/app/utils/FirebaseUtils' -import FlavorUtils from 'src/app/utils/FlavorUtils' -import MachineUtils, { UNSUPPORTED_PRYSM } from 'src/app/utils/MachineUtils' -import { MerchantUtils } from 'src/app/utils/MerchantUtils' -import { SubscribePage } from '../subscribe/subscribe.page' -import { Browser } from '@capacitor/browser' -import { ValidatorUtils } from 'src/app/utils/ValidatorUtils' -@Component({ - selector: 'app-notifications', - templateUrl: './notifications.page.html', - styleUrls: ['./notifications.page.scss'], -}) -export class NotificationsPage extends NotificationBase implements OnInit { - network = 'main' - authUser = null - - canCustomizeThresholds = false - - initialized = false - - allMachines: Promise - noMachines = true - - unsupportedPrysm = false - - noGoogle = false - - disableRocketpoolNode = true - - constructor( - protected api: ApiService, - protected storage: StorageService, - protected firebaseUtils: FirebaseUtils, - protected platform: Platform, - protected alerts: AlertService, - public sync: SyncService, - private merchantUtils: MerchantUtils, - private modalController: ModalController, - private machineUtils: MachineUtils, - protected clientUpdateUtils: ClientUpdateUtils, - private router: Router, - private flavor: FlavorUtils, - private validatorUtils: ValidatorUtils - ) { - super(api, storage, firebaseUtils, platform, alerts, sync, clientUpdateUtils) - - this.flavor.isNoGoogleFlavor().then((result) => { - this.noGoogle = result - }) - } - - saveAndBack() { - if (this.settingsChanged) { - this.sync.syncAllSettings(true) - } - - this.router.navigate(['/tabs/preferences']) - } - - handleLockedClick() { - if (this.canCustomizeThresholds) return - - this.openUpgrades() - } - - async configureWebhooks() { - await Browser.open({ url: this.api.getBaseUrl() + '/user/webhooks', toolbarColor: '#2f2e42' }) - } - - async ionViewWillEnter() { - this.initialized = false - - this.storage.getBooleanSetting(UNSUPPORTED_PRYSM, false).then((result) => { - this.unsupportedPrysm = result - }) - - this.storage.getAuthUser().then((result) => (this.authUser = result)) - this.network = this.api.capitalize(this.api.getNetworkName()) - this.merchantUtils.hasCustomizableNotifications().then((result) => { - this.canCustomizeThresholds = result - }) - - await this.loadAllToggles() - setTimeout(() => { - this.initialized = true - }, 400) - - this.disableRocketpoolNode = !(await this.validatorUtils.areRocketpoolValidatorsSubscribed()) - } - - changeValidatorOffline() { - if (!this.initialized) return - this.notifyEventFilterToggle('validator_is_offline', null, 3) - } - - changeDiskNotification() { - if (!this.initialized) return - this.storage.setSetting(HDD_THRESHOLD, this.storageThreshold) - const thresholdConv = (100 - this.storageThreshold) / 100 // endpoint takes in percantage of free space available - this.notifyEventToggleAllMachines('monitoring_hdd_almostfull', thresholdConv) - } - - changeCPUNotification() { - if (!this.initialized) return - this.storage.setSetting(CPU_THRESHOLD, this.cpuThreshold) - const thresholdConv = this.cpuThreshold / 100 - this.notifyEventToggleAllMachines('monitoring_cpu_load', thresholdConv) - } - - changeMemoryNotification() { - if (!this.initialized) return - this.storage.setSetting(RAM_THRESHOLD, this.memoryThreshold) - const thresholdConv = this.memoryThreshold / 100 - this.notifyEventToggleAllMachines('monitoring_memory_usage', thresholdConv) - } - - changeRocketpoolMaxCollateral() { - if (!this.initialized) return - - let thresholdConv = 0 - if (this.maxCollateralThreshold >= 0) { - thresholdConv = 1 + (this.maxCollateralThreshold - 100) / 1000 - } else { - thresholdConv = (1 - (this.maxCollateralThreshold + 100) / 1000) * -1 - } - - this.notifyEventFilterToggle('rocketpool_colleteral_max', null, thresholdConv) - } - - changeRocketpoolMinCollateral() { - if (!this.initialized) return - - const thresholdConv = 1 + this.minCollateralThreshold / 100 - this.notifyEventFilterToggle('rocketpool_colleteral_min', null, thresholdConv) - } - - async notifyEventToggleAllMachines(event: string, threshold: number = null) { - const array = await this.allMachines - array.forEach((machine) => { - this.notifyEventFilterToggle(event, machine, threshold) - }) - } - - async ngOnInit() { - this.allMachines = this.machineUtils.getAllMachineNames() - const result = await this.allMachines - this.noMachines = result.length == 0 - } - - changeStorageThreshold($event) { - this.storageThreshold = $event.detail.value - } - - changeCPUThreshold($event) { - this.cpuThreshold = $event.detail.value - } - - async openUpgrades() { - const modal = await this.modalController.create({ - component: SubscribePage, - cssClass: 'my-custom-class', - }) - return await modal.present() - } -} diff --git a/src/app/pages/slotviz-legend/slotviz-legend.component.html b/src/app/pages/slotviz-legend/slotviz-legend.component.html new file mode 100644 index 00000000..a9c7a1df --- /dev/null +++ b/src/app/pages/slotviz-legend/slotviz-legend.component.html @@ -0,0 +1,194 @@ + + + + + + + + Legend + + + + + + + + +

Block States

+

+ Each block has two states. The border color represents the network status while the + content color indicates your validator's status. This makes it easy to backtrack if a missed duty was related to a network + issue or an issue on your end. +

+
+
+ + + + +

Content Color Scheme

+

+ + Green = All validator duties successful
+ + Red = All validator duties failed
+ + Yellow = Some duties successful / some failed
+ + Empty = Some duties are still pending +

+
+
+ + + + +

Border Color Scheme

+

+ + Green = Network proposed block
+ + Red = Network missed block +

+
+
+ + + + +

Symbols

+ + + + + + +

Block Proposal Duty

+
+
+ + + + + +

Attestation Duty

+
+
+ + + + + +

Sync Committee Duty

+
+
+ + + + + +

Slashing

+
+
+ + + + + +

Multiple duties / events in this block

+ You can click on any block for a breakdown +
+
+
+
+
+ + + + +

Examples

+ + + +
+ +
+
+ +

+ Green content with green border:
+ Network proposed a block and you successfully attested to it +

+
+
+ + +
+ +
+
+ +

+ Red content with red border:
+ You missed your block proposal +

+
+
+ + +
+ +
+
+ +

+ Yellow content with green border:
+ Network proposed the block, but only some of your validators successfully attested to it. +

+
+
+ + +
+ +
+
+ +

+ Green content with red border:
+ Network missed the block but your duties were successful +

+
+
+ + +
+ +
+
+ +

+ Green content with green border:
+ Network proposed and you caught someone else's validator cheating and slashed them +

+
+
+ + +
+ +
+
+ +

+ Red content with green border:
+ Network proposed but your validator has been slashed. +

+
+
+
+
+
+
+
+
diff --git a/src/app/pages/slotviz-legend/slotviz-legend.component.scss b/src/app/pages/slotviz-legend/slotviz-legend.component.scss new file mode 100644 index 00000000..ad2ddfbf --- /dev/null +++ b/src/app/pages/slotviz-legend/slotviz-legend.component.scss @@ -0,0 +1,113 @@ +// Copyright (C) 2025 bitfly explorer GmbH +// +// This file is part of Beaconchain Dashboard. +// +// Beaconchain Dashboard is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Beaconchain Dashboard is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Beaconchain Dashboard. If not, see . + +@use '../../../theme/variables.scss'; + +:host { + display: block; +} + +.legend-content { + padding: 16px; +} + +ion-item { + margin-bottom: 12px; +} + +h2 { + font-size: 18px; + margin-bottom: 8px; +} + +p { + font-size: 14px; + line-height: 1.4; + margin: 0; +} + +/* Color swatches for content status */ +.color-example { + display: inline-block; + width: 16px; + height: 16px; + border-radius: 2px; + margin-right: 8px; + vertical-align: middle; +} +.color-example.success { + background-color: var(--ion-color-success); +} +.color-example.danger { + background-color: var(--ion-color-danger); +} +.color-example.warning { + background-color: var(--ion-color-warning); +} +.color-example.pending { + background-color: transparent; + border: 1px solid #ccc; +} + +/* Border examples for network status */ +.border-example { + display: inline-block; + width: 16px; + height: 16px; + border: 2px solid; + border-radius: 2px; + margin-right: 8px; +} +.border-example.success { + border-color: var(--ion-color-success); +} +.border-example.danger { + border-color: var(--ion-color-danger); +} + +/* Symbol row styling */ +.symbol-row { + align-items: center; + margin-bottom: 8px; +} +.symbol-icon { + font-size: 24px; + margin-right: 4px; +} + +/* Example block styling */ +.example-row { + align-items: center; + margin-bottom: 16px; +} + +/* Simulated block (square) style */ +.square { + position: relative; + display: flex; + justify-content: center; + align-items: center; + width: 48px; + height: 48px; + border: 2px solid #ccc; + box-sizing: border-box; + background-color: var(--ion-card-background); + transition: + border-color 0.3s ease, + background-color 0.3s ease; + border-radius: 4px; +} diff --git a/src/app/pages/slotviz-legend/slotviz-legend.component.ts b/src/app/pages/slotviz-legend/slotviz-legend.component.ts new file mode 100644 index 00000000..cf91058c --- /dev/null +++ b/src/app/pages/slotviz-legend/slotviz-legend.component.ts @@ -0,0 +1,17 @@ +import { CommonModule } from '@angular/common' +import { Component } from '@angular/core' +import { IonicModule, ModalController } from '@ionic/angular' + +@Component({ + selector: 'app-slotviz-legend', + imports: [CommonModule, IonicModule], + templateUrl: './slotviz-legend.component.html', + styleUrl: './slotviz-legend.component.scss', +}) +export class SlotvizLegendComponent { + constructor(private modalCtrl: ModalController) {} + + closeModal() { + this.modalCtrl.dismiss() + } +} diff --git a/src/app/pages/slotviz/slotviz.component.html b/src/app/pages/slotviz/slotviz.component.html new file mode 100644 index 00000000..98bcb20b --- /dev/null +++ b/src/app/pages/slotviz/slotviz.component.html @@ -0,0 +1,68 @@ + + + + + + + + + Duty {{ slotViz.nextDutyTs() | countdown | async }} + + + + + + + + + + Filters + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/app/pages/slotviz/slotviz.component.scss b/src/app/pages/slotviz/slotviz.component.scss new file mode 100644 index 00000000..dfcdfdfd --- /dev/null +++ b/src/app/pages/slotviz/slotviz.component.scss @@ -0,0 +1,18 @@ +// Copyright (C) 2025 bitfly explorer GmbH +// +// This file is part of Beaconchain Dashboard. +// +// Beaconchain Dashboard is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Beaconchain Dashboard is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Beaconchain Dashboard. If not, see . + +@use '../../../theme/variables.scss'; diff --git a/src/app/pages/slotviz/slotviz.component.ts b/src/app/pages/slotviz/slotviz.component.ts new file mode 100644 index 00000000..a30efa90 --- /dev/null +++ b/src/app/pages/slotviz/slotviz.component.ts @@ -0,0 +1,93 @@ +import { CommonModule } from '@angular/common' +import { Component, computed, Input, signal, WritableSignal } from '@angular/core' +import { FullPageLoadingComponent } from '@components/full-page-loading/full-page-loading.component' +import { FullPageOfflineComponent } from '@components/full-page-offline/full-page-offline.component' +import { FilterType, SlotVizProvider } from '@controllers/SlotVizController' +import { IonicModule, ModalController } from '@ionic/angular' + +import { fromEvent, Subscription } from 'rxjs' +import { SlotGridComponent } from '../../components/slotgrid/slotgrid.component' +import { SlotvizLegendComponent } from '@pages/slotviz-legend/slotviz-legend.component' +import { PipesModule } from '@pipes/pipes.module' +import { StorageService } from '@services/storage.service' +import { SlotVizEpoch } from '@requests/types/slot_viz' +import { dashboardID } from '@requests/v2-dashboard' + +@Component({ + selector: 'app-slotviz', + imports: [CommonModule, IonicModule, FullPageLoadingComponent, FullPageOfflineComponent, SlotGridComponent, PipesModule], + templateUrl: './slotviz.component.html', + styleUrl: './slotviz.component.scss', +}) +export class SlotvizComponent { + initialLoading: boolean = true + online: boolean = true + fadeInCompleted: boolean = false + + private backbuttonSubscription: Subscription + + @Input() dashboardID: dashboardID + @Input() groupID: number + + filterMap: WritableSignal> = signal(new Map()) + + constructor( + public slotViz: SlotVizProvider, + private modalCtrl: ModalController, + private storage: StorageService + ) {} + + update() { + this.initialLoading = false + } + + getSlots(epoch: SlotVizEpoch) { + return computed(() => epoch.slots ?? []) + } + + ngOnInit() { + this.storage.getObject('slotviz_filters').then((filters) => { + if (filters) { + this.filterMap.update(() => filters as Map) + } + }) + console.log('start slot viz with dashboardID', this.dashboardID, 'and groupID', this.groupID) + this.slotViz.start(this.dashboardID, this.groupID) + } + + ionViewWillEnter() { + const event = fromEvent(document, 'backbutton') + this.backbuttonSubscription = event.subscribe(() => { + this.modalCtrl.dismiss() + }) + this.update() + } + + ngOnDestroy() { + this.backbuttonSubscription.unsubscribe() + } + + closeModal() { + this.modalCtrl.dismiss() + } + + async openLegend() { + const modal = await this.modalCtrl.create({ + component: SlotvizLegendComponent, + }) + return await modal.present() + } + + filter(filter: FilterType) { + this.filterMap.update((map) => { + const newMap = new Map(map) // Create a shallow copy of the map + newMap.set(filter, !map.get(filter)) + return newMap // Return the new instance + }) + this.storage.setObject('slotviz_filters', this.filterMap()) + } + + isFiltered(filter: FilterType) { + return this.filterMap().get(filter) + } +} diff --git a/src/app/pages/subscribe/subscribe.module.ts b/src/app/pages/subscribe/subscribe.module.ts index 1cb05666..f75821cd 100644 --- a/src/app/pages/subscribe/subscribe.module.ts +++ b/src/app/pages/subscribe/subscribe.module.ts @@ -8,9 +8,21 @@ import { SubscribePageRoutingModule } from './subscribe-routing.module' import { SubscribePage } from './subscribe.page' import { PipesModule } from '../../pipes/pipes.module' +import { BoolCheckedComponent } from '@components/bool-checked/bool-checked.component' +import { FullPageLoadingComponent } from '@components/full-page-loading/full-page-loading.component' +import { FullPageOfflineComponent } from '@components/full-page-offline/full-page-offline.component' @NgModule({ - imports: [CommonModule, FormsModule, IonicModule, SubscribePageRoutingModule, PipesModule], + imports: [ + CommonModule, + FormsModule, + IonicModule, + SubscribePageRoutingModule, + PipesModule, + BoolCheckedComponent, + FullPageLoadingComponent, + FullPageOfflineComponent, + ], declarations: [SubscribePage], }) export class SubscribePageModule {} diff --git a/src/app/pages/subscribe/subscribe.page.html b/src/app/pages/subscribe/subscribe.page.html index e7c9f688..c1407f07 100644 --- a/src/app/pages/subscribe/subscribe.page.html +++ b/src/app/pages/subscribe/subscribe.page.html @@ -1,10 +1,11 @@ - - + + + Premium @@ -12,104 +13,207 @@
- +
- Support open source. + Support open source.
-
-
- {{ package.name }} -
- {{ package.price }} / m + + + Monthly + Try it out + + + Yearly + Save up to 20% + + + +
+
+
+ {{ package.name }} + {{ package.price }} / m + {{ calculateYearlyPrice(package) }} / y +
-
- - - - Validators - {{ selectedPackage.maxValidators }} - - - - Monitoring Setups - {{ selectedPackage.maxBeaconNodes }} - - - - Device Monitoring - - last {{ selectedPackage.deviceMonitoringHours < 24 ? selectedPackage.deviceMonitoringHours : selectedPackage.deviceMonitoringHours / 24 }} {{ - selectedPackage.deviceMonitoringHours < 24 ? "hours" : "days" }} - - - - - Custom Notification - - - - - - - - No Ads - - - - - - - - Custom Themes - - - - - - - - Widgets - - - - - - - - Support us - - - - - - - - -
- Start with a 14 day trial. - -
- Subscribe for {{ selectedPackage.price }} / month - You own this package +
+
+
+ {{ package.name }} + {{ calculateMonthlyPrice(package) }} / m + {{ package.price }} / y +
+
- - Restore purchase -

- - After the free trial, you'll be charged the full amount if not canceled. You can cancel the subscription at any time. - *¹ Requires iOS 14 or newer.
-
+
+ + + + + General + + + No Ads + + + + + + Support us + + + + + + + Dashboard + + + + Max Dashboards + {{ selectedProduct()?.premium_perks.validator_dashboards }} + + + + Validators per Dashboard + {{ selectedProduct()?.premium_perks.validators_per_dashboard }} + + + + Groups per Dashboard + {{ selectedProduct()?.premium_perks.validator_groups_per_dashboard }} + + + + Share Dashboards + + + + + + + + Bulk Adding + + + + + + + + Efficiency Chart History + + + + Epoch + + + {{ selectedProduct()?.premium_perks.chart_history_seconds.epoch | subSecondsToTime }} + + + + + Hourly + + + {{ selectedProduct()?.premium_perks.chart_history_seconds.hourly | subSecondsToTime }} + + + + + Daily + + + {{ selectedProduct()?.premium_perks.chart_history_seconds.daily | subSecondsToTime }} + + + + + Weekly + + + {{ selectedProduct()?.premium_perks.chart_history_seconds.weekly | subSecondsToTime }} + + + + + App + + + + Device Monitoring + {{ selectedProduct()?.premium_perks.machine_monitoring_history_seconds | subSecondsToTime }} + + + + Monitoring Setups + {{ selectedProduct()?.premium_perks.monitor_machines }} + + + + Widgets + + + + + + +
+ Start with a 14 day trial. + +
+ Subscribe for {{ selectedPackage()?.price }} / month + You own this package + +
+ + Restore purchase +

+ + After the free trial, you'll be charged the full amount if not canceled. You can cancel the subscription at any time. + *¹ Requires iOS 14 or newer. +
+ +
+
+
+
diff --git a/src/app/pages/subscribe/subscribe.page.scss b/src/app/pages/subscribe/subscribe.page.scss index aab9c48b..bc448e8a 100644 --- a/src/app/pages/subscribe/subscribe.page.scss +++ b/src/app/pages/subscribe/subscribe.page.scss @@ -1,4 +1,4 @@ -@import '../../../theme/variables.scss'; +@use '../../../theme/variables.scss'; .purchase-btn { --border-radius: var(--button-border-radius); @@ -32,6 +32,20 @@ ion-content { padding-bottom: 0px; } +ion-segment-button { + color: var(--x-toolbar-title-color); +} + +ion-segment { + background-color: var(--ion-toolbar-background); + padding-top: 10px; + padding-bottom: 10px; +} + +.segment-button-checked { + opacity: 1; +} + .packages { } @@ -49,7 +63,7 @@ h2 { } .status-icon { - margin-bottom: 12px; + margin-bottom: 8px; font-size: 60px; color: var(--x-toolbar-title-color); } @@ -66,35 +80,30 @@ h2 { .slide-container { display: block; - padding-bottom: 22px; + padding-bottom: 8px; } -ion-label { +.white { color: var(--x-toolbar-title-color); + padding: 0px; + margin: 0px; } .package { - width: 33.33%; + width: 25%; text-align: center; display: inline-block; background-color: var(--x-update-messages-background); - height: 74px; + height: 82px; } .package-inner { - margin-top: 0.68em; + margin-top: 0.3em; height: 30px; } -.pkg-name { - font-size: 1.15em; -} - -.slide-container { - margin-bottom: 6px; -} .value { text-align: end; font-weight: bold !important; @@ -131,18 +140,14 @@ ion-list { line-height: 1em !important; } -.check { - color: var(--ion-color-success); -} - -.nocheck { - color: var(--ion-color-danger); -} - // Makes the iOS top bounce in our primary color // and the bottom bounce in main themes color ion-content { - --background: linear-gradient(0deg, var(--ion-background-color) 65%, var(--ion-toolbar-background) 35%); + --background: linear-gradient(0deg, var(--ion-background-color) 60%, var(--ion-toolbar-background) 40%); +} + +.smallest-info { + font-size: 0.5rem !important; } @media only screen and (max-width: 380px) { @@ -150,6 +155,29 @@ ion-content { width: 85%; } .pkg-name { - font-size: 1.05em; + font-size: 1rem; } } + +.pkg-name { + font-size: 1rem; + display: block; +} + +.pkg-price { + font-size: var(--smaller-info-size); + display: block; +} + +.pkg-price-yearly { + font-size: var(--smallest-info-size); + opacity: 0.8; + display: block; +} + +.segment-label { + text-shadow: 0.65px 0 0 currentcolor; + font-weight: 400 !important; + font-family: 'Varela'; + font-size: 0.77rem; +} diff --git a/src/app/pages/subscribe/subscribe.page.spec.ts b/src/app/pages/subscribe/subscribe.page.spec.ts deleted file mode 100644 index 7e1f42b8..00000000 --- a/src/app/pages/subscribe/subscribe.page.spec.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing' -import { IonicModule } from '@ionic/angular' - -import { SubscribePage } from './subscribe.page' - -describe('SubscribePage', () => { - let component: SubscribePage - let fixture: ComponentFixture - - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [SubscribePage], - imports: [IonicModule.forRoot()], - }).compileComponents() - - fixture = TestBed.createComponent(SubscribePage) - component = fixture.componentInstance - fixture.detectChanges() - })) - - it('should create', () => { - expect(component).toBeTruthy() - }) -}) diff --git a/src/app/pages/subscribe/subscribe.page.ts b/src/app/pages/subscribe/subscribe.page.ts index e0114e4c..932c1b77 100644 --- a/src/app/pages/subscribe/subscribe.page.ts +++ b/src/app/pages/subscribe/subscribe.page.ts @@ -1,31 +1,52 @@ -import { Component, Input, OnInit } from '@angular/core' +import { Component, computed, OnInit, Signal, signal, WritableSignal } from '@angular/core' import { ModalController, Platform } from '@ionic/angular' import { fromEvent, Subscription } from 'rxjs' -import { StorageService } from 'src/app/services/storage.service' -import { MerchantUtils, Package } from 'src/app/utils/MerchantUtils' -import { OAuthUtils } from 'src/app/utils/OAuthUtils' -import { AlertService } from 'src/app/services/alert.service' +import { StorageService } from '@services/storage.service' +import { MerchantUtils, Package } from '@utils/MerchantUtils' +import { OAuthUtils } from '@utils/OAuthUtils' +import { AlertService } from '@services/alert.service' import { Toast } from '@capacitor/toast' -import FlavorUtils from 'src/app/utils/FlavorUtils' +import FlavorUtils from '@utils/FlavorUtils' import { Browser } from '@capacitor/browser' -import { ApiService } from 'src/app/services/api.service' +import { ApiService, capitalize } from '@services/api.service' +import { V2ProductSummary } from '@requests/v2-general' +import { PremiumProduct, ProductSummary, UserSubscription } from '@requests/types/user' +const ASSOCIATED_CACHE_KEY = 'subscribe' @Component({ selector: 'app-subscribe', templateUrl: './subscribe.page.html', styleUrls: ['./subscribe.page.scss'], + standalone: false, }) export class SubscribePage implements OnInit { - @Input() tab: string = null - currentY = 0 - private backbuttonSubscription: Subscription - selectedPackage: Package - activeUserPackageName = 'standard' isiOS = false + renewalFrame: 'monthly' | 'yearly' = 'monthly' + + // all available products from server + products: WritableSignal = signal(null) + + // currently selected product from server + selectedProduct: Signal = computed(() => { + if (this.products() == null) return null + if (this.selectedPackage() == null) return null + const result = this.products().premium_products.find( + (product) => + product.product_id_monthly === this.selectedPackage().purchaseKey || product.product_id_yearly === this.selectedPackage().purchaseKey + ) + if (result) return result + return this.products().premium_products.find((product) => product.product_name == 'Free') + }) + + // currently selected local package (we need it for the purchase key and the appstore pricing, otherwise use selectedProduct) + selectedPackage: WritableSignal = signal(null) + + online: boolean = true + constructor( private modalCtrl: ModalController, public merchant: MerchantUtils, @@ -36,46 +57,108 @@ export class SubscribePage implements OnInit { private flavor: FlavorUtils, private api: ApiService ) { - this.selectedPackage = this.merchant.PACKAGES[1] - } - - ngOnInit() { const event = fromEvent(document, 'backbutton') this.backbuttonSubscription = event.subscribe(() => { this.modalCtrl.dismiss() }) + } - this.merchant.getCurrentPlanConfirmed().then((result) => { - this.activeUserPackageName = result - if (this.tab) { - result = this.tab - } - const pkg = this.merchant.findProduct(result) - if (pkg) { - this.selectedPackage = pkg - } - }) + async setup() { + const result = await this.api.set(new V2ProductSummary(), this.products, ASSOCIATED_CACHE_KEY) + if (result.error) { + Toast.show({ + text: 'Can not load, please check your internet connection.', + }) + this.online = false + } + } + + async ngOnInit() { + this.online = true + this.setup() + await this.merchant.getUserInfo() + + const current = this.merchant.findProduct(this.merchant.getUsersSubscription().product_id) + if (current) { + this.selectedPackage.set(current) + } else { + this.selectedPackage.set(this.merchant.PACKAGES[1]) + } this.isiOS = this.platform.is('ios') } - onScroll($event) { - this.currentY = $event.detail.currentY + changeSelectedPackage(selectedPackage: Package) { + this.selectedPackage.set(selectedPackage) } - ngOnDestroy() { - this.backbuttonSubscription.unsubscribe() + equalPackage(pkg: Package, pkg2: Package): boolean { + if (pkg == null || pkg2 == null) { + return false + } + if (pkg.purchaseKey == null || pkg2.purchaseKey == null) { + return pkg.purchaseKey == pkg2.purchaseKey + } + return pkg.purchaseKey.split('.')[0] === pkg2.purchaseKey.split('.')[0] } - closeModal() { - this.modalCtrl.dismiss() + // UserSubscription is remote while Package is local + // Package might contain an old pre v2 fish package, so we need to map it to the corresponding new one + equalProduct(product: UserSubscription, pkg: Package): boolean { + if (product == null || pkg == null) { + return false + } + const myPackageV2 = product.product_id // remote id + if (!product) return false + + // removes apple prefix and converts any old fish package to new one (returns the monthly package since v1 was only monthly) + const selectedPackageV2 = this.merchant.removeApplePrefix(this.merchant.mapv1Tov2(pkg.purchaseKey)) + if (!selectedPackageV2) return false + + return myPackageV2.split('.')[0] === selectedPackageV2.split('.')[0] + } + + calculateMonthlyPrice(pkg: Package): string { + let monthlyPrice = Math.ceil(pkg.priceMicros / 1000000 / 12).toFixed(2) + if (Number.isInteger(Number(monthlyPrice)) && Number(monthlyPrice) > 0) { + monthlyPrice = (Number(monthlyPrice) - 0.01).toFixed(2) + } + return this.replaceNumberInString(pkg.price, monthlyPrice) + } + + replaceNumberInString(inputString: string, newNumber: string): string { + const regex = /[0-9,.]+/g + return inputString.replace(regex, newNumber) + } + + calculateYearlyPrice(pkg: Package): string { + let yearlyPrice = Math.ceil((pkg.priceMicros / 1000000) * 12).toFixed(2) + if (Number.isInteger(Number(yearlyPrice)) && Number(yearlyPrice) > 0) { + yearlyPrice = (Number(yearlyPrice) - 0.01).toFixed(2) + } + return this.replaceNumberInString(pkg.price, yearlyPrice) + } + + getFrameShort(pkg: Package): string { + return pkg.renewFrame === 'monthly' ? 'm' : 'y' + } + + monthlyYearlySwitch() { + if (this.selectedPackage() == this.merchant.PACKAGES[0]) { + this.selectedPackage.set(this.merchant.PACKAGES[1]) + this.selectedPackage.set(this.merchant.PACKAGES[0]) + return + } + this.selectedPackage.set( + this.merchant.PACKAGES.find((pkg) => pkg.renewFrame === this.renewalFrame && this.equalPackage(pkg, this.selectedPackage())) + ) } async continuePurchaseIntern() { - const isPremium = await this.merchant.hasMachineHistoryPremium() + const isPremium = this.merchant.hasMachineMonitoringPremium() const isNoGoogle = await this.flavor.isNoGoogleFlavor() if (isPremium) { - const packageName = capitalize(await this.merchant.getCurrentPlanConfirmed()) + const packageName = capitalize(this.merchant.getUsersSubscription().product_name) this.alertService.confirmDialog( 'Already Premium', 'You already own the ' + packageName + ' package, are you sure that you want to continue with your purchase?', @@ -84,7 +167,7 @@ export class SubscribePage implements OnInit { if (isNoGoogle) { await Browser.open({ url: this.api.getBaseUrl() + '/premium', toolbarColor: '#2f2e42' }) } else { - this.merchant.purchase(this.selectedPackage.purchaseKey) + this.merchant.purchase(this.selectedPackage().purchaseKey) } } ) @@ -94,7 +177,7 @@ export class SubscribePage implements OnInit { if (isNoGoogle) { await Browser.open({ url: this.api.getBaseUrl() + '/premium', toolbarColor: '#2f2e42' }) } else { - this.merchant.purchase(this.selectedPackage.purchaseKey) + this.merchant.purchase(this.selectedPackage().purchaseKey) } } @@ -120,9 +203,9 @@ export class SubscribePage implements OnInit { this.alertService.confirmDialog( 'Free Trial Info', 'You can test ' + - this.selectedPackage.name + + this.selectedPackage().name + " for free for 14 days. You'll be charged the regular subscription amount of " + - this.selectedPackage.price + + this.selectedPackage().price + ' per month if you do not cancel the subscription before the trial concludes. You can cancel the subscription at any time.', 'Start trial', () => { @@ -136,21 +219,16 @@ export class SubscribePage implements OnInit { if (!loggedIn) { await this.oauth.login() } else { - await this.merchant.refreshToken() - const currentPackage = await this.merchant.getCurrentPlanConfirmed() - if (currentPackage != 'standard') { + await this.merchant.restore(this.merchant.getUsersSubscription().product_id) + + await this.merchant.getUserInfo(true, () => { Toast.show({ - text: 'Purchase restored', + text: 'Error restoring purchase', }) - this.closeModal() - return - } - - await this.merchant.restore(this.selectedPackage.purchaseKey) + }) } - const currentPackage = await this.merchant.getCurrentPlanConfirmed() - if (currentPackage != 'standard') { + if (this.merchant.isPremium()) { Toast.show({ text: 'Purchase restored', }) @@ -161,9 +239,16 @@ export class SubscribePage implements OnInit { }) } } -} -const capitalize = (s) => { - if (typeof s !== 'string') return '' - return s.charAt(0).toUpperCase() + s.slice(1) + onScroll($event: { detail: { currentY: number } }) { + this.currentY = $event.detail.currentY + } + + ngOnDestroy() { + this.backbuttonSubscription.unsubscribe() + } + + closeModal() { + this.modalCtrl.dismiss() + } } diff --git a/src/app/pages/validatordetail/validatordetail-routing.module.ts b/src/app/pages/validatordetail/validatordetail-routing.module.ts deleted file mode 100644 index c9b1212c..00000000 --- a/src/app/pages/validatordetail/validatordetail-routing.module.ts +++ /dev/null @@ -1,37 +0,0 @@ -/* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) - * // - * // This file is part of Beaconchain Dashboard. - * // - * // Beaconchain Dashboard is free software: you can redistribute it and/or modify - * // it under the terms of the GNU General Public License as published by - * // the Free Software Foundation, either version 3 of the License, or - * // (at your option) any later version. - * // - * // Beaconchain Dashboard is distributed in the hope that it will be useful, - * // but WITHOUT ANY WARRANTY; without even the implied warranty of - * // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * // GNU General Public License for more details. - * // - * // You should have received a copy of the GNU General Public License - * // along with Beaconchain Dashboard. If not, see . - */ - -import { NgModule } from '@angular/core' -import { Routes, RouterModule } from '@angular/router' - -import { ValidatordetailPage } from './validatordetail.page' - -const routes: Routes = [ - { - path: '', - component: ValidatordetailPage, - }, -] - -@NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule], -}) -export class ValidatordetailPageRoutingModule {} diff --git a/src/app/pages/validatordetail/validatordetail.module.ts b/src/app/pages/validatordetail/validatordetail.module.ts deleted file mode 100644 index 4c931fc8..00000000 --- a/src/app/pages/validatordetail/validatordetail.module.ts +++ /dev/null @@ -1,36 +0,0 @@ -/* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) - * // - * // This file is part of Beaconchain Dashboard. - * // - * // Beaconchain Dashboard is free software: you can redistribute it and/or modify - * // it under the terms of the GNU General Public License as published by - * // the Free Software Foundation, either version 3 of the License, or - * // (at your option) any later version. - * // - * // Beaconchain Dashboard is distributed in the hope that it will be useful, - * // but WITHOUT ANY WARRANTY; without even the implied warranty of - * // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * // GNU General Public License for more details. - * // - * // You should have received a copy of the GNU General Public License - * // along with Beaconchain Dashboard. If not, see . - */ - -import { NgModule } from '@angular/core' -import { CommonModule } from '@angular/common' -import { FormsModule } from '@angular/forms' - -import { IonicModule } from '@ionic/angular' - -import { ValidatordetailPageRoutingModule } from './validatordetail-routing.module' - -import { ValidatordetailPage } from './validatordetail.page' -import { DashboardComponentModule } from '../../components/dashboard/dashboard.module' - -@NgModule({ - imports: [CommonModule, FormsModule, IonicModule, ValidatordetailPageRoutingModule, DashboardComponentModule], - declarations: [ValidatordetailPage], -}) -export class ValidatordetailPageModule {} diff --git a/src/app/pages/validatordetail/validatordetail.page.html b/src/app/pages/validatordetail/validatordetail.page.html deleted file mode 100644 index bc7bf80f..00000000 --- a/src/app/pages/validatordetail/validatordetail.page.html +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - - - - - - - - - - {{ name }} - - - - - - diff --git a/src/app/pages/validatordetail/validatordetail.page.scss b/src/app/pages/validatordetail/validatordetail.page.scss deleted file mode 100644 index d45bd284..00000000 --- a/src/app/pages/validatordetail/validatordetail.page.scss +++ /dev/null @@ -1,31 +0,0 @@ -/* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) - * // - * // This file is part of Beaconchain Dashboard. - * // - * // Beaconchain Dashboard is free software: you can redistribute it and/or modify - * // it under the terms of the GNU General Public License as published by - * // the Free Software Foundation, either version 3 of the License, or - * // (at your option) any later version. - * // - * // Beaconchain Dashboard is distributed in the hope that it will be useful, - * // but WITHOUT ANY WARRANTY; without even the implied warranty of - * // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * // GNU General Public License for more details. - * // - * // You should have received a copy of the GNU General Public License - * // along with Beaconchain Dashboard. If not, see . - */ - -@import '../../../theme/variables.scss'; - -// Makes the iOS top bounce in our primary color -// and the bottom bounce in main themes color -ion-content { - --background: linear-gradient(0deg, var(--ion-background-color) 60%, var(--ion-toolbar-background) 40%); -} - -ion-refresher-content { - --color: #fff !important; -} diff --git a/src/app/pages/validatordetail/validatordetail.page.spec.ts b/src/app/pages/validatordetail/validatordetail.page.spec.ts deleted file mode 100644 index 8bf9002a..00000000 --- a/src/app/pages/validatordetail/validatordetail.page.spec.ts +++ /dev/null @@ -1,47 +0,0 @@ -/* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) - * // - * // This file is part of Beaconchain Dashboard. - * // - * // Beaconchain Dashboard is free software: you can redistribute it and/or modify - * // it under the terms of the GNU General Public License as published by - * // the Free Software Foundation, either version 3 of the License, or - * // (at your option) any later version. - * // - * // Beaconchain Dashboard is distributed in the hope that it will be useful, - * // but WITHOUT ANY WARRANTY; without even the implied warranty of - * // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * // GNU General Public License for more details. - * // - * // You should have received a copy of the GNU General Public License - * // along with Beaconchain Dashboard. If not, see . - */ - -import { async, ComponentFixture, TestBed } from '@angular/core/testing' -import { IonicModule, ModalController } from '@ionic/angular' -import { ValidatorUtils } from 'src/app/utils/ValidatorUtils' - -import { ValidatordetailPage } from './validatordetail.page' - -describe('ValidatordetailPage', () => { - let component: ValidatordetailPage - let fixture: ComponentFixture - - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [ValidatordetailPage], - imports: [IonicModule.forRoot()], - providers: [{ provide: ModalController }, { provide: ValidatorUtils }], - }).compileComponents() - - fixture = TestBed.createComponent(ValidatordetailPage) - component = fixture.componentInstance - - fixture.detectChanges() - })) - - it('should create', () => { - expect(component).toBeTruthy() - }) -}) diff --git a/src/app/pages/validatordetail/validatordetail.page.ts b/src/app/pages/validatordetail/validatordetail.page.ts deleted file mode 100644 index 2fb125fb..00000000 --- a/src/app/pages/validatordetail/validatordetail.page.ts +++ /dev/null @@ -1,111 +0,0 @@ -/* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) - * // - * // This file is part of Beaconchain Dashboard. - * // - * // Beaconchain Dashboard is free software: you can redistribute it and/or modify - * // it under the terms of the GNU General Public License as published by - * // the Free Software Foundation, either version 3 of the License, or - * // (at your option) any later version. - * // - * // Beaconchain Dashboard is distributed in the hope that it will be useful, - * // but WITHOUT ANY WARRANTY; without even the implied warranty of - * // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * // GNU General Public License for more details. - * // - * // You should have received a copy of the GNU General Public License - * // along with Beaconchain Dashboard. If not, see . - */ - -import { Component, OnInit, Input } from '@angular/core' -import { ValidatorUtils, Validator, getDisplayName, SAVED } from '../../utils/ValidatorUtils' -import { ModalController } from '@ionic/angular' -import OverviewController, { OverviewData } from '../../controllers/OverviewController' -import { fromEvent, Subscription } from 'rxjs' -import { MerchantUtils } from 'src/app/utils/MerchantUtils' -import { UnitconvService } from 'src/app/services/unitconv.service' -import { ApiService } from 'src/app/services/api.service' - -@Component({ - selector: 'app-validatordetail', - templateUrl: './validatordetail.page.html', - styleUrls: ['./validatordetail.page.scss'], -}) -export class ValidatordetailPage implements OnInit { - @Input() item: Validator - name: string - - data: OverviewData - - tagged = false - - currentY = 0 - - private backbuttonSubscription: Subscription - - scrolling = false - - constructor( - private validatorUtils: ValidatorUtils, - private modalCtrl: ModalController, - private merchant: MerchantUtils, - private unit: UnitconvService, - private api: ApiService - ) {} - - setInput(validator: Validator) { - this.item = validator - } - - ngOnInit() { - const event = fromEvent(document, 'backbutton') - this.backbuttonSubscription = event.subscribe(() => { - this.modalCtrl.dismiss() - }) - this.updateDetails(this.item) - this.tagged = this.item.storage == SAVED - } - - ngOnChanges() { - this.updateDetails(this.item) - } - - onScroll($event) { - this.currentY = $event.detail.currentY - } - - onScrollStarted() { - this.scrolling = true - } - - onScrollEnded() { - this.scrolling = false - } - - ngOnDestroy() { - this.backbuttonSubscription.unsubscribe() - } - - closeModal() { - this.modalCtrl.dismiss() - } - - async updateDetails(item: Validator) { - this.name = getDisplayName(item) - - const epoch = await this.validatorUtils.getRemoteCurrentEpoch() - const overviewController = new OverviewController(null, await this.merchant.getCurrentPlanMaxValidator(), this.unit) - this.data = overviewController.processDetail([item], epoch, this.api.getNetwork()) - } - - tag() { - this.validatorUtils.convertToValidatorModelAndSaveValidatorLocal(false, this.item.data) - this.tagged = true - } - - untag() { - this.validatorUtils.deleteValidatorLocal(this.item.data) - this.tagged = false - } -} diff --git a/src/app/pipes/countdown.ts b/src/app/pipes/countdown.ts new file mode 100644 index 00000000..57aed537 --- /dev/null +++ b/src/app/pipes/countdown.ts @@ -0,0 +1,44 @@ +// Copyright (C) 2024 bitfly explorer GmbH +// +// This file is part of Beaconchain Dashboard. +// +// Beaconchain Dashboard is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Beaconchain Dashboard is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Beaconchain Dashboard. If not, see .import { Pipe, PipeTransform } from '@angular/core'; +import { timer, Observable } from 'rxjs' +import { map } from 'rxjs/operators' +import { defaultFormattter } from './shortertimeago.pipe' +import { Pipe, PipeTransform } from '@angular/core' + +@Pipe({ + name: 'countdown', + pure: true, + standalone: false, +}) +export class CountdownPipe implements PipeTransform { + transform(timestamp: number): Observable { + // Create an observable that fires every 1000ms (1 second) + return timer(0, 1000).pipe( + map(() => { + // Calculate the countdown string on each tick + const result = defaultFormattter(Math.ceil(timestamp / 1000) * 1000) + if (result.value === 0) { + return 'in 1s' + } + const space = result.unit === 's' ? '' : ' ' + const prefix = result.suffix !== 'ago' ? 'in ' : '' + const postfix = result.suffix === 'ago' ? 'ago' : '' + return `${prefix}${result.value}${space}${result.unit} ${postfix}` + }) + ) + } +} diff --git a/src/app/pipes/delegater.pipi.ts b/src/app/pipes/delegater.pipi.ts index 1ad704b4..c5157276 100644 --- a/src/app/pipes/delegater.pipi.ts +++ b/src/app/pipes/delegater.pipi.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -23,11 +22,12 @@ import { ProcessedStats } from '../controllers/MachineController' @Pipe({ name: 'delegate', + standalone: false, }) export class DelegatorPipe implements PipeTransform { // TODO: improve this typing, unknown not working when used with async pipe in template, investigate // eslint-disable-next-line @typescript-eslint/no-explicit-any - transform(data: ProcessedStats, delegateMethod: (any: ProcessedStats) => any) { + transform(data: ProcessedStats | string, delegateMethod: (any: ProcessedStats | string) => any) { return delegateMethod(data) } } diff --git a/src/app/pipes/fadeoutpipe.pipe.ts b/src/app/pipes/fadeoutpipe.pipe.ts index 7ee30ad7..61dccec4 100644 --- a/src/app/pipes/fadeoutpipe.pipe.ts +++ b/src/app/pipes/fadeoutpipe.pipe.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -22,6 +21,7 @@ import { Pipe, PipeTransform } from '@angular/core' @Pipe({ name: 'fadeoutpipe', + standalone: false, }) export class FadeoutpipePipe implements PipeTransform { transform(currentY: number, fullHide: number): number { @@ -31,3 +31,17 @@ export class FadeoutpipePipe implements PipeTransform { return opacity } } + +@Pipe({ + name: 'fadeinpipe', + standalone: false, +}) +export class FadeinpipePipe implements PipeTransform { + transform(currentY: number, fullHide: number, offset = 0): number { + currentY -= offset + if (currentY <= 0) return 0 + const opacity = currentY / fullHide + if (opacity >= 1) return 1 + return opacity + } +} diff --git a/src/app/pipes/mcurrency.pipe.ts b/src/app/pipes/mcurrency.pipe.ts index 9aeadbf3..a1d5bce6 100644 --- a/src/app/pipes/mcurrency.pipe.ts +++ b/src/app/pipes/mcurrency.pipe.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -20,10 +19,11 @@ import { Pipe, PipeTransform } from '@angular/core' import BigNumber from 'bignumber.js' -import { UnitconvService } from '../services/unitconv.service' +import { UnitconvService } from '@services/unitconv.service' @Pipe({ name: 'mcurrency', + standalone: false, }) export class McurrencyPipe implements PipeTransform { constructor(private unit: UnitconvService) {} diff --git a/src/app/pipes/percentageabs.pipe.ts b/src/app/pipes/percentageabs.pipe.ts index 2daeb055..5eb1b3f0 100644 --- a/src/app/pipes/percentageabs.pipe.ts +++ b/src/app/pipes/percentageabs.pipe.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -23,6 +22,7 @@ import BigNumber from 'bignumber.js' @Pipe({ name: 'percentageabs', + standalone: false, }) export class PercentageabsPipe implements PipeTransform { /** diff --git a/src/app/pipes/pipes.module.ts b/src/app/pipes/pipes.module.ts index 8250e9ed..85306cbe 100644 --- a/src/app/pipes/pipes.module.ts +++ b/src/app/pipes/pipes.module.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -18,19 +17,69 @@ * // along with Beaconchain Dashboard. If not, see . */ -import { NgModule } from '@angular/core' +import { NgModule, Pipe, PipeTransform } from '@angular/core' import { McurrencyPipe } from './mcurrency.pipe' import { ValuestylePipe } from './valuestyle.pipe' import { PercentageabsPipe } from './percentageabs.pipe' -import { FadeoutpipePipe } from './fadeoutpipe.pipe' +import { FadeinpipePipe, FadeoutpipePipe } from './fadeoutpipe.pipe' import { TimeagoModule, TimeagoFormatter } from 'ngx-timeago' -import { CustomTimeAgoFormatter } from '../utils/CustomTimeAgoFormatter' +import { CustomTimeAgoFormatter } from '@utils/CustomTimeAgoFormatter' import { DelegatorPipe } from './delegater.pipi' +import { ShorterTimeAgo } from './shortertimeago.pipe' +import { CountdownPipe } from './countdown' + +@Pipe({ + name: 'subSecondsToTime', + standalone: false, +}) +export class SubSecondsToTime implements PipeTransform { + transform(ts: number): string { + if (ts > 1000 * 60 * 60 * 24) { + return 'Full History' + } + + const seconds = Math.floor(ts) + const minutes = Math.floor(seconds / 60) + const hours = Math.floor(minutes / 60) + const days = Math.floor(hours / 24) + + if (days > 0) { + return days > 1 ? `${days} days` : '1 day' + } else if (hours > 0) { + return hours > 1 ? `${hours} hours` : '1 hour' + } else if (minutes > 0) { + return minutes > 1 ? `${minutes} minutes` : '1 minute' + } else { + return seconds > 1 ? `${seconds} seconds` : '1 second' + } + } +} @NgModule({ imports: [TimeagoModule.forRoot({ formatter: { provide: TimeagoFormatter, useClass: CustomTimeAgoFormatter } })], - declarations: [McurrencyPipe, ValuestylePipe, PercentageabsPipe, FadeoutpipePipe, DelegatorPipe], - exports: [McurrencyPipe, ValuestylePipe, PercentageabsPipe, FadeoutpipePipe, DelegatorPipe, TimeagoModule], + declarations: [ + McurrencyPipe, + ValuestylePipe, + PercentageabsPipe, + FadeoutpipePipe, + CountdownPipe, + FadeinpipePipe, + DelegatorPipe, + ShorterTimeAgo, + SubSecondsToTime, + ], + exports: [ + McurrencyPipe, + ValuestylePipe, + PercentageabsPipe, + FadeoutpipePipe, + FadeinpipePipe, + DelegatorPipe, + TimeagoModule, + ShorterTimeAgo, + SubSecondsToTime, + CountdownPipe, + ], }) export class PipesModule {} diff --git a/src/app/pipes/shortertimeago.pipe.ts b/src/app/pipes/shortertimeago.pipe.ts new file mode 100644 index 00000000..fb7e1073 --- /dev/null +++ b/src/app/pipes/shortertimeago.pipe.ts @@ -0,0 +1,66 @@ +// Copyright (C) 2024 bitfly explorer GmbH +// +// This file is part of Beaconchain Dashboard. +// +// Beaconchain Dashboard is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Beaconchain Dashboard is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Beaconchain Dashboard. If not, see . + +import { Pipe, PipeTransform } from '@angular/core' + +@Pipe({ + name: 'shortertimeago', + standalone: false, +}) +export class ShorterTimeAgo implements PipeTransform { + transform(ts: number): string { + const result = defaultFormattter(ts) + return result.value + '' + result.unit + ' ' + result.suffix + } +} + +export type Unit = 's' | 'min' | 'h' | 'd' | 'w' | 'm' | 'y' +export type Suffix = 'ago' | 'from now' + +export type StringOrFn = ((value: number, millisDelta: number) => string) | string + +export type NumberArray = [string, string, string, string, string, string, string, string, string, string] + +export const MINUTE = 60 +export const HOUR = MINUTE * 60 +export const DAY = HOUR * 24 +export const WEEK = DAY * 7 +export const MONTH = DAY * 30 +export const YEAR = DAY * 365 + +export const defaultFormattter = function (then: number): { value: number; unit: Unit; suffix: Suffix } { + const now = Date.now() + const seconds = Math.round(Math.abs(now - then) / 1000) + const suffix: Suffix = then < now ? 'ago' : 'from now' + + const [value, unit]: [number, Unit] = + seconds < MINUTE + ? [Math.round(seconds), 's'] + : seconds < HOUR + ? [Math.round(seconds / MINUTE), 'min'] + : seconds < DAY + ? [Math.round(seconds / HOUR), 'h'] + : seconds < WEEK + ? [Math.round(seconds / DAY), 'd'] + : seconds < MONTH + ? [Math.round(seconds / WEEK), 'w'] + : seconds < YEAR + ? [Math.round(seconds / MONTH), 'm'] + : [Math.round(seconds / YEAR), 'y'] + + return { value, unit, suffix } +} diff --git a/src/app/pipes/valuestyle.pipe.ts b/src/app/pipes/valuestyle.pipe.ts index af45370f..afbeb332 100644 --- a/src/app/pipes/valuestyle.pipe.ts +++ b/src/app/pipes/valuestyle.pipe.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -27,9 +26,10 @@ const NEGATIVE = 'negative-value' @Pipe({ name: 'valuestyle', + standalone: false, }) export class ValuestylePipe implements PipeTransform { - transform(tempvalue: number | string | BigNumber, ...args: (number | BigNumber)[]): string { + transform(tempvalue: number | string | BigNumber, ...args: (number | BigNumber | string)[]): string { const value = tempvalue instanceof BigNumber ? tempvalue : new BigNumber(tempvalue) const firstDrop = args[0] instanceof BigNumber ? args[0] : new BigNumber(args[0]) diff --git a/src/app/requests/requests.ts b/src/app/requests/requests.ts index 6793a604..026ca24a 100644 --- a/src/app/requests/requests.ts +++ b/src/app/requests/requests.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -19,14 +18,14 @@ */ import { HttpHeaders, HttpOptions } from '@capacitor/core' -import BigNumber from 'bignumber.js' -import { StatsResponse } from '../controllers/MachineController' -import { Response } from '../services/api.service' -import { ZoneInfo } from '../utils/AdUtils' +import { Response } from '@services/api.service' +import { ZoneInfo } from '@utils/AdUtils' export enum Method { GET, POST, + DELETE, + PUT, } export interface APIResponse { @@ -34,17 +33,121 @@ export interface APIResponse { data: unknown } +// eslint-disable-next-line @typescript-eslint/no-empty-object-type +export interface NoContent {} + +interface Paging { + next_cursor: string +} + +export class APIError extends Error { + code: number + constructor(message: string, code: number) { + super(message) + this.code = code + } +} +export class APINotFoundError extends APIError { + constructor(message: string, code: number) { + super(message, code) + this.name = 'DashboardNotFoundError' + } +} + +export class APIUnauthorizedError extends APIError { + constructor(message: string, code: number) { + super(message, code) + this.name = 'UnauthorizedError' + } +} + +export class APIForbiddenError extends APIError { + constructor(message: string, code: number) { + super(message, code) + this.name = 'ForbiddenError' + } +} + +export class APIRateLimitedError extends APIError { + constructor(message: string, code: number) { + super(message, code) + this.name = 'RateLimitedError' + } +} + +export class APIUnknownError extends APIError { + constructor(message: string, code: number) { + super(message, code) + this.name = 'UnknownError' + } +} + +export interface ApiResult { + data: T | null + error: Error | null + cached: boolean + paging: Paging | null +} + +export function getProperty(obj: unknown, key: string) { + if (typeof obj === 'object' && obj !== null && key in obj) { + return (obj as { [key: string]: unknown })[key] + } + return undefined +} + export abstract class APIRequest { abstract resource: string abstract method: Method endPoint = 'default' postData?: unknown + expectedResponseStatus = 200 + customCacheKey: string | null = null + allowCachedResponse = true + + withCustomCacheKey(key: string): this { + this.customCacheKey = key + return this + } + + withAllowedCacheResponse(cached: boolean): this { + this.allowCachedResponse = cached + return this + } + + sortResultFn: ((a: T extends Array ? U : T, b: T extends Array ? U : T) => number) | null = null - parse(response: Response): T[] { + parse(response: Response): T | null { return this.parseBase(response) } + parse2(response: Response): ApiResult { + if (this.wasSuccessful(response)) { + return { + data: this.parse(response), + error: null, + cached: response.cached, + paging: (getProperty(response?.data, 'paging') as Paging) || null, + } + } + + let error: Error | null = null + if (!response || response.status != this.expectedResponseStatus) { + error = getHTTPError( + response ? response.status : 0, + (getProperty(response?.data, 'error') as string) || response ? 'HTTP status code: ' + response.status : 'No response error' + ) + } + + return { + data: null, + error: error, + cached: response?.cached || false, + paging: null, + } + } + // Usually you can expect either a Response or a boolean // response.status can be a string though depending on the type of http connector used // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -52,76 +155,58 @@ export abstract class APIRequest { if (typeof response === 'boolean') { return response } - return response && (response.status == 'OK' || response.status == 200 || !hasDataStatus) + return response && (response.status == 'OK' || response.status == this.expectedResponseStatus || !hasDataStatus) } - protected parseBase(response: Response, hasDataStatus = true): T[] { + protected parseBase(response: Response, hasDataStatus = true): T | null { if (!this.wasSuccessful(response, hasDataStatus)) { - return [] + return null } - const data = response.data.data - if (Array.isArray(data)) { - return data - } else { - return [data] + if (response && response.data && getProperty(response?.data, 'data')) { + const data = getProperty(response?.data, 'data') + if (Array.isArray(data)) { + if (this.sortResultFn) { + data.sort(this.sortResultFn) + } + } + return data as T } + return null } options: HttpOptions = { - url: null, // unused + url: undefined, // unused headers: { 'Content-Type': 'application/json', Accept: 'application/json', } as HttpHeaders, } + /** @deprecated can be removed in v2 */ cacheablePOST = false + + /** @deprecated can be removed in v2 */ requiresAuth = false + updatesLastRefreshState = false - ignoreFails = false maxCacheAge = 6 * 60 * 1000 } -// ------------- Responses ------------- - -export interface BlockResponse { - baseFee: number - blockHash: string - blockMevReward: string - blockNumber: number - blockReward: string - consensusAlgorithm: string - feeRecipient: string - gasLimit: number - gasUsed: number - internalTxCount: number - parentHash: string - producerReward: string - timestamp: number - txCount: number - uncleCount: number - posConsensus: PoSConsensus - relay: Relay -} - -export interface Relay { - builderPubkey: string - producerFeeRecipient: string - tag: string -} - -export interface PoSConsensus { - epoch: number - slot: number - proposerIndex: number - finalized: boolean +export function getHTTPError(code: number, msg: string): APIError { + if (code == 404) { + return new APINotFoundError(msg, code) + } else if (code == 401) { + return new APIUnauthorizedError(msg, code) + } else if (code == 403) { + return new APIForbiddenError(msg, code) + } else if (code == 429) { + return new APIRateLimitedError(msg, code) + } + return new APIUnknownError(msg, code) } -export interface MyValidatorResponse { - PubKey: string - Index: number -} +// ------------- Responses ------------- export interface ApiTokenResponse { access_token: string @@ -129,11 +214,6 @@ export interface ApiTokenResponse { refresh_token: string token_type: string } - -export interface MobileSettingsResponse { - notify_enabled: boolean -} - export interface GithubReleaseResponse { url: string html_url: string @@ -151,446 +231,21 @@ export interface CoinbaseExchangeResponse { amount: string } -export interface ETH1ValidatorResponse { - publickey: string - validatorindex: number -} - -export interface ValidatorResponse { - activationeligibilityepoch: number - activationepoch: number - balance: BigNumber - effectivebalance: BigNumber - exitepoch: number - lastattestationslot: number - name: string - pubkey: string - slashed: boolean - validatorindex: number - withdrawableepoch: number - withdrawalcredentials: string - status: string - performance1d: BigNumber - performance31d: BigNumber - performance365d: BigNumber - performance7d: BigNumber - performancetotal: BigNumber - rank7d: number - rankpercentage: number -} - -export interface AttestationPerformanceResponse { - attestation_efficiency: BigNumber - pubkey: string - validatorindex: number -} - -export interface SyncCommitteeResponse { - end_epoch: number - period: number - start_epoch: number - validators: number[] -} - -export interface SyncCommitteesStatistics { - committeesParticipated: number - committeesExpected: number - slotsPerSyncCommittee: number - slotsLeftInSyncCommittee: number - slotsParticipated: number - slotsMissed: number - slotsScheduled: number - efficiency: number - luck: number -} - -export interface SyncCommitteesStatisticsResponse { - expectedSlots: number - participatedSlots: number - missedSlots: number - scheduledSlots: number -} - -export interface EpochResponse { - attestationscount: number - attesterslashingscount: number - averagevalidatorbalance: BigNumber - blockscount: number - depositscount: BigNumber - eligibleether: BigNumber - epoch: number - finalized: boolean - globalparticipationrate: BigNumber - missedblocks: number - orphanedblocks: number - proposedblocks: number - proposerslashingscount: BigNumber - scheduledblocks: number - totalvalidatorbalance: BigNumber - validatorscount: number - voluntaryexitscount: number - votedether: BigNumber - lastCachedTimestamp: number -} - -export interface BalanceHistoryResponse { - balance: BigNumber - effectivebalance: BigNumber - epoch: number - validatorindex: number -} - -export interface DashboardResponse { - validators: ValidatorResponse[] - effectiveness: AttestationPerformanceResponse[] - currentEpoch: EpochResponse[] - olderEpoch: EpochResponse[] - rocketpool_validators: RocketPoolResponse[] - execution_performance: ExecutionResponse[] - rocketpool_network_stats: RocketPoolNetworkStats[] - current_sync_committee: SyncCommitteeResponse[] - next_sync_committee: SyncCommitteeResponse[] - sync_committees_stats: SyncCommitteesStatisticsResponse - proposal_luck_stats: ProposalLuckResponse -} - -export interface RocketPoolNetworkStats { - rpl_price: string - claim_interval_time: string // TODO? - claim_interval_time_start: number // TODO? - current_node_fee: number - current_node_demand: string - reth_supply: string - reth_apr: number - effective_rpl_staked: string - node_operator_rewards: string - reth_exchange_rate: string -} - -export interface RocketPoolResponse { - index: number - minipool_address: string - minipool_deposit_type: string - minipool_node_fee: string - minipool_status: string - minipool_status_time: number - node_address: string - node_max_rpl_stake: string - node_min_rpl_stake: string - node_rpl_stake: string - rpl_cumulative_rewards: string - node_timezone_location: string - unclaimed_rpl_rewards: string - unclaimed_smoothing_pool: string - claimed_smoothing_pool: string - smoothing_pool_opted_in: boolean - penalty_count: number - user_deposit_balance: BigNumber - node_refund_balance: BigNumber - node_deposit_balance: BigNumber - node_deposit_credit: BigNumber - is_vacant: boolean - version: number -} - -export interface ExecutionResponse { - validatorindex: number - performance1d: number - performance7d: number - performance31d: number - performance365d: number - performanceTotal: number -} - -export interface NotificationGetResponse { - CreatedEpoch: number - CreatedTime: string - EventFilter: string - EventName: string - EventThreshold: string -} - export interface BitflyAdResponse { html: string width: string height: string } -export interface ProposalLuckResponse { - proposal_luck: number - average_proposal_interval: number - next_proposal_estimate_ts: number - time_frame_name: string -} - -// ------------- Reqests ------------- - -export class DashboardRequest extends APIRequest { - resource = 'app/dashboard' - method = Method.POST - updatesLastRefreshState = true - cacheablePOST = true - - /** - * @param validator Index or PubKey - */ - constructor(...validator: number[] | string[]) { - super() - this.postData = { indicesOrPubkey: validator.join().replace(/\s/g, '') } - } -} - -export class ValidatorRequest extends APIRequest { - resource = 'validator/' - method = Method.GET - - /** - * @param validator Index or PubKey - */ - constructor(...validator: number[] | string[]) { - super() - this.resource += validator.join().replace(/\s/g, '') - } -} - -export class ValidatorViaDepositAddress extends APIRequest { - resource = 'validator/eth1/' - method = Method.GET - - /** - * @param ethAddress Address - */ - constructor(ethAddress: string) { - super() - this.resource += ethAddress.replace(/\s/g, '') - } -} - -export class ValidatorViaWithdrawalAddress extends APIRequest { - resource = 'validator/withdrawalCredentials/' - method = Method.GET - - /** - * @param ethAddress Address or Withdrawal Credential - */ - constructor(ethAddress: string) { - super() - this.resource += ethAddress.replace(/\s/g, '') - this.resource += '?limit=300' - } -} - -export class BlockProducedByRequest extends APIRequest { - resource = 'execution/' - method = Method.GET - ignoreFails = true - - parse(response: Response): BlockResponse[] { - if (!this.wasSuccessful(response, true)) { - return [] - } - return response.data.data - } - - /** - * @param validator Index or PubKey - */ - constructor(offset: number, limit: number, ...validator: number[] | string[]) { - super() - this.resource += validator.join().replace(/\s/g, '') + '/produced?offset=' + offset + '&limit=' + limit - } -} - -export class DashboardDataRequest extends APIRequest { - resource = 'dashboard/data/' - method = Method.GET - ignoreFails = true - - parse(response: Response): number[][] { - if (!this.wasSuccessful(response, false)) { - return [] - } - return response.data - } - - /** - * @param validator Index or PubKey - */ - constructor(data: 'allbalances' | 'proposals', ...validator: number[] | string[]) { - super() - this.resource += data + '?validators=' + validator.join().replace(/\s/g, '') - } -} - // ------------ Authorized Calls ----------------- -export class SetMobileSettingsRequest extends APIRequest { - resource = 'user/mobile/settings' - method = Method.POST - - requiresAuth = true - ignoreFails = true - - parse(response: Response): MobileSettingsResponse[] { - if (!response || !response.data) return null - return response.data as MobileSettingsResponse[] - } - - constructor(notifyEnabled: boolean) { - super() - this.postData = { notify_enabled: notifyEnabled } - } -} - -export interface SubscriptionTransaction { - id: string - receipt: string - type: string -} - -export interface SubscriptionData { - currency: string - id: string - priceMicros: number - transaction: SubscriptionTransaction - valid: boolean -} - -export class PostMobileSubscription extends APIRequest { - resource = 'user/subscription/register' - method = Method.POST - requiresAuth = true - ignoreFails = true - - constructor(subscriptionData: SubscriptionData) { - super() - this.postData = subscriptionData - } -} - -export class GetMobileSettingsRequest extends APIRequest { - resource = 'user/mobile/settings' - method = Method.GET - requiresAuth = true - ignoreFails = true -} - -export class GetMyValidatorsRequest extends APIRequest { - resource = 'user/validator/saved' - method = Method.GET - requiresAuth = true -} - -export class GetMyMachinesRequest extends APIRequest { - resource = 'user/stats' - method = Method.GET - requiresAuth = true - ignoreFails = true - - constructor(offset = 0, limit = 180) { - super() - this.resource += '/' + offset + '/' + limit - } -} - -export class RemoveMyValidatorsRequest extends APIRequest { - resource = 'user/validator/{pubkey}/remove' - method = Method.POST - requiresAuth = true - postData = {} - ignoreFails = true - - options = { - url: null, // unused - headers: { - 'Content-Type': 'application/text', - Accept: 'application/json', - }, - } - - parse(response: Response): ApiTokenResponse[] { - if (!response || !response.data) return null - return response.data as ApiTokenResponse[] - } - - constructor(pubKey: string) { - super() - this.resource = this.resource.replace('{pubkey}', pubKey) - } -} - -export class AddMyValidatorsRequest extends APIRequest { - resource = 'user/dashboard/save' - method = Method.POST - requiresAuth = true - ignoreFails = true - - options = { - url: null, // unused - headers: { - 'Content-Type': 'application/text', - Accept: 'application/json', - }, - } - - parse(response: Response): ApiTokenResponse[] { - if (!response || !response.data) return null - return response.data as ApiTokenResponse[] - } - - constructor(indices: string[]) { - super() - this.postData = indices - } -} - -export class NotificationGetRequest extends APIRequest { - resource = 'user/notifications' - method = Method.GET - requiresAuth = true - postData = {} - ignoreFails = true - - constructor() { - super() - } - - parse(response: Response): NotificationGetResponse[] { - if (!response || !response.data || !response.data.data) return [] - return response.data.data as NotificationGetResponse[] - } -} - -export interface BundleSub { - event_name: string - event_filter: string - event_threshold: number -} - -export class NotificationBundleSubsRequest extends APIRequest { - private subscribe = 'subscribe' - private unsubscribe = 'unsubscribe' - - resource = 'user/notifications/bundled/' - method = Method.POST - requiresAuth = true - postData = {} - ignoreFails = true - - constructor(enabled: boolean, data: BundleSub[]) { - super() - this.resource += enabled ? this.subscribe : this.unsubscribe - this.postData = data - } -} - +/** @deprecated */ export class RefreshTokenRequest extends APIRequest { resource = 'user/token' method = Method.POST requiresAuth = true - ignoreFails = true maxCacheAge = 1000 - options = { + options: HttpOptions = { url: null, headers: { 'Content-Type': 'application/x-www-form-urlencoded', @@ -598,9 +253,9 @@ export class RefreshTokenRequest extends APIRequest { }, } - parse(response: Response): ApiTokenResponse[] { - if (response && response.data) return [response.data] as ApiTokenResponse[] - else return [] + parse(response: Response): ApiTokenResponse { + if (response && response.data) return response.data as ApiTokenResponse + else return null } constructor(refreshToken: string, isIOS: boolean) { @@ -621,14 +276,14 @@ export class RefreshTokenRequest extends APIRequest { } } +/** @deprecated Has been replaced by V2RegisterPushNotificationToken */ export class UpdateTokenRequest extends APIRequest { resource = 'user/mobile/notify/register' method = Method.POST requiresAuth = true - ignoreFails = true - parse(response: Response): APIResponse[] { - if (response && response.data) return response.data as APIResponse[] + parse(response: Response): APIResponse | null { + if (response && response.data) return response.data as APIResponse return null } @@ -640,20 +295,19 @@ export class UpdateTokenRequest extends APIRequest { // ------------ Special external api requests ----------------- -export class BitflyAdRequest extends APIRequest { +export class BitflyAdRequest extends APIRequest { endPoint = 'https://ads.bitfly.at' resource = '/www/delivery/asyncspc.php?zones={ZONE}&prefix={PREFIX}' method = Method.GET - ignoreFails = true maxCacheAge = 4 * 60 * 1000 - options = { + options: HttpOptions = { url: null, // unused headers: undefined, } - parse(response: Response): BitflyAdResponse[] { + parse(response: Response): BitflyAdResponse[] | null { if (!response || !response.data) { return [] } @@ -673,10 +327,9 @@ export class CoinbaseExchangeRequest extends APIRequest { +export class GithubReleaseRequest extends APIRequest { endPoint = 'https://api.github.com' resource = 'repos/' method = Method.GET - ignoreFails = true maxCacheAge = 4 * 60 * 60 * 1000 - options = { + options: HttpOptions = { url: null, // unused headers: { 'Content-Type': 'application/json', @@ -711,7 +363,7 @@ export class GithubReleaseRequest extends APIRequest { if (Array.isArray(data)) { return data } else { - return [data] + return [data as GithubReleaseResponse] } } @@ -721,4 +373,48 @@ export class GithubReleaseRequest extends APIRequest { } } +export interface V1BlockResponse { + baseFee: number + blockHash: string + blockMevReward: string + blockNumber: number + blockReward: string + consensusAlgorithm: string + feeRecipient: string + gasLimit: number + gasUsed: number + internalTxCount: number + parentHash: string + producerReward: string + timestamp: number + txCount: number + uncleCount: number + posConsensus: PoSConsensus + relay: Relay +} +export interface Relay { + builderPubkey: string + producerFeeRecipient: string + tag: string +} + +export interface PoSConsensus { + epoch: number + slot: number + proposerIndex: number + finalized: boolean +} + +export class V1BlocksOverview extends APIRequest { + endPoint = 'v1' + resource = 'execution/block/{block}' + + method = Method.GET + + constructor(block: number) { + super() + this.resource = this.resource.replace('{block}', block.toString()) + } +} + export default class {} diff --git a/src/app/requests/types.ts b/src/app/requests/types.ts new file mode 100644 index 00000000..d035f0f4 --- /dev/null +++ b/src/app/requests/types.ts @@ -0,0 +1,6 @@ +export interface ChartHistorySeconds { + epoch: number /* uint64 */ + hourly: number /* uint64 */ + daily: number /* uint64 */ + weekly: number /* uint64 */ +} diff --git a/src/app/requests/types/block.ts b/src/app/requests/types/block.ts new file mode 100644 index 00000000..a054e87f --- /dev/null +++ b/src/app/requests/types/block.ts @@ -0,0 +1,188 @@ +// Code generated by tygo. DO NOT EDIT. +/* eslint-disable */ +import type { ApiDataResponse, Hash, Address, ClElValue } from './common' + +////////// +// source: block.go + +/** + * count indicator per block details tab; each tab is only present if count > 0 + */ +export interface BlockSummary { + transactions: number /* uint64 */ + votes: number /* uint64 */ + attestations: number /* uint64 */ + withdrawals: number /* uint64 */ + bls_changes: number /* uint64 */ + voluntary_exits: number /* uint64 */ + blobs: number /* uint64 */ +} +export type InternalGetBlockResponse = ApiDataResponse +export interface BlockExecutionPayload { + block_hash: Hash + parent_hash: Hash + priority_fees_recipient: Address + gas_used: number /* uint64 */ + gas_limit: number /* uint64 */ + base_fee_per_gas: string /* decimal.Decimal */ + base_fees: string /* decimal.Decimal */ +} +export interface BlockConsensusLayer { + state_root: Hash + signature: Hash + randao_reveal: Hash + attestations: number /* uint64 */ + votes: number /* uint64 */ + voting_validators: number /* uint64 */ + voluntary_exits: number /* uint64 */ + attester_slashings: number /* uint64 */ + proposer_slashings: number /* uint64 */ + deposit: number /* uint64 */ + sync_committee: BlockSyncCommittee + eth1_data: BlockEth1Data + graffiti: string +} +export interface BlockSyncCommittee { + participation: number /* float64 */ + bits: boolean[] + sync_committee: number /* uint64 */[] + signature: Hash +} +export interface BlockEth1Data { + block_hash: Hash + deposit_count: number /* uint64 */ + deposit_root: Hash +} +export interface BlobInfo { + name: number /* uint64 */ + tx_count: number /* uint64 */ + gas_used: number /* uint64 */ + gas_price?: string /* decimal.Decimal */ + excess_gas: number /* uint64 */ + burned_fees?: string /* decimal.Decimal */ +} +export interface BlockOverview { + /** + * General + */ + block: number /* uint64 */ + time: number /* int64 */ + /** + * Old blocks only + */ + miner?: Address + rewards?: string /* decimal.Decimal */ + tx_fees?: string /* decimal.Decimal */ + gas_usage?: string /* decimal.Decimal */ + gas_limit?: { + value: number /* uint64 */ + percent: number /* float64 */ + } + lowest_gas_price?: string /* decimal.Decimal */ + difficulty?: string /* decimal.Decimal */ + /** + * base + burned fee only present post EIP-1559 + */ + base_fee?: string /* decimal.Decimal */ + burned_fees?: string /* decimal.Decimal */ + extra?: string + hash?: Hash + parent_hash?: Hash + /** + * New blocks only + */ + mev_tags?: { + name: string + color: string + }[] + epoch?: number /* uint64 */ + slot?: number /* uint64 */ + proposer?: number /* uint64 */ + proposer_reward?: ClElValue + proposer_reward_recipient?: Address + status?: { + proposal: 'proposed' | 'orphaned' | 'missed' | 'scheduled' + finalized: 'finalized' | 'justified' | 'not_finalized' + } + priority_fees?: string /* decimal.Decimal */ + transactions?: { + general: number /* uint64 */ + internal: number /* uint64 */ + blob?: number /* uint64 */ + } + block_root?: Hash + parent_root?: Hash + execution_payload?: BlockExecutionPayload + consensus_layer?: BlockConsensusLayer +} +export type InternalGetBlockOverviewResponse = ApiDataResponse +export interface BlockTransactionTableRow { + success: boolean + tx_hash: Hash + method: string + block: number /* uint64 */ + age: number /* uint64 */ + from: Address + type: 'out' | 'in' | 'out_in' | 'self' | 'contract' + to: Address + value: string /* decimal.Decimal */ + gas_price: string /* decimal.Decimal */ + tx_fee: string /* decimal.Decimal */ +} +export type InternalGetBlockTransactionsResponse = ApiDataResponse +export interface BlockVoteTableRow { + allocated_slot: number /* uint64 */ + committee: number /* uint64 */ + included_in_block: number /* uint64 */ + validators: number /* uint64 */[] +} +export type InternalGetBlockVotesResponse = ApiDataResponse +export interface EpochInfo { + epoch: number /* uint64 */ + block_root: Hash +} +export interface BlockAttestationTableRow { + slot: number /* uint64 */ + committee_index: number /* uint64 */ + aggregation_bits: boolean[] + validators: number /* uint64 */[] + beacon_block_root: Hash + source: EpochInfo + target: EpochInfo + signature: Hash +} +export type InternalGetBlockAttestationsResponse = ApiDataResponse +export interface BlockWithdrawalTableRow { + /** + * no design present yet, TODO confirm this + */ + index: number /* uint64 */ + epoch: number /* uint64 */ + slot: number /* uint64 */ + age: number /* uint64 */ + recipient: Address + amount: string /* decimal.Decimal */ +} +export type InternalGetBlockWtihdrawalsResponse = ApiDataResponse +export interface BlockBlsChangeTableRow { + index: number /* uint64 */ + signature: Hash + bls_pubkey: Hash + new_withdrawal_address: Address +} +export type InternalGetBlockBlsChangesResponse = ApiDataResponse +export interface BlockVoluntaryExitTableRow { + validator: number /* uint64 */ + signature: Hash +} +export type InternalGetBlockVoluntaryExitsResponse = ApiDataResponse +export interface BlockBlobTableRow { + versioned_hash: Hash + commitment: Hash + proof: Hash + size: number /* uint64 */ + transaction_hash: Hash + block: number /* uint64 */ + data: string +} +export type InternalGetBlockBlobsResponse = ApiDataResponse diff --git a/src/app/requests/types/common.ts b/src/app/requests/types/common.ts new file mode 100644 index 00000000..35744913 --- /dev/null +++ b/src/app/requests/types/common.ts @@ -0,0 +1,126 @@ +// Code generated by tygo. DO NOT EDIT. +/* eslint-disable */ + +////////// +// source: common.go + +export interface Paging { + prev_cursor?: string + next_cursor?: string + total_count?: number /* uint64 */ +} +export interface ApiResponse { + paging?: Paging + data: any +} +export interface ApiErrorResponse { + error: string +} +export interface ApiDataResponse { + data: T +} +export interface ApiPagingResponse { + paging: Paging + data: T[] +} +export type PubKey = string +export type Hash = string // blocks, txs etc. +export interface Address { + hash: Hash + is_contract: boolean + ens?: string + label?: string +} +export interface LuckItem { + percent: number /* float64 */ + expected_timestamp: number /* uint64 */ + average_interval_seconds: number /* uint64 */ +} +export interface Luck { + proposal: LuckItem + sync: LuckItem +} +export interface StatusCount { + success: number /* uint64 */ + failed: number /* uint64 */ +} +export interface ClElValue { + el: T + cl: T +} +export interface PeriodicValues { + all_time: T + last_24h: T + last_7d: T + last_30d: T +} +export interface PercentageDetails { + percentage: number /* float64 */ + min_value: T + max_value: T +} +export interface ChartSeries { + id: I // id may be a string or an int + property?: string // for stacking bar charts + data: D[] // y-axis values +} +export interface ChartData { + categories: number /* uint64 */[] // x-axis + series: ChartSeries[] +} +export interface ValidatorHistoryEvent { + status: 'success' | 'partial' | 'failed' + income: string /* decimal.Decimal */ +} +export interface ValidatorHistoryProposal { + status: 'success' | 'partial' | 'failed' + el_income: string /* decimal.Decimal */ + cl_attestation_inclusion_income: string /* decimal.Decimal */ + cl_sync_inclusion_income: string /* decimal.Decimal */ + cl_slashing_inclusion_income: string /* decimal.Decimal */ +} +export interface ValidatorHistoryDuties { + attestation_source?: ValidatorHistoryEvent + attestation_target?: ValidatorHistoryEvent + attestation_head?: ValidatorHistoryEvent + sync?: ValidatorHistoryEvent + slashing?: ValidatorHistoryEvent + proposal?: ValidatorHistoryProposal + sync_count?: number /* uint64 */ // count of successful sync duties for the epoch +} +export interface ChainConfig { + chain_id: number /* uint64 */ + name: string +} +export interface VDBPublicId { + public_id: string + name?: string + share_settings: { + share_groups: boolean + } +} +export interface ChartHistorySeconds { + epoch: number /* uint64 */ + hourly: number /* uint64 */ + daily: number /* uint64 */ + weekly: number /* uint64 */ +} +export interface IndexEpoch { + index: number /* uint64 */ + epoch: number /* uint64 */ +} +export interface IndexBlocks { + index: number /* uint64 */ + blocks: number /* uint64 */[] +} +export interface IndexSlots { + index: number /* uint64 */ + slots: number /* uint64 */[] +} +export interface ValidatorStateCounts { + online: number /* uint64 */ + offline: number /* uint64 */ + pending: number /* uint64 */ + exited: number /* uint64 */ + slashed: number /* uint64 */ +} diff --git a/src/app/requests/types/dashboard.ts b/src/app/requests/types/dashboard.ts new file mode 100644 index 00000000..834aa38a --- /dev/null +++ b/src/app/requests/types/dashboard.ts @@ -0,0 +1,26 @@ +// Code generated by tygo. DO NOT EDIT. +/* eslint-disable */ +import type { VDBPublicId, ApiDataResponse } from './common' + +////////// +// source: dashboard.go + +export interface AccountDashboard { + id: number /* uint64 */ + name: string +} +export interface ValidatorDashboard { + id: number /* uint64 */ + name: string + network: number /* uint64 */ + public_ids?: VDBPublicId[] + is_archived: boolean + archived_reason?: 'dashboard_limit' | 'validator_limit' | 'group_limit' + validator_count: number /* uint64 */ + group_count: number /* uint64 */ +} +export interface UserDashboardsData { + validator_dashboards: ValidatorDashboard[] + account_dashboards: AccountDashboard[] +} +export type GetUserDashboardsResponse = ApiDataResponse diff --git a/src/app/requests/types/latest_state.ts b/src/app/requests/types/latest_state.ts new file mode 100644 index 00000000..0f99f949 --- /dev/null +++ b/src/app/requests/types/latest_state.ts @@ -0,0 +1,31 @@ +// Code generated by tygo. DO NOT EDIT. +/* eslint-disable */ +import type { ApiDataResponse } from './common' + +////////// +// source: latest_state.go + +/** + * EthConversionRate is the exchange rate of ETH to a specific currency + */ +export interface EthConversionRate { + currency: string + code: string + symbol: string + rate: number /* float64 */ +} +export interface LatestStateData { + current_slot: number /* uint64 */ + exchange_rates: EthConversionRate[] + finalized_epoch: number /* uint64 */ +} +export type InternalGetLatestStateResponse = ApiDataResponse +export interface RocketPoolData { + last_update_slot: number /* uint64 */ + next_update_slot: number /* uint64 */ + eth_rates: { + rpl: number /* float64 */ + reth: number /* float64 */ + } +} +export type InternalGetRocketPoolResponse = ApiDataResponse diff --git a/src/app/requests/types/machine_metrics.ts b/src/app/requests/types/machine_metrics.ts new file mode 100644 index 00000000..a0ef869c --- /dev/null +++ b/src/app/requests/types/machine_metrics.ts @@ -0,0 +1,97 @@ +// Code generated by tygo. DO NOT EDIT. +/* eslint-disable */ +import { StatsBase } from '@controllers/MachineController' +import type { ApiDataResponse } from './common' + +////////// +// source: machine_metrics.go + +export interface MachineMetricSystem { + timestamp?: number /* uint64 */ + exporter_version?: string + /** + * system + */ + cpu_cores?: number /* uint64 */ + cpu_threads?: number /* uint64 */ + cpu_node_system_seconds_total?: number /* uint64 */ + cpu_node_user_seconds_total?: number /* uint64 */ + cpu_node_iowait_seconds_total?: number /* uint64 */ + cpu_node_idle_seconds_total?: number /* uint64 */ + memory_node_bytes_total?: number /* uint64 */ + memory_node_bytes_free?: number /* uint64 */ + memory_node_bytes_cached?: number /* uint64 */ + memory_node_bytes_buffers?: number /* uint64 */ + disk_node_bytes_total?: number /* uint64 */ + disk_node_bytes_free?: number /* uint64 */ + disk_node_io_seconds?: number /* uint64 */ + disk_node_reads_total?: number /* uint64 */ + disk_node_writes_total?: number /* uint64 */ + network_node_bytes_total_receive?: number /* uint64 */ + network_node_bytes_total_transmit?: number /* uint64 */ + misc_node_boot_ts_seconds?: number /* uint64 */ + misc_os?: string + /** + * do not store in bigtable but include them in generated model + */ + machine?: string +} +export interface MachineMetricValidator { + timestamp?: number /* uint64 */ + exporter_version?: string + /** + * process + */ + cpu_process_seconds_total?: number /* uint64 */ + memory_process_bytes?: number /* uint64 */ + client_name?: string + client_version?: string + client_build?: number /* uint64 */ + sync_eth2_fallback_configured?: boolean + sync_eth2_fallback_connected?: boolean + /** + * validator + */ + validator_total?: number /* uint64 */ + validator_active?: number /* uint64 */ + /** + * do not store in bigtable but include them in generated model + */ + machine?: string +} +export interface MachineMetricNode { + timestamp?: number /* uint64 */ + exporter_version?: string + /** + * process + */ + cpu_process_seconds_total?: number /* uint64 */ + memory_process_bytes?: number /* uint64 */ + client_name?: string + client_version?: string + client_build?: number /* uint64 */ + sync_eth2_fallback_configured?: boolean + sync_eth2_fallback_connected?: boolean + /** + * node + */ + disk_beaconchain_bytes_total?: number /* uint64 */ + network_libp2p_bytes_total_receive?: number /* uint64 */ + network_libp2p_bytes_total_transmit?: number /* uint64 */ + network_peers_connected?: number /* uint64 */ + sync_eth1_connected?: boolean + sync_eth2_synced?: boolean + sync_beacon_head_slot?: number /* uint64 */ + sync_eth1_fallback_configured?: boolean + sync_eth1_fallback_connected?: boolean + /** + * do not store in bigtable but include them in generated model + */ + machine?: string +} +export interface MachineMetricsData { + system_metrics: (MachineMetricSystem | undefined)[] + validator_metrics: (MachineMetricValidator | undefined)[] + node_metrics: (MachineMetricNode | undefined)[] +} +export type GetUserMachineMetricsRespone = ApiDataResponse diff --git a/src/app/requests/types/mobile.ts b/src/app/requests/types/mobile.ts new file mode 100644 index 00000000..0f1a1976 --- /dev/null +++ b/src/app/requests/types/mobile.ts @@ -0,0 +1,46 @@ +// Code generated by tygo. DO NOT EDIT. +/* eslint-disable */ +import type { ApiDataResponse, PubKey, Hash, ApiPagingResponse } from './common' + +////////// +// source: mobile.go + +export interface MobileBundleData { + bundle_url?: string + has_native_update_available: boolean +} +export type GetMobileLatestBundleResponse = ApiDataResponse +export interface MobileValidatorDashboardValidatorsRocketPool { + deposit_amount: string /* decimal.Decimal */ + commission: number /* float64 */ // percentage, 0-1 + status: 'Staking' | 'Dissolved' | 'Prelaunch' | 'Initialized' | 'Withdrawable' + penalty_count: number /* uint64 */ + is_in_smoothing_pool: boolean +} +export interface MobileValidatorDashboardValidatorsTableRow { + index: number /* uint64 */ + public_key: PubKey + group_id: number /* uint64 */ + balance: string /* decimal.Decimal */ + status: + | 'slashed' + | 'exited' + | 'deposited' + | 'pending' + | 'slashing_offline' + | 'slashing_online' + | 'exiting_offline' + | 'exiting_online' + | 'active_offline' + | 'active_online' + queue_position?: number /* uint64 */ + withdrawal_credential: Hash + /** + * additional mobile fields + */ + is_in_sync_committee: boolean + is_in_next_sync_committee: boolean + efficiency: number /* float64 */ + rocket_pool?: MobileValidatorDashboardValidatorsRocketPool +} +export type InternalGetValidatorDashboardMobileValidatorsResponse = ApiPagingResponse diff --git a/src/app/requests/types/notifications.ts b/src/app/requests/types/notifications.ts new file mode 100644 index 00000000..d4d8c30d --- /dev/null +++ b/src/app/requests/types/notifications.ts @@ -0,0 +1,239 @@ +// Code generated by tygo. DO NOT EDIT. +/* eslint-disable */ +import type { ApiDataResponse, ApiPagingResponse, Address, IndexSlots, IndexBlocks, IndexEpoch, Hash } from './common' + +////////// +// source: notifications.go + +/** + * ------------------------------------------------------------ + * Overview + */ +export interface NotificationOverviewData { + is_email_notifications_enabled: boolean + is_push_notifications_enabled: boolean + /** + * these will list 3 group names + */ + vdb_most_notified_groups: string[] + adb_most_notified_groups: string[] + next_email_count_reset_timestamp: number /* int64 */ + last_24h_email_count: number /* uint64 */ // daily limit should be available in user info + last_24h_push_count: number /* uint64 */ + last_24h_webhook_count: number /* uint64 */ + /** + * counts are shown in their respective tables + */ + vdb_subscriptions_count: number /* uint64 */ + adb_subscriptions_count: number /* uint64 */ + machines_subscription_count: number /* uint64 */ + clients_subscription_count: number /* uint64 */ + networks_subscription_count: number /* uint64 */ +} +export type InternalGetUserNotificationsResponse = ApiDataResponse +/** + * ------------------------------------------------------------ + * Dashboards Table + */ +export interface NotificationDashboardsTableRow { + is_account_dashboard: boolean // if false it's a validator dashboard + chain_id: number /* uint64 */ + epoch: number /* uint64 */ + dashboard_id: number /* uint64 */ + dashboard_name: string + group_id: number /* uint64 */ + group_name: string + entity_count: number /* uint64 */ + event_types: ( + | 'validator_online' + | 'validator_offline' + | 'group_efficiency_below' + | 'attestation_missed' + | 'proposal_success' + | 'proposal_missed' + | 'proposal_upcoming' + | 'max_collateral' + | 'min_collateral' + | 'sync' + | 'withdrawal' + | 'validator_got_slashed' + | 'validator_has_slashed' + | 'incoming_tx' + | 'outgoing_tx' + | 'transfer_erc20' + | 'transfer_erc721' + | 'transfer_erc1155' + )[] +} +export type InternalGetUserNotificationDashboardsResponse = ApiPagingResponse +export interface NotificationEventValidatorBackOnline { + index: number /* uint64 */ + epoch_count: number /* uint64 */ +} +export interface NotificationEventWithdrawal { + index: number /* uint64 */ + amount: string /* decimal.Decimal */ + address: Address +} +export interface NotificationValidatorDashboardDetail { + dashboard_name: string + group_name: string + validator_offline: number /* uint64 */[] // validator indices + validator_offline_reminder: number /* uint64 */[] // validator indices; TODO not filled yet + validator_online: NotificationEventValidatorBackOnline[] + group_efficiency_below?: number /* float64 */ // fill with the `group_efficiency_below` threshold if event is present + proposal_missed: IndexSlots[] + proposal_success: IndexBlocks[] + proposal_upcoming: IndexSlots[] + slashed: number /* uint64 */[] // validator indices + sync: number /* uint64 */[] // validator indices + attestation_missed: IndexEpoch[] // index (epoch) + withdrawal: NotificationEventWithdrawal[] + min_collateral: Address[] // node addresses + max_collateral: Address[] // node addresses +} +export type InternalGetUserNotificationsValidatorDashboardResponse = ApiDataResponse +export interface NotificationEventExecution { + address: Address + amount: string /* decimal.Decimal */ + transaction_hash: Hash + token_name: string // this field will prob change depending on how execution stuff is implemented +} +export interface NotificationAccountDashboardDetail { + incoming_transactions: NotificationEventExecution[] + outgoing_transactions: NotificationEventExecution[] + erc20_token_transfers: NotificationEventExecution[] + erc721_token_transfers: NotificationEventExecution[] + erc1155_token_transfers: NotificationEventExecution[] +} +export type InternalGetUserNotificationsAccountDashboardResponse = ApiDataResponse +/** + * ------------------------------------------------------------ + * Machines Table + */ +export interface NotificationMachinesTableRow { + machine_name: string + threshold?: number /* float64 */ + event_type: 'offline' | 'storage' | 'cpu' | 'memory' + timestamp: number /* int64 */ +} +export type InternalGetUserNotificationMachinesResponse = ApiPagingResponse +/** + * ------------------------------------------------------------ + * Clients Table + */ +export interface NotificationClientsTableRow { + client_name: string + version: string + url: string + timestamp: number /* int64 */ +} +export type InternalGetUserNotificationClientsResponse = ApiPagingResponse +/** + * ------------------------------------------------------------ + * Networks Table + */ +export interface NotificationNetworksTableRow { + chain_id: number /* uint64 */ + timestamp: number /* int64 */ + event_type: 'new_reward_round' | 'gas_above' | 'gas_below' | 'participation_rate' + threshold?: string /* decimal.Decimal */ // participation rate threshold should also be passed as decimal string +} +export type InternalGetUserNotificationNetworksResponse = ApiPagingResponse +/** + * ------------------------------------------------------------ + * Notification Settings + */ +export interface NotificationSettingsNetwork { + is_gas_above_subscribed: boolean + gas_above_threshold: string /* decimal.Decimal */ + is_gas_below_subscribed: boolean + gas_below_threshold: string /* decimal.Decimal */ + is_participation_rate_subscribed: boolean + participation_rate_threshold: number /* float64 */ + is_new_reward_round_subscribed: boolean +} +export interface NotificationNetwork { + chain_id: number /* uint64 */ + settings: NotificationSettingsNetwork +} +export type InternalPutUserNotificationSettingsNetworksResponse = ApiDataResponse +export interface NotificationPairedDevice { + id: number /* uint64 */ + paired_timestamp: number /* int64 */ + name?: string + is_notifications_enabled: boolean +} +export type InternalPutUserNotificationSettingsPairedDevicesResponse = ApiDataResponse +export interface NotificationSettingsClient { + id: number /* uint64 */ + name: string + category: 'execution_layer' | 'consensus_layer' | 'other' + is_subscribed: boolean +} +export type InternalPutUserNotificationSettingsClientResponse = ApiDataResponse +export interface NotificationSettingsGeneral { + do_not_disturb_timestamp: number /* int64 */ // notifications are disabled until this timestamp + is_email_notifications_enabled: boolean + is_push_notifications_enabled: boolean + is_machine_offline_subscribed: boolean + is_machine_storage_usage_subscribed: boolean + machine_storage_usage_threshold: number /* float64 */ + is_machine_cpu_usage_subscribed: boolean + machine_cpu_usage_threshold: number /* float64 */ + is_machine_memory_usage_subscribed: boolean + machine_memory_usage_threshold: number /* float64 */ +} +export type InternalPutUserNotificationSettingsGeneralResponse = ApiDataResponse +export interface NotificationSettings { + general_settings: NotificationSettingsGeneral + has_machines: boolean + networks: NotificationNetwork[] + paired_devices: NotificationPairedDevice[] + clients: NotificationSettingsClient[] +} +export type InternalGetUserNotificationSettingsResponse = ApiDataResponse +export interface NotificationSettingsValidatorDashboard { + webhook_url: string + is_webhook_discord_enabled: boolean + is_validator_offline_subscribed: boolean + is_group_efficiency_below_subscribed: boolean + group_efficiency_below_threshold: number /* float64 */ + is_attestations_missed_subscribed: boolean + is_block_proposal_subscribed: boolean + is_upcoming_block_proposal_subscribed: boolean + is_sync_subscribed: boolean + is_withdrawal_processed_subscribed: boolean + is_slashed_subscribed: boolean + is_max_collateral_subscribed: boolean + max_collateral_threshold: number /* float64 */ + is_min_collateral_subscribed: boolean + min_collateral_threshold: number /* float64 */ +} +export type InternalPutUserNotificationSettingsValidatorDashboardResponse = ApiDataResponse +export interface NotificationSettingsAccountDashboard { + webhook_url: string + is_webhook_discord_enabled: boolean + is_ignore_spam_transactions_enabled: boolean + subscribed_chain_ids: number /* uint64 */[] + is_incoming_transactions_subscribed: boolean + is_outgoing_transactions_subscribed: boolean + is_erc20_token_transfers_subscribed: boolean + erc20_token_transfers_value_threshold: number /* float64 */ + is_erc721_token_transfers_subscribed: boolean + is_erc1155_token_transfers_subscribed: boolean +} +export type InternalPutUserNotificationSettingsAccountDashboardResponse = ApiDataResponse +export interface NotificationSettingsDashboardsTableRow { + is_account_dashboard: boolean // if false it's a validator dashboard + dashboard_id: number /* uint64 */ + dashboard_name: string + group_id: number /* uint64 */ + group_name: string + /** + * if it's a validator dashboard, Settings is NotificationSettingsAccountDashboard, otherwise NotificationSettingsValidatorDashboard + */ + settings: NotificationSettingsAccountDashboard | NotificationSettingsValidatorDashboard + chain_ids: number /* uint64 */[] +} +export type InternalGetUserNotificationSettingsDashboardsResponse = ApiPagingResponse diff --git a/src/app/requests/types/search.ts b/src/app/requests/types/search.ts new file mode 100644 index 00000000..0518b0a6 --- /dev/null +++ b/src/app/requests/types/search.ts @@ -0,0 +1,41 @@ +// Code generated by tygo. DO NOT EDIT. +/* eslint-disable */ + +////////// +// source: search.go + +export interface SearchValidator { + index: number /* uint64 */ + public_key: string +} +export interface SearchValidatorList { + validators: number /* uint64 */[] +} +export interface SearchValidatorsByDepositAddress { + ens_name?: string + deposit_address: string + count: number /* uint64 */ +} +export interface SearchValidatorsByWithdrwalCredential { + ens_name?: string + withdrawal_credential: string + count: number /* uint64 */ +} +export interface SearchValidatorsByGraffiti { + graffiti: string + count: number /* uint64 */ +} +export interface SearchResult { + type: string + chain_id: number /* uint64 */ + value: any +} +export interface InternalPostSearchResponse { + data: ( + | { type: 'validator'; chain_id: number; value: SearchValidator } + | { type: 'validator_list'; chain_id: number; value: SearchValidatorList } + | { type: 'validators_by_deposit_address'; chain_id: number; value: SearchValidatorsByDepositAddress } + | { type: 'validators_by_withdrawal_credential'; chain_id: number; value: SearchValidatorsByWithdrwalCredential } + | { type: 'validators_by_graffiti'; chain_id: number; value: SearchValidatorsByGraffiti } + )[] +} diff --git a/src/app/requests/types/slot_viz.ts b/src/app/requests/types/slot_viz.ts new file mode 100644 index 00000000..a75b8c5b --- /dev/null +++ b/src/app/requests/types/slot_viz.ts @@ -0,0 +1,49 @@ +// Code generated by tygo. DO NOT EDIT. +/* eslint-disable */ +import type { ApiDataResponse } from './common' + +////////// +// source: slot_viz.go + +/** + * ------------------------------------------------------------ + * Slot Viz + */ +export interface VDBSlotVizDuty { + total_count: number /* uint64 */ + validators: number /* uint64 */[] // up to 6 validators that performed the duty, only for scheduled and failed +} +export interface VDBSlotVizTuple { + validator: number /* uint64 */ + /** + * If the duty is a proposal & it's successful, the duty_object is the proposed block + * If the duty is a proposal & it failed/scheduled, the duty_object is the slot + * If the duty is a slashing & it's successful, the duty_object is the validator you slashed + * If the duty is a slashing & it failed, the duty_object is your validator that was slashed + */ + duty_object: number /* uint64 */ +} +export interface VDBSlotVizSlashing { + total_count: number /* uint64 */ + slashings: VDBSlotVizTuple[] // up to 6 slashings, validator is always the slashing validator +} +export interface VDBSlotVizStatus { + success?: T + failed?: T + scheduled?: T +} +export interface VDBSlotVizSlot { + slot: number /* uint64 */ + status: 'proposed' | 'missed' | 'scheduled' | 'orphaned' + proposal?: VDBSlotVizTuple + attestations?: VDBSlotVizStatus + sync?: VDBSlotVizStatus + slashing?: VDBSlotVizStatus +} +export interface SlotVizEpoch { + epoch: number /* uint64 */ + state?: 'scheduled' | 'head' | 'justifying' | 'justified' | 'finalized' // all on landing page, only 'head' on dashboard page + progress?: number /* float64 */ // only on landing page + slots?: VDBSlotVizSlot[] // only on dashboard page +} +export type InternalGetValidatorDashboardSlotVizResponse = ApiDataResponse diff --git a/src/app/requests/types/user.ts b/src/app/requests/types/user.ts new file mode 100644 index 00000000..36055686 --- /dev/null +++ b/src/app/requests/types/user.ts @@ -0,0 +1,128 @@ +// Code generated by tygo. DO NOT EDIT. +/* eslint-disable */ +import type { ApiDataResponse, ChartHistorySeconds } from './common' + +////////// +// source: user.go + +export interface UserInfo { + id: number /* uint64 */ + email: string + api_keys: string[] + api_perks: ApiPerks + premium_perks: PremiumPerks + subscriptions: UserSubscription[] +} +export interface UserSubscription { + product_id: string + product_name: string + product_category: ProductCategory + product_store: ProductStore + start: number /* int64 */ + end: number /* int64 */ +} +export type InternalGetUserInfoResponse = ApiDataResponse +export interface EmailUpdate { + id: number /* uint64 */ + current_email: string + pending_email: string +} +export type InternalPutUserEmailResponse = ApiDataResponse +export interface AdConfigurationUpdateData { + jquery_selector: string + insert_mode: string + refresh_interval: number /* uint64 */ + for_all_users: boolean + banner_id: number /* uint64 */ + html_content: string + enabled: boolean +} +export interface AdConfigurationData { + key: string + AdConfigurationUpdateData?: AdConfigurationUpdateData +} +export type ProductCategory = string +export const ProductCategoryApi: ProductCategory = 'api' +export const ProductCategoryPremium: ProductCategory = 'premium' +export const ProductCategoryPremiumAddon: ProductCategory = 'premium_addon' +export type ProductStore = string +export const ProductStoreStripe: ProductStore = 'stripe' +export const ProductStoreIosAppstore: ProductStore = 'ios-appstore' +export const ProductStoreAndroidPlaystore: ProductStore = 'android-playstore' +export const ProductStoreEthpool: ProductStore = 'ethpool' +export const ProductStoreCustom: ProductStore = 'custom' +export interface ProductSummary { + validators_per_dashboard_limit: number /* uint64 */ + stripe_public_key: string + api_products: ApiProduct[] + premium_products: PremiumProduct[] + extra_dashboard_validators_premium_addons: ExtraDashboardValidatorsPremiumAddon[] +} +export type InternalGetProductSummaryResponse = ApiDataResponse +export interface ApiProduct { + product_id: string + product_name: string + api_perks: ApiPerks + price_per_year_eur: number /* float64 */ + price_per_month_eur: number /* float64 */ + is_popular: boolean + stripe_price_id_monthly: string + stripe_price_id_yearly: string +} +export interface ApiPerks { + units_per_second: number /* uint64 */ + units_per_month: number /* uint64 */ + api_keys: number /* uint64 */ + consensus_layer_api: boolean + execution_layer_api: boolean + layer2_api: boolean + no_ads: boolean // note that this is somhow redunant, since there is already PremiumPerks.AdFree + discord_support: boolean +} +export interface PremiumProduct { + product_name: string + premium_perks: PremiumPerks + price_per_year_eur: number /* float64 */ + price_per_month_eur: number /* float64 */ + is_popular: boolean + product_id_monthly: string + product_id_yearly: string + stripe_price_id_monthly: string + stripe_price_id_yearly: string +} +export interface ExtraDashboardValidatorsPremiumAddon { + product_name: string + extra_dashboard_validators: number /* uint64 */ + price_per_year_eur: number /* float64 */ + price_per_month_eur: number /* float64 */ + product_id_monthly: string + product_id_yearly: string + stripe_price_id_monthly: string + stripe_price_id_yearly: string +} +export interface PremiumPerks { + ad_free: boolean // note that this is somhow redunant, since there is already ApiPerks.NoAds + validator_dashboards: number /* uint64 */ + validators_per_dashboard: number /* uint64 */ + validator_groups_per_dashboard: number /* uint64 */ + share_custom_dashboards: boolean + manage_dashboard_via_api: boolean + bulk_adding: boolean + chart_history_seconds: ChartHistorySeconds + email_notifications_per_day: number /* uint64 */ + configure_notifications_via_api: boolean + validator_group_notifications: number /* uint64 */ + webhook_endpoints: number /* uint64 */ + mobile_app_custom_themes: boolean + mobile_app_widget: boolean + monitor_machines: number /* uint64 */ + machine_monitoring_history_seconds: number /* uint64 */ + custom_machine_alerts: boolean +} +export interface StripeCreateCheckoutSession { + sessionId?: string + error?: string +} +export interface StripeCustomerPortal { + url: string +} diff --git a/src/app/requests/types/validator_dashboard.ts b/src/app/requests/types/validator_dashboard.ts new file mode 100644 index 00000000..c0aa26f0 --- /dev/null +++ b/src/app/requests/types/validator_dashboard.ts @@ -0,0 +1,390 @@ +// Code generated by tygo. DO NOT EDIT. +/* eslint-disable */ +import type { + PeriodicValues, + ClElValue, + ChartHistorySeconds, + ApiDataResponse, + StatusCount, + ApiPagingResponse, + Luck, + ChartData, + ValidatorHistoryDuties, + Address, + PubKey, + Hash, + PercentageDetails, +} from './common' + +////////// +// source: validator_dashboard.go + +/** + * ------------------------------------------------------------ + * Overview + */ +export interface VDBOverviewValidators { + online: number /* uint64 */ + offline: number /* uint64 */ + pending: number /* uint64 */ + exited: number /* uint64 */ + slashed: number /* uint64 */ +} +export interface VDBOverviewGroup { + id: number /* uint64 */ + name: string + count: number /* uint64 */ +} +export interface VDBOverviewBalances { + total: number /* uint64 */ + effective: number /* uint64 */ + staked_eth: number /* uint64 */ +} +export interface VDBOverviewData { + name?: string + network: number /* uint64 */ + groups: VDBOverviewGroup[] + validators: VDBOverviewValidators + efficiency: PeriodicValues + rewards: PeriodicValues> + apr: PeriodicValues> + chart_history_seconds: ChartHistorySeconds + balances: VDBOverviewBalances +} +export type InternalGetValidatorDashboardResponse = ApiDataResponse +export interface VDBPostArchivingReturnData { + id: number /* uint64 */ + is_archived: boolean +} +export interface VDBSummaryStatus { + next_sync_count: number /* uint64 */ + current_sync_count: number /* uint64 */ + slashed_count: number /* uint64 */ +} +export interface VDBSummaryValidators { + online: number /* uint64 */ + offline: number /* uint64 */ + exited: number /* uint64 */ +} +export interface VDBSummaryTableRow { + group_id: number /* int64 */ + status: VDBSummaryStatus + validators: VDBSummaryValidators + efficiency: number /* float64 */ + average_network_efficiency: number /* float64 */ + attestations: StatusCount + proposals: StatusCount + reward: ClElValue +} +export type InternalGetValidatorDashboardSummaryResponse = ApiPagingResponse +export interface VDBGroupSummaryColumnItem { + status_count: StatusCount + validators?: number /* uint64 */[] +} +export interface VDBGroupSummarySyncCount { + current_validators: number /* uint64 */ + upcoming_validators: number /* uint64 */ + past_periods: number /* uint64 */ +} +export interface VDBGroupSummaryMissedRewards { + proposer_rewards: ClElValue + attestations: string /* decimal.Decimal */ + sync: string /* decimal.Decimal */ +} +export interface VDBGroupSummaryData { + attestations_head: StatusCount + attestations_source: StatusCount + attestations_target: StatusCount + attestation_efficiency: number /* float64 */ + attestation_avg_incl_dist: number /* float64 */ + sync: VDBGroupSummaryColumnItem + sync_count: VDBGroupSummarySyncCount + slashings: VDBGroupSummaryColumnItem // Failed slashings are count of validators in the group that were slashed + proposal_validators: number /* uint64 */[] + missed_rewards: VDBGroupSummaryMissedRewards + apr: ClElValue + luck: Luck + rocket_pool?: { + minipools: number /* uint64 */ + collateral: number /* float64 */ + } +} +export type InternalGetValidatorDashboardGroupSummaryResponse = ApiDataResponse +export type InternalGetValidatorDashboardSummaryChartResponse = ApiDataResponse> // line chart, series id is group id +/** + * ------------------------------------------------------------ + * Summary Validators + */ +export interface VDBSummaryValidator { + index: number /* uint64 */ + duty_objects?: number /* uint64 */[] +} +export interface VDBSummaryValidatorsData { + category: + | 'deposited' + | 'online' + | 'offline' + | 'slashing' + | 'slashed' + | 'exited' + | 'withdrawn' + | 'pending' + | 'exiting' + | 'withdrawing' + | 'sync_current' + | 'sync_upcoming' + | 'sync_past' + | 'has_slashed' + | 'got_slashed' + | 'proposal_proposed' + | 'proposal_missed' + validators: VDBSummaryValidator[] +} +export type InternalGetValidatorDashboardSummaryValidatorsResponse = ApiDataResponse +/** + * ------------------------------------------------------------ + * Rewards Tab + */ +export interface VDBRewardsTableDuty { + attestation?: number /* float64 */ + proposal?: number /* float64 */ + sync?: number /* float64 */ + slashing?: number /* uint64 */ +} +export interface VDBRewardsTableRow { + epoch: number /* uint64 */ + duty: VDBRewardsTableDuty + group_id: number /* int64 */ + reward: ClElValue +} +export type InternalGetValidatorDashboardRewardsResponse = ApiPagingResponse +export interface VDBGroupRewardsDetails { + status_count: StatusCount + income: string /* decimal.Decimal */ +} +export interface VDBGroupRewardsData { + attestations_source: VDBGroupRewardsDetails + attestations_target: VDBGroupRewardsDetails + attestations_head: VDBGroupRewardsDetails + sync: VDBGroupRewardsDetails + slashing: VDBGroupRewardsDetails + inactivity: VDBGroupRewardsDetails + proposal: VDBGroupRewardsDetails + proposal_el_reward: string /* decimal.Decimal */ + proposal_cl_att_inc_reward: string /* decimal.Decimal */ + proposal_cl_sync_inc_reward: string /* decimal.Decimal */ + proposal_cl_slashing_inc_reward: string /* decimal.Decimal */ +} +export type InternalGetValidatorDashboardGroupRewardsResponse = ApiDataResponse +export type InternalGetValidatorDashboardRewardsChartResponse = ApiDataResponse> // bar chart, series id is group id, property is 'el' or 'cl' +export interface VDBEpochDutiesTableRow { + validator: number /* uint64 */ + duties: ValidatorHistoryDuties +} +export type InternalGetValidatorDashboardDutiesResponse = ApiPagingResponse +/** + * ------------------------------------------------------------ + * Blocks Tab + */ +export interface VDBBlocksTableRow { + proposer: number /* uint64 */ + group_id: number /* uint64 */ + epoch: number /* uint64 */ + slot: number /* uint64 */ + status: 'success' | 'missed' | 'orphaned' | 'scheduled' + block?: number /* uint64 */ + reward_recipient?: Address + reward?: ClElValue + graffiti?: string +} +export type InternalGetValidatorDashboardBlocksResponse = ApiPagingResponse +export interface VDBHeatmapEvents { + proposal: boolean + slash: boolean + sync: boolean +} +export interface VDBHeatmapCell { + x: number /* int64 */ // Timestamp + y: number /* uint64 */ // Group ID + value: number /* float64 */ // Attestaton Rewards + events?: VDBHeatmapEvents +} +export interface VDBHeatmap { + timestamps: number /* int64 */[] // X-Axis Categories (unix timestamp) + group_ids: number /* uint64 */[] // Y-Axis Categories + data: VDBHeatmapCell[] + aggregation: 'epoch' | 'hourly' | 'daily' | 'weekly' +} +export type InternalGetValidatorDashboardHeatmapResponse = ApiDataResponse +export interface VDBHeatmapTooltipData { + timestamp: number /* int64 */ + proposers: StatusCount + syncs: number /* uint64 */ + slashings: StatusCount + attestations_head: StatusCount + attestations_source: StatusCount + attestations_target: StatusCount + attestation_income: string /* decimal.Decimal */ + attestation_efficiency: number /* float64 */ +} +export type InternalGetValidatorDashboardGroupHeatmapResponse = ApiDataResponse +/** + * ------------------------------------------------------------ + * Deposits Tab + */ +export interface VDBExecutionDepositsTableRow { + public_key: PubKey + index?: number /* uint64 */ + group_id: number /* uint64 */ + block: number /* uint64 */ + timestamp: number /* int64 */ + from: Address + depositor: Address + tx_hash: Hash + withdrawal_credential: Hash + amount: string /* decimal.Decimal */ + valid: boolean +} +export type InternalGetValidatorDashboardExecutionLayerDepositsResponse = ApiPagingResponse +export interface VDBConsensusDepositsTableRow { + public_key: PubKey + index: number /* uint64 */ + group_id: number /* uint64 */ + epoch: number /* uint64 */ + slot: number /* uint64 */ + withdrawal_credential: Hash + amount: string /* decimal.Decimal */ + signature: Hash +} +export type InternalGetValidatorDashboardConsensusLayerDepositsResponse = ApiPagingResponse +export interface VDBTotalExecutionDepositsData { + total_amount: string /* decimal.Decimal */ +} +export type InternalGetValidatorDashboardTotalExecutionDepositsResponse = ApiDataResponse +export interface VDBTotalConsensusDepositsData { + total_amount: string /* decimal.Decimal */ +} +export type InternalGetValidatorDashboardTotalConsensusDepositsResponse = ApiDataResponse +/** + * ------------------------------------------------------------ + * Withdrawals Tab + */ +export interface VDBWithdrawalsTableRow { + epoch: number /* uint64 */ + slot: number /* uint64 */ + index: number /* uint64 */ + group_id: number /* uint64 */ + recipient: Address + amount: string /* decimal.Decimal */ + is_missing_estimate: boolean +} +export type InternalGetValidatorDashboardWithdrawalsResponse = ApiPagingResponse +export interface VDBTotalWithdrawalsData { + total_amount: string /* decimal.Decimal */ +} +export type InternalGetValidatorDashboardTotalWithdrawalsResponse = ApiDataResponse +/** + * ------------------------------------------------------------ + * Rocket Pool Tab + */ +export interface VDBRocketPoolTableRow { + node: Address + staked_eth: string /* decimal.Decimal */ + staked_rpl: string /* decimal.Decimal */ + minipools_count_total: number /* uint64 */ + minipools_count_leb_16: number /* uint64 */ + minipools_count_leb_8: number /* uint64 */ + collateral: PercentageDetails + avg_commission: number /* float64 */ + rpl_claimed: string /* decimal.Decimal */ + rpl_unclaimed: string /* decimal.Decimal */ + effective_rpl: string /* decimal.Decimal */ + rpl_apr: number /* float64 */ + rpl_apr_update_ts: number /* int64 */ + rpl_estimate: string /* decimal.Decimal */ + smoothingpool_opt_in: boolean + smoothingpool_claimed: string /* decimal.Decimal */ + smoothingpool_unclaimed: string /* decimal.Decimal */ + node_deposit_balance: string /* decimal.Decimal */ + user_deposit_balance: string /* decimal.Decimal */ + timezone: string + refund_balance: string /* decimal.Decimal */ + deposit_credit: string /* decimal.Decimal */ +} +export type InternalGetValidatorDashboardRocketPoolResponse = ApiPagingResponse +export type InternalGetValidatorDashboardTotalRocketPoolResponse = ApiDataResponse +export interface VDBNodeRocketPoolData { + timezone: string + refund_balance: string /* decimal.Decimal */ + deposit_credit: string /* decimal.Decimal */ + rpl_stake: { + min: string /* decimal.Decimal */ + max: string /* decimal.Decimal */ + } +} +export type InternalGetValidatorDashboardNodeRocketPoolResponse = ApiDataResponse +export interface VDBRocketPoolMinipoolsTableRow { + node: Address + validator_index: number /* uint64 */ + minipool_status: 'initialized' | 'prelaunch' | 'staking' | 'withdrawable' | 'dissolved' + validator_status: + | 'slashed' + | 'exited' + | 'deposited' + | 'pending' + | 'slashing_offline' + | 'slashing_online' + | 'exiting_offline' + | 'exiting_online' + | 'active_offline' + | 'active_online' + group_id: number /* uint64 */ + deposit: string /* decimal.Decimal */ + commission: number /* float64 */ + created_timestamp: number /* int64 */ + penalties: number /* uint64 */ +} +export type InternalGetValidatorDashboardRocketPoolMinipoolsResponse = ApiPagingResponse +/** + * ------------------------------------------------------------ + * Manage Modal + */ +export interface VDBManageValidatorsTableRow { + index: number /* uint64 */ + public_key: PubKey + group_id: number /* uint64 */ + balance: string /* decimal.Decimal */ + status: + | 'slashed' + | 'exited' + | 'deposited' + | 'pending' + | 'slashing_offline' + | 'slashing_online' + | 'exiting_offline' + | 'exiting_online' + | 'active_offline' + | 'active_online' + queue_position?: number /* uint64 */ + withdrawal_credential: Hash +} +export type InternalGetValidatorDashboardValidatorsResponse = ApiPagingResponse +/** + * ------------------------------------------------------------ + * Misc. + */ +export interface VDBPostReturnData { + id: number /* uint64 */ + user_id: number /* uint64 */ + name: string + network: number /* uint64 */ + created_at: number /* int64 */ +} +export interface VDBPostCreateGroupData { + id: number /* uint64 */ + name: string +} +export interface VDBPostValidatorsData { + public_key: string + group_id: number /* uint64 */ +} diff --git a/src/app/requests/v2-auth.ts b/src/app/requests/v2-auth.ts new file mode 100644 index 00000000..68710304 --- /dev/null +++ b/src/app/requests/v2-auth.ts @@ -0,0 +1,49 @@ +// Copyright (C) 2024 bitfly explorer GmbH +// +// This file is part of Beaconchain Dashboard. +// +// Beaconchain Dashboard is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Beaconchain Dashboard is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Beaconchain Dashboard. If not, see . + +import { Response } from '@services/api.service' +import { APIRequest, Method } from './requests' + +export interface V2AuthResponse { + Session: string +} + +export class MigrateV1AuthToV2 extends APIRequest { + resource = 'mobile/equivalent-exchange' + method = Method.POST + requiresAuth = true // important for v2 still + + constructor(refreshToken: string, deviceID: string, deviceName: string) { + super() + this.postData = { + refresh_token: refreshToken, + client_id: deviceID, + client_name: deviceName, + } + } + + parseBase(response: Response, hasDataStatus = true): V2AuthResponse | null { + if (!this.wasSuccessful(response, hasDataStatus)) { + return null + } + + if (response && response.data) { + return response.data as V2AuthResponse + } + return null + } +} diff --git a/src/app/requests/v2-blocks.ts b/src/app/requests/v2-blocks.ts new file mode 100644 index 00000000..6a5450d7 --- /dev/null +++ b/src/app/requests/v2-blocks.ts @@ -0,0 +1,47 @@ +// Copyright (C) 2024 bitfly explorer GmbH +// +// This file is part of Beaconchain Dashboard. +// +// Beaconchain Dashboard is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Beaconchain Dashboard is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Beaconchain Dashboard. If not, see . + +import { APIRequest, Method } from './requests' +import { BlockOverview } from './types/block' +import { VDBBlocksTableRow } from './types/validator_dashboard' +import { dashboardID, networkID, setID } from './v2-dashboard' + +export class V2DashboardBlocks extends APIRequest { + resource = 'validator-dashboards/{id}/blocks' + method = Method.GET + + constructor(id: dashboardID, cursor: string, limit: number = 10, sort: string = 'block:desc') { + super() + this.resource = setID(this.resource, id) + this.resource += '?limit=' + limit + this.resource += '&sort=' + sort + if (cursor !== undefined) { + this.resource += '&cursor=' + cursor + } + } +} + +export class V2BlockOverview extends APIRequest { + resource = 'networks/{network}/blocks/{block}/overview' + method = Method.GET + + constructor(network: networkID, block: number) { + super() + this.resource = this.resource.replace('{network}', network.toString()) + this.resource = this.resource.replace('{block}', block.toString()) + } +} diff --git a/src/app/requests/v2-dashboard.ts b/src/app/requests/v2-dashboard.ts new file mode 100644 index 00000000..639685c3 --- /dev/null +++ b/src/app/requests/v2-dashboard.ts @@ -0,0 +1,330 @@ +// Copyright (C) 2024 bitfly explorer GmbH +// +// This file is part of Beaconchain Dashboard. +// +// Beaconchain Dashboard is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Beaconchain Dashboard is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Beaconchain Dashboard. If not, see . + +import { encodeDashboardID } from '@utils/DashboardHelper' +import { APIRequest, Method, NoContent } from './requests' +import { ChartData } from './types/common' +import { + VDBGroupSummaryData, + VDBOverviewData, + VDBPostCreateGroupData, + VDBPostReturnData, + VDBPostValidatorsData, + VDBRocketPoolTableRow, + VDBSummaryTableRow, + VDBSummaryValidatorsData, +} from './types/validator_dashboard' +import { MobileValidatorDashboardValidatorsTableRow } from './types/mobile' +import { SlotVizEpoch } from './types/slot_viz' + +export type dashboardID = string | number | number[] +export type networkID = string | number +export enum Period { + AllTime = 'all_time', + Last1h = 'last_1h', + Last24h = 'last_24h', + Last7d = 'last_7d', + Last30d = 'last_30d', +} + +export enum EfficiencyType { + All = 'all', + Attestation = 'attestation', + Sync = 'sync', + Proposal = 'proposal', +} + +export enum Aggregation { + Epoch = 'epoch', + Hourly = 'hourly', + Daily = 'daily', + Weekly = 'weekly', +} + +export class V2DashboardOverview extends APIRequest { + resource = 'validator-dashboards/{id}' + method = Method.GET + updatesLastRefreshState = true + + constructor(id: dashboardID) { + super() + this.resource = setID(this.resource, id) + this.resource += '?modes=rocket_pool' + } +} + +export class V2DashboardSummaryTable extends APIRequest { + resource = 'validator-dashboards/{id}/summary' + method = Method.GET + updatesLastRefreshState = true + + sortResultFn = function (a: VDBSummaryTableRow, b: VDBSummaryTableRow) { + // sort by group_id asc + if (a.group_id < b.group_id) return -1 + if (a.group_id > b.group_id) return 1 + return 0 + } + + constructor(id: dashboardID, period: Period, limit?: number) { + super() + this.resource = setID(this.resource, id) + '?period=' + period + if (limit) this.resource += '&limit=' + limit + } +} + +export class V2DashboardSummaryGroupTable extends APIRequest { + resource = 'validator-dashboards/{id}/groups/{group_id}/summary' + method = Method.GET + + constructor(id: dashboardID, groupID: number, period: Period, limit?: number) { + super() + this.resource = setID(this.resource, id).replace('{group_id}', groupID + '') + '?period=' + period + if (limit) this.resource += '&limit=' + limit + } +} + +export class V2DashboardSummaryChart extends APIRequest> { + resource = 'validator-dashboards/{id}/summary-chart' + method = Method.GET + + static SUMMARY_CHART_GROUP_TOTAL = -1 + static SUMMARY_CHART_GROUP_NETWORK_AVERAGE = -2 + + constructor( + id: dashboardID, + efficiencyType: EfficiencyType, + aggregation: Aggregation, + afterTs: number, + beforeTs: number = Math.floor(Date.now() / 1000), + groupIds: number[] = [-1, -2] + ) { + super() + this.resource = setID(this.resource, id) + this.resource = this.resource + '?group_ids=' + groupIds.join(',') + this.resource = this.resource + '&after_ts=' + Math.floor(afterTs) + this.resource = this.resource + '&before_ts=' + Math.floor(beforeTs) + this.resource = this.resource + '&efficiency_type=' + efficiencyType + this.resource = this.resource + '&aggregation=' + aggregation + } +} + +export class V2DashboardRewardChart extends APIRequest> { + resource = 'validator-dashboards/{id}/rewards-chart' + method = Method.GET + + constructor(id: dashboardID) { + super() + this.resource = setID(this.resource, id) + } +} + +// Validator management +export interface V2AddValidatorToDashboardData { + group_id: number // starts at 0 + validators?: string[] | number[] + deposit_address?: string + withdrawal_address?: string + graffiti?: string +} + +export class V2AddValidatorToDashboard extends APIRequest { + resource = 'validator-dashboards/{id}/validators' + method = Method.POST + expectedResponseStatus: number = 201 // created + + constructor(id: dashboardID, data: V2AddValidatorToDashboardData) { + super() + this.resource = setID(this.resource, id) + this.postData = data + } +} + +export class V2GetValidatorStatusOfGroup extends APIRequest { + resource = 'validator-dashboards/{id}/summary/validators?duty' + method = Method.GET + + constructor(id: dashboardID, groupID: number, period: Period) { + super() + this.resource = setID(this.resource, id) + this.resource += '&group_id=' + groupID + this.resource += '&period=' + period + } +} + +export class V2GetValidatorFromDashboard extends APIRequest { + resource = 'validator-dashboards/{id}/mobile/validators' + method = Method.GET + + constructor( + id: dashboardID, + groupID: number | undefined = undefined, + cursor: string | undefined = undefined, + limit: number = 10, + sort: string = 'index:asc', + period: Period = Period.Last24h + ) { + super() + this.resource = setID(this.resource, id) + if (groupID !== undefined) { + this.resource += '?group_id=' + groupID + } + if (sort !== undefined) { + this.resource += '&sort=' + sort + } + if (limit !== undefined) { + this.resource += '&limit=' + limit + } + if (cursor !== undefined) { + this.resource += '&cursor=' + cursor + } + if (period !== undefined) { + this.resource += '&period=' + period + } + } +} + +export class V2DeleteValidatorFromDashboard extends APIRequest { + resource = 'validator-dashboards/{id}/validators/bulk-deletions' + method = Method.POST + expectedResponseStatus: number = 204 // no content + + constructor(id: dashboardID, validators: number[]) { + super() + this.resource = setID(this.resource, id) + this.postData = { + validators: validators, + } + } +} + +// -- Dashboard management + +export class V2CreateDashboard extends APIRequest { + resource = 'validator-dashboards' + method = Method.POST + expectedResponseStatus: number = 201 // created + + /** + * @param name for the dashboard + * @param network Can be string or network id + */ + constructor(name: string, network: networkID) { + super() + this.postData = { + name: name, + network: network, + } + } +} + +export class V2DeleteDashboard extends APIRequest { + resource = 'validator-dashboards/{id}' + method = Method.DELETE + expectedResponseStatus: number = 204 // no content + + constructor(id: dashboardID) { + super() + this.resource = setID(this.resource, id) + } +} + +export class V2ChangeDashboardName extends APIRequest { + resource = 'validator-dashboards/{id}/name' + method = Method.PUT + + constructor(id: dashboardID, name: string) { + super() + this.resource = setID(this.resource, id) + this.postData = { name: name } + } +} + +// -- Group management + +export class V2AddDashboardGroup extends APIRequest { + resource = 'validator-dashboards/{id}/groups' + method = Method.POST + expectedResponseStatus: number = 201 // created + + constructor(id: dashboardID, name: string) { + super() + this.resource = setID(this.resource, id) + this.postData = { name: name } + } +} + +export class V2DeleteDashboardGroup extends APIRequest { + resource = 'validator-dashboards/{id}/groups/{group_id}' + method = Method.DELETE + expectedResponseStatus: number = 204 // no content + + constructor(id: dashboardID, groupID: number) { + super() + this.resource = setID(this.resource, id).replace('{group_id}', groupID + '') + } +} + +export class V2UpdateDashboardGroup extends APIRequest { + resource = 'validator-dashboards/{id}/groups/{group_id}' + method = Method.PUT + + constructor(id: dashboardID, groupID: number, name: string) { + super() + this.resource = setID(this.resource, id).replace('{group_id}', groupID + '') + this.postData = { name: name } + } +} + +// Rocket Pool + +export class V2DashboardRocketPool extends APIRequest { + resource = 'validator-dashboards/{id}/rocket-pool' + method = Method.GET + + sortResultFn: (a: VDBRocketPoolTableRow, b: VDBRocketPoolTableRow) => number = (a, b) => { + return a.node.hash.localeCompare(b.node.hash) + } + + constructor(id: dashboardID) { + super() + this.resource = setID(this.resource, id) + } +} + +export function setID(resource: string, id: dashboardID): string { + if (typeof id === 'string') { + return resource.replace('{id}', id) + } + if (Array.isArray(id)) { + return resource.replace('{id}', encodeDashboardID(id)) + } + return resource.replace('{id}', id + '') +} + +export class V2SlotViz extends APIRequest { + resource = 'validator-dashboards/{id}/slot-viz' + method = Method.GET + + // does not accept -1 for all groups + constructor(id: dashboardID, groupID: number) { + super() + this.resource = setID(this.resource, id) + if (groupID !== -1) { + this.resource += '?group_ids=' + groupID + } + } +} diff --git a/src/app/requests/v2-general.ts b/src/app/requests/v2-general.ts new file mode 100644 index 00000000..3d8a7811 --- /dev/null +++ b/src/app/requests/v2-general.ts @@ -0,0 +1,46 @@ +// Copyright (C) 2024 bitfly explorer GmbH +// +// This file is part of Beaconchain Dashboard. +// +// Beaconchain Dashboard is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Beaconchain Dashboard is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Beaconchain Dashboard. If not, see . + +import { APIRequest, Method } from './requests' +import { MobileBundleData } from './types/mobile' +import { ProductSummary } from './types/user' + +export class V2ProductSummary extends APIRequest { + resource = 'product-summary' + method = Method.GET +} + +export class V2LatestAppBundle extends APIRequest { + resource = 'mobile/latest-bundle' + method = Method.GET + + constructor(bundleVersion: number, nativeVersion: number, force: boolean = false) { + super() + this.resource += `?bundle_version=${bundleVersion}&native_version=${nativeVersion}&force=${force}` + } +} + +export class V2AckBundleUpdate extends APIRequest { + resource = 'mobile/bundles/{bundle_version}/deliveries' + method = Method.POST + expectedResponseStatus: number = 204 + + constructor(bundleVersion: number) { + super() + this.resource = this.resource.replace('{bundle_version}', bundleVersion.toString()) + } +} diff --git a/src/app/requests/v2-network.ts b/src/app/requests/v2-network.ts new file mode 100644 index 00000000..eb895e99 --- /dev/null +++ b/src/app/requests/v2-network.ts @@ -0,0 +1,24 @@ +// Copyright (C) 2024 bitfly explorer GmbH +// +// This file is part of Beaconchain Dashboard. +// +// Beaconchain Dashboard is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Beaconchain Dashboard is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Beaconchain Dashboard. If not, see . + +import { APIRequest, Method } from './requests' +import { LatestStateData } from './types/latest_state' + +export class V2LatestState extends APIRequest { + resource = 'latest-state' + method = Method.GET +} diff --git a/src/app/requests/v2-notifications.ts b/src/app/requests/v2-notifications.ts new file mode 100644 index 00000000..72123616 --- /dev/null +++ b/src/app/requests/v2-notifications.ts @@ -0,0 +1,113 @@ +// Copyright (C) 2024 bitfly explorer GmbH +// +// This file is part of Beaconchain Dashboard. +// +// Beaconchain Dashboard is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Beaconchain Dashboard is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Beaconchain Dashboard. If not, see . + +import { APIRequest, Method, NoContent } from './requests' +import { + NotificationClientsTableRow, + NotificationDashboardsTableRow, + NotificationMachinesTableRow, + NotificationNetworksTableRow, + NotificationSettings, + NotificationValidatorDashboardDetail, +} from './types/notifications' +import { dashboardID, setID } from './v2-dashboard' + +export class V2SubscribedClients extends APIRequest { + resource = 'users/me/notifications/settings' + method = Method.GET + + constructor(limit: number = 25) { + super() + this.resource += `?limit=${limit}` + } +} + +export class V2ChangeSubscribedClient extends APIRequest { + resource = 'users/me/notifications/settings/clients/' + method = Method.PUT + expectedResponseStatus = 200 + + constructor(clientID: number, enabled: boolean) { + super() + this.resource += `${clientID}` + this.postData = { is_subscribed: enabled } + } +} + +export class V2NotificationDetails extends APIRequest { + resource = 'users/me/notifications/validator-dashboards/{id}/groups/{group_id}/epochs/{epoch}' + method = Method.GET + + constructor(id: dashboardID, groupID: number, epoch: number) { + super() + this.resource = setID(this.resource, id) + this.resource = this.resource.replace('{group_id}', groupID.toString()) + this.resource = this.resource.replace('{epoch}', epoch.toString()) + } +} + +export class V2NotificationsDashboard extends APIRequest { + resource = 'users/me/notifications/dashboards' + method = Method.GET + + constructor(cursor: string, limit: number = 25) { + super() + this.resource += '?limit=' + limit + if (cursor !== undefined) { + this.resource += '&cursor=' + cursor + } + } +} + +export class V2NotificationsMachines extends APIRequest { + resource = 'users/me/notifications/machines' + method = Method.GET + + constructor(cursor: string, limit: number = 25) { + super() + this.resource += '?limit=' + limit + if (cursor !== undefined) { + this.resource += '&cursor=' + cursor + } + } +} + +export class V2NotificationsClients extends APIRequest { + resource = 'users/me/notifications/clients' + method = Method.GET + + constructor(cursor: string, limit: number = 25) { + super() + this.resource += '?limit=' + limit + if (cursor !== undefined) { + this.resource += '&cursor=' + cursor + } + } +} + +export class V2NotificationsNetworks extends APIRequest { + resource = 'users/me/notifications/networks' + method = Method.GET + + constructor(cursor: string, limit: number = 25) { + super() + this.resource += '?limit=' + limit + if (cursor !== undefined) { + this.resource += '&cursor=' + cursor + } + } +} diff --git a/src/app/requests/v2-search.ts b/src/app/requests/v2-search.ts new file mode 100644 index 00000000..2fe7330d --- /dev/null +++ b/src/app/requests/v2-search.ts @@ -0,0 +1,69 @@ +// Copyright (C) 2024 bitfly explorer GmbH +// +// This file is part of Beaconchain Dashboard. +// +// Beaconchain Dashboard is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Beaconchain Dashboard is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Beaconchain Dashboard. If not, see . + +import { APIRequest, Method } from './requests' +import { + SearchValidator, + SearchValidatorList, + SearchValidatorsByDepositAddress, + SearchValidatorsByGraffiti, + SearchValidatorsByWithdrwalCredential, +} from './types/search' +import { networkID } from './v2-dashboard' + +// possible search types for a search request +export enum searchType { + validatorByIndex = 'validator_by_index', + validatorByPublicKey = 'validator_by_public_key', + validatorsByDepositAddress = 'validators_by_deposit_address', + validatorsByDepositEnsName = 'validators_by_deposit_ens_name', + validatorsByWithdrawalCredential = 'validators_by_withdrawal_credential', + validatorsByWithdrawalAddress = 'validators_by_withdrawal_address', + validatorsByWithdrawalEns = 'validators_by_withdrawal_ens_name', + validatorsByGraffiti = 'validators_by_graffiti', + validatorList = 'validator_list', +} + +// Possible data types of a search response +export enum SearchResponseType { + validator = 'validator', + validatorList = 'validator_list', + validatorsByDepositAddress = 'validators_by_deposit_address', + validatorsByWithdrawalCredential = 'validators_by_withdrawal_credential', + validatorsByGraffiti = 'validators_by_graffiti', +} + +export type SearchResultData = + | { type: 'validator'; chain_id: number; value: SearchValidator } + | { type: 'validator_list'; chain_id: number; value: SearchValidatorList } + | { type: 'validators_by_deposit_address'; chain_id: number; value: SearchValidatorsByDepositAddress } + | { type: 'validators_by_withdrawal_credential'; chain_id: number; value: SearchValidatorsByWithdrwalCredential } + | { type: 'validators_by_graffiti'; chain_id: number; value: SearchValidatorsByGraffiti } + +export class V2SearchValidators extends APIRequest { + resource = 'search' + method = Method.POST + + constructor(query: string, networks: networkID[], types: searchType[] | undefined = undefined) { + super() + if (types) { + this.postData = { input: query, networks: networks, types: types } + } else { + this.postData = { input: query, networks: networks } + } + } +} diff --git a/src/app/requests/v2-user.ts b/src/app/requests/v2-user.ts new file mode 100644 index 00000000..4dcb1509 --- /dev/null +++ b/src/app/requests/v2-user.ts @@ -0,0 +1,88 @@ +// Copyright (C) 2024 bitfly explorer GmbH +// +// This file is part of Beaconchain Dashboard. +// +// Beaconchain Dashboard is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Beaconchain Dashboard is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Beaconchain Dashboard. If not, see . + +import { APIRequest, Method, NoContent } from './requests' +import { Response } from '@services/api.service' +import { UserInfo } from './types/user' +import { UserDashboardsData } from './types/dashboard' +import { StatsResponse } from '../controllers/MachineController' + +// export class V2GetDashboards extends APIRequest { +// resource = 'users/me/dashboards' +// method = Method.GET +// requiresAuth = true +// } + +export class V2Me extends APIRequest { + resource = 'users/me' + method = Method.GET +} + +export class V2MyDashboards extends APIRequest { + resource = 'users/me/dashboards' + method = Method.GET +} + +export class V2RegisterPushNotificationToken extends APIRequest { + resource = 'users/me/notifications/settings/paired-devices/{client_id}/token' + method = Method.PUT + + parse(response: Response): NoContent[] { + if (response && response.data) return response.data as NoContent[] + return null + } + + constructor(token: string, clientID: string) { + super() + this.resource = this.resource.replace('{client_id}', clientID) + this.postData = { token: token } + } +} + +export class V2MyMachines extends APIRequest { + resource = 'users/me/machine-metrics' + method = Method.GET + + constructor(offset: number, limit: number) { + super() + this.resource += `?offset=${offset}&limit=${limit}` + } +} + +export class V2PurchaseValidation extends APIRequest { + resource = 'mobile/purchase' + method = Method.POST + + constructor(subscriptionData: SubscriptionData) { + super() + this.postData = subscriptionData + } +} + +export interface SubscriptionTransaction { + id: string + receipt: string + type: string +} + +export interface SubscriptionData { + currency: string + id: string + priceMicros: number + transaction: SubscriptionTransaction + valid: boolean +} diff --git a/src/app/services/alert.service.ts b/src/app/services/alert.service.ts index 8b05d2ae..7fe4e472 100644 --- a/src/app/services/alert.service.ts +++ b/src/app/services/alert.service.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -23,12 +22,16 @@ import { AlertController, LoadingController } from '@ionic/angular' export const VALIDATORUTILS = 140 export const PURCHASEUTILS = 150 +export const DASHBOARD_SELECTOR = 160 @Injectable({ providedIn: 'root', }) export class AlertService { - constructor(private alertController: AlertController, private loadingController: LoadingController) {} + constructor( + private alertController: AlertController, + private loadingController: LoadingController + ) {} async showError(title: string, message: string, code: number) { const alert = await this.alertController.create({ @@ -40,7 +43,7 @@ export class AlertService { await alert.present() } - async showSelect(title: string, inputs: unknown[], callback: (data) => void) { + async showSelect(title: string, inputs: unknown[], callback: (data: unknown) => void) { const alert = await this.alertController.create({ header: title, inputs: inputs, @@ -55,6 +58,29 @@ export class AlertService { await alert.present() } + async showSelectWithCancel(title: string, inputs: unknown[], callback: (data: unknown) => void) { + const alert = await this.alertController.create({ + header: title, + inputs: inputs, + buttons: [ + { + text: 'Cancel', + role: 'cancel', + cssClass: 'secondary', + handler: () => { + return + }, + }, + { + text: 'OK', + handler: callback, + }, + ], + }) + + await alert.present() + } + async showInfo(title: string, message: string, customCss: '' | 'bigger-alert' = '') { const alert = await this.alertController.create({ cssClass: customCss, @@ -66,7 +92,31 @@ export class AlertService { await alert.present() } - async confirmDialog(title: string, message: string, confirmButton: string, confirmCallback: () => void) { + async noChoiceDialog(title: string, message: string, action: () => void, customCss: '' | 'bigger-alert' = '') { + const alert = await this.alertController.create({ + cssClass: customCss, + header: title, + message: message, + backdropDismiss: false, + buttons: [ + { + text: 'OK', + handler: action, + }, + ], + }) + + await alert.present() + } + + async confirmDialog( + title: string, + message: string, + confirmButton: string, + confirmCallback: () => void, + customCSS: string | undefined = undefined, + cancelCallback: () => void = null + ) { const alert = await this.alertController.create({ cssClass: 'my-custom-class', header: title, @@ -77,11 +127,15 @@ export class AlertService { role: 'cancel', cssClass: 'secondary', handler: () => { + if (cancelCallback) { + cancelCallback() + } return }, }, { text: confirmButton, + cssClass: customCSS, handler: confirmCallback, }, ], @@ -90,6 +144,31 @@ export class AlertService { await alert.present() } + async confirmDialogReverse(title: string, message: string, confirmButton: string, confirmCallback: () => void, customCSS: string | null = null) { + const alert = await this.alertController.create({ + cssClass: 'my-custom-class', + header: title, + message: message, + buttons: [ + { + text: confirmButton, + cssClass: customCSS, + handler: confirmCallback, + }, + { + text: 'Cancel', + role: 'cancel', + cssClass: 'secondary', + handler: () => { + return + }, + }, + ], + }) + + await alert.present() + } + async presentLoading(message: string) { return await this.loadingController.create({ cssClass: 'my-custom-class', diff --git a/src/app/services/alerts.service.spec.ts b/src/app/services/alerts.service.spec.ts deleted file mode 100644 index 4f31008e..00000000 --- a/src/app/services/alerts.service.spec.ts +++ /dev/null @@ -1,36 +0,0 @@ -/* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) - * // - * // This file is part of Beaconchain Dashboard. - * // - * // Beaconchain Dashboard is free software: you can redistribute it and/or modify - * // it under the terms of the GNU General Public License as published by - * // the Free Software Foundation, either version 3 of the License, or - * // (at your option) any later version. - * // - * // Beaconchain Dashboard is distributed in the hope that it will be useful, - * // but WITHOUT ANY WARRANTY; without even the implied warranty of - * // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * // GNU General Public License for more details. - * // - * // You should have received a copy of the GNU General Public License - * // along with Beaconchain Dashboard. If not, see . - */ - -import { TestBed } from '@angular/core/testing' - -import { AlertService } from './alert.service' - -describe('AlertService', () => { - let service: AlertService - - beforeEach(() => { - TestBed.configureTestingModule({}) - service = TestBed.inject(AlertService) - }) - - it('should be created', () => { - expect(service).toBeTruthy() - }) -}) diff --git a/src/app/services/api.service.spec.ts b/src/app/services/api.service.spec.ts deleted file mode 100644 index 4131b65c..00000000 --- a/src/app/services/api.service.spec.ts +++ /dev/null @@ -1,36 +0,0 @@ -/* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) - * // - * // This file is part of Beaconchain Dashboard. - * // - * // Beaconchain Dashboard is free software: you can redistribute it and/or modify - * // it under the terms of the GNU General Public License as published by - * // the Free Software Foundation, either version 3 of the License, or - * // (at your option) any later version. - * // - * // Beaconchain Dashboard is distributed in the hope that it will be useful, - * // but WITHOUT ANY WARRANTY; without even the implied warranty of - * // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * // GNU General Public License for more details. - * // - * // You should have received a copy of the GNU General Public License - * // along with Beaconchain Dashboard. If not, see . - */ - -import { TestBed } from '@angular/core/testing' - -import { ApiService } from './api.service' - -describe('ApiService', () => { - let service: ApiService - - beforeEach(() => { - TestBed.configureTestingModule({}) - service = TestBed.inject(ApiService) - }) - - it('should be created', () => { - expect(service).toBeTruthy() - }) -}) diff --git a/src/app/services/api.service.ts b/src/app/services/api.service.ts index 4952cfb7..b4cab84f 100644 --- a/src/app/services/api.service.ts +++ b/src/app/services/api.service.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -18,42 +17,58 @@ * // along with Beaconchain Dashboard. If not, see . */ -import { Injectable } from '@angular/core' -import { APIRequest, Method, RefreshTokenRequest } from '../requests/requests' +import { Injectable, WritableSignal } from '@angular/core' +import { APIRequest, ApiResult, Method, RefreshTokenRequest } from '@requests/requests' import { StorageService } from './storage.service' import { ApiNetwork } from '../models/StorageTypes' import { Mutex } from 'async-mutex' -import { findConfigForKey, MAP } from '../utils/NetworkData' -import { CacheModule } from '../utils/CacheModule' +import { CHAIN_NETWORKS, findChainNetworkById, findConfigForKey, MAP } from '@utils/NetworkData' +import { CacheModule } from '@utils/CacheModule' import { Capacitor, HttpOptions } from '@capacitor/core' - +import { CapacitorCookies } from '@capacitor/core' +import { LatestStateData } from '@requests/types/latest_state' +import { V2LatestState } from '@requests/v2-network' +import { environment } from 'src/environments/environment' +import { MigrateV1AuthToV2 } from '@requests/v2-auth' +import { V2MyDashboards } from '@requests/v2-user' +import { UserDashboardsData, ValidatorDashboard } from '@requests/types/dashboard' const LOGTAG = '[ApiService]' const SERVER_TIMEOUT = 25000 +const R = 2 + @Injectable({ providedIn: 'root', }) export class ApiService extends CacheModule { - networkConfig: ApiNetwork - - public connectionStateOK = true + networkConfig: ApiNetwork // todo signal? private awaitingResponses: Map = new Map() - debug = false - public lastRefreshed = 0 // only updated by calls that have the updatesLastRefreshState flag enabled private lastCacheInvalidate = 0 + private sessionCookie: string + private apiUserKey: string = null + private apiAccessKey: string = null + + // holds all cache keys if executed via execute2 and provided with a cacheKey + private associatedCacheKeyMap: Map> = new Map() + + // debug + debug = false + private lastCsrfHeader: Map = new Map() + private r = 8 + constructor(private storage: StorageService) { super('api', 6 * 60 * 1000, storage, 1000, false) - this.storage.getBooleanSetting('migrated_4_4_0', false).then((migrated) => { + this.storage.getBooleanSetting('migrated_5_0_0', false).then((migrated) => { if (!migrated) { this.clearHardCache() - console.info('Cleared hard cache storage as part of 4.4.0 migration') - this.storage.setBooleanSetting('migrated_4_4_0', true) + console.info('Cleared hard cache storage as part of 5.0.0 migration') + this.storage.setBooleanSetting('migrated_5_0_0', true) } }) @@ -64,10 +79,6 @@ export class ApiService extends CacheModule { this.lastCacheInvalidate = Date.now() } - mayInvalidateOnFaultyConnectionState() { - if (!this.connectionStateOK) this.invalidateCache() - } - invalidateCache() { if (this.lastCacheInvalidate + 40000 < Date.now()) { this.lastCacheInvalidate = Date.now() @@ -77,30 +88,68 @@ export class ApiService extends CacheModule { } } + storeInHardCache(cacheKey: string): boolean { + return ( + (cacheKey.indexOf('dashboards') >= 0 && cacheKey.indexOf('slot-viz') < 0) || // do not save slotviz to hardcache + cacheKey.indexOf('produced?offset=0') >= 0 || // first page of blocks page // todo v2 + (cacheKey.indexOf('beaconcha.in') < 0 && cacheKey.indexOf('gnosischa.in') < 0 && cacheKey.indexOf('ads.bitfly') < 0) + ) + } + async initialize() { - this.networkConfig = await this.storage.getNetworkPreferences().then((config) => { + await this.loadNetworkConfig() + await Promise.all([this.initV2Cookies(), this.init()]) + this.apiUserKey = await this.getApiKey() + this.apiAccessKey = this.use(environment.API_ACCESS_KEY) + console.log('API SERVICE INITIALISEDs', this.apiAccessKey, this.r) + return this + } + + async loadNetworkConfig() { + async function getConfig(storage: StorageService, config: ApiNetwork) { const temp = findConfigForKey(config.key) if (temp) { + if (temp.v2NetworkConfigKey && (await storage.isV2())) { + const v2Config = findConfigForKey(config.v2NetworkConfigKey) + if (v2Config) { + return v2Config + } + } return temp } return config - }) - await this.init() - console.log('API SERVICE INITIALISED') + } + + this.networkConfig = await getConfig(this.storage, await this.storage.getNetworkPreferences()) + this.storage.setWidgetNetworkConfig(this.networkConfig) } - networkName = null + networkName: string = null getNetworkName(): string { const temp = this.networkConfig.key this.networkName = temp return temp } + findParentNetworkKey(childNetwork: ApiNetwork): ApiNetwork { + for (const entry of MAP) { + if (entry.v2NetworkConfigKey?.replace('_prod', '') == childNetwork.key) { + return entry + } + } + return childNetwork + } + + getParentNetwork(): ApiNetwork { + return this.findParentNetworkKey(this.networkConfig) + } + getNetwork(): ApiNetwork { const temp = this.networkConfig return temp } + /** @deprecated v1 */ private async getAuthHeader(isTokenRefreshCall: boolean) { let user = await this.storage.getAuthUser() if (!user || !user.accessToken) return null @@ -131,6 +180,33 @@ export class ApiService extends CacheModule { } } + public async initV2Cookies() { + this.r = 3 + const user = await this.storage.getAuthUserv2() + this.r += this.r * R - R ** R + if (!user || !user.Session) return + + console.log('init cookies', this.networkConfig.protocol + '://' + this.networkConfig.net + this.networkConfig.host, user.Session) + + await CapacitorCookies.clearAllCookies() + + for (const network of MAP) { + // only v2 networks with https + if (!network.v2NetworkConfigKey && network.protocol == 'https') { + console.log('init cookies', network.protocol + '://' + network.net + network.host, user.Session && user.Session.length > 0) + + await CapacitorCookies.setCookie({ + url: network.protocol + '://' + network.net + network.host, + key: 'session_id', + value: user.Session, + }) + } + } + + this.sessionCookie = user.Session + } + + /** @deprecated v1 */ async refreshToken() { const user = await this.storage.getAuthUser() if (!user || !user.refreshToken) { @@ -141,9 +217,8 @@ export class ApiService extends CacheModule { const now = Date.now() const req = new RefreshTokenRequest(user.refreshToken, Capacitor.getPlatform() == 'ios') - const resp = await this.execute(req) - const response = req.parse(resp) - const result = response[0] + const resp = await this.executeLegacy(req) + const result = req.parse(resp) // Intention to not log access token in app logs if (this.debug) { @@ -168,15 +243,15 @@ export class ApiService extends CacheModule { return user } - private async lockOrWait(resource) { - if (!this.awaitingResponses[resource]) { - this.awaitingResponses[resource] = new Mutex() + private async lockOrWait(resource: string) { + if (!this.awaitingResponses.get(resource)) { + this.awaitingResponses.set(resource, new Mutex()) } - await this.awaitingResponses[resource].acquire() + await this.awaitingResponses.get(resource).acquire() } - private unlock(resource) { - this.awaitingResponses[resource].release() + private unlock(resource: string) { + this.awaitingResponses.get(resource).release() } isNotEthereumMainnet(): boolean { @@ -188,74 +263,250 @@ export class ApiService extends CacheModule { return !this.isNotEthereumMainnet() } - private getCacheKey(request: APIRequest): string { + private getCacheKey(request: APIRequest, networkConfig: ApiNetwork): string { if (request.method == Method.GET) { - return request.method + this.getResourceUrl(request.resource, request.endPoint) + if (request.customCacheKey) { + return request.customCacheKey + } + return request.method + this.getResourceUrl(request.resource, request.endPoint, networkConfig) } else if (request.cacheablePOST) { - return request.method + this.getResourceUrl(request.resource, request.endPoint) + JSON.stringify(request.postData) + return request.method + this.getResourceUrl(request.resource, request.endPoint, networkConfig) + JSON.stringify(request.postData) } return null } - async execute(request: APIRequest): Promise { - await this.initialized + async clearAllAssociatedCacheKeys(associatedCacheKey: string) { + const keys = this.associatedCacheKeyMap.get(associatedCacheKey) + if (keys) { + for (const key of keys) { + await this.putCache(key, null, 0) + this.findAndClearAssociatedKeyInOtherKeys(associatedCacheKey) + } + this.associatedCacheKeyMap.delete(associatedCacheKey) + } + } + + private findAndClearAssociatedKeyInOtherKeys(associatedCacheKey: string) { + for (const [_, value] of this.associatedCacheKeyMap) { + if (value.has(associatedCacheKey)) { + value.delete(associatedCacheKey) + } + } + } + + /** + * Shortcut to execute(new Request()).then(data => writeableSignal.set(data.data)) + * Executes requests and writes the data to the signal + * @param request ApiRequest + * @param s signal to write to + * @param associatedCacheKey optional cache key to invalidate + * @returns ApiResult + */ + set(request: APIRequest, s: WritableSignal, associatedCacheKey: string = null, chainID: number = undefined) { + return this.getExecuteProvider(request, associatedCacheKey, chainID).then((data) => { + if (data.error) { + return data + } + s.set(data.data) + return data + }) + } + + getExecuteProvider(request: APIRequest, associatedCacheKey: string = null, chainID: number = undefined) { + if (chainID === undefined) { + return this.execute(request, associatedCacheKey) + } else { + return this.executeOnChainID(request, associatedCacheKey, chainID) + } + } + + /** + * This method can be used to break out of the global current network config and execute + * a request on the beaconcha.in endpoint associated with a given chain id + * @param request + * @param associatedCacheKey + * @param chainID + * @returns + */ + public executeOnChainID(request: APIRequest, associatedCacheKey: string, chainID: number) { + const chain = findChainNetworkById(chainID) + const v1network = findConfigForKey(chain.legacyKey) + const v2network = findConfigForKey(v1network.v2NetworkConfigKey) + console.log('v2 network config for chain id', chainID, v2network) + return this.execute(request, associatedCacheKey, v2network) + } + + /** + * This method ignored current network config and queries all networks + * whether they contain dashboards. In the future an API endpoint will be provided to query across + * networks. + */ + async getAllUserDashboards(associatedCacheKey: string): Promise> { + const requests = CHAIN_NETWORKS.map((item) => this.executeOnChainID(new V2MyDashboards(), associatedCacheKey, item.id)) + const results = await Promise.allSettled(requests) + + let dashboards: ValidatorDashboard[] = [] + let error: Error = null + + for (const result of results) { + if (result.status === 'fulfilled') { + console.log('dashboard response', result) + if (result.value.error) { + error = result.value.error + break + } + + if (result.value.data.validator_dashboards) { + dashboards = dashboards.concat(result.value.data.validator_dashboards) + } + } else if (result.status === 'rejected') { + console.log(`Promise rejected:`, result.reason) + } + } + + return { + error: dashboards.length > 0 ? null : error, + data: { + validator_dashboards: dashboards, + account_dashboards: [], + }, + cached: false, + paging: null, + } + } + + async execute(request: APIRequest, associatedCacheKey: string = null, networkConfig: ApiNetwork = this.networkConfig): Promise> { + try { + if (request.method != Method.GET && !this.lastCsrfHeader.get(networkConfig.host)) { + // use latest state to get csrf token for this network + await this.executeUnhandled(new V2LatestState(), networkConfig) + } - if (!this.connectionStateOK) { - this.invalidateCache() + const response = await this.executeUnhandled(request, networkConfig) + if (associatedCacheKey) { + if (this.associatedCacheKeyMap.has(associatedCacheKey)) { + this.associatedCacheKeyMap.get(associatedCacheKey).add(this.getCacheKey(request, networkConfig)) + } else { + this.associatedCacheKeyMap.set(associatedCacheKey, new Set([this.getCacheKey(request, networkConfig)])) + } + } + return request.parse2(response) + } catch (e) { + return { + error: e, + data: null, + cached: false, + paging: null, + } } + } - await this.lockOrWait(request.resource) + /** + * Old v1 execute method, should not be used any more unless for v1 migration. + * @deprecated Use execute instead + * */ + private async executeLegacy(request: APIRequest): Promise { + try { + return await this.executeUnhandled(request) + } catch (e) { + console.error('Error in execute', e) + return null + } + } + + private async executeUnhandled(request: APIRequest, networkConfig: ApiNetwork = this.networkConfig): Promise { + await this.initialized + + const lockKey = networkConfig.endpoint + request.resource + await this.lockOrWait(lockKey) // no parallel requests to the same resource + + if (environment.dangerousCookiePassing) { + // This is a dangerous setting, only for development purposes + // This must never be enabled in production + console.warn('DANGEROUS COOKIE PASSING ENABLED') + } try { - // If cached and not stale, return cache - const cached = (await this.getCache(this.getCacheKey(request))) as Response - if (cached) { - if (this.lastRefreshed == 0) this.lastRefreshed = Date.now() - cached.cached = true - return cached + if (request.allowCachedResponse) { + // If cached and not stale, return cache + const cached = (await this.getCache(this.getCacheKey(request, networkConfig))) as Response + if (cached) { + if (this.lastRefreshed == 0) this.lastRefreshed = Date.now() + cached.cached = true + return cached + } } const options = request.options - // second is special case for notifications - // notifications are rescheduled if response is != 200 - // but user can switch network in the mean time, so we need to reapply the network - // the user was currently on, when they set the notification toggle - // hence the additional request.requiresAuth + // endPoint default = network specific beaconcha.in if (request.endPoint == 'default' || request.requiresAuth) { - const authHeader = await this.getAuthHeader(request instanceof RefreshTokenRequest) - - if (authHeader) { - const headers = { ...options.headers, ...authHeader } - options.headers = headers + // special case, migration needs the v1 token + csrf token + if (request instanceof MigrateV1AuthToV2) { + const authHeader = await this.getAuthHeader(false) + if (authHeader) { + const headers = { ...options.headers, ...authHeader } + options.headers = headers + } + + options.headers = { ...options.headers, 'X-Csrf-Token': this.lastCsrfHeader.get(networkConfig.host) } + } else if (await this.storage.isV2()) { + if (!this.sessionCookie) { + await this.initV2Cookies() + } + + if (request.method != Method.GET) { + options.headers = { ...options.headers, 'X-Csrf-Token': this.lastCsrfHeader.get(networkConfig.host) } + } + + // DANGEROUS + // Strictly for development purposes. Intention is this to be used in local + // setup to develop in browser instead of native device. Since fetch does not allow + // setting cookies yourself, we can use the X-Cookie header with a reverse proxy to + // get sessions working in development environment. + if (environment.dangerousCookiePassing) { + let sessionExtra = '' + if (this.sessionCookie) { + sessionExtra = 'session_id=' + this.sessionCookie + '; ' + } + + options.headers = { ...options.headers, 'X-Cookie': sessionExtra } + } else { + if (this.apiAccessKey) { + options.headers = { ...options.headers, 'x-mobile-token': this.apiAccessKey } + } + } + } else { + const authHeader = await this.getAuthHeader(request instanceof RefreshTokenRequest) + + if (authHeader) { + const headers = { ...options.headers, ...authHeader } + options.headers = headers + } } } console.log(LOGTAG + ' Send request: ' + request.resource, request.method, request) const startTs = Date.now() - let response: Promise - switch (request.method) { - case Method.GET: - response = this.get(request.resource, request.endPoint, request.ignoreFails, options) - break - case Method.POST: - response = this.post(request.resource, request.postData, request.endPoint, request.ignoreFails, options) - break - default: - throw 'Unsupported method: ' + request.method - } + const response = this.doHttp(request.method, request.resource, request.postData, request.endPoint, options, networkConfig) const result = await response - this.updateConnectionState(request.ignoreFails, result && result.data && !!result.url) if (!result) { console.log(LOGTAG + ' Empty Response: ' + request.resource, 'took ' + (Date.now() - startTs) + 'ms') return result } - if ((request.method == Method.GET || request.cacheablePOST) && result && result.status == 200 && result.data) { - this.putCache(this.getCacheKey(request), result, request.maxCacheAge) + if ((request.method == Method.GET || request.cacheablePOST) && result && result.status == request.expectedResponseStatus && result.data) { + this.putCache(this.getCacheKey(request, networkConfig), result, request.maxCacheAge) + } + + if (request.method == Method.GET) { + const temp = result.headers.get('x-csrf-token') + if (temp) { + this.lastCsrfHeader.set(networkConfig.host, temp) + } } if (request.updatesLastRefreshState) this.updateLastRefreshed(result) @@ -266,80 +517,93 @@ export class ApiService extends CacheModule { return result } finally { - this.unlock(request.resource) + this.unlock(lockKey) } } - async clearSpecificCache(request: APIRequest) { - await this.putCache(this.getCacheKey(request), null, request.maxCacheAge) - } + private async doHttp( + method: Method, + resource: string, + data: unknown, + endpoint = 'default', + options: HttpOptions = { url: null, headers: {} }, + networkConfig: ApiNetwork + ) { + let body: BodyInit = undefined + if (method == Method.POST || method == Method.PUT) { + if (!Object.prototype.hasOwnProperty.call(options.headers, 'Content-Type')) { + if (!(data instanceof FormData)) { + options.headers = { ...options.headers, ...{ 'Content-Type': this.getContentTypeBasedOnData(data) } } + } + } + body = this.formatPostData(data, resource) + } - private updateLastRefreshed(response: Response) { - if (response && response.status == 200) { - this.lastRefreshed = Date.now() + if (this.apiUserKey && endpoint == 'default') { + options.headers = { + ...options.headers, + ...{ + Authorization: 'Bearer ' + this.apiUserKey, + }, + } } - } - private async get(resource: string, endpoint = 'default', ignoreFails = false, options: HttpOptions = { url: null, headers: {} }) { - const result = await fetch(this.getResourceUrl(resource, endpoint), { - method: 'GET', + const isV2 = await this.storage.isV2() + const result = await fetch(this.getResourceUrl(resource, endpoint, networkConfig), { + method: Method[method], headers: options.headers, - }).catch((err) => { - this.updateConnectionState(ignoreFails, false) - console.warn('Connection err', err) + mode: 'cors', + body: body, + credentials: endpoint == 'default' && isV2 ? 'include' : 'omit', }) if (!result) return null - return await this.validateResponse(ignoreFails, result) + return await this.validateResponse(result) } - private async post(resource: string, data, endpoint = 'default', ignoreFails = false, options: HttpOptions = { url: null, headers: {} }) { - if (!Object.prototype.hasOwnProperty.call(options.headers, 'Content-Type')) { - if (!(data instanceof FormData)) { - options.headers = { ...options.headers, ...{ 'Content-Type': this.getContentTypeBasedOnData(data) } } - } - } + async clearSpecificCache(request: APIRequest, networkConfig: ApiNetwork = this.networkConfig) { + await this.putCache(this.getCacheKey(request, networkConfig), null, request.maxCacheAge) + } - const result = await fetch(this.getResourceUrl(resource, endpoint), { - method: 'POST', - headers: options.headers, - body: this.formatPostData(data, resource), - }).catch((err) => { - this.updateConnectionState(ignoreFails, false) - console.warn('Connection err', err) - }) - if (!result) return null - return await this.validateResponse(ignoreFails, result) + private updateLastRefreshed(response: Response) { + if (response && response.status == 200) { + this.lastRefreshed = Date.now() + } } + /** @deprecated not needed in v2 any more */ private getContentTypeBasedOnData(data: unknown): string { if (data instanceof FormData) return 'application/x-www-form-urlencoded' return 'application/json' } - private formatPostData(data, resource: string): BodyInit { - if (data instanceof FormData || resource.indexOf('user/token') != -1) return data + /** @deprecated not needed in v2 any more, only json in v2 */ + private formatPostData(data: unknown, resource: string): string | FormData { + if (data instanceof FormData || resource.indexOf('user/token') != -1) return data as FormData return JSON.stringify(data) } - private updateConnectionState(ignoreFails: boolean, working: boolean) { - if (ignoreFails) return - this.connectionStateOK = working - console.log(LOGTAG + ' setting status', working) - } - - private async validateResponse(ignoreFails, response: globalThis.Response): Promise { + private async validateResponse(response: globalThis.Response): Promise { if (!response) { console.warn('can not get response', response) - this.updateConnectionState(ignoreFails, false) return } - const jsonData = await response.json() - if (!jsonData) { - console.warn('not json response', response, jsonData) - this.updateConnectionState(ignoreFails, false) - return + let jsonData + try { + jsonData = await response.json() + if (!jsonData) { + console.warn('not json response', response, jsonData) + return { + data: null, + status: response.status, + headers: response.headers, + url: response.url, + cached: false, + } as Response + } + } catch (e) { + console.log('could not parse json', e) + // Auth response can be empty, maybe improve handling in the future } - this.updateConnectionState(ignoreFails, true) return { data: jsonData, status: response.status, @@ -349,44 +613,28 @@ export class ApiService extends CacheModule { } as Response } - getResourceUrl(resource: string, endpoint = 'default'): string { - const base = this.getBaseUrl() + getResourceUrl(resource: string, endpoint = 'default', networkConfig: ApiNetwork = this.networkConfig): string { + const base = this.getBaseUrl(networkConfig) if (endpoint == 'default') { - return this.getApiBaseUrl() + '/' + resource + return this.getApiBaseUrl(networkConfig) + '/' + resource + } else if (endpoint == 'v1') { + const v1 = this.getParentNetwork() + console.log('v1 endpoint', v1) + return v1.protocol + '://' + v1.net + v1.host + v1.endpoint + v1.version + '/' + resource } else { const substitute = endpoint.replace('{$BASE}', base) return substitute + '/' + resource } } - getApiBaseUrl() { - const cfg = this.networkConfig - return this.getBaseUrl() + cfg.endpoint + cfg.version + getApiBaseUrl(cfg: ApiNetwork) { + return this.getBaseUrl(cfg) + cfg.endpoint + cfg.version } - getBaseUrl(): string { - const cfg = this.networkConfig + getBaseUrl(cfg: ApiNetwork = this.networkConfig): string { return cfg.protocol + '://' + cfg.net + cfg.host } - async getAllTestNetNames() { - const debug = await this.storage.isDebugMode() - const re: string[][] = [] - - for (const entry of MAP) { - if (entry.key == 'main') continue - if (entry.key == 'gnosis') continue - if (!entry.active) continue - if (entry.onlyDebug && !debug) continue - re.push([this.capitalize(entry.key) + ' (Testnet)', entry.key]) - } - return re - } - - capitalize(text) { - return text.charAt(0).toUpperCase() + text.slice(1) - } - getHostName() { const network = this.networkConfig return network.host @@ -400,25 +648,82 @@ export class ApiService extends CacheModule { * @returns true if the current network is the mainnet */ isGnosis() { + // todo refactor to chainID return this.networkConfig.key == 'gnosis' } /** * Returns the formatted currencies for the network */ - public getCurrenciesFormatted(): string { - const network = this.networkConfig + public getCurrenciesFormatted(chainID: number): string { + const network = findChainNetworkById(chainID) if (network.elCurrency.internalName == network.clCurrency.internalName) { return network.clCurrency.formattedName } return network.clCurrency.formattedName + ' / ' + network.elCurrency.formattedName } + + // Helper function since this is used quite often + // and caching is already done by ApiService itself + public async getLatestState(force: boolean = false): Promise { + const temp = await this.execute(new V2LatestState().withAllowedCacheResponse(!force)) + if (temp.error) { + console.warn('getLatestState error', temp.error) + return null + } + const result = { + state: temp.data, + ts: Date.now(), + } + + if (temp.cached != true) { + await this.storage.setLastEpochRequestTime(Date.now()) + } else { + result.ts = await this.storage.getLastEpochRequestTime() + } + return result + } + + setApiKey(apiKey: string) { + this.apiUserKey = apiKey + return this.storage.setItem('api_key', apiKey) + } + + getApiKey(): Promise { + return this.storage.getItem('api_key') + } + + // @ts-expect-error ignore + use(e) { + if (!e) return null + const t = e.split('').reverse().join('') + let l = '' + for (e = 0; e < t.length; e += 2) l += t[e] + let n = '' + for (e = 0; e < l.length; e++) n += String.fromCharCode(l.charCodeAt(e) - this.r) + return n + } + + async getCurrentDashboardChainID(): Promise { + await this.initialized + return this.networkConfig.supportedChainIds + } +} + +export interface LatestStateWithTime { + state: LatestStateData + ts: number // at which the request was made } export interface Response { cached: boolean - data + data: unknown headers: Headers status: number url: string } + +export function capitalize(text: string) { + if (typeof text !== 'string') return '' + return text.charAt(0).toUpperCase() + text.slice(1) +} diff --git a/src/app/services/boot-preload.service.ts b/src/app/services/boot-preload.service.ts index a972508f..5a632b95 100644 --- a/src/app/services/boot-preload.service.ts +++ b/src/app/services/boot-preload.service.ts @@ -1,5 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -18,23 +18,44 @@ */ import { Injectable } from '@angular/core' -import { ValidatorUtils } from '../utils/ValidatorUtils' -import ClientUpdateUtils from '../utils/ClientUpdateUtils' -import { BlockUtils } from '../utils/BlockUtils' +import ClientUpdateUtils from '@utils/ClientUpdateUtils' +import { ApiService } from './api.service' +import { StorageService } from './storage.service' +import { V2DashboardOverview, V2DashboardSummaryGroupTable, V2DashboardSummaryTable } from '@requests/v2-dashboard' @Injectable({ providedIn: 'root', }) export class BootPreloadService { - constructor(private validatorUtils: ValidatorUtils, private clientUpdateUtils: ClientUpdateUtils, private blockUtils: BlockUtils) {} + constructor( + private clientUpdateUtils: ClientUpdateUtils, + private storage: StorageService + ) {} - preload() { + preload(api: ApiService) { try { - this.validatorUtils.getAllMyValidators() + // This might seem weird but if there is no dashboard ID yet, + // stuff like validator search (post) won't work since we have no CSRF token yet. + // By getting latest state, we also get the csrf token. + api.getLatestState(true) + + this.preloadDashboard(api) + this.clientUpdateUtils.checkAllUpdates() - this.blockUtils.getMyBlocks(0) // preload blocks } catch (e) { console.warn('can not preload', e) } } + + async preloadDashboard(api: ApiService) { + const id = await this.storage.getDashboardID() + if (id) { + const timeFrame = await this.storage.getDashboardTimeframe() + + // preload the 3 calls needed for display + api.execute(new V2DashboardOverview(id), 'dashboard') + api.execute(new V2DashboardSummaryTable(id, timeFrame, null), 'dashboard') + api.execute(new V2DashboardSummaryGroupTable(id, 0, timeFrame, null), 'dashboard') + } + } } diff --git a/src/app/services/storage.service.spec.ts b/src/app/services/storage.service.spec.ts deleted file mode 100644 index 1346f75b..00000000 --- a/src/app/services/storage.service.spec.ts +++ /dev/null @@ -1,36 +0,0 @@ -/* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) - * // - * // This file is part of Beaconchain Dashboard. - * // - * // Beaconchain Dashboard is free software: you can redistribute it and/or modify - * // it under the terms of the GNU General Public License as published by - * // the Free Software Foundation, either version 3 of the License, or - * // (at your option) any later version. - * // - * // Beaconchain Dashboard is distributed in the hope that it will be useful, - * // but WITHOUT ANY WARRANTY; without even the implied warranty of - * // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * // GNU General Public License for more details. - * // - * // You should have received a copy of the GNU General Public License - * // along with Beaconchain Dashboard. If not, see . - */ - -import { TestBed } from '@angular/core/testing' - -import { StorageService } from './storage.service' - -describe('StorageService', () => { - let service: StorageService - - beforeEach(() => { - TestBed.configureTestingModule({}) - service = TestBed.inject(StorageService) - }) - - it('should be created', () => { - expect(service).toBeTruthy() - }) -}) diff --git a/src/app/services/storage.service.ts b/src/app/services/storage.service.ts index a94c2fe5..0ff7e8c5 100644 --- a/src/app/services/storage.service.ts +++ b/src/app/services/storage.service.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -18,20 +17,24 @@ * // along with Beaconchain Dashboard. If not, see . */ -import { Injectable, isDevMode } from '@angular/core' -import { Plugins } from '@capacitor/core' +import { Injectable, isDevMode, OnInit } from '@angular/core' import * as StorageTypes from '../models/StorageTypes' -import { MAP, findConfigForKey } from '../utils/NetworkData' -import { CacheModule } from '../utils/CacheModule' -import BigNumber from 'bignumber.js' -import { Platform } from '@ionic/angular' +import { findConfigForKey } from '@utils/NetworkData' +import { CacheModule } from '@utils/CacheModule' +import { ModalController, Platform } from '@ionic/angular' import { Preferences } from '@capacitor/preferences' -import { LogviewPage } from '../pages/logview/logview.page' -const { StorageMirror } = Plugins +import { LogviewPage } from '@pages/logview/logview.page' +import { Device } from '@capacitor/device' +import { Aggregation, dashboardID, Period } from '@requests/v2-dashboard' +import { StorageMirror } from 'storage-mirror' +import { environment } from 'src/environments/environment' const AUTH_USER = 'auth_user' +const AUTH_USER_V2 = 'auth_user_v2' const PREFERENCES = 'network_preferences' +const WIDGET_PREFERENCES = 'widget_network_preferences' +const DASHBOARD_ID = 'dashboard_id' export const SETTING_NOTIFY = 'setting_notify' export const CPU_THRESHOLD = 'cpu_usage_threshold' @@ -42,43 +45,86 @@ export const DEBUG_SETTING_OVERRIDE_PACKAGE = 'debug_setting_override_package' @Injectable({ providedIn: 'root', }) -export class StorageService extends CacheModule { +export class StorageService extends CacheModule implements OnInit { constructor(private platform: Platform) { super() + } + + ngOnInit() { this.reflectiOSStorage() } + storeInHardCache(): boolean { + return false + } + // --- upper level helper --- + async getDeviceID() { + return (await Device.getId()).identifier + } + async backupAuthUser() { - return this.setObject(AUTH_USER + '_backup', await this.getAuthUser()) + return this.setObject(AUTH_USER_V2 + '_backup', await this.getAuthUserv2()) } async restoreAuthUser() { - return this.setAuthUser((await this.getObject(AUTH_USER + '_backup')) as StorageTypes.AuthUser) + return this.setAuthUserv2((await this.getObject(AUTH_USER_V2 + '_backup')) as StorageTypes.AuthUserv2) } + /**@deprecated */ async getAuthUser(): Promise { return this.getObject(AUTH_USER) as Promise } + /**@deprecated */ async setAuthUser(value: StorageTypes.AuthUser) { return this.setObject(AUTH_USER, value) } + async getAuthUserv2(): Promise { + return this.getObject(AUTH_USER_V2) as Promise + } + + async setAuthUserv2(value: StorageTypes.AuthUserv2) { + const expires = new Date() + expires.setMonth(expires.getMonth() + 12) + document.cookie = 'session_id' + '=' + value.Session + ';domain=.beaconcha.in;path=/;expires=' + expires + return this.setObject(AUTH_USER_V2, value) + } + + async isV2() { + return this.getBooleanSetting('use_v2_api', false) + } + + setV2(value: boolean) { + return this.setBooleanSetting('use_v2_api', value) + } + + async getDeviceName(): Promise { + return (await Device.getInfo()).model + } + async isLoggedIn(): Promise { - const user = await this.getAuthUser() - if (!user || !user.accessToken) return false - return true + if (await this.isV2()) { + const user = await this.getAuthUserv2() + if (!user || !user.Session) return false + return true + } else { + const user = await this.getAuthUser() + if (!user || !user.accessToken) return false + return true + } } async removeAuthUser() { + this.remove(AUTH_USER_V2) return this.remove(AUTH_USER) } public async isDebugMode() { const devMode = isDevMode() - if (devMode) return true + if (devMode || environment.debug) return true const permanentDevMode = (await this.getObject('dev_mode')) as DevModeEnabled return permanentDevMode && permanentDevMode.enabled } @@ -95,21 +141,29 @@ export class StorageService extends CacheModule { return await this.setObject(PREFERENCES, value) } + /** + * Since v2 this is inferred at runtime so we write back the actual config for widget + * @param network + */ + async setWidgetNetworkConfig(network: StorageTypes.ApiNetwork) { + await this.setObject(WIDGET_PREFERENCES, network) + } + async loadPreferencesToggles(network: string): Promise { const notifyLocal = await this.getBooleanSetting(network + SETTING_NOTIFY, null) return notifyLocal } - setBooleanSetting(key, value) { - this.setSetting(key, value) + setBooleanSetting(key: string, value: boolean) { + return this.setSetting(key, value) } getBooleanSetting(key: string, defaultV = true): Promise { return this.getSetting(key, defaultV) as Promise } - setSetting(key, value) { - this.setObject(key, { value: value } as ValueWrapper) + setSetting(key: string, value: unknown) { + return this.setObject(key, { value: value } as ValueWrapper) } getSetting(key: string, defaultV: unknown = 0) { @@ -119,11 +173,11 @@ export class StorageService extends CacheModule { }) } - async getStakingShare(): Promise { - const value = await this.getItem('staking_share') - if (!value) return null - return new BigNumber(value) - } + // async getStakingShare(): Promise { + // const value = await this.getItem('staking_share') + // if (!value) return null + // return new BigNumber(value) + // } async setLastEpochRequestTime(time: number) { await this.setObject('last_epoch_time', { ts: time } as EpochRequestTime) @@ -145,7 +199,7 @@ export class StorageService extends CacheModule { } } - async openLogSession(modalCtr, offset: number) { + async openLogSession(modalCtr: ModalController, offset: number) { let lastLogSession = parseInt(window.localStorage.getItem('last_log_session')) if (isNaN(lastLogSession)) lastLogSession = 0 @@ -153,7 +207,7 @@ export class StorageService extends CacheModule { component: LogviewPage, cssClass: 'my-custom-class', componentProps: { - logs: JSON.parse(window.localStorage.getItem('log_session_' + ((lastLogSession + (3 - offset)) % 3))), + logs: JSON.parse(window.localStorage.getItem('log_session_' + ((lastLogSession + (2 - offset)) % 2))), }, }) return await modal.present() @@ -192,16 +246,17 @@ export class StorageService extends CacheModule { this.reflectiOSStorage() } - // sigh + // iOS widget can't access app storage, so we need to reflect certain keys + // to a common shared space that the widget can access private reflectiOSStorage() { try { if (!this.platform.is('ios')) return - const reflectKeys = ['CapacitorStorage.prefered_unit', 'CapacitorStorage.network_preferences', 'CapacitorStorage.auth_user'] - for (let i = 0; i < MAP.length; i++) { - if (MAP[i].key.indexOf('invalid') > -1) continue - if (MAP[i].key.indexOf('local') > -1) continue - reflectKeys.push('CapacitorStorage.validators_' + MAP[i].key) - } + const reflectKeys = [ + 'CapacitorStorage.prefered_unit', + 'CapacitorStorage.' + WIDGET_PREFERENCES, + 'CapacitorStorage.' + AUTH_USER_V2, + 'CapacitorStorage.' + DASHBOARD_ID, + ] StorageMirror.reflect({ keys: reflectKeys, @@ -239,9 +294,56 @@ export class StorageService extends CacheModule { await Preferences.clear() this.reflectiOSStorage() } + + async getDashboardID(): Promise { + const data = (await this.getObject(DASHBOARD_ID)) as DashboardSetting + if (!data) return null + return data.id as dashboardID + } + + async setDashboardID(id: dashboardID): Promise { + await this.setObject(DASHBOARD_ID, { + id: id, + } as DashboardSetting) + } + + async getDashboardTimeframe(): Promise { + const data = (await this.getObject('dashboard_timeframe')) as Period + if (!data) return Period.AllTime + return data + } + + async getDashboardSummaryAggregation(): Promise { + const data = (await this.getObject('dashboard_summary_aggregation')) as Aggregation + if (!data) return Aggregation.Hourly + return data + } + + async setDashboardSummaryAggregation(aggregation: Aggregation): Promise { + await this.setObject('dashboard_summary_aggregation', aggregation) + } + + async setDashboardTimeframe(timeframe: Period): Promise { + return await this.setObject('dashboard_timeframe', timeframe) + } + + async setDashboardGroupID(groupID: number): Promise { + return await this.setObject('dashboard_group_id', groupID) + } + + async getDashboardGroupID(): Promise { + const data = (await this.getObject('dashboard_group_id')) as number + if (data === null || data === undefined) return -1 + return data + } +} + +interface DashboardSetting { + id: dashboardID } -export function replacer(key, value) { +export function replacer(key: string, value: unknown) { + // @ts-expect-error: noImplicitThis disabled for this line const originalObject = this[key] if (originalObject instanceof Map) { return { @@ -253,7 +355,8 @@ export function replacer(key, value) { } } -function reviver(key, value) { +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function reviver(_: string, value: any) { if (typeof value === 'object' && value !== null) { if (value.dataType === 'Map') { return new Map(value.value) diff --git a/src/app/services/sync.service.spec.ts b/src/app/services/sync.service.spec.ts deleted file mode 100644 index 12e26f42..00000000 --- a/src/app/services/sync.service.spec.ts +++ /dev/null @@ -1,36 +0,0 @@ -/* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) - * // - * // This file is part of Beaconchain Dashboard. - * // - * // Beaconchain Dashboard is free software: you can redistribute it and/or modify - * // it under the terms of the GNU General Public License as published by - * // the Free Software Foundation, either version 3 of the License, or - * // (at your option) any later version. - * // - * // Beaconchain Dashboard is distributed in the hope that it will be useful, - * // but WITHOUT ANY WARRANTY; without even the implied warranty of - * // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * // GNU General Public License for more details. - * // - * // You should have received a copy of the GNU General Public License - * // along with Beaconchain Dashboard. If not, see . - */ - -import { TestBed } from '@angular/core/testing' - -import { SyncService } from './sync.service' - -describe('SyncService', () => { - let service: SyncService - - beforeEach(() => { - TestBed.configureTestingModule({}) - service = TestBed.inject(SyncService) - }) - - it('should be created', () => { - expect(service).toBeTruthy() - }) -}) diff --git a/src/app/services/sync.service.ts b/src/app/services/sync.service.ts deleted file mode 100644 index e3f31e9e..00000000 --- a/src/app/services/sync.service.ts +++ /dev/null @@ -1,495 +0,0 @@ -/* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) - * // - * // This file is part of Beaconchain Dashboard. - * // - * // Beaconchain Dashboard is free software: you can redistribute it and/or modify - * // it under the terms of the GNU General Public License as published by - * // the Free Software Foundation, either version 3 of the License, or - * // (at your option) any later version. - * // - * // Beaconchain Dashboard is distributed in the hope that it will be useful, - * // but WITHOUT ANY WARRANTY; without even the implied warranty of - * // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * // GNU General Public License for more details. - * // - * // You should have received a copy of the GNU General Public License - * // along with Beaconchain Dashboard. If not, see . - */ - -import { Injectable, Injector } from '@angular/core' -import { ApiService } from './api.service' -import { SETTING_NOTIFY, StorageService } from './storage.service' -import { Mutex } from 'async-mutex' -import { - BundleSub, - GetMobileSettingsRequest, - NotificationBundleSubsRequest, - NotificationGetRequest, - SetMobileSettingsRequest, -} from '../requests/requests' -import ClientUpdateUtils, { Clients } from '../utils/ClientUpdateUtils' -import { ValidatorSyncUtils } from '../utils/ValidatorSyncUtils' -import { NotificationBase } from '../tab-preferences/notification-base' - -const NOTIFY_SYNCCHANGE = 'notify_syncchange_' - -const MAX_SERVER_BUNDLE_SIZE = 100 - -interface SyncChanged { - lastChanged: number - lastSynced: number - eventName: string - network: string - eventFilter?: string - eventThreshold?: number - subscribeAction: 'subscribe' | 'unsubscribe' -} - -enum SyncActionEvent { - NOTIFY_GLOBAL, - CLIENT_UPDATE_GENERAL, - NOTIFICATIONS, -} - -interface BundleSubWithAction extends BundleSub { - onComplete: (boolean) => void -} - -interface BundleSubContainer { - bundle: BundleSubWithAction - network: string - enabled: boolean -} - -interface NetworkBundle { - bundles: BundleSubWithAction[] - network: string - subscribe: boolean -} - -@Injectable({ - providedIn: 'root', -}) -export class SyncService { - private syncLock = new Mutex() - private lastNotifySync = 0 - private bundleList: BundleSubContainer[] = [] - private notificationBase: NotificationBase - - constructor( - private api: ApiService, - private storage: StorageService, - private validatorSyncUtils: ValidatorSyncUtils, - private updateUtils: ClientUpdateUtils, - protected injector: Injector - ) { - // HACK to avoid dependency cycle - setTimeout(() => (this.notificationBase = injector.get(NotificationBase)), 0) - } - - public async mightSyncUpAndSyncDelete() { - await this.validatorSyncUtils.mightSyncUpAndSyncDelete(() => { - this.syncAllSettingsForceStaleNotifications() - }) - } - - public async fullSync() { - await this.validatorSyncUtils.fullSync(() => { - this.syncAllSettingsForceStaleNotifications() - }) - } - - public async syncDown() { - await this.validatorSyncUtils.syncDown() - } - - async syncAllSettings(useForce = false) { - const loggedIn = await this.storage.isLoggedIn() - if (!loggedIn) return false - - if (this.syncLock.isLocked()) return - - if (!useForce && this.lastNotifySync + 15 * 1000 > Date.now()) { - console.log('Syncing notify cancelled, last update was less than 15 seconds ago') - return - } - - console.log('== Syncing notify ==') - - console.log('== Step 2: Sync changes ==') - - const unlock = await this.syncLock.acquire() - this.bundleList = [] - - const allNotifyKeys = await this.getAllSyncChangeKeys() - for (const key of allNotifyKeys) { - const cleanKey = key.replace(NOTIFY_SYNCCHANGE, '') - const syncAction = this.getSyncAction(cleanKey) - - await this.syncSingle(cleanKey, syncAction) - } - - await this.postNotifyBundles() - - if (allNotifyKeys.length > 0) { - await this.api.clearSpecificCache(new NotificationGetRequest()) - await this.api.clearSpecificCache(new GetMobileSettingsRequest()) - } - - unlock() - - console.log('== Step 1: Loading notification preferences from beaconcha.in ==') - await this.notificationBase.loadAllToggles() - - console.log('== Syncing notify completed ==') - } - - /** - * Stale all validator specific notifications so they can be reapplied according to the current settings. - * This is needed when we add a new validators and want to apply the notification settings for them - */ - async syncAllSettingsForceStaleNotifications() { - const loggedIn = await this.storage.isLoggedIn() - if (!loggedIn) return false - - const allNotifyKeys = await this.getAllSyncChangeKeys() - for (const key of allNotifyKeys) { - const cleanKey = key.replace(NOTIFY_SYNCCHANGE, '') - if (cleanKey.indexOf('monitoring_') >= 0) continue - if (cleanKey.indexOf('setting_notify_newround') >= 0) continue - if (cleanKey.indexOf('setting_notify_clientupdate') >= 0) continue - if (cleanKey.indexOf('rocketpool_new_claimround') >= 0) continue - if (cleanKey.indexOf('eth_client_update') >= 0) continue - if (cleanKey.indexOf('setting_notify_machineoffline') >= 0) continue - if (cleanKey.indexOf('setting_notify_hddwarn') >= 0) continue - if (cleanKey.indexOf('setting_notify_cpuwarn') >= 0) continue - if (cleanKey.indexOf('setting_notify_memorywarn') >= 0) continue - - const syncAction = this.getSyncActionEvent(cleanKey) - if (syncAction != SyncActionEvent.NOTIFICATIONS) continue - console.log('STALE CHECK ' + cleanKey, syncAction) - - if (syncAction == SyncActionEvent.NOTIFICATIONS) { - const temp = await this.getChanged(cleanKey) - console.log('== STALING ' + cleanKey + ' ==', temp) - await this.setLastChanged(cleanKey, temp.eventName, temp.eventFilter, temp.eventThreshold, temp.subscribeAction) - } - } - - this.syncAllSettings() - } - - async developDeleteQueue() { - const allNotifyKeys = await this.getAllSyncChangeKeys() - for (const key of allNotifyKeys) { - this.storage.remove(key) - } - } - - private getSyncAction(key: string): (syncChange: SyncChanged, onComplete: (boolean) => void) => Promise { - const actionEvent = this.getSyncActionEvent(key) - - if (actionEvent == SyncActionEvent.NOTIFY_GLOBAL) { - return async (syncChange: SyncChanged, onComplete) => { - const result = await this.updateRemoteGeneralNotifySettings(syncChange.subscribeAction != 'unsubscribe') - onComplete(result) - return result - } - } else if (actionEvent == SyncActionEvent.CLIENT_UPDATE_GENERAL) { - return this.getClientUpdateSyncAction() - } - - return this.getNotifySubSyncAction() - } - - getGeneralFilter(item: SyncChanged): string { - return item.eventFilter - } - - getNotifySubSyncAction() { - return async (syncChange: SyncChanged, superOnComplete: (boolean) => void) => { - let eventFilter = syncChange.eventFilter - if (eventFilter) { - eventFilter = eventFilter.replace('unsub_', '').replace('sub_', '') - } - this.queueForPost(syncChange.subscribeAction != 'unsubscribe', syncChange.network, { - event_name: syncChange.eventName, - event_filter: eventFilter, - event_threshold: syncChange.eventThreshold, - onComplete: superOnComplete, - }) - return Promise.resolve(true) - } - } - - private getSyncActionEvent(key: string) { - if (key.endsWith(SETTING_NOTIFY)) { - return SyncActionEvent.NOTIFY_GLOBAL - } else { - for (const client of Clients) { - if (key.endsWith(client.key)) { - return SyncActionEvent.CLIENT_UPDATE_GENERAL - } - } - } - - return SyncActionEvent.NOTIFICATIONS - } - - private getClientUpdateSyncAction() { - return async (syncChange: SyncChanged, superOnComplete: (boolean) => void) => { - return this.getNotifySubSyncAction()(syncChange, superOnComplete) - } - } - - private queueForPost(enabled: boolean, network: string, bundle: BundleSubWithAction) { - this.bundleList.push({ - bundle: bundle, - enabled: enabled, - network: network, - }) - } - - private getNetworkBundles(filterEnabled: boolean): NetworkBundle[] { - // Prepare by filtering to networks - const networkMap = new Map() - this.bundleList.forEach((it) => { - if (it.enabled == filterEnabled) { - let array: BundleSubWithAction[] = [] - if (networkMap.has(it.network)) { - array = networkMap.get(it.network) - } - - array.push(it.bundle) - networkMap.set(it.network, array) - } - }) - - // Adding all networks in an array for return - const result: NetworkBundle[] = [] - networkMap.forEach((value, key) => { - result.push({ - bundles: value, - network: key, - subscribe: filterEnabled, - }) - }) - return result - } - - private getBundles(): NetworkBundle[] { - return this.getNetworkBundles(true).concat(this.getNetworkBundles(false)) - } - - async postNotifyBundles() { - const bundles = this.getBundles() - for (let i = 0; i < bundles.length; i++) { - const bundle = bundles[i] - while (bundle.bundles.length) { - const splice = bundle.bundles.splice(0, MAX_SERVER_BUNDLE_SIZE) - const success = await this.postNotifyBundle(bundle.subscribe, splice, bundle.network) - if (success) this.lastNotifySync = Date.now() - - for (let j = 0; j < splice.length; j++) { - splice[j].onComplete(success) - } - } - } - } - - private async postNotifyBundle(subscribe: boolean, data: BundleSub[], network: string): Promise { - const loggedIn = await this.storage.isLoggedIn() - if (!loggedIn) return false - - const request = new NotificationBundleSubsRequest(subscribe, data) - if (network) { - request.endPoint = network - } - - const response = await this.api.execute(request) - const result = request.wasSuccessful(response) - if (!result) { - return false - } - - return true - } - - private async updateRemoteGeneralNotifySettings(value): Promise { - const req = new SetMobileSettingsRequest(value) - const resp = await this.api.execute(req) - const result = req.parse(resp) - if (!result || (result.length >= 0 && result[0].notify_enabled != value)) { - return false - } - return true - } - - private async syncSingle(key: string, syncAction: (syncChange: SyncChanged, onComplete: (boolean) => void) => Promise) { - const syncChange = await this.getChanged(key) - if (syncChange.eventName == '') { - console.log('== Sync notify: (key) ' + key + ' has no event name, abort') - return - } - - if (syncChange.lastChanged > syncChange.lastSynced) { - console.log('== Syncing notify: ' + key + ' changed, updating on remote... ==', syncChange.lastChanged, syncChange.lastSynced) - const actionPromise = syncAction(syncChange, (success) => { - if (success) { - console.log('== Syncing notify: ' + key + ' synced successfully! ==') - this.setLastSynced(key, syncChange.eventName, syncChange.subscribeAction) - } - }) - await actionPromise - - return true - } - return false - } - - async changeClient(clientKey: string, value: string) { - // do not sync to remote if notification for client updates isn't enabled in the first place - const isEnabled = await this.storage.isNotifyClientUpdatesEnabled() - if (!isEnabled) return - - if (value) { - value = value.toUpperCase() - } - - const client = this.updateUtils.getClientInfo(clientKey) - if (value && value != 'NULL') { - this.setLastChanged(client.storageKey, 'eth_client_update', value.toLocaleLowerCase(), null, 'subscribe') - } else { - this.setLastChanged('UN' + client.storageKey, 'eth_client_update', client.key.toLocaleLowerCase(), null, 'unsubscribe') - } - } - - async changeGeneralNotify(value: boolean, filter: string = null) { - this.storage.setBooleanSetting(SETTING_NOTIFY, value) - await this.setLastChanged(SETTING_NOTIFY, SETTING_NOTIFY, filter, null, value ? 'subscribe' : 'unsubscribe') - } - - async changeNotifyEvent(key: string, event: string, value: boolean, filter: string = null, threshold: number = null) { - const net = this.api.networkConfig.net - this.storage.setBooleanSetting(net + key, value) - await this.setLastChanged(net + key, event, filter, threshold, value ? 'subscribe' : 'unsubscribe') - } - - async changeNotifyEventUser(key: string, event: string, value: boolean, filter: string = null, threshold: number = null) { - this.storage.setBooleanSetting(key, value) - await this.setLastChanged(key, event, filter, threshold, value ? 'subscribe' : 'unsubscribe') - } - - async reapplyNotifyEvent(event: string, filter: string = null): Promise { - const currentKey = await this.findSimilarChanged(event) - if (currentKey == null) { - console.log('ignoring reapplyNotifyEvent, no key with similar name found', event, event) - return false - } - - const current = await this.getChanged(currentKey) - if (current.eventName == '') { - console.log('ignoring reapplyNotifyEvent since no previous setting change has been found for event', event, event) - return false - } - - let subscribeAction = current.subscribeAction - if (!subscribeAction) { - subscribeAction = (await this.storage.getBooleanSetting(current.eventName)) ? 'subscribe' : 'unsubscribe' - } - - this.setLastChanged(event + filter, event, filter, current.eventThreshold, subscribeAction) - return true - } - - changeNotifyClientUpdate(key: string, value: boolean) { - this.storage.setBooleanSetting(key, value) - - Clients.forEach(async (client) => { - const clientName = await this.updateUtils.getClient(client.key) - if (clientName != 'null') { - this.setLastChanged(client.storageKey, 'eth_client_update', clientName.toLocaleLowerCase(), null, value ? 'subscribe' : 'unsubscribe') - } - }) - } - - private async setLastSynced(key: string, event: string, subscribeAction: 'subscribe' | 'unsubscribe', value: number = Date.now()) { - const current = await this.getChanged(key) - this.setChanged(key, { - lastChanged: current.lastChanged, - lastSynced: value, - eventName: event, - network: this.api.getApiBaseUrl(), - eventFilter: current.eventFilter, - eventThreshold: current.eventThreshold, - subscribeAction: subscribeAction, - }) - } - - private async setLastChanged( - key: string, - event: string, - filter: string, - threshold: number, - subscribeAction: 'subscribe' | 'unsubscribe', - value: number = Date.now() - ) { - const current = await this.getChanged(key) - this.setChanged(key, { - lastChanged: value, - lastSynced: current.lastSynced, - eventName: event, - network: this.api.getApiBaseUrl(), - eventFilter: filter, - eventThreshold: threshold, - subscribeAction: subscribeAction, - }) - } - - private async getAllSyncChangeKeys() { - return await this.storage.findAllKeys(NOTIFY_SYNCCHANGE) - } - - private setChanged(key: string, syncChanged: SyncChanged) { - this.storage.setObject(NOTIFY_SYNCCHANGE + key, syncChanged) - } - - private async getChanged(key: string): Promise { - const temp: SyncChanged = (await this.storage.getObject(NOTIFY_SYNCCHANGE + key)) as SyncChanged - if (temp && temp.lastChanged) return temp - return { - lastChanged: 0, - lastSynced: 0, - eventName: '', - network: this.api.getApiBaseUrl(), - eventFilter: null, - eventThreshold: null, - subscribeAction: 'subscribe', - } - } - - // finds newest changed key with similar name - private async findSimilarChanged(keySearch: string) { - let erg: string = null - let ergRetrieved: SyncChanged - const allNotifyKeys = await this.getAllSyncChangeKeys() - for (const key of allNotifyKeys) { - const cleanKey = key.replace(NOTIFY_SYNCCHANGE, '').replace('unsub_', '').replace('sub_', '') - if (cleanKey.indexOf(keySearch) >= 0) { - if (erg == null) { - erg = cleanKey - ergRetrieved = await this.getChanged(key) - } else { - const retrieved = await this.getChanged(key) - if (retrieved.lastChanged > ergRetrieved.lastChanged) { - erg = cleanKey - ergRetrieved = await this.getChanged(key) - } - } - } - } - return erg - } -} diff --git a/src/app/services/unitconv.service.spec.ts b/src/app/services/unitconv.service.spec.ts deleted file mode 100644 index ed2ba154..00000000 --- a/src/app/services/unitconv.service.spec.ts +++ /dev/null @@ -1,36 +0,0 @@ -/* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) - * // - * // This file is part of Beaconchain Dashboard. - * // - * // Beaconchain Dashboard is free software: you can redistribute it and/or modify - * // it under the terms of the GNU General Public License as published by - * // the Free Software Foundation, either version 3 of the License, or - * // (at your option) any later version. - * // - * // Beaconchain Dashboard is distributed in the hope that it will be useful, - * // but WITHOUT ANY WARRANTY; without even the implied warranty of - * // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * // GNU General Public License for more details. - * // - * // You should have received a copy of the GNU General Public License - * // along with Beaconchain Dashboard. If not, see . - */ - -import { TestBed } from '@angular/core/testing' - -import { UnitconvService } from './unitconv.service' - -describe('UnitconvService', () => { - let service: UnitconvService - - beforeEach(() => { - TestBed.configureTestingModule({}) - service = TestBed.inject(UnitconvService) - }) - - it('should be created', () => { - expect(service).toBeTruthy() - }) -}) diff --git a/src/app/services/unitconv.service.ts b/src/app/services/unitconv.service.ts index 87f0e157..aee0efec 100644 --- a/src/app/services/unitconv.service.ts +++ b/src/app/services/unitconv.service.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -19,11 +18,12 @@ */ import { Injectable } from '@angular/core' -import Unit, { convertDisplayable, MAPPING, convertEthUnits } from '../utils/EthereumUnits' +import Unit, { convertDisplayable, MAPPING, convertEthUnits } from '@utils/EthereumUnits' import { StorageService } from './storage.service' import BigNumber from 'bignumber.js' import { ApiService } from './api.service' -import { CoinbaseExchangeRequest, CoinbaseExchangeResponse } from '../requests/requests' +import { CoinbaseExchangeRequest, CoinbaseExchangeResponse } from '@requests/requests' +import { CHAIN_NETWORKS, ChainNetwork, findChainNetworkById } from '@utils/NetworkData' const STORAGE_KEY_CONS = 'prefered_unit' // cons const STORAGE_KEY_EXEC = 'prefered_unit_exec' @@ -42,6 +42,7 @@ export class UnitconvService { } public lastPrice: LastPrice private rplETHPrice: BigNumber = new BigNumber(1) + chainNetwork: ChainNetwork = CHAIN_NETWORKS[0] private mGNOXDAI = { value: 'GNOXDAI', type: 'cons', unit: Unit.DAI_GNO_HELPER } as Currency // dummy var to help us get the price of mGNO in xDAI @@ -51,13 +52,19 @@ export class UnitconvService { */ static currencyPipe: CurrencyPipe = { Cons: null, Exec: null, RPL: null } - constructor(private storage: StorageService, private api: ApiService) { + constructor( + private storage: StorageService, + private api: ApiService + ) { this.init() } private async init() { await this.migrateToGnosisEra() + this.chainNetwork = findChainNetworkById(await this.api.getCurrentDashboardChainID()) + console.log('unitconvservice chainNetwork', this.chainNetwork) + this.lastPrice = { Cons: await this.getLastStoredPrice(this.pref.Cons), Exec: await this.getLastStoredPrice(this.pref.Exec), @@ -73,9 +80,14 @@ export class UnitconvService { this.save() } + await this.loadCurrentChainNetwork() await this.updatePriceData() } + public async loadCurrentChainNetwork() { + this.chainNetwork = findChainNetworkById(await this.api.getCurrentDashboardChainID()) + } + public async networkSwitchReload() { UnitconvService.currencyPipe = { Cons: null, Exec: null, RPL: null } await this.init() @@ -145,11 +157,10 @@ export class UnitconvService { // Coinbase spot name (for api calls) if (result.coinbaseSpot) { - const network = this.api.getNetwork() if (currency.type == 'cons') { - result.coinbaseSpot = result.coinbaseSpot.replace('XXX', network.clCurrency.coinbaseSpot) + result.coinbaseSpot = result.coinbaseSpot.replace('XXX', this.chainNetwork.clCurrency.coinbaseSpot) } else if (currency.type == 'exec') { - result.coinbaseSpot = result.coinbaseSpot.replace('XXX', network.elCurrency.coinbaseSpot) + result.coinbaseSpot = result.coinbaseSpot.replace('XXX', this.chainNetwork.elCurrency.coinbaseSpot) } } return result @@ -168,11 +179,10 @@ export class UnitconvService { type = type.type } - const network = this.api.getNetwork() if (type == 'cons') { - return network.clCurrency.internalName + return this.chainNetwork.clCurrency.internalName } else if (type == 'exec') { - return network.elCurrency.internalName + return this.chainNetwork.elCurrency.internalName } else if (type == 'rpl') { return 'RPL' } @@ -270,7 +280,7 @@ export class UnitconvService { this.pref.RPL = this.createCurrency(this.pref.RPL.value, 'rpl') } - public convertToPref(value: BigNumber, from, type: RewardType) { + public convertToPref(value: BigNumber, from: string, type: RewardType) { if (type == 'cons') { return this.convert(value, from, this.pref.Cons) } @@ -322,6 +332,10 @@ export class UnitconvService { return this.convertBase(value, from, MAPPING.get(to), displayable) } + public weiToEth(value: BigNumber | number | string, displayable = true) { + return this.convertBase(value, 'WEI', Unit.ETHER, displayable) + } + private convertBase(value: BigNumber | number | string, from: string, to: Unit, displayable = true) { if (!value || !from || !to) return value @@ -370,7 +384,7 @@ export class UnitconvService { } this.storage.setBooleanSetting('migrated_gnosis', true) } catch (e) { - console.warn('could not migrate to gnosis') + console.warn('could not migrate to gnosis', e) } } } @@ -425,7 +439,9 @@ export class UnitconvService { this.lastPrice.mGNOXDAI = this.lastPrice.Exec.dividedBy(this.lastPrice.Cons) } - console.log('skipFetchingMGNOtoDAIPrice', skipFetchingMGNOtoDAIPrice, this.lastPrice.mGNOXDAI.toString()) + console.log('unitconvservice skipFetchingMGNOtoDAIPrice units', this.pref.Cons, this.pref.Exec) + console.log('unitconvservice skipFetchingMGNOtoDAIPrice details', this.lastPrice.Cons.toString(), this.lastPrice.Exec.toString()) + console.log('unitconvservice skipFetchingMGNOtoDAIPrice', skipFetchingMGNOtoDAIPrice, this.lastPrice.mGNOXDAI.toString()) this.triggerPropertyChange() } @@ -452,15 +468,10 @@ export class UnitconvService { } private async getExchangeRate(unitPair: string): Promise { - const req = new CoinbaseExchangeRequest(unitPair) - const response = await this.api.execute(req).catch((e) => { - console.warn('error in response getExchangeRate', e) - return null - }) - const temp = req.parse(response) - if (temp.length <= 0) return null - console.log('requested exchange rate for ', unitPair, 'got', temp[0].amount, 'as response') - return temp[0] + const temp = await this.api.execute(new CoinbaseExchangeRequest(unitPair)) + if (temp.error) return null + console.log('requested exchange rate for ', unitPair, 'got', temp.data.amount, 'as response') + return temp.data } } @@ -474,7 +485,7 @@ interface LastPrice { mGNOXDAI: BigNumber } -interface PreferredCurrency { +export interface PreferredCurrency { Cons: Currency Exec: Currency RPL: Currency diff --git a/src/app/tab-blocks/tab-blocks.page.html b/src/app/tab-blocks/tab-blocks.page.html deleted file mode 100644 index d6d55b13..00000000 --- a/src/app/tab-blocks/tab-blocks.page.html +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - - - Blocks - - - - Proposal Luck: - {{ luck.luckPercentage*100 | number:'1.0-1' }}% - - - - - - - - - - - - - -

- On average next block expected in - On average next block was expected -
- ~{{ luck.nextBlockEstimate | timeago }} -

- - - -
- -

No Blocks so far

- Your proposed blocks will show up here. -
- -
-
- -
-
- - -
- -
-
- Loading... -
-
-
diff --git a/src/app/tab-blocks/tab-blocks.page.spec.ts b/src/app/tab-blocks/tab-blocks.page.spec.ts deleted file mode 100644 index 0f86f35d..00000000 --- a/src/app/tab-blocks/tab-blocks.page.spec.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing' -import { IonicModule } from '@ionic/angular' - -import { TabBlocksPage } from './tab-blocks.page' - -describe('TabBlocksPage', () => { - let component: TabBlocksPage - let fixture: ComponentFixture - - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [TabBlocksPage], - imports: [IonicModule.forRoot()], - }).compileComponents() - - fixture = TestBed.createComponent(TabBlocksPage) - component = fixture.componentInstance - fixture.detectChanges() - })) - - it('should create', () => { - expect(component).toBeTruthy() - }) -}) diff --git a/src/app/tab-blocks/tab-blocks.page.ts b/src/app/tab-blocks/tab-blocks.page.ts deleted file mode 100644 index 54df0f0a..00000000 --- a/src/app/tab-blocks/tab-blocks.page.ts +++ /dev/null @@ -1,123 +0,0 @@ -import { Component, OnInit, ViewChild } from '@angular/core' -import { ModalController } from '@ionic/angular' -import { BlockDetailPage } from '../pages/block-detail/block-detail.page' -import { BlockResponse } from '../requests/requests' -import { AlertService } from '../services/alert.service' -import { ApiService } from '../services/api.service' -import { UnitconvService } from '../services/unitconv.service' -import { BlockUtils, Luck } from '../utils/BlockUtils' -import { ValidatorUtils } from '../utils/ValidatorUtils' -import { InfiniteScrollDataSource, sleep } from '../utils/InfiniteScrollDataSource' -import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling' -import { trigger, style, animate, transition } from '@angular/animations' -@Component({ - selector: 'app-tab-blocks', - templateUrl: './tab-blocks.page.html', - styleUrls: ['./tab-blocks.page.scss'], - animations: [trigger('fadeIn', [transition(':enter', [style({ opacity: 0 }), animate('300ms 100ms', style({ opacity: 1 }))])])], -}) -export class TabBlocksPage implements OnInit { - public classReference = UnitconvService - - dataSource: InfiniteScrollDataSource - @ViewChild(CdkVirtualScrollViewport) virtualScroll: CdkVirtualScrollViewport - - loading = false - loadMore = false - - initialized = false - - luck: Luck = null - - valis = null - - constructor( - public api: ApiService, - public unit: UnitconvService, - private blockUtils: BlockUtils, - public modalController: ModalController, - private validatorUtils: ValidatorUtils, - private alertService: AlertService - ) { - this.validatorUtils.registerListener(() => { - this.refresh() - }) - this.validatorUtils.getAllValidatorsLocal().then((validators) => { - this.dataSource = new InfiniteScrollDataSource(this.blockUtils.getLimit(validators.length), async (offset: number) => { - if (offset > 0) { - let sleepTime = 1000 - if (offset >= 50) { - sleepTime = 3500 // 20 req per minute => wait at least 3 seconds. Buffer for dashboard and sync stuff - } else if (offset >= 120) { - sleepTime = 4500 - } - this.loadMore = true - await sleep(sleepTime) // handling rate limit of some sorts - } - const result = await this.blockUtils.getMyBlocks(offset) - this.loadMore = false - return result - }) - }) - } - - ngOnInit() { - this.refresh() - } - - private async init() { - this.luck = await this.blockUtils.getProposalLuck() - this.valis = await this.validatorUtils.getAllValidatorsLocal() - this.virtualScroll.scrollToIndex(0) - await this.dataSource.reset() - this.initialized = true - } - - private async refresh() { - this.setLoading(true) - await this.init() - this.setLoading(false) - } - - private setLoading(loading: boolean) { - this.loading = loading - } - - async clickBlock(item: BlockResponse) { - const modal = await this.modalController.create({ - component: BlockDetailPage, - cssClass: 'my-custom-class', - componentProps: { - block: item, - }, - }) - return await modal.present() - } - - doRefresh(event) { - setTimeout(async () => { - this.virtualScroll.scrollToIndex(0) - await this.dataSource.reset() - event.target.complete() - }, 1500) - } - - luckHelp() { - if (!this.luck) { - this.alertService.showInfo( - 'Proposal Luck', - `Compares the number of your actual proposed blocks to the expected average blocks per validator during the last month. - You'll see your luck percentage once you have proposed a block.` - ) - } else { - this.alertService.showInfo( - 'Proposal Luck', - `Compares the number of your actual proposed blocks to the expected average blocks per validator during the last ${ - this.luck.timeFrameName ? this.luck.timeFrameName : 'month' - }. -

Your ${this.luck.userValidators == 1 ? `validator is` : `${this.luck.userValidators} validators are`} - expected to produce ${this.luck.expectedBlocksPerMonth.toFixed(2)} blocks per month on average with current network conditions.` - ) - } - } -} diff --git a/src/app/tab-dashboard/tab-dashboard.page.html b/src/app/tab-dashboard/tab-dashboard.page.html deleted file mode 100644 index 3847f8a6..00000000 --- a/src/app/tab-dashboard/tab-dashboard.page.html +++ /dev/null @@ -1,49 +0,0 @@ - - - - - Dashboard - - - - - -
-
- -

Let´s get started

-
-
- - - - - - - - - -
diff --git a/src/app/tab-dashboard/tab-dashboard.page.spec.ts b/src/app/tab-dashboard/tab-dashboard.page.spec.ts deleted file mode 100644 index 0fd81265..00000000 --- a/src/app/tab-dashboard/tab-dashboard.page.spec.ts +++ /dev/null @@ -1,45 +0,0 @@ -/* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) - * // - * // This file is part of Beaconchain Dashboard. - * // - * // Beaconchain Dashboard is free software: you can redistribute it and/or modify - * // it under the terms of the GNU General Public License as published by - * // the Free Software Foundation, either version 3 of the License, or - * // (at your option) any later version. - * // - * // Beaconchain Dashboard is distributed in the hope that it will be useful, - * // but WITHOUT ANY WARRANTY; without even the implied warranty of - * // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * // GNU General Public License for more details. - * // - * // You should have received a copy of the GNU General Public License - * // along with Beaconchain Dashboard. If not, see . - */ - -import { async, ComponentFixture, TestBed } from '@angular/core/testing' -import { IonicModule } from '@ionic/angular' -import { DashboardComponentModule } from '../components/dashboard/dashboard.module' - -import { Tab1Page } from './tab-dashboard.page' - -describe('Tab1Page', () => { - let component: Tab1Page - let fixture: ComponentFixture - - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [Tab1Page], - imports: [IonicModule.forRoot(), DashboardComponentModule], - }).compileComponents() - - fixture = TestBed.createComponent(Tab1Page) - component = fixture.componentInstance - fixture.detectChanges() - })) - - it('should create', () => { - expect(component).toBeTruthy() - }) -}) diff --git a/src/app/tab-dashboard/tab-dashboard.page.ts b/src/app/tab-dashboard/tab-dashboard.page.ts deleted file mode 100644 index c47ff596..00000000 --- a/src/app/tab-dashboard/tab-dashboard.page.ts +++ /dev/null @@ -1,158 +0,0 @@ -/* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) - * // - * // This file is part of Beaconchain Dashboard. - * // - * // Beaconchain Dashboard is free software: you can redistribute it and/or modify - * // it under the terms of the GNU General Public License as published by - * // the Free Software Foundation, either version 3 of the License, or - * // (at your option) any later version. - * // - * // Beaconchain Dashboard is distributed in the hope that it will be useful, - * // but WITHOUT ANY WARRANTY; without even the implied warranty of - * // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * // GNU General Public License for more details. - * // - * // You should have received a copy of the GNU General Public License - * // along with Beaconchain Dashboard. If not, see . - */ - -import { Component } from '@angular/core' -import { ApiService } from '../services/api.service' -import { ValidatorUtils } from '../utils/ValidatorUtils' -import OverviewController, { OverviewData } from '../controllers/OverviewController' -import ClientUpdateUtils from '../utils/ClientUpdateUtils' -import { StorageService } from '../services/storage.service' -import { UnitconvService } from '../services/unitconv.service' -import { App, AppState } from '@capacitor/app' -import { SyncService } from '../services/sync.service' -import { MerchantUtils } from '../utils/MerchantUtils' - -export const REAPPLY_KEY = 'reapply_notification2' - -@Component({ - selector: 'app-tab1', - templateUrl: 'tab-dashboard.page.html', - styleUrls: ['tab-dashboard.page.scss'], -}) -export class Tab1Page { - lastRefreshTs = 0 - overallData: OverviewData - initialized = true - currentY = 0 - scrolling = false - - constructor( - private validatorUtils: ValidatorUtils, - public api: ApiService, - public updates: ClientUpdateUtils, - private storage: StorageService, - private unitConv: UnitconvService, - private sync: SyncService, - private merchant: MerchantUtils - ) { - this.validatorUtils.registerListener(() => { - this.refresh() - }) - - App.addListener('appStateChange', (state: AppState) => { - if (state.isActive) { - if (this.lastRefreshTs + 6 * 60 > this.getUnixSeconds()) return - this.refresh() - } else { - console.log('App has become inactive') - } - }) - - this.reApplyNotifications() - } - - async reApplyNotifications() { - const isLoggedIn = await this.storage.getAuthUser() - if (!isLoggedIn) return - - const reapply = await this.storage.getBooleanSetting(REAPPLY_KEY, false) - if (!reapply) { - this.sync.syncAllSettingsForceStaleNotifications() - } - this.storage.setBooleanSetting(REAPPLY_KEY, true) - } - - onScroll($event) { - this.currentY = $event.detail.currentY - } - - onScrollStarted() { - this.scrolling = true - this.removeTooltips() - } - - onScrollEnded() { - this.scrolling = false - } - - private removeTooltips() { - const inputs = Array.from(document.getElementsByTagName('tooltip') as HTMLCollectionOf) - for (let i = 0; i < inputs.length; i++) { - inputs[i].style.display = 'none' - } - } - - ionViewWillEnter() { - if (this.lastRefreshTs + 6 * 60 > this.getUnixSeconds()) return - - this.refresh() - } - - async refresh() { - this.initialized = true - if (!(await this.validatorUtils.hasLocalValdiators())) { - this.initialized = false - return - } - this.updates.checkAllUpdates() - const validators = await this.validatorUtils.getAllMyValidators().catch((error) => { - console.warn('error getAllMyValidators', error) - return [] - }) - const epoch = await this.validatorUtils.getRemoteCurrentEpoch().catch((error) => { - console.warn('error getRemoteCurrentEpoch', error) - return null - }) - const overviewController = new OverviewController( - () => { - if (this.lastRefreshTs + 60 > this.getUnixSeconds()) return - this.api.invalidateCache() - this.refresh() - }, - await this.merchant.getCurrentPlanMaxValidator(), - this.unitConv - ) - - this.overallData = overviewController.processDashboard( - validators, - epoch, - this.validatorUtils.syncCommitteesStatsResponse, - this.validatorUtils.proposalLuckResponse, - this.api.getNetwork() - ) - this.lastRefreshTs = this.getUnixSeconds() - } - - getUnixSeconds() { - return new Date().getTime() / 1000 - } - - async doRefresh(event) { - const old = Object.assign({}, this.overallData) - this.overallData = null - await this.refresh().catch(() => { - this.api.mayInvalidateOnFaultyConnectionState() - this.overallData = old - event.target.complete() - }) - await this.unitConv.updatePriceData() - event.target.complete() - } -} diff --git a/src/app/tab-preferences/notification-base.ts b/src/app/tab-preferences/notification-base.ts deleted file mode 100644 index c92c3de8..00000000 --- a/src/app/tab-preferences/notification-base.ts +++ /dev/null @@ -1,326 +0,0 @@ -import { Injectable, OnInit } from '@angular/core' -import { Platform } from '@ionic/angular' -import { ApiService } from 'src/app/services/api.service' -import { CPU_THRESHOLD, HDD_THRESHOLD, RAM_THRESHOLD, SETTING_NOTIFY, StorageService } from 'src/app/services/storage.service' -import { GetMobileSettingsRequest, MobileSettingsResponse, NotificationGetRequest } from '../requests/requests' -import { AlertService } from '../services/alert.service' -import { SyncService } from '../services/sync.service' -import ClientUpdateUtils, { Clients } from '../utils/ClientUpdateUtils' -import FirebaseUtils from '../utils/FirebaseUtils' - -@Injectable({ - providedIn: 'root', -}) -export class NotificationBase implements OnInit { - notifyInitialized = false - - notify = false - - storageThreshold = 90 - cpuThreshold = 60 - memoryThreshold = 80 - - maxCollateralThreshold = 100 - minCollateralThreshold = 0 - - activeSubscriptionsPerEventMap = new Map() // map storing the count of subscribed validators per event - notifyTogglesMap = new Map() - clientUpdatesTogglesMap = new Map() // identifier = client key - - settingsChanged = false - - constructor( - protected api: ApiService, - protected storage: StorageService, - protected firebaseUtils: FirebaseUtils, - protected platform: Platform, - protected alerts: AlertService, - public sync: SyncService, // If you have to use this, be cautios: This is not always available. We don't know why yet but will research this via BIDS-1117 - protected clientUpdate: ClientUpdateUtils - ) {} - - ngOnInit() { - this.notifyInitialized = false - } - - async setClientToggleState(clientKey: string, state: boolean) { - this.clientUpdatesTogglesMap.set(clientKey, state) - this.settingsChanged = true - if (state) { - await this.clientUpdate.setClient(clientKey, clientKey) - } else { - await this.clientUpdate.setClient(clientKey, 'null') - } - this.clientUpdate.checkClientUpdate(clientKey) - } - - getClientToggleState(clientKey: string): boolean { - const toggle = this.clientUpdatesTogglesMap.get(clientKey) - if (toggle == undefined) { - console.log('Could not return toggle state for client', clientKey) - return false - } - return toggle - } - - setNotifyToggle(eventName: string, event) { - console.log('change notify toggle', eventName, event) - this.settingsChanged = true - this.notifyTogglesMap.set(eventName, event) - } - - public async getDefaultNotificationSetting() { - return (await this.firebaseUtils.hasNotificationConsent()) && (await this.firebaseUtils.hasNotificationToken()) - } - - // Android registers firebase service at app start - // So if there is no token present when enabling notifications, - // there might be no google play services on this device - private async isSupportedOnAndroid() { - if (this.platform.is('android')) { - const hasToken = await this.firebaseUtils.hasNotificationToken() - if (!hasToken) { - return false - } - } - return true - } - - remoteNotifyLoadedOnce = false - async loadAllToggles() { - if (!(await this.storage.isLoggedIn())) return - - const net = this.api.networkConfig.net - - const request = new NotificationGetRequest() - const response = await this.api.execute(request) - const results = request.parse(response) - - const isNotifyClientUpdatesEnabled = await this.storage.isNotifyClientUpdatesEnabled() - - let network = this.api.getNetworkName() - if (network == 'main') { - network = 'mainnet' - } else if (network == 'local dev') { - console.warn( - 'You have set your network to ', - network, - ', subscriptions will not work unless you overwrite the variable below this warning in your code.' - ) - //network = 'prater' // use me, dear developer - } - - const clientsToActivate = [] - - for (const result of results) { - this.setToggleFromEvent(result.EventName, network, true, net) - if (result.EventName == 'monitoring_cpu_load') { - this.cpuThreshold = Math.round(parseFloat(result.EventThreshold) * 100) - this.storage.setSetting(CPU_THRESHOLD, this.cpuThreshold) - } else if (result.EventName == 'monitoring_hdd_almostfull') { - this.storageThreshold = Math.round(100 - parseFloat(result.EventThreshold) * 100) - this.storage.setSetting(HDD_THRESHOLD, this.storageThreshold) - } else if (result.EventName == 'monitoring_memory_usage') { - this.memoryThreshold = Math.round(parseFloat(result.EventThreshold) * 100) - this.storage.setSetting(RAM_THRESHOLD, this.memoryThreshold) - } else if (result.EventName == network + ':rocketpool_colleteral_max') { - const threshold = parseFloat(result.EventThreshold) - if (threshold >= 0) { - this.maxCollateralThreshold = Math.round((threshold - 1) * 1000 + 100) //1 + ((this.maxCollateralThreshold - 100) / 1000) - } else { - this.maxCollateralThreshold = Math.round((1 - threshold * -1) * 1000 - 100) //(1 - ((this.maxCollateralThreshold + 100) / 1000)) * -1 - } - } else if (result.EventName == network + ':rocketpool_colleteral_min') { - this.minCollateralThreshold = Math.round((parseFloat(result.EventThreshold) - 1) * 100) //1 + this.minCollateralThreshold / 100 - } else if (isNotifyClientUpdatesEnabled && result.EventName == 'eth_client_update') { - if ( - result.EventFilter && - result.EventFilter.length >= 1 && - result.EventFilter.charAt(0).toUpperCase() != result.EventFilter.charAt(0) && - result.EventFilter != 'null' && - result.EventFilter != 'none' - ) { - clientsToActivate.push(result.EventFilter) - } - } - } - - if (isNotifyClientUpdatesEnabled) { - Clients.forEach((client) => { - if (clientsToActivate.find((activate) => client.name.toLocaleLowerCase() == activate) != undefined) { - this.setClientToggleState(client.key, true) - } else { - this.setClientToggleState(client.key, false) - } - }) - } - - // locking toggle so we dont execute onChange when setting initial values - const preferences = await this.storage.loadPreferencesToggles(net) - - if (this.api.isNotEthereumMainnet()) { - this.notify = preferences - this.notifyInitialized = true - this.disableToggleLock() - return - } - - await this.getNotificationSetting(preferences).then((result) => { - this.notify = result - this.disableToggleLock() - }) - - this.disableToggleLock() - - this.notifyInitialized = true - - if (!this.remoteNotifyLoadedOnce) { - const remoteNofiy = await this.getRemoteNotificationSetting(preferences) - if (remoteNofiy != this.notify) { - this.notify = remoteNofiy - this.disableToggleLock() - } - this.remoteNotifyLoadedOnce = true - } - } - - async notifyToggle() { - if (!(await this.isSupportedOnAndroid())) { - this.alerts.showInfo( - 'Play Service', - 'Your device can not receive push notifications. Please note that notifications do not work without Google Play Services. As an alternative you can configure webhook notifications on the ' + - this.api.getHostName() + - ' website, otherwise changing these settings will have no effect.' - ) - } - - if (this.platform.is('ios') && (await this.firebaseUtils.hasSeenConsentScreenAndNotConsented())) { - this.notify = false - - this.firebaseUtils.alertIOSManuallyEnableNotifications() - return - } - - if (this.notify == false) { - for (const key of this.notifyTogglesMap.keys()) { - this.notifyTogglesMap.set(key, this.notify) - } - } - - const net = this.api.networkConfig.net - this.storage.setBooleanSetting(net + SETTING_NOTIFY, this.notify) - this.settingsChanged = true - // TODO: instead of using this.api.isEthereumMainnet(), check each app supported network and if - // one single network has notifications enabled, also sync general als true. If all are disabled, - // set general notify as false - if (this.api.isEthereumMainnet() || this.notify == true) { - this.sync.changeGeneralNotify(this.notify) - } - - if (this.notify) this.firebaseUtils.registerPush(true) - - this.api.clearSpecificCache(new NotificationGetRequest()) - } - - private async getRemoteNotificationSetting(notifyLocalStore): Promise { - const local = await this.getNotificationSetting(notifyLocalStore) - const remote = await this.getRemoteNotificationSettingResponse() - - if (remote && notifyLocalStore) { - console.log('Returning notification enabled remote state:', remote.notify_enabled) - return remote.notify_enabled - } - return local - } - - private async getNotificationSetting(notifyLocalStore): Promise { - const local = notifyLocalStore != null ? notifyLocalStore : await this.getDefaultNotificationSetting() - if (!(await this.firebaseUtils.hasNotificationConsent())) return false - console.log('Returning notification enabled local state:', local) - return local - } - - private async getRemoteNotificationSettingResponse(): Promise { - const request = new GetMobileSettingsRequest() - const response = await this.api.execute(request) - const result = request.parse(response) - if (result && result.length >= 1) return result[0] - return null - } - - notifyClientUpdates() { - this.settingsChanged = true - this.sync.changeNotifyClientUpdate('eth_client_update', this.notifyTogglesMap.get('eth_client_update')) - this.api.clearSpecificCache(new NotificationGetRequest()) - } - - private getNotifyToggleFromEvent(eventName: string) { - const toggle = this.notifyTogglesMap.get(eventName) - if (toggle == undefined) { - console.log('Could not return toggle state for event', eventName) - return false - } - return toggle - } - - private setToggleFromEvent(eventNameTagges, network, value, net) { - const parts = eventNameTagges.split(':') - let eventName = eventNameTagges - if (parts.length == 2) { - if (parts[0] != network) { - return - } - if (parts[1].indexOf('monitoring_') >= 0) { - return - } - if (parts[1].indexOf('eth_client_update') >= 0) { - return - } - eventName = parts[1] - } - this.settingsChanged = true - this.notifyTogglesMap.set(eventName, value) - const count = this.activeSubscriptionsPerEventMap.get(eventName) - this.activeSubscriptionsPerEventMap.set(eventName, count ? count + 1 : 1) - - this.storage.setBooleanSetting(net + eventName, value) - } - - getCount(eventName) { - const count = this.activeSubscriptionsPerEventMap.get(eventName) - return count ? count : 0 - } - - notifyEventToggle(eventName, filter = null, threshold = null) { - this.settingsChanged = true - this.sync.changeNotifyEvent(eventName, eventName, this.getNotifyToggleFromEvent(eventName), filter, threshold) - this.api.clearSpecificCache(new NotificationGetRequest()) - } - - clientUpdateOnToggle(clientKey: string) { - this.settingsChanged = true - if (this.getClientToggleState(clientKey)) { - this.sync.changeClient(clientKey, clientKey) - } else { - this.sync.changeClient(clientKey, 'null') - this.api.deleteAllHardStorageCacheKeyContains(clientKey) - } - } - - // include filter in key (fe used by machine toggles) - notifyEventFilterToggle(eventName, filter = null, threshold = null) { - const key = eventName + filter - const value = this.getNotifyToggleFromEvent(eventName) - this.settingsChanged = true - this.storage.setBooleanSetting(eventName, value) - - this.sync.changeNotifyEventUser(key, eventName, value, filter, threshold) - this.api.clearSpecificCache(new NotificationGetRequest()) - } - - disableToggleLock() { - setTimeout(() => { - this.settingsChanged = false - }, 300) - } -} diff --git a/src/app/tab-preferences/tab-preferences.page.html b/src/app/tab-preferences/tab-preferences.page.html index 1c73acc7..416a0bc8 100644 --- a/src/app/tab-preferences/tab-preferences.page.html +++ b/src/app/tab-preferences/tab-preferences.page.html @@ -1,5 +1,5 @@ - - - - - - - - - - - - - - Validators - Edit Mode - - - - - - - Stake Share - RPL Share - - - - - Search Results - My Validators - - - - - - - - - - - - - - - - - -
- -

Nothing found

- We couldn't find the validators you are looking for. Try searching by index, public key, deposit / withdrawal address or withdrawal - credential. -
- -
- -

Add Validators

- - You can add your validators by searching for a public key, validator index, your deposit / withdrawal address or withdrawal credential. - -
- -
-
- -
-
- - -
- -
-
-
diff --git a/src/app/tab-validators/tab-validators.page.spec.ts b/src/app/tab-validators/tab-validators.page.spec.ts deleted file mode 100644 index bdd98e4e..00000000 --- a/src/app/tab-validators/tab-validators.page.spec.ts +++ /dev/null @@ -1,45 +0,0 @@ -/* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) - * // - * // This file is part of Beaconchain Dashboard. - * // - * // Beaconchain Dashboard is free software: you can redistribute it and/or modify - * // it under the terms of the GNU General Public License as published by - * // the Free Software Foundation, either version 3 of the License, or - * // (at your option) any later version. - * // - * // Beaconchain Dashboard is distributed in the hope that it will be useful, - * // but WITHOUT ANY WARRANTY; without even the implied warranty of - * // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * // GNU General Public License for more details. - * // - * // You should have received a copy of the GNU General Public License - * // along with Beaconchain Dashboard. If not, see . - */ - -import { async, ComponentFixture, TestBed } from '@angular/core/testing' -import { IonicModule } from '@ionic/angular' -import { DashboardComponentModule } from '../components/dashboard/dashboard.module' - -import { Tab2Page } from './tab-validators.page' - -describe('Tab2Page', () => { - let component: Tab2Page - let fixture: ComponentFixture - - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [Tab2Page], - imports: [IonicModule.forRoot(), DashboardComponentModule], - }).compileComponents() - - fixture = TestBed.createComponent(Tab2Page) - component = fixture.componentInstance - fixture.detectChanges() - })) - - it('should create', () => { - expect(component).toBeTruthy() - }) -}) diff --git a/src/app/tab-validators/tab-validators.page.ts b/src/app/tab-validators/tab-validators.page.ts deleted file mode 100644 index 9765c9b4..00000000 --- a/src/app/tab-validators/tab-validators.page.ts +++ /dev/null @@ -1,627 +0,0 @@ -/* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) - * // - * // This file is part of Beaconchain Dashboard. - * // - * // Beaconchain Dashboard is free software: you can redistribute it and/or modify - * // it under the terms of the GNU General Public License as published by - * // the Free Software Foundation, either version 3 of the License, or - * // (at your option) any later version. - * // - * // Beaconchain Dashboard is distributed in the hope that it will be useful, - * // but WITHOUT ANY WARRANTY; without even the implied warranty of - * // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * // GNU General Public License for more details. - * // - * // You should have received a copy of the GNU General Public License - * // along with Beaconchain Dashboard. If not, see . - */ - -import { Component, ViewChild } from '@angular/core' -import { ValidatorUtils, Validator, ValidatorState } from '../utils/ValidatorUtils' -import { IonSearchbar, ModalController, Platform } from '@ionic/angular' -import { ValidatordetailPage } from '../pages/validatordetail/validatordetail.page' -import { ApiService } from '../services/api.service' -import { AlertController } from '@ionic/angular' -import { ValidatorResponse } from '../requests/requests' -import { StorageService } from '../services/storage.service' -import { AlertService } from '../services/alert.service' -import { SyncService } from '../services/sync.service' -import BigNumber from 'bignumber.js' -import { SubscribePage } from '../pages/subscribe/subscribe.page' -import { MerchantUtils } from '../utils/MerchantUtils' - -import { Keyboard } from '@capacitor/keyboard' - -import { Toast } from '@capacitor/toast' -import ThemeUtils from '../utils/ThemeUtils' - -import { Haptics } from '@capacitor/haptics' -import { UnitconvService } from '../services/unitconv.service' -import { InfiniteScrollDataSource } from '../utils/InfiniteScrollDataSource' -import { trigger, style, animate, transition } from '@angular/animations' -@Component({ - selector: 'app-tab2', - templateUrl: 'tab-validators.page.html', - styleUrls: ['tab-validators.page.scss'], - animations: [trigger('fadeIn', [transition(':enter', [style({ opacity: 0 }), animate('300ms 100ms', style({ opacity: 1 }))])])], -}) -export class Tab2Page { - dataSource: InfiniteScrollDataSource - - public classReference = UnitconvService - - searchResultMode = false - loading = false - - reachedMaxValidators = false - - isLoggedIn = false - - initialized = false - - currentPackageMaxValidators = 100 - - selectMode = false - - selected = new Map() - - @ViewChild('searchbarRef', { static: true }) searchbarRef: IonSearchbar - - constructor( - private validatorUtils: ValidatorUtils, - public modalController: ModalController, - public api: ApiService, - private alertController: AlertController, - private storage: StorageService, - private alerts: AlertService, - private sync: SyncService, - private merchant: MerchantUtils, - private themeUtils: ThemeUtils, - private platform: Platform, - public unit: UnitconvService - ) { - this.validatorUtils.registerListener(() => { - if (this.searchResultMode && this.searchbarRef) { - this.searchResultMode = false - this.searchbarRef.value = null - } - this.refresh() - }) - this.merchant.getCurrentPlanMaxValidator().then((result) => { - this.currentPackageMaxValidators = result - }) - - this.dataSource = new InfiniteScrollDataSource(InfiniteScrollDataSource.ALL_ITEMS_AT_ONCE, this.getDefaultDataRetriever()) - } - - ngOnInit() { - this.refresh() - } - - private async refresh() { - this.reachedMaxValidators = false - this.storage.isLoggedIn().then((result) => (this.isLoggedIn = result)) - - if (!this.searchResultMode) { - this.dataSource.setLoadFrom(this.getDefaultDataRetriever()) - } - await this.dataSource.reset() - } - - async syncRemote() { - const loading = await this.alerts.presentLoading('Syncing...') - loading.present() - this.sync.fullSync() - setTimeout(() => { - loading.dismiss() - }, 2000) - } - - private getDefaultDataRetriever() { - return () => { - return this.getValidatorData() - } - } - - private async getValidatorData() { - this.searchResultMode = false - - if (!(await this.validatorUtils.hasLocalValdiators())) { - this.initialized = true - return [] - } - - this.setLoading(true) - - let temp = await this.validatorUtils.getAllMyValidators().catch((error) => { - console.warn('error getAllMyValidators', error) - return [] as Validator[] - }) - - temp = temp.sort((a, b) => { - if (a.state == ValidatorState.SLASHED && b.state != ValidatorState.SLASHED) { - return -1 - } - if (b.state == ValidatorState.SLASHED && a.state != ValidatorState.SLASHED) { - return 1 - } - - if (a.state == ValidatorState.OFFLINE && b.state == ValidatorState.OFFLINE) { - return -1 - } - if (b.state == ValidatorState.OFFLINE && a.state == ValidatorState.OFFLINE) { - return 1 - } - - if (a.state == ValidatorState.WAITING && b.state == ValidatorState.WAITING) { - return -1 - } - if (b.state == ValidatorState.WAITING && a.state == ValidatorState.WAITING) { - return 1 - } - - if (a.index > b.index) { - return 1 - } else if (a.index == b.index) { - return 0 - } else { - return -1 - } - }) - this.setLoading(false) - return temp - } - - private setLoading(loading: boolean) { - if (loading) { - if (!this.dataSource || !this.dataSource.hasItems()) { - this.loading = true - } - } else { - if (this.loading) { - setTimeout(() => { - this.initialized = true - this.loading = false - }, 350) - } else { - this.initialized = true - this.loading = false - } - } - } - - removeAllDialog() { - this.showDialog('Remove all', 'Do you want to remove {AMOUNT} validators from your dashboard?', () => { - this.confirmRemoveAll() - }) - } - - addAllDialog() { - this.showDialog('Add all', 'Do you want to add {AMOUNT} validators to your dashboard?', () => { - this.confirmAddAll() - }) - } - - private async showDialog(title, text, action: () => void) { - const size = this.dataSource.length() - const alert = await this.alertController.create({ - header: title, - message: text.replace('{AMOUNT}', size + ''), - buttons: [ - { - text: 'Cancel', - role: 'cancel', - cssClass: 'secondary', - }, - { - text: 'Yes', - handler: action, - }, - ], - }) - - await alert.present() - } - - async confirmRemoveAll() { - await this.validatorUtils.deleteAll() - await this.dataSource.reset() - } - - async confirmAddAll() { - const responses: ValidatorResponse[] = [] - this.dataSource.getItems().forEach((item) => { - responses.push(item.data) - }) - - await this.validatorUtils.convertToValidatorModelsAndSaveLocal(false, responses) - await this.dataSource.reset() - } - - searchEvent(event) { - this.searchFor(event.target.value) - } - - async searchFor(searchString) { - if (!searchString || searchString.length < 0) return - if (this.platform.is('ios') || this.platform.is('android')) { - Keyboard.hide() - } - - this.searchResultMode = true - this.loading = true - const isETH1Address = searchString.startsWith('0x') && searchString.length == 42 - const isWithdrawalCredential = searchString.startsWith('0x') && searchString.length == 66 - - if (isETH1Address || isWithdrawalCredential) await this.searchETH1(searchString) - else await this.searchByPubKeyOrIndex(searchString) - - // this.loading = false would be preferable here but somehow the first time it is called the promises resolve instantly without waiting - // but it works for any subsequent calls ¯\_(ツ)_/¯ - // workaround for now is to set it in searchETH1 and searchByPubKeyOrIndex - } - - private async searchByPubKeyOrIndex(target) { - this.dataSource.setLoadFrom(() => { - return this.validatorUtils - .searchValidators(target) - .catch((error) => { - console.warn('search error', error) - return [] - }) - .then((result) => { - this.loading = false - return result - }) - }) - return await this.dataSource.reset() - } - - private async searchETH1(target) { - this.dataSource.setLoadFrom(() => { - return this.validatorUtils - .searchValidatorsViaETHAddress(target) - .catch(async (error) => { - if (error && error.message && error.message.indexOf('only a maximum of') > 0) { - console.log('SET reachedMaxValidators to true') - this.reachedMaxValidators = true - return this.validatorUtils.searchValidatorsViaETHAddress(target, this.currentPackageMaxValidators - 1) - } - return [] - }) - .then((result) => { - this.loading = false - return result - }) - }) - return await this.dataSource.reset() - } - - cancelSearch() { - if (this.searchResultMode) { - this.searchResultMode = false - this.refresh() - } - } - - async doRefresh(event) { - await this.refresh().catch(() => { - this.api.mayInvalidateOnFaultyConnectionState() - event.target.complete() - }) - event.target.complete() - } - - async presentModal(item: Validator) { - const modal = await this.modalController.create({ - component: ValidatordetailPage, - cssClass: 'my-custom-class', - componentProps: { - item: item, - }, - }) - return await modal.present() - } - - ionViewDidLeave() { - this.validatorUtils.notifyListenersIfDeletedWithoutNotifying() - this.sync.mightSyncUpAndSyncDelete() - } - - async upgrade() { - const modal = await this.modalController.create({ - component: SubscribePage, - cssClass: 'my-custom-class', - componentProps: { - tab: 'whale', - }, - }) - return await modal.present() - } - - private clickBlocked = false - blockClick(forTime) { - this.clickBlocked = true - setTimeout(() => { - this.clickBlocked = false - }, forTime) - } - - selectValidator(item: Validator) { - this.selectMode = !this.selectMode - if (!this.selectMode) { - this.cancelSelect() - } else { - this.blockClick(250) - const color = getComputedStyle(document.body).getPropertyValue('--ion-color-primary') - this.themeUtils.setStatusBarColor(color) - Haptics.selectionStart() - - if (item) { - this.selected.set(item.index, true) - Haptics.selectionChanged() - } - } - } - - clickValidator(item: Validator) { - if (this.clickBlocked) return - if (this.selectMode) { - if (this.selected.get(item.index)) { - this.selected.delete(item.index) - } else { - this.selected.set(item.index, true) - } - Haptics.selectionChanged() - } else { - this.presentModal(item) - } - } - - cancelSelect() { - this.selectMode = false - this.selected = new Map() - this.themeUtils.revertStatusBarColor() - Haptics.selectionEnd() - } - - getValidatorsByIndex(indexMap): Validator[] { - const result = [] - indexMap.forEach((value, key) => { - const temp = this.dataSource.getItems().find((item) => { - return item.index == key - }) - if (temp) { - result.push(temp) - } - }) - return result - } - - /** - * Returns the current stake share for the provided validator set. Returns the stake share if all share the same or null otherwise. - * @param subArray - */ - getCurrentShare(subArray: Validator[]): number { - if (subArray.length <= 0) return null - const lastShare = subArray[0].share - for (let i = 1; i < subArray.length; i++) { - if (lastShare != subArray[i].share) return null - } - return lastShare - } - - getCurrentELShare(subArray: Validator[]): number { - if (subArray.length <= 0) return null - const lastShare = subArray[0].execshare - for (let i = 1; i < subArray.length; i++) { - if (lastShare != subArray[i].execshare) return null - } - return lastShare - } - - async setRPLShares() { - if (this.selected.size <= 0) { - Toast.show({ - text: 'Select the validators you want to apply this setting to.', - }) - return - } - - const validatorSubArray = this.getValidatorsByIndex(this.selected).filter((item) => { - return item.rocketpool != null - }) - - if (validatorSubArray.length <= 0) { - console.log('You did not select any Rocketpool validator.') - Toast.show({ - text: 'You did not select any Rocketpool validator.', - }) - return - } - - const onlyOneNodeAddress = validatorSubArray.reduce((prev, cur) => { - return prev && prev.rocketpool.node_address == cur.rocketpool.node_address ? cur : null - }) - if (!onlyOneNodeAddress) { - console.log('You selected validators belonging to multiple node addresses. Currently only one at a time can be edited.') - Toast.show({ - text: 'You selected validators belonging to multiple node addresses. Currently only one at a time can be edited.', - }) - return - } - - const minShareStake = 0 - const maxStakeShare = new BigNumber(onlyOneNodeAddress.rocketpool.node_rpl_stake).dividedBy(new BigNumber(1e18)).decimalPlaces(2) - - const currentShares = await this.validatorUtils.getRocketpoolCollateralShare(onlyOneNodeAddress.rocketpool.node_address) - let current = null - if (currentShares) { - current = new BigNumber(currentShares).multipliedBy(new BigNumber(maxStakeShare)).decimalPlaces(4) - } - - console.log('change RPL', onlyOneNodeAddress, current, maxStakeShare) - - const alert = await this.alertController.create({ - cssClass: 'my-custom-class', - header: 'Define RPL share', - message: - 'If you own partial amounts of the collateral of the selected Rocketpool node address (' + - onlyOneNodeAddress.rocketpool.node_address.substring(0, 8) + - '), specify the amount of RPL for a custom dashboard.', - inputs: [ - { - name: 'share', - type: 'number', - placeholder: minShareStake + ' - ' + maxStakeShare + ' RPL', - value: current, - }, - ], - buttons: [ - { - text: 'Remove', - handler: () => { - this.validatorUtils.saveRocketpoolCollateralShare(onlyOneNodeAddress.rocketpool.node_address, null) - this.cancelSelect() - this.validatorUtils.notifyListeners() - }, - }, - { - text: 'Save', - handler: (alertData) => { - const shares = alertData.share - if (shares < minShareStake) { - Toast.show({ - text: 'Share must be at least ' + minShareStake + ' RPL or more.', - }) - return - } - - if (shares > maxStakeShare.toNumber()) { - Toast.show({ - text: 'Share amount is higher than your RPL collateral.', - }) - return - } - - const share = new BigNumber(alertData.share).div(new BigNumber(maxStakeShare)) - this.validatorUtils.saveRocketpoolCollateralShare(onlyOneNodeAddress.rocketpool.node_address, share.toNumber()) - - this.cancelSelect() - this.validatorUtils.notifyListeners() - }, - }, - ], - }) - - await alert.present() - } - - async setShares() { - if (this.selected.size <= 0) { - Toast.show({ - text: 'Select the validators you want to apply this setting to.', - }) - return - } - - const validatorSubArray = this.getValidatorsByIndex(this.selected) - console.log('selected', this.selected, validatorSubArray) - - let sum = new BigNumber('0') - for (const val of validatorSubArray) { - let temp = new BigNumber(val.data.effectivebalance) - if (val.rocketpool) { - const nodeBalance = new BigNumber(val.rocketpool.node_deposit_balance).dividedBy(1e9) - const partRatio = nodeBalance.dividedBy(temp) - temp = temp.multipliedBy(partRatio) - } - sum = sum.plus(temp) - } - - const minShareStake = 0 - const maxStakeShare = sum.dividedBy(1e9).decimalPlaces(0).toNumber() - - const current = new BigNumber(this.getCurrentShare(validatorSubArray)).multipliedBy(new BigNumber(maxStakeShare)).decimalPlaces(4) - - const currentEL = new BigNumber(this.getCurrentELShare(validatorSubArray)).multipliedBy(new BigNumber(maxStakeShare)).decimalPlaces(4) - - const alert = await this.alertController.create({ - cssClass: 'my-custom-class', - header: 'Define stake share', - message: - 'If you own partial amounts of these validators, specify the amount of ' + - this.api.getCurrenciesFormatted() + - ' for a custom dashboard. First value defines your consensus share, second value your execution share.', - inputs: [ - { - name: 'share', - type: 'number', - placeholder: 'Consensus Share (' + minShareStake + ' - ' + maxStakeShare + ' ETH)', - value: current, - }, - { - name: 'execshare', - type: 'number', - placeholder: 'Execution Share (' + minShareStake + ' - ' + maxStakeShare + ' ETH)', - value: currentEL, - }, - ], - buttons: [ - { - text: 'Remove', - handler: () => { - for (let i = 0; i < validatorSubArray.length; i++) { - validatorSubArray[i].share = null - validatorSubArray[i].execshare = null - } - this.validatorUtils.saveValidatorsLocal(validatorSubArray) - this.cancelSelect() - this.validatorUtils.notifyListeners() - }, - }, - { - text: 'Save', - handler: (alertData) => { - const shares = alertData.share - const sharesEL = alertData.execshare - if ((shares && shares < minShareStake) || (sharesEL && sharesEL < minShareStake)) { - Toast.show({ - text: 'Share must be at least ' + minShareStake + ' ETH or more', - }) - return - } - - if ((shares && shares > maxStakeShare) || (sharesEL && shares > maxStakeShare)) { - Toast.show({ - text: 'Share amount is higher than all of your added validators.', - }) - return - } - - const share = new BigNumber(alertData.share).div(new BigNumber(maxStakeShare)) - const shareEL = new BigNumber(alertData.execshare).div(new BigNumber(maxStakeShare)) - - for (let i = 0; i < validatorSubArray.length; i++) { - if (shares && !share.isNaN()) { - validatorSubArray[i].share = share.toNumber() - } - if (shareEL && !shareEL.isNaN()) { - validatorSubArray[i].execshare = shareEL.toNumber() - } - } - - this.validatorUtils.saveValidatorsLocal(validatorSubArray) - - this.cancelSelect() - this.validatorUtils.notifyListeners() - }, - }, - ], - }) - - await alert.present() - } -} diff --git a/src/app/tab-blocks/tab-blocks-routing.module.ts b/src/app/tabs/tab-blocks/tab-blocks-routing.module.ts similarity index 100% rename from src/app/tab-blocks/tab-blocks-routing.module.ts rename to src/app/tabs/tab-blocks/tab-blocks-routing.module.ts diff --git a/src/app/tab-blocks/tab-blocks.module.ts b/src/app/tabs/tab-blocks/tab-blocks.module.ts similarity index 53% rename from src/app/tab-blocks/tab-blocks.module.ts rename to src/app/tabs/tab-blocks/tab-blocks.module.ts index acdf25cb..8c50b0b1 100644 --- a/src/app/tab-blocks/tab-blocks.module.ts +++ b/src/app/tabs/tab-blocks/tab-blocks.module.ts @@ -7,10 +7,13 @@ import { IonicModule } from '@ionic/angular' import { TabBlocksPageRoutingModule } from './tab-blocks-routing.module' import { TabBlocksPage } from './tab-blocks.page' -import { BlockComponentModule } from '../components/block/block.module' -import { AdComponentModule } from '../components/ad/ad.module' -import { PipesModule } from '../pipes/pipes.module' +import { BlockComponentModule } from '@components/block/block.module' +import { AdComponentModule } from '@components/ad/ad.module' +import { PipesModule } from '../../pipes/pipes.module' import { ScrollingModule } from '@angular/cdk/scrolling' +import { FullPageLoadingComponent } from '@components/full-page-loading/full-page-loading.component' +import { FullPageOfflineComponent } from '@components/full-page-offline/full-page-offline.component' +import { OfflineComponentModule } from '@components/offline/offline.module' @NgModule({ imports: [ @@ -22,6 +25,9 @@ import { ScrollingModule } from '@angular/cdk/scrolling' BlockComponentModule, AdComponentModule, PipesModule, + FullPageLoadingComponent, + FullPageOfflineComponent, + OfflineComponentModule, ], declarations: [TabBlocksPage], }) diff --git a/src/app/tabs/tab-blocks/tab-blocks.page.html b/src/app/tabs/tab-blocks/tab-blocks.page.html new file mode 100644 index 00000000..bd58456b --- /dev/null +++ b/src/app/tabs/tab-blocks/tab-blocks.page.html @@ -0,0 +1,77 @@ + + + + + + Blocks + + + + + + + + + Proposal Luck: + {{ summaryGroup().luck.proposal.percent | number:'1.0-1' }}% + - + + + + + + + + + + + + + + +

+ On average, next block expected in + On average, next block was expected +
+ ~{{ expectedNextBlockTs() | timeago }} +

+ + + +
+ +

No Blocks So Far

+ Your proposed blocks will show up here. +
+ + +
+ +
+
+ Loading... +
+
+
+
+
diff --git a/src/app/tab-blocks/tab-blocks.page.scss b/src/app/tabs/tab-blocks/tab-blocks.page.scss similarity index 82% rename from src/app/tab-blocks/tab-blocks.page.scss rename to src/app/tabs/tab-blocks/tab-blocks.page.scss index 0d4b0cab..dd98c835 100644 --- a/src/app/tab-blocks/tab-blocks.page.scss +++ b/src/app/tabs/tab-blocks/tab-blocks.page.scss @@ -1,4 +1,4 @@ -// Copyright (C) 2022 Bitfly GmbH +// Copyright (C) 2022 bitfly explorer GmbH // // This file is part of Beaconchain Dashboard. // @@ -15,7 +15,7 @@ // You should have received a copy of the GNU General Public License // along with Beaconchain Dashboard. If not, see . -@import '../../theme/variables.scss'; +@use '../../../theme/variables.scss'; .toolbar-btn::part(native) { --ion-color-contrast: var(--x-toolbar-title-color); @@ -36,17 +36,18 @@ } .top-bar { - padding-bottom: 0px !important; + padding: 0px !important; + background: var(--ion-item-background); margin-bottom: 0px !important; } .next-block-hint { opacity: 0.6; - font-size: 0.85rem; + font-size: var(--smaller-info-size); + font-weight: 400; //var(--smaller-label-weight); text-align: center; - margin-block-start: 6px; - margin-block-end: 6px; + margin: 6px 6px 6px 6px; } .nothingfound { @@ -59,8 +60,9 @@ } ion-label { - font-weight: normal; - color: var(--ion-text-color-lighter); + //font-weight: normal; + //color: var(--ion-text-color-lighter); + opacity: var(--default-secondary-transparency); } cdk-virtual-scroll-viewport { @@ -84,8 +86,3 @@ cdk-virtual-scroll-viewport { margin-top: 7px; font-size: 69px; } - -.loading-spinner { - margin-top: 55px; - margin-bottom: 10px; -} diff --git a/src/app/tabs/tab-blocks/tab-blocks.page.ts b/src/app/tabs/tab-blocks/tab-blocks.page.ts new file mode 100644 index 00000000..ef238461 --- /dev/null +++ b/src/app/tabs/tab-blocks/tab-blocks.page.ts @@ -0,0 +1,236 @@ +import { Component, computed, OnInit, signal, ViewChild, WritableSignal } from '@angular/core' +import { ModalController } from '@ionic/angular' +import { BlockDetailPage } from '@pages/block-detail/block-detail.page' +import { APINotFoundError, ApiResult, APIUnauthorizedError } from '@requests/requests' +import { AlertService } from '@services/alert.service' +import { ApiService } from '@services/api.service' +import { UnitconvService } from '@services/unitconv.service' +import { InfiniteScrollDataSource, loadMoreType } from '@utils/InfiniteScrollDataSource' +import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling' +import { VDBBlocksTableRow, VDBGroupSummaryData } from '@requests/types/validator_dashboard' +import { StorageService } from '@services/storage.service' +import { dashboardID, Period, V2DashboardSummaryGroupTable } from '@requests/v2-dashboard' +import { Toast } from '@capacitor/toast' +import { V2DashboardBlocks } from '@requests/v2-blocks' +import { DashboardAndGroupSelectComponent } from '@modals/dashboard-and-group-select/dashboard-and-group-select.component' +import { DashboardUtils } from '@utils/DashboardUtils' +import { relativeTs, toDateTime } from '@utils/TimeUtils' + +const PAGE_SIZE = 25 +const DASHBOARD_UPDATE = 'blocks_update' +const ASSOCIATED_CACHE_KEY = 'blocks' +@Component({ + selector: 'app-tab-blocks', + templateUrl: './tab-blocks.page.html', + styleUrls: ['./tab-blocks.page.scss'], + standalone: false, +}) +export class TabBlocksPage implements OnInit { + public classReference = UnitconvService + + dataSource: InfiniteScrollDataSource + @ViewChild(CdkVirtualScrollViewport) virtualScroll: CdkVirtualScrollViewport + + initialLoading = true + loadMore = false + + initialized = false + + isLoggedIn = false + dashboardID: dashboardID + + summaryGroup: WritableSignal = signal(null) + + chainID = 0 + + online: boolean = true + + constructor( + public api: ApiService, + public unit: UnitconvService, + public modalController: ModalController, + private alertService: AlertService, + private storage: StorageService, + private modalCtrl: ModalController, + private alerts: AlertService, + private dashboardUtils: DashboardUtils + ) { + this.dashboardUtils.dashboardAwareListener.register(DASHBOARD_UPDATE) + } + + async ionViewWillEnter() { + if (this.dashboardUtils.dashboardAwareListener.hasAndConsume(DASHBOARD_UPDATE)) { + await this.clearRequestCache() + await this.setup() + await this.update() + return + } + } + + async ngOnInit() { + this.initialized = false + await this.setup() + await this.update() + } + + /** + * Call when you need to clear the API request cache for all calls this view made. + * Note: when making calls in this view, always use the ASSOCIATED_CACHE_KEY + * @returns promise void + */ + clearRequestCache() { + return this.api.clearAllAssociatedCacheKeys(ASSOCIATED_CACHE_KEY) + } + + private async setup() { + this.dashboardID = await this.dashboardUtils.initDashboard() + this.isLoggedIn = await this.storage.isLoggedIn() + this.chainID = await this.api.getCurrentDashboardChainID() + + if (!this.dashboardID) { + this.initialized = true + this.initialLoading = false + return + } + + await this.loadSummaryGroup() + this.dataSource = new InfiniteScrollDataSource(PAGE_SIZE, this.getDefaultDataRetriever()) + } + + private async loadSummaryGroup(recursiveMax = false): Promise> { + const result = await this.api.set( + new V2DashboardSummaryGroupTable(this.dashboardID, 0, Period.AllTime, null), + this.summaryGroup, + ASSOCIATED_CACHE_KEY + ) + if (result.error) { + if (result.error instanceof APINotFoundError) { + if (recursiveMax) { + Toast.show({ + text: 'Dashboard not found', + }) + return + } + this.storage.setDashboardID(null) + // if dashboard is not available any more (maybe user deleted it) reinit and try again + this.dashboardID = await this.dashboardUtils.initDashboard() + return this.loadSummaryGroup(true) + } else { + this.dashboardUtils.defaultDashboardErrorHandler(result.error) + } + } + return result + } + + private getDefaultDataRetriever(): loadMoreType { + return async (cursor) => { + this.loadMore = !!cursor + const result = await this.api.execute(new V2DashboardBlocks(this.dashboardID, cursor, PAGE_SIZE), ASSOCIATED_CACHE_KEY) + if (result.error) { + Toast.show({ + text: 'Could not load blocks', + duration: 'long', + }) + if (!(result.error instanceof APIUnauthorizedError)) { + // todo change to just if timeout? + this.online = false + } + + console.error('Could not load blocks', result.error) + return { + data: undefined, + next_cursor: null, + } + } + this.loadMore = false + + return { + data: result.data as VDBBlocksTableRow[], + next_cursor: result.paging?.next_cursor, + } + } + } + + expectedNextBlockTs = computed(() => { + console.log('expectedNextBlockTs', this.summaryGroup()) + if (!this.summaryGroup()) { + return new Date() + } + return toDateTime(this.summaryGroup()?.luck?.proposal?.expected_timestamp ?? 0) + }) + + private async update() { + if (!this.dashboardID) { + return + } + this.initialLoading = true + this.online = true + + await this.dataSource.reset() + this.virtualScroll.scrollToIndex(0) + this.initialized = true + + this.initialLoading = false + } + + async clickBlock(item: VDBBlocksTableRow) { + const modal = await this.modalController.create({ + component: BlockDetailPage, + cssClass: 'my-custom-class', + componentProps: { + block: item, + }, + }) + return await modal.present() + } + + private lastRefreshedTs: number = 0 + async doRefresh(event: { target: { complete: () => void } }) { + if (this.lastRefreshedTs + 15 * 1000 > new Date().getTime()) { + Toast.show({ + text: 'Nothing to update', + }) + if (event) event.target.complete() + return + } + this.lastRefreshedTs = new Date().getTime() + + await this.clearRequestCache() + this.update() + if (event) event.target.complete() + } + + luckHelp() { + if (!this.summaryGroup()) { + this.alertService.showInfo( + 'Proposal Luck', + `Compares the number of your actual proposed blocks to the expected average blocks per validator during the last month. + You'll see your luck percentage once you have proposed a block.` + ) + } else { + this.alertService.showInfo( + 'Proposal Luck', + `With current network conditions, your validators are expected to produce a block every ${relativeTs( + this.summaryGroup().luck.proposal.average_interval_seconds + )} (on average).` + ) + } + } + + async openDashboardAndGroupSelect() { + const modal = await this.modalCtrl.create({ + component: DashboardAndGroupSelectComponent, + componentProps: { + dashboardChangedCallback: async () => { + const loading = await this.alerts.presentLoading('Loading...') + loading.present() + await this.ngOnInit() + loading.dismiss() + }, + }, + }) + modal.present() + + await modal.onWillDismiss() + } +} diff --git a/src/app/tab-dashboard/tab-dashboard-routing.module.ts b/src/app/tabs/tab-dashboard/tab-dashboard-routing.module.ts similarity index 92% rename from src/app/tab-dashboard/tab-dashboard-routing.module.ts rename to src/app/tabs/tab-dashboard/tab-dashboard-routing.module.ts index a1e321ba..ad3461b0 100644 --- a/src/app/tab-dashboard/tab-dashboard-routing.module.ts +++ b/src/app/tabs/tab-dashboard/tab-dashboard-routing.module.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // diff --git a/src/app/tab-dashboard/tab-dashboard.module.ts b/src/app/tabs/tab-dashboard/tab-dashboard.module.ts similarity index 74% rename from src/app/tab-dashboard/tab-dashboard.module.ts rename to src/app/tabs/tab-dashboard/tab-dashboard.module.ts index 62dcace3..98db634d 100644 --- a/src/app/tab-dashboard/tab-dashboard.module.ts +++ b/src/app/tabs/tab-dashboard/tab-dashboard.module.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -23,11 +22,12 @@ import { NgModule } from '@angular/core' import { CommonModule } from '@angular/common' import { FormsModule } from '@angular/forms' import { Tab1Page } from './tab-dashboard.page' -import { DashboardComponentModule } from '../components/dashboard/dashboard.module' -import { OfflineComponentModule } from '../components/offline/offline.module' -import { HelpComponentModule } from '../components/help/help.module' +import { DashboardComponentModule } from '@components/dashboard/dashboard.module' +import { OfflineComponentModule } from '@components/offline/offline.module' +import { HelpComponentModule } from '@components/help/help.module' import { Tab1PageRoutingModule } from './tab-dashboard-routing.module' -import { PipesModule } from '../pipes/pipes.module' +import { PipesModule } from '../../pipes/pipes.module' +import { FullPageOfflineComponent } from '@components/full-page-offline/full-page-offline.component' @NgModule({ imports: [ @@ -39,6 +39,7 @@ import { PipesModule } from '../pipes/pipes.module' Tab1PageRoutingModule, HelpComponentModule, PipesModule, + FullPageOfflineComponent, ], declarations: [Tab1Page], }) diff --git a/src/app/tabs/tab-dashboard/tab-dashboard.page.html b/src/app/tabs/tab-dashboard/tab-dashboard.page.html new file mode 100644 index 00000000..d46c9fc3 --- /dev/null +++ b/src/app/tabs/tab-dashboard/tab-dashboard.page.html @@ -0,0 +1,110 @@ + + + + + + + + Dashboard + {{ dashboardName }} + + {{formattedSelectedTimeframe()}} + + + + + + + + + + + Show All Time + Show Last Hour + Show Last 24h + Show Last 7d + Show Last 30d + + + + + + + +
+
+ +

Let´s get started

+
+
+ + + + + +
+
diff --git a/src/app/tab-dashboard/tab-dashboard.page.scss b/src/app/tabs/tab-dashboard/tab-dashboard.page.scss similarity index 69% rename from src/app/tab-dashboard/tab-dashboard.page.scss rename to src/app/tabs/tab-dashboard/tab-dashboard.page.scss index 5087562d..c0953796 100644 --- a/src/app/tab-dashboard/tab-dashboard.page.scss +++ b/src/app/tabs/tab-dashboard/tab-dashboard.page.scss @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -18,7 +17,7 @@ * // along with Beaconchain Dashboard. If not, see . */ -@import '../../theme/variables.scss'; +@use '../../../theme/variables.scss'; .inner-setup-head ion-icon { width: 100%; @@ -47,12 +46,54 @@ font-size: 69px; } +ion-content { + width: calc(100% + 15px); +} // Makes the iOS top bounce in our primary color // and the bottom bounce in main themes color -ion-content { +.ios-background { --background: linear-gradient(0deg, var(--ion-background-color) 60%, var(--ion-toolbar-background) 40%); } +ion-content::part(scroll) { + padding-right: 15px; +} + +.ion-content-scroll-host::before, +.ion-content-scroll-host::after { + position: absolute; + + width: 1px; + height: 1px; + + content: ''; +} + +.ion-content-scroll-host::before { + bottom: -1px; +} + +.ion-content-scroll-host::after { + top: -1px; +} + ion-refresher-content { --color: #fff !important; } + +.selected { + font-weight: bold; + color: var(--ion-color-primary); +} + +.sub-text { + --color: var(--x-toolbar-title-color); + left: 0; + top: 40px; + bottom: 0; + margin: auto; + position: absolute; + width: 100%; + text-align: center; + font-size: 0.65rem; +} diff --git a/src/app/tabs/tab-dashboard/tab-dashboard.page.ts b/src/app/tabs/tab-dashboard/tab-dashboard.page.ts new file mode 100644 index 00000000..2fc5bb53 --- /dev/null +++ b/src/app/tabs/tab-dashboard/tab-dashboard.page.ts @@ -0,0 +1,254 @@ +/* + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH + * // + * // This file is part of Beaconchain Dashboard. + * // + * // Beaconchain Dashboard is free software: you can redistribute it and/or modify + * // it under the terms of the GNU General Public License as published by + * // the Free Software Foundation, either version 3 of the License, or + * // (at your option) any later version. + * // + * // Beaconchain Dashboard is distributed in the hope that it will be useful, + * // but WITHOUT ANY WARRANTY; without even the implied warranty of + * // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * // GNU General Public License for more details. + * // + * // You should have received a copy of the GNU General Public License + * // along with Beaconchain Dashboard. If not, see . + */ + +import { Component, computed, OnInit } from '@angular/core' +import { ApiService } from '@services/api.service' +import { OverviewData2, OverviewProvider, SummaryChartOptions } from '../../controllers/OverviewController' +import ClientUpdateUtils from '@utils/ClientUpdateUtils' +import { StorageService } from '@services/storage.service' +import { UnitconvService } from '@services/unitconv.service' +import { App, AppState } from '@capacitor/app' +import { MerchantUtils } from '@utils/MerchantUtils' +import { ModalController } from '@ionic/angular' +import { DashboardAndGroupSelectComponent } from '@modals/dashboard-and-group-select/dashboard-and-group-select.component' +import { dashboardID, Period } from '@requests/v2-dashboard' +import { AlertService } from '@services/alert.service' +import { Toast } from '@capacitor/toast' +import { DashboardUtils } from '@utils/DashboardUtils' +import { APIError, APINotFoundError, APIUnauthorizedError } from '@requests/requests' + +export const REAPPLY_KEY = 'reapply_notification2' + +const DASHBOARD_UPDATE = 'dashboard_update' +export const ASSOCIATED_CACHE_KEY = 'dashboard' + +@Component({ + selector: 'app-tab1', + templateUrl: 'tab-dashboard.page.html', + styleUrls: ['tab-dashboard.page.scss'], + standalone: false, +}) +export class Tab1Page implements OnInit { + readonly Period = Period + + lastRefreshTs = 0 + overallData: OverviewData2 + currentY = 0 + scrolling = false + isLoggedIn = false + dashboardID: dashboardID = null + + loading: boolean = true + fadeInCompleted: boolean = false + + online: boolean = true + dashboardName: string = '' + + constructor( + public api: ApiService, + public updates: ClientUpdateUtils, + private storage: StorageService, + private unitConv: UnitconvService, + public merchant: MerchantUtils, + private modalCtrl: ModalController, + private alert: AlertService, + private overviewProvider: OverviewProvider, + private dashboardUtils: DashboardUtils + ) { + this.dashboardUtils.dashboardAwareListener.register(DASHBOARD_UPDATE) + App.addListener('appStateChange', (state: AppState) => { + if (state.isActive) { + if (this.lastRefreshTs + 6 * 60 > this.getUnixSeconds()) return + this.setup(false) + } else { + console.log('App has become inactive') + } + }) + } + + ngOnInit() {} + + ionViewWillEnter() { + if (this.dashboardUtils.dashboardAwareListener.hasAndConsume(DASHBOARD_UPDATE)) { + this.setup(false, true) + return + } + + if (this.lastRefreshTs + 6 * 60 > this.getUnixSeconds()) return + this.setup() + } + + async changedGroup() { + await Promise.all([ + this.overviewProvider.setGroup(this.overallData, await this.storage.getDashboardGroupID()), + this.changeTimeframe(await this.storage.getDashboardTimeframe()), + ]) + } + + async changeTimeframe(period: Period) { + if (!this.overallData) { + return + } + this.storage.setDashboardTimeframe(period) + const groupID = await this.storage.getDashboardGroupID() + + const loading = await this.alert.presentLoading('Loading...') + loading.present() + const result = await this.overviewProvider.setTimeframe(this.overallData, period, groupID) + this.online = true + if (result[0].error) { + console.error('Error fetching summary table', result[0].error) + Toast.show({ + text: 'Error fetching summary table', + }) + this.online = false + } + if (result[1].error) { + console.error('Error fetching summary group', result[1].error) + Toast.show({ + text: 'Error fetching summary group', + }) + this.online = false + } + loading.dismiss() + } + + onScroll($event: { detail: { currentY: number } }) { + this.currentY = $event.detail.currentY + } + + onScrollStarted() { + this.scrolling = true + this.removeTooltips() + } + + onScrollEnded() { + this.scrolling = false + } + + private removeTooltips() { + const inputs = Array.from(document.getElementsByTagName('tooltip') as HTMLCollectionOf) + for (let i = 0; i < inputs.length; i++) { + inputs[i].style.display = 'none' + } + } + + async openDashboardAndGroupSelect() { + const modal = await this.modalCtrl.create({ + component: DashboardAndGroupSelectComponent, + componentProps: { + dashboardChangedCallback: () => { + this.overallData = null + this.setup(false) + }, + }, + }) + modal.present() + + await modal.onWillDismiss() + } + + async setup(checkUpdates: boolean = true, force: boolean = false, recursiveMax = false): Promise { + if (checkUpdates) { + this.updates.checkAllUpdates() + } + this.isLoggedIn = await this.storage.isLoggedIn() + this.dashboardID = await this.dashboardUtils.initDashboard() + this.online = true + this.loading = true + try { + this.overallData = await this.overviewProvider.create( + this.dashboardID, + await this.storage.getDashboardTimeframe(), + await this.storage.getDashboardGroupID(), + { + aggregation: await this.storage.getDashboardSummaryAggregation(), + startTime: null, + force: false, + } as SummaryChartOptions, + ASSOCIATED_CACHE_KEY + ) + } catch (e) { + if (e instanceof APINotFoundError) { + if (recursiveMax) { + Toast.show({ + text: 'Dashboard not found', + }) + return + } + await this.storage.setDashboardID(null) + + // if dashboard is not available any more (maybe user deleted it) reinit and try again + this.dashboardID = await this.dashboardUtils.initDashboard() + return this.setup(false, force, true) + } else if (e instanceof APIUnauthorizedError) { + this.dashboardUtils.defaultDashboardErrorHandler(e) + } else if (e instanceof APIError) { + this.dashboardUtils.defaultDashboardErrorHandler(e) + this.online = false + } else { + console.error(e) + Toast.show({ + text: 'Error loading dashboard', + }) + this.online = false + } + } + this.loading = false + if (this.overallData) { + //this.api.setCurrentDashboardChainID(this.overallData.chainNetwork().id) + } + + console.log('overallData', this.overallData) + //this.dashboardName = this.overallData.overviewData().name + this.lastRefreshTs = this.getUnixSeconds() + } + + getUnixSeconds() { + return new Date().getTime() / 1000 + } + + private lastRefreshedTs: number = 0 + async doRefresh(event: { target: { complete: () => void } }) { + console.log('henlo 2') + if (this.lastRefreshedTs + 60 * 1000 > new Date().getTime()) { + Toast.show({ + text: 'Nothing to update', + }) + if (event) event.target.complete() + return + } + this.lastRefreshedTs = new Date().getTime() + + const old = Object.assign({}, this.overallData) + await this.overviewProvider.clearRequestCache(this.overallData) + this.overallData = null + await this.setup(true, true).catch(() => { + this.overallData = old + if (event) event.target.complete() + }) + await this.unitConv.updatePriceData() + if (event) event.target.complete() + } + + formattedSelectedTimeframe = computed(() => { + if (!this.overallData) return '' + return this.overallData.timeframeDisplay() + }) +} diff --git a/src/app/pages/machines/machines-routing.module.ts b/src/app/tabs/tab-machines/machines-routing.module.ts similarity index 100% rename from src/app/pages/machines/machines-routing.module.ts rename to src/app/tabs/tab-machines/machines-routing.module.ts diff --git a/src/app/tabs/tab-machines/machines.module.ts b/src/app/tabs/tab-machines/machines.module.ts new file mode 100644 index 00000000..d7f78ce6 --- /dev/null +++ b/src/app/tabs/tab-machines/machines.module.ts @@ -0,0 +1,29 @@ +import { NgModule } from '@angular/core' +import { CommonModule } from '@angular/common' +import { FormsModule } from '@angular/forms' + +import { IonicModule } from '@ionic/angular' + +import { MachinesPageRoutingModule } from './machines-routing.module' +import { MachinesPage } from './machines.page' +import { MachineChartComponentModule } from '@components/machinechart/machinechart.module' +import { PipesModule } from '@pipes/pipes.module' +import { AdComponentModule } from '@components/ad/ad.module' +import { FullPageLoadingComponent } from '@components/full-page-loading/full-page-loading.component' +import { FullPageOfflineComponent } from '@components/full-page-offline/full-page-offline.component' + +@NgModule({ + imports: [ + CommonModule, + FormsModule, + IonicModule, + MachinesPageRoutingModule, + MachineChartComponentModule, + PipesModule, + AdComponentModule, + FullPageLoadingComponent, + FullPageOfflineComponent, + ], + declarations: [MachinesPage], +}) +export class MachinesPageModule {} diff --git a/src/app/tabs/tab-machines/machines.page.html b/src/app/tabs/tab-machines/machines.page.html new file mode 100644 index 00000000..bad12088 --- /dev/null +++ b/src/app/tabs/tab-machines/machines.page.html @@ -0,0 +1,86 @@ + + + Monitoring + + + + CPU + + + Memory + + + Sync + + + + + + + + + Last {{ this.selectedTimeFrame }} + + + +
+
+ +
+ +
+ + + + + + + + +
+
+ +
+
+
+ Machine Monitoring

+ + Monitor your {{ api.getNetwork().name }} staking machines on the go. +

+ Login + Setup Monitoring +
+
+ +
+
+
+
diff --git a/src/app/pages/machines/machines.page.scss b/src/app/tabs/tab-machines/machines.page.scss similarity index 85% rename from src/app/pages/machines/machines.page.scss rename to src/app/tabs/tab-machines/machines.page.scss index bb05951b..1cfee9e1 100644 --- a/src/app/pages/machines/machines.page.scss +++ b/src/app/tabs/tab-machines/machines.page.scss @@ -1,16 +1,4 @@ -@import '../../../theme/variables.scss'; - -ion-segment-button { - color: var(--x-toolbar-title-color); - - font-family: 'Varela'; - font-size: 0.75em; - --indicator-height: 0px !important; - text-transform: none !important; - --ripple-color: transparent !important; - //transition: color 0.15s ease; - opacity: 0.65; -} +@use '../../../theme/variables.scss'; ion-segment { background-color: var(--ion-toolbar-background); diff --git a/src/app/pages/machines/machines.page.ts b/src/app/tabs/tab-machines/machines.page.ts similarity index 59% rename from src/app/pages/machines/machines.page.ts rename to src/app/tabs/tab-machines/machines.page.ts index f432d6b1..92caee38 100644 --- a/src/app/pages/machines/machines.page.ts +++ b/src/app/tabs/tab-machines/machines.page.ts @@ -1,37 +1,38 @@ import { ChangeDetectorRef, Component, OnInit } from '@angular/core' import { ModalController } from '@ionic/angular' -import { MachineDetailPage } from '../machine-detail/machine-detail.page' +import { MachineDetailPage } from '@pages/machine-detail/machine-detail.page' import MachineController, { ProcessedStats } from '../../controllers/MachineController' -import { AlertService } from 'src/app/services/alert.service' -import { MerchantUtils } from 'src/app/utils/MerchantUtils' -import { ValidatorUtils } from 'src/app/utils/ValidatorUtils' -import { StorageService } from 'src/app/services/storage.service' -import { OAuthUtils } from 'src/app/utils/OAuthUtils' -import MachineUtils from 'src/app/utils/MachineUtils' +import { AlertService } from '@services/alert.service' +import { MerchantUtils } from '@utils/MerchantUtils' +import { StorageService } from '@services/storage.service' +import { OAuthUtils } from '@utils/OAuthUtils' import { Browser } from '@capacitor/browser' -import { trigger, style, animate, transition } from '@angular/animations' -import { ApiService } from 'src/app/services/api.service' +import { ApiService } from '@services/api.service' +import { APIUnauthorizedError } from '@requests/requests' +import { V2MyMachines } from '@requests/v2-user' @Component({ selector: 'app-machines', templateUrl: './machines.page.html', styleUrls: ['./machines.page.scss'], - animations: [trigger('fadeIn', [transition(':enter', [style({ opacity: 0 }), animate('300ms 100ms', style({ opacity: 1 }))])])], + standalone: false, }) export class MachinesPage extends MachineController implements OnInit { - data: ProcessedStats[] = null + data: Map = null scrolling = false selectedChart = 'cpu' showData = true - selectedTimeFrame = '3h' + selectedTimeFrame: string = '3h' - hasHistoryPremium = false loggedIn = false orderedKeys: string[] = [] legacyApi = false + initialLoading: boolean = true + online: boolean = true + cpuDelegate = (data: ProcessedStats) => { return this.doCPUCharts(data) } @@ -47,7 +48,7 @@ export class MachinesPage extends MachineController implements OnInit { onlineStateDelegate = async (data: ProcessedStats) => { return await this.getOnlineState(data) } - machineClickDelegate = (data: ProcessedStats) => { + machineClickDelegate = (data: string) => { return () => { return this.openMachineDetail(data) } @@ -56,11 +57,9 @@ export class MachinesPage extends MachineController implements OnInit { constructor( private modalController: ModalController, private alertService: AlertService, - private merchant: MerchantUtils, - private validatorUtils: ValidatorUtils, + public merchant: MerchantUtils, private storage: StorageService, private oauthUtils: OAuthUtils, - private machineUtils: MachineUtils, private ref: ChangeDetectorRef, protected api: ApiService ) { @@ -68,19 +67,15 @@ export class MachinesPage extends MachineController implements OnInit { } ngOnInit() { - this.validatorUtils.registerListener(() => { - this.getAndProcessData() - }) - - this.merchant.hasMachineHistoryPremium().then((result) => { - this.hasHistoryPremium = result - }) + // this.validatorUtils.registerListener(() => { + // this.getAndProcessData() + // }) } - async doRefresh(event) { + async doRefresh(event: { target: { complete: () => void } }) { await this.getAndProcessData() setTimeout(() => { - event.target.complete() + if (event) event.target.complete() this.ref.detectChanges() }, 500) } @@ -94,7 +89,7 @@ export class MachinesPage extends MachineController implements OnInit { this.loggedIn = await this.storage.isLoggedIn() } - delegater(func) { + delegater(func: unknown) { return () => { return func } @@ -111,12 +106,15 @@ export class MachinesPage extends MachineController implements OnInit { if (!result) return result if (data.clientVersion) result += ' v' + data.clientVersion + if (result.length > 22) { + return result.substring(0, 20) + '...' + } return result } openTimeSelection() { - if (!this.hasHistoryPremium) { - this.alertService.showInfo('Premium Feature', 'For more machine history upgrade to a premium version.') + if (!this.merchant.hasMachineMonitoringPremium()) { + this.alertService.showInfo('Limit Reached', 'Upgrade to premium to get up to 30 days of monitoring data') return } @@ -169,7 +167,7 @@ export class MachinesPage extends MachineController implements OnInit { (data) => { if (data) { if (data != this.selectedChart) { - this.selectedTimeFrame = data + this.selectedTimeFrame = data as string this.selectionTimeFrame = this.getTimeSelectionLimit() this.data = null this.getAndProcessData() @@ -202,25 +200,66 @@ export class MachinesPage extends MachineController implements OnInit { async getAndProcessData() { this.loggedIn = await this.storage.isLoggedIn() if (!this.loggedIn) { - this.data = [] + this.data = new Map() this.orderedKeys = [] this.showData = false + this.initialLoading = false return } - this.data = await this.machineUtils.getAndProcessData(this.getTimeSelectionLimit()) + this.data = await this.getAndProcessDataBase(this.getTimeSelectionLimit()) + // const machineNames = this.getAllMachineNamesFrom(this.data) + // console.log('machine names', machineNames) + this.orderedKeys = await this.getOrderedKeys(this.data) - this.showData = Object.keys(this.data).length > 0 - this.checkForLegacyApi(this.data) + this.showData = this.data.size > 0 + this.initialLoading = false + } + + // private getAllMachineNamesFrom(data: Map): string[] { + // const result: string[] = [] + // for (const key of data.keys()) { + // result.push(key) + // } + // return result + // } + + private async getAndProcessDataBase(timeslot = 180) { + const apiResult = await this.api.execute(new V2MyMachines(0, timeslot)) + if (apiResult.error) { + //this.dashboardUtils.defaultDashboardErrorHandler(apiResult.error) + if (!(apiResult.error instanceof APIUnauthorizedError)) { + this.online = false + } + return + } + + if (apiResult.data == null) { + return new Map() + } + + const machineController = new MachineController(this.storage) + + const result = await machineController.combineByMachineName( + machineController.filterMachines(apiResult.data.validator_metrics), + machineController.filterMachines(apiResult.data.node_metrics), + machineController.filterMachines(apiResult.data.system_metrics) + ) + + console.log('baum', result.size, machineController.filterMachines(apiResult.data.system_metrics)) + + return result } - private async getOrderedKeys(data: ProcessedStats[]): Promise { + private async getOrderedKeys(data: Map): Promise { + if (!data) return [] + const online = [] const attention = [] const offline = [] - for (const key in data) { - const it = data[key] + for (const key of Array.from(data.keys())) { + const it = data.get(key) const status = await this.getOnlineState(it) if (status == 'online') { online.push(key) @@ -242,16 +281,17 @@ export class MachinesPage extends MachineController implements OnInit { return result } - async openMachineDetail(key) { - const attention = this.getSyncAttention(this.data[key]) - const diskAttention = await this.getDiskAttention(this.data[key]) - const memoryAttention = await this.getMemoryAttention(this.data[key]) + async openMachineDetail(key: string) { + const processedStats = this.data.get(key) as ProcessedStats + const attention = this.getSyncAttention(processedStats) + const diskAttention = await this.getDiskAttention(processedStats) + const memoryAttention = await this.getMemoryAttention(processedStats) const modal = await this.modalController.create({ component: MachineDetailPage, cssClass: 'my-custom-class', componentProps: { - data: this.data[key], + data: processedStats, key: key, timeframe: this.selectionTimeFrame, selectedTab: attention ? 'sync' : diskAttention ? 'disk' : memoryAttention ? 'memory' : this.selectedChart, @@ -260,42 +300,6 @@ export class MachinesPage extends MachineController implements OnInit { return await modal.present() } - async checkForLegacyApi(data: ProcessedStats[]) { - const dismissed = await this.storage.getBooleanSetting('legacy_monitoring_api_dismissed', false) - if (dismissed || !data) { - this.legacyApi = false - return - } - - let offlineCount = 0 - let count = 0 - for (const key in data) { - const it = data[key] - const status = await this.getOnlineState(it) - if (status == 'offline') offlineCount++ - count++ - } - - this.legacyApi = offlineCount == count - } - - closeLegacyApiDialog() { - this.legacyApi = false - this.storage.setBooleanSetting('legacy_monitoring_api_dismissed', true) - } - - legacyApiMigrateDialog() { - this.alertService.showInfo( - 'How to Migrate', - '1. Head over to https://beaconcha.in and go to settings.
' + - '2. Go to "Mobile App".
' + - '3. Make sure, the URL matches those in your clients config.

' + - '-) If not, use the new URL presented on beaconcha.in and restart your staking services.

' + - '-) If the URL matches, you can ignore this warning and dismiss it. Make sure the URL is exactly the same since they both start the same way.
', - 'bigger-alert' - ) - } - onScrollStarted() { this.scrolling = true } @@ -304,7 +308,7 @@ export class MachinesPage extends MachineController implements OnInit { this.scrolling = false } - async openBrowser(link) { + async openBrowser(link: string) { await Browser.open({ url: link, toolbarColor: '#2f2e42' }) } } diff --git a/src/app/tabs/tab-preferences/notification-base.ts b/src/app/tabs/tab-preferences/notification-base.ts new file mode 100644 index 00000000..36f6b07e --- /dev/null +++ b/src/app/tabs/tab-preferences/notification-base.ts @@ -0,0 +1,148 @@ +import { Injectable, signal, WritableSignal } from '@angular/core' +import { Platform } from '@ionic/angular' +import { ApiService } from '@services/api.service' +import { StorageService } from '@services/storage.service' +import { AlertService } from '@services/alert.service' +import ClientUpdateUtils, { Clients } from '@utils/ClientUpdateUtils' +import { V2ChangeSubscribedClient, V2SubscribedClients } from '@requests/v2-notifications' + +@Injectable({ + providedIn: 'root', +}) +export class NotificationBase { + clientUpdatesTogglesMap = new Map>() // identifier = client key + + settingsChanged = false + + constructor( + protected api: ApiService, + protected storage: StorageService, + protected platform: Platform, + protected alerts: AlertService, + protected clientUpdate: ClientUpdateUtils + ) { + for (const client of Clients) { + this.clientUpdatesTogglesMap.set(client.key, signal(false)) + } + } + + async setClientToggleState(clientKey: string, state: boolean) { + const current = this.clientUpdatesTogglesMap.get(clientKey) + if (!current) { + console.log('Could not set toggle state for client', clientKey) + return + } + current.set(state) + this.settingsChanged = true + if (state) { + await this.clientUpdate.setClient(clientKey, clientKey) + this.clientUpdate.checkClientUpdate(clientKey) + } else { + await this.clientUpdate.setClient(clientKey, 'null') + } + } + + getClientToggleState(clientKey: string): boolean { + const toggle = this.clientUpdatesTogglesMap.get(clientKey) + if (toggle == undefined) { + console.log('Could not return toggle state for client', clientKey) + return false + } + return toggle() + } + + async clientUpdateOnToggle(clientKey: string) { + this.settingsChanged = true + + if (!(await this.storage.isLoggedIn())) return + const enabled = this.getClientToggleState(clientKey) + const result = await this.setRemote(clientKey, enabled) + if (result.error) { + console.log('error changing client subscribed state', result.error) + } + this.api.clearSpecificCache(new V2SubscribedClients()) + } + + private async setRemote(clientKey: string, enabled: boolean) { + const remoteID = Clients.find((c) => c.key == clientKey).remoteId + const updateRequest = new V2ChangeSubscribedClient(remoteID, enabled) + const result = await this.api.execute(updateRequest) + return result + } + + remoteNotifyLoadedOnce = false + async updateClientsFromRemote(force: boolean) { + if (!(await this.storage.isLoggedIn())) return + const result = this.remoteInitClientIDs(force, (clientKey, exists) => this.setClientToggleState(clientKey, exists)) + this.settingsChanged = false + return result + } + + /** + * V2 API changed the the ethereum client ids to integer. We use this function to retrieve all remote client ids and + * update the local state based on the remote name. Essentially it uses(maps) the locally defined remote name to the remote id + * @param force + * @param callback + * @returns + */ + private async remoteInitClientIDs(force: boolean, callback: (clientKey: string, exists: boolean) => Promise = null) { + const result = await this.api.execute(new V2SubscribedClients().withAllowedCacheResponse(!force)) + if (result.error) { + console.warn('Failed to load subscribed clients', result.error) + return result + } + + for (let i = 0; i < Clients.length; i++) { + const client = Clients[i] + const foundClient = result.data.clients.find((remoteClient) => remoteClient.name == client.remoteKey) + const exists = foundClient?.is_subscribed ?? false + Clients[i].remoteId = foundClient?.id + + if (callback) { + await callback(client.key, exists) + } + } + + return result + } + + async syncClientUpdates() { + // only sync when logged in + if (!(await this.storage.isLoggedIn())) { + return + } + + // first get remote ids + const result = await this.remoteInitClientIDs(true) + if (result.error || (result.data?.clients?.length ?? 0) == 0) { + return + } + + // sync up local enabled client updates to remote + const promiseArray: Promise[] = [] + for (let i = 0; i < Clients.length; i++) { + promiseArray.push(this.storage.getItem(Clients[i].storageKey)) + } + + const results = await Promise.all(promiseArray) + for (let i = 0; i < results.length; i++) { + if (results[i] && results[i] != 'null') { + const foundClient = result.data.clients.find((remoteClient) => remoteClient.name == Clients[i].remoteKey) + const exists = foundClient?.is_subscribed ?? false + if (!exists) { + // only set if not already set on remote + this.setRemote(Clients[i].key, true) + } + } + } + + // sync down, applying remote to local + this.updateClientsFromRemote(false) + } + + disableToggleLock() { + setTimeout(() => { + this.settingsChanged = false + }, 300) + } +} diff --git a/src/app/tab-preferences/tab-preferences-routing.module.ts b/src/app/tabs/tab-preferences/tab-preferences-routing.module.ts similarity index 92% rename from src/app/tab-preferences/tab-preferences-routing.module.ts rename to src/app/tabs/tab-preferences/tab-preferences-routing.module.ts index a6c11bdb..a43a28cb 100644 --- a/src/app/tab-preferences/tab-preferences-routing.module.ts +++ b/src/app/tabs/tab-preferences/tab-preferences-routing.module.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // diff --git a/src/app/tab-preferences/tab-preferences.module.ts b/src/app/tabs/tab-preferences/tab-preferences.module.ts similarity index 83% rename from src/app/tab-preferences/tab-preferences.module.ts rename to src/app/tabs/tab-preferences/tab-preferences.module.ts index 511c973e..ed4cc980 100644 --- a/src/app/tab-preferences/tab-preferences.module.ts +++ b/src/app/tabs/tab-preferences/tab-preferences.module.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -24,10 +23,11 @@ import { NgModule } from '@angular/core' import { CommonModule } from '@angular/common' import { FormsModule } from '@angular/forms' import { Tab3Page } from './tab-preferences.page' -import { DashboardComponentModule } from '../components/dashboard/dashboard.module' +import { DashboardComponentModule } from '@components/dashboard/dashboard.module' import { Tab3PageRoutingModule } from './tab-preferences-routing.module' -import { PipesModule } from '../pipes/pipes.module' +import { PipesModule } from '../../pipes/pipes.module' +import { FirebaseUtilsModule } from '@utils/Firebase.module' @NgModule({ imports: [ @@ -39,6 +39,7 @@ import { PipesModule } from '../pipes/pipes.module' Tab3PageRoutingModule, PipesModule, RouterModule, + FirebaseUtilsModule, ], declarations: [Tab3Page], }) diff --git a/src/app/tabs/tab-preferences/tab-preferences.page.html b/src/app/tabs/tab-preferences/tab-preferences.page.html new file mode 100644 index 00000000..2c7d0b16 --- /dev/null +++ b/src/app/tabs/tab-preferences/tab-preferences.page.html @@ -0,0 +1,256 @@ + + + + + Preferences + + + + + + + + Upgrade to Premium + + + Premium is ad free, supports up to 280 validators, Widgets and more. + + + + General + + + + + + Toggle Dark Theme + + + + + + {{ item[0] }} + + + + + + + Premium {{ premiumLabel() }} + + + + + + + Default + Ethpool + Rocketpool + Gnosis + Teal + Green + Cyan + Purple + Sun + Indigo + Pink + Red + Orange + Bronze + Gold + Metal + + + + Themes + + + + + Widgets + + + + + + + + Manage Premium + + + + + + + Notifications + + + + + + Login to Receive Notifications + + + + + Notification Preferences + + + + + + Notification History + + + + + + Client Updates + + + + + + Execution Clients + + + + + + Consensus Clients + + + + + + Other Clients + + + + + + General + + + + + + Enable Test Networks + + + + + Rate this App + + + + + Guides & FAQ + + + + + Manage Subscriptions + + + + + Bug Report + + + + + Logout + + + + Login + + + + + Delete Account + + + + + Legal + + + + Privacy Policy + + + + Terms of Service + + + Open Source Licences + + + + Imprint + + + + + Dev + + + +

+ +

+

Logged in as {{ this.merchant.userInfo().email }}

+

2020 - {{ currentYear }} © bitfly explorer GmbH

+

Version {{ appVersion }}

+

{{ package }}

+
+
diff --git a/src/app/tab-preferences/tab-preferences.page.scss b/src/app/tabs/tab-preferences/tab-preferences.page.scss similarity index 94% rename from src/app/tab-preferences/tab-preferences.page.scss rename to src/app/tabs/tab-preferences/tab-preferences.page.scss index 8b0dd3ba..33c7b890 100644 --- a/src/app/tab-preferences/tab-preferences.page.scss +++ b/src/app/tabs/tab-preferences/tab-preferences.page.scss @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -17,6 +16,7 @@ * // You should have received a copy of the GNU General Public License * // along with Beaconchain Dashboard. If not, see . */ +@use '../../../theme/variables.scss'; ion-select::part(icon) { display: none !important; diff --git a/src/app/tab-preferences/tab-preferences.page.ts b/src/app/tabs/tab-preferences/tab-preferences.page.ts similarity index 60% rename from src/app/tab-preferences/tab-preferences.page.ts rename to src/app/tabs/tab-preferences/tab-preferences.page.ts index a62f26ef..5313becc 100644 --- a/src/app/tab-preferences/tab-preferences.page.ts +++ b/src/app/tabs/tab-preferences/tab-preferences.page.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -18,70 +17,72 @@ * // along with Beaconchain Dashboard. If not, see . */ -import { Component } from '@angular/core' -import { ApiService } from '../services/api.service' -import { StorageService } from '../services/storage.service' -import { UnitconvService } from '../services/unitconv.service' -import { OAuthUtils } from '../utils/OAuthUtils' -import ClientUpdateUtils from '../utils/ClientUpdateUtils' -import ThemeUtils from '../utils/ThemeUtils' -import { findConfigForKey } from '../utils/NetworkData' +import { Component, computed } from '@angular/core' +import { ApiService, capitalize } from '@services/api.service' +import { StorageService } from '@services/storage.service' +import { PreferredCurrency, UnitconvService } from '@services/unitconv.service' +import { OAuthUtils } from '@utils/OAuthUtils' +import ClientUpdateUtils from '@utils/ClientUpdateUtils' +import ThemeUtils from '@utils/ThemeUtils' +import { findConfigForKey } from '@utils/NetworkData' import { ModalController } from '@ionic/angular' -import { HelppagePage } from '../pages/helppage/helppage.page' -import { ValidatorUtils } from '../utils/ValidatorUtils' -import Unit, { MAPPING } from '../utils/EthereumUnits' +import { HelppagePage } from '@pages/helppage/helppage.page' +import Unit, { MAPPING } from '@utils/EthereumUnits' import { AlertController } from '@ionic/angular' -import FirebaseUtils from '../utils/FirebaseUtils' +import FirebaseUtils, { updateRemoteNotificationToken } from '@utils/FirebaseUtils' import { Platform } from '@ionic/angular' -import { AlertService } from '../services/alert.service' -import { SyncService } from '../services/sync.service' -import { LicencesPage } from '../pages/licences/licences.page' -import { SubscribePage } from '../pages/subscribe/subscribe.page' -import { MerchantUtils, PRODUCT_STANDARD } from '../utils/MerchantUtils' +import { AlertService } from '@services/alert.service' +import { LicencesPage } from '@pages/licences/licences.page' +import { SubscribePage } from '@pages/subscribe/subscribe.page' +import { MerchantUtils } from '@utils/MerchantUtils' import { NotificationBase } from './notification-base' -import { Router } from '@angular/router' -import { App } from '@capacitor/app' import { Browser } from '@capacitor/browser' import { Toast } from '@capacitor/toast' -import { MergeChecklistPage } from '../pages/merge-checklist/merge-checklist.page' -import { ClientsPage } from '../pages/clients/clients.page' -import FlavorUtils from '../utils/FlavorUtils' -import { Capacitor } from '@capacitor/core' -import { trigger, style, animate, transition } from '@angular/animations' +import { ClientsPage } from '@pages/clients/clients.page' +import FlavorUtils from '@utils/FlavorUtils' +import V2Migrator from '@utils/V2Migrator' +import { DashboardUtils } from '@utils/DashboardUtils' +import { AuthUser, AuthUserv2 } from '../../models/StorageTypes' +import { ValidatorUtils } from '@utils/ValidatorUtils' +import { AppUpdater } from '@utils/AppUpdater' + +export const SHOW_TESTNETS_CONFIG = 'show_testnets' @Component({ selector: 'app-tab3', templateUrl: 'tab-preferences.page.html', styleUrls: ['tab-preferences.page.scss'], - animations: [trigger('fadeIn', [transition(':enter', [style({ opacity: 0 }), animate('300ms 100ms', style({ opacity: 1 }))])])], + standalone: false, }) export class Tab3Page { darkMode: boolean + showTestnets: boolean network = 'main' - allTestNetworks: string[][] - - authUser + authUser: AuthUserv2 | AuthUser updateChannel: string - allCurrencies + allCurrencies: Array> appVersion: string - debug = false - - snowing: boolean + debug = true themeColor: string - currentPlan: string - premiumLabel = '' + premiumLabel = computed(() => { + if (this.merchant.getUsersSubscription()?.product_name) { + return ' - ' + capitalize(this.merchant.getUsersSubscription().product_name) + } else { + return '' + } + }) protected package = '' - protected currentFiatCurrency + protected currentFiatCurrency: string protected currentYear = new Date().getFullYear() @@ -92,17 +93,18 @@ export class Tab3Page { public unit: UnitconvService, protected storage: StorageService, protected updateUtils: ClientUpdateUtils, - protected validatorUtils: ValidatorUtils, protected modalController: ModalController, protected alertController: AlertController, protected firebaseUtils: FirebaseUtils, + protected dashboardUtils: DashboardUtils, public platform: Platform, protected alerts: AlertService, - protected sync: SyncService, protected merchant: MerchantUtils, - public notificationBase: NotificationBase, - private router: Router, - private flavor: FlavorUtils + protected notificationBase: NotificationBase, + private flavor: FlavorUtils, + protected v2migrator: V2Migrator, + protected validatorUtils: ValidatorUtils, + protected appUpdater: AppUpdater ) {} ngOnInit() { @@ -110,31 +112,17 @@ export class Tab3Page { this.currentFiatCurrency = result }) this.theme.isDarkThemed().then((result) => (this.darkMode = result)) + this.storage.getBooleanSetting(SHOW_TESTNETS_CONFIG, false).then((result) => (this.showTestnets = result)) this.theme.getThemeColor().then((result) => (this.themeColor = result)) - this.updateUtils.getClient('ROCKETPOOL').then((result) => { - this.notificationBase.setClientToggleState('ROCKETPOOL', result && result.toUpperCase() == 'ROCKETPOOL') - }) - this.updateUtils.getClient('MEV-BOOST').then((result) => { - this.notificationBase.setClientToggleState('MEV-BOOST', result && result.toUpperCase() == 'MEV-BOOST') - }) this.updateUtils.getUpdateChannel().then((result) => (this.updateChannel = result)) - this.theme.isWinterEnabled().then((result) => (this.snowing = result)) - this.allCurrencies = this.getAllCurrencies() - this.api.getAllTestNetNames().then((result) => { - this.allTestNetworks = result - }) - if (Capacitor.isNativePlatform()) { - App.getInfo().then((result) => { - this.appVersion = result.version - }) - } else { - this.appVersion = 'dev' - } + this.appUpdater.getFormattedCurrentVersion().then((result) => { + this.appVersion = result + }) this.flavor.isBetaFlavor().then((result) => { if (result) { @@ -148,25 +136,33 @@ export class Tab3Page { } }) - this.merchant.getCurrentPlanConfirmed().then((result) => { - this.currentPlan = result - if (this.currentPlan != PRODUCT_STANDARD) { - this.premiumLabel = ' - ' + this.api.capitalize(this.currentPlan) - } - }) this.notificationBase.disableToggleLock() - - this.updateUtils.convertOldToNewClientSettings() } - private loadingNotificationPage = false - async goToNotificationPage() { - if (this.loadingNotificationPage) return - this.loadingNotificationPage = true + changeShowTestnets() { + if (this.showTestnets) { + this.alerts.confirmDialog( + 'Test Networks', + `Test Networks let you practice staking without real money. They share features with Ethereum but use worthless ETH. +

+ Enabling test networks allows you to create dashboards to track testnet validators.`, + 'Enable', + () => { + this.showTestnets = true + this.storage.setBooleanSetting(SHOW_TESTNETS_CONFIG, this.showTestnets) + }, + undefined, + () => { + this.showTestnets = false + } + ) + } else { + this.storage.setBooleanSetting(SHOW_TESTNETS_CONFIG, this.showTestnets) + } + } - await this.sync.syncAllSettings(true) - this.loadingNotificationPage = false - this.router.navigate(['/notifications']) + goToNotificationPage() { + this.openBrowser(this.api.getBaseUrl() + '/notifications#dashboards', false) } async openClientsPage(identifier: string) { @@ -192,7 +188,7 @@ export class Tab3Page { } widgetSetupInfo() { - if (this.currentPlan == 'standard' || this.currentPlan == 'plankton') { + if (this.merchant.userInfo()?.premium_perks.mobile_app_widget != true) { this.openUpgrades() return } @@ -220,13 +216,13 @@ export class Tab3Page { } ionViewWillEnter() { - this.storage.getAuthUser().then((result) => (this.authUser = result)) + this.storage.getAuthUserv2().then((result) => (this.authUser = result)) this.debug = this.api.debug - this.network = this.api.getNetworkName() + this.network = this.api.getParentNetwork().key } private getAllCurrencies() { - const erg = [] + const erg: Array> = [] MAPPING.forEach((value: Unit, key) => { if (value.settingName) { erg.push([[value.settingName], [key]]) @@ -239,7 +235,7 @@ export class Tab3Page { this.theme.toggle(this.darkMode) } - overrideDisplayCurrency = null + overrideDisplayCurrency: PreferredCurrency = null private changeCurrencyLocked = false async changeCurrency() { if (this.changeCurrencyLocked) return @@ -260,7 +256,8 @@ export class Tab3Page { openOAuth() { this.oauth.login().then((success) => { if (success) { - this.storage.getAuthUser().then((result) => (this.authUser = result)) + this.storage.getAuthUserv2().then((result) => (this.authUser = result)) + this.dashboardUtils.dashboardAwareListener.notifyAll() } }) } @@ -273,12 +270,7 @@ export class Tab3Page { } } - changeUpdateChannel() { - this.updateUtils.setUpdateChannel(this.updateChannel) - this.updateUtils.checkAllUpdates() - } - - async openBrowser(link, native = false) { + async openBrowser(link: string, native = false) { if (native) { window.open(link, '_system', 'location=yes') } else { @@ -287,54 +279,38 @@ export class Tab3Page { } logout() { - this.alerts.confirmDialog('Confirm logout', 'Notifications will stop working if you sign out. Continue?', 'Logout', () => { - this.confirmLogout() - }) + this.alerts.confirmDialog( + 'Confirm Logout', + `You are signed in as ${this.merchant.userInfo()?.email}.

` + 'Notifications will stop working if you sign out. Continue?', + 'Logout', + () => { + this.confirmLogout() + } + ) } count = 0 notAnEasterEgg() { this.count++ if (this.count % 3 != 0) return - const random = Math.floor(Math.random() * 2) - switch (random) { - case 0: { - const currentSnow = this.theme.snow() - setTimeout(() => { - this.theme.stopSnow(currentSnow) - }, 45000) - break - } - case 1: - this.theme.silvesterFireworks() - break - } + this.theme.silvesterFireworks() } - confirmLogout() { + async confirmLogout() { + await updateRemoteNotificationToken(this.storage, this.api, '', true) + + // TODO destroy session on server by calling logout + this.storage.removeAuthUser() + this.storage.setDashboardID(null) + this.merchant.clearTempUserInfo() this.authUser = null + this.dashboardUtils.dashboardAwareListener.notifyAll() Toast.show({ text: 'Logged out', }) } - async changeNetwork() { - await changeNetwork( - this.network, - this.storage, - this.api, - this.validatorUtils, - this.unit, - this.notificationBase, - this.theme, - this.alerts, - this.merchant, - false - ) - this.currentFiatCurrency = await this.unit.getCurrentConsFiat() - } - async openIconCredit() { const alert = await this.alertController.create({ cssClass: 'my-custom-class', @@ -347,18 +323,6 @@ export class Tab3Page { await alert.present() } - async partialStake() { - const alert = await this.alertController.create({ - cssClass: 'my-custom-class', - header: 'Define stake share', - message: - 'If you own partial amounts of a validator, you can define your share on a per validator basis. To do that, go to the validators tab, select your validators by holding down and set the stake share.', - buttons: ['OK'], - }) - - await alert.present() - } - async openUpgrades() { const modal = await this.modalController.create({ component: SubscribePage, @@ -383,30 +347,10 @@ export class Tab3Page { return await modal.present() } - ionViewDidLeave() { - this.sync.syncAllSettings() - } - manageSubs() { this.merchant.manageSubscriptions() } - toggleSnow() { - this.theme.toggleWinter(this.snowing) - } - - async openMergeChecklist() { - const modal = await this.modalController.create({ - component: MergeChecklistPage, - cssClass: 'my-custom-class', - componentProps: { - fromSettings: true, - }, - }) - - return await modal.present() - } - versionClickCount = 0 openLogSessionDialog() { this.versionClickCount++ @@ -432,12 +376,6 @@ export class Tab3Page { this.storage.openLogSession(this.modalController, 1) }, }, - { - text: 'Last Last Session', - handler: () => { - this.storage.openLogSession(this.modalController, 2) - }, - }, { text: 'Cancel', }, @@ -452,13 +390,12 @@ export async function changeNetwork( network: string, storage: StorageService, api: ApiService, - validatorUtils: ValidatorUtils, unit: UnitconvService, - notificationBase: NotificationBase, theme: ThemeUtils, alertService: AlertService, merchant: MerchantUtils, - forceThemeSwitch: boolean + forceThemeSwitch: boolean, + dashboardUtils: DashboardUtils ) { const darkTheme = await theme.isDarkThemed() @@ -468,28 +405,28 @@ export async function changeNetwork( await storage.setNetworkPreferences(newConfig) await api.initialize() - await notificationBase.loadAllToggles() await unit.networkSwitchReload() - //await this.unit.changeCurrency(this.currentFiatCurrency) - validatorUtils.notifyListeners() + dashboardUtils.dashboardAwareListener.notifyAll() + //await unit.changeCurrency(currentFiatCurrency) const currentTheme = theme.currentThemeColor if (forceThemeSwitch && (currentTheme == '' || currentTheme == 'gnosis')) { theme.undoColor() setTimeout(() => { - theme.toggle(darkTheme, true, api.isGnosis() ? 'gnosis' : ''), 50 - }) + theme.toggle(darkTheme, true, api.isGnosis() ? 'gnosis' : '') + }, 50) } else { - const hasTheming = await merchant.hasPremiumTheming() + await merchant.initialize + const hasTheming = merchant.userInfo()?.premium_perks.mobile_app_custom_themes == true if (hasTheming) return if (currentTheme == '' && !api.isGnosis()) return if (currentTheme == 'gnosis' && api.isGnosis()) return alertService.confirmDialog('Switch App Theme', 'Do you want to switch to the free ' + api.getNetwork().name + ' App theme?', 'Sure', () => { theme.undoColor() setTimeout(() => { - theme.toggle(darkTheme, true, api.isGnosis() ? 'gnosis' : ''), 50 - }) + theme.toggle(darkTheme, true, api.isGnosis() ? 'gnosis' : '') + }, 50) }) } } diff --git a/src/app/tab-validators/tab-validators-routing.module.ts b/src/app/tabs/tab-validators/tab-validators-routing.module.ts similarity index 92% rename from src/app/tab-validators/tab-validators-routing.module.ts rename to src/app/tabs/tab-validators/tab-validators-routing.module.ts index bae57e38..c1867ee5 100644 --- a/src/app/tab-validators/tab-validators-routing.module.ts +++ b/src/app/tabs/tab-validators/tab-validators-routing.module.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // diff --git a/src/app/tab-validators/tab-validators.module.ts b/src/app/tabs/tab-validators/tab-validators.module.ts similarity index 64% rename from src/app/tab-validators/tab-validators.module.ts rename to src/app/tabs/tab-validators/tab-validators.module.ts index 1b23f328..e262b3f2 100644 --- a/src/app/tab-validators/tab-validators.module.ts +++ b/src/app/tabs/tab-validators/tab-validators.module.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -23,12 +22,16 @@ import { NgModule } from '@angular/core' import { CommonModule } from '@angular/common' import { FormsModule } from '@angular/forms' import { Tab2Page } from './tab-validators.page' -import { ValidatorComponentModule } from '../components/validator/validator.module' -import { OfflineComponentModule } from '../components/offline/offline.module' +import { ValidatorComponentModule } from '@components/validator/validator.module' +import { OfflineComponentModule } from '@components/offline/offline.module' import { Tab2PageRoutingModule } from './tab-validators-routing.module' -import { MessageComponentModule } from '../components/message/message.module' -import { AdComponentModule } from '../components/ad/ad.module' +import { MessageComponentModule } from '@components/message/message.module' +import { AdComponentModule } from '@components/ad/ad.module' import { ScrollingModule } from '@angular/cdk/scrolling' +import { FullPageLoadingComponent } from '@components/full-page-loading/full-page-loading.component' +import { FullPageOfflineComponent } from '@components/full-page-offline/full-page-offline.component' +import { LoadingComponent } from '@components/loading/loading.component' +import { PressDirective } from 'src/app/directive/press.directive' @NgModule({ imports: [ @@ -36,11 +39,15 @@ import { ScrollingModule } from '@angular/cdk/scrolling' IonicModule, CommonModule, FormsModule, + PressDirective, ValidatorComponentModule, OfflineComponentModule, Tab2PageRoutingModule, MessageComponentModule, AdComponentModule, + FullPageLoadingComponent, + FullPageOfflineComponent, + LoadingComponent, ], declarations: [Tab2Page], }) diff --git a/src/app/tabs/tab-validators/tab-validators.page.html b/src/app/tabs/tab-validators/tab-validators.page.html new file mode 100644 index 00000000..48851932 --- /dev/null +++ b/src/app/tabs/tab-validators/tab-validators.page.html @@ -0,0 +1,197 @@ + + + + + + + + + + + + + Validators + Edit Mode + + + + + + + + + + + + Delete + + + + + + Search Results + +
+
+ +
+
+ +
+ +
+ +
+ +
+ Nothing found + Try searching for public key, validator index, ENS, deposit address or withdrawal address / credential. +
+
+
+ + +
+ +
+ +
+ {{ dashboardUtils.searchResultHandler.resultCount(item) }} Validators + Validator {{item.value.index}} + Found via {{ dashboardUtils.searchResultHandler.formatSearchType(item.type) }} +
+ + + +
+ + My Validators +
+ + + Group: + + All Groups ({{ validatorCountAcrossAllGroups() }}) + {{group.name}} ({{group.count}}) + Create New Group + + + + + + + + Add Group + Delete Group + Rename Group + Sort Validators + Edit Validators + + + + + +
+ + + + + + + + + + + + + +
+ +

Add Validators

+ + You can add your validators by searching for a public key, validator index, your deposit / withdrawal address / withdrawal credential or + ENS. + +
+ + +
+ +
+
+ Loading... +
+
+
+
+
diff --git a/src/app/tab-validators/tab-validators.page.scss b/src/app/tabs/tab-validators/tab-validators.page.scss similarity index 73% rename from src/app/tab-validators/tab-validators.page.scss rename to src/app/tabs/tab-validators/tab-validators.page.scss index 62aecf8c..8dcb08f0 100644 --- a/src/app/tab-validators/tab-validators.page.scss +++ b/src/app/tabs/tab-validators/tab-validators.page.scss @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -18,7 +17,11 @@ * // along with Beaconchain Dashboard. If not, see . */ -@import '../../theme/variables.scss'; +@use '../../../theme/variables.scss'; + +.last-icon { + margin: var(--edge-padding-left-minus-5px); +} ion-searchbar { --background: var(--ion-toolbar-background); @@ -29,6 +32,20 @@ ion-searchbar { --icon-color: var(--x-toolbar-title-color); --placeholder-color: var(--x-toolbar-title-color); --placeholder-opacity: 0.8; + width: 100%; + margin: var(--edge-padding); +} + +@media (min-width: 360px) { + ion-searchbar { + padding-right: 30px !important; + } +} + +@media (min-width: 480px) { + ion-searchbar { + padding-right: 50px !important; + } } .toolbar-btn::part(native) { @@ -63,9 +80,10 @@ ion-label { color: var(--ion-text-color-lighter); } -.top-bar { - padding-bottom: 0px !important; - margin-bottom: 0px !important; +ion-select { + --highlight-color-valid: var(--ion-text-color-lighter); + --highlight-color-invalid: var(--ion-text-color-lighter); + --highlight-color-focused: var(--ion-text-color-lighter); } cdk-virtual-scroll-viewport { @@ -100,3 +118,19 @@ cdk-virtual-scroll-viewport { overflow: hidden; visibility: hidden; } + +.search-result-container { + padding: 10px 0px 8px 0px; +} +.search-result-title { + font-size: 16px; + font-weight: bold; +} +.search-result-icon { + height: 30px; + width: 30px; +} +.search-result-icon-container { + width: 43px; + margin-left: 7px; +} diff --git a/src/app/tabs/tab-validators/tab-validators.page.ts b/src/app/tabs/tab-validators/tab-validators.page.ts new file mode 100644 index 00000000..b86129f7 --- /dev/null +++ b/src/app/tabs/tab-validators/tab-validators.page.ts @@ -0,0 +1,1071 @@ +/* + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH + * // + * // This file is part of Beaconchain Dashboard. + * // + * // Beaconchain Dashboard is free software: you can redistribute it and/or modify + * // it under the terms of the GNU General Public License as published by + * // the Free Software Foundation, either version 3 of the License, or + * // (at your option) any later version. + * // + * // Beaconchain Dashboard is distributed in the hope that it will be useful, + * // but WITHOUT ANY WARRANTY; without even the implied warranty of + * // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * // GNU General Public License for more details. + * // + * // You should have received a copy of the GNU General Public License + * // along with Beaconchain Dashboard. If not, see . + */ + +import { Component, computed, OnInit, signal, ViewChild, WritableSignal } from '@angular/core' +import { AlertController, IonSearchbar, ModalController, Platform, SearchbarCustomEvent } from '@ionic/angular' +import { ApiService } from '@services/api.service' +import { StorageService } from '@services/storage.service' +import { AlertService } from '@services/alert.service' +import { SubscribePage } from '@pages/subscribe/subscribe.page' +import { MerchantUtils } from '@utils/MerchantUtils' + +import { Keyboard } from '@capacitor/keyboard' + +import { UnitconvService } from '@services/unitconv.service' +import { InfiniteScrollDataSource, loadMoreType } from '@utils/InfiniteScrollDataSource' +import { DashboardAndGroupSelectComponent } from '@modals/dashboard-and-group-select/dashboard-and-group-select.component' +import { + dashboardID, + V2AddDashboardGroup, + V2DashboardOverview, + V2DeleteDashboardGroup, + V2GetValidatorFromDashboard, + V2UpdateDashboardGroup, +} from '@requests/v2-dashboard' +import { VDBOverviewData, VDBOverviewGroup } from '@requests/types/validator_dashboard' +import { Toast } from '@capacitor/toast' +import { Haptics } from '@capacitor/haptics' +import { SearchResultData, searchType, V2SearchValidators } from '@requests/v2-search' +import { DashboardUtils, isLocalDashboard } from '@utils/DashboardUtils' +import ThemeUtils from '@utils/ThemeUtils' +import { APIError, APIForbiddenError, APINotFoundError, ApiResult, APIUnauthorizedError } from '@requests/requests' +import { AppComponent } from '../../app.component' +import { V2MyDashboards } from '@requests/v2-user' +import { NotificationDetailComponent } from '@pages/notification-detail/notification-detail.component' +import FirebaseUtils from '@utils/FirebaseUtils' +import { MobileValidatorDashboardValidatorsTableRow } from '@requests/types/mobile' + +const PAGE_SIZE = 25 +const DASHBOARD_UPDATE = 'validators_tab' +const ASSOCIATED_CACHE_KEY = 'validators' + +@Component({ + selector: 'app-tab2', + templateUrl: 'tab-validators.page.html', + styleUrls: ['tab-validators.page.scss'], + standalone: false, +}) +export class Tab2Page implements OnInit { + NEW_GROUP_OFFSET = 900 + + public classReference = UnitconvService + @ViewChild('searchbarRef', { static: true }) searchbarRef: IonSearchbar + dataSource: InfiniteScrollDataSource + + initialLoading = true + reachedMaxValidators = false + isLoggedIn = false + initialized = false // when first data has been loaded and displayed + loadMore = false // infinite scroll load more text at bottom + + dashboardID: WritableSignal = signal(null) + private dashboardData: WritableSignal = signal(null) + validatorLoader: ValidatorLoader = null + + searchResultMode = false + searchResult: SearchResultData[] = null + + selectedGroup: number + + selectMode: boolean = false + selected = new Map() + + private validatorSetAltered = false + + private sort: string + + online: boolean = true + + constructor( + public modalController: ModalController, + public api: ApiService, + private storage: StorageService, + private alerts: AlertService, + public merchant: MerchantUtils, + public unit: UnitconvService, + private modalCtrl: ModalController, + protected dashboardUtils: DashboardUtils, + private themeUtils: ThemeUtils, + private platform: Platform, + private alertController: AlertController, + private firebaseUtils: FirebaseUtils + ) { + this.dashboardUtils.dashboardAwareListener.register(DASHBOARD_UPDATE) + + // Back key on android should cancel select mode + this.platform.backButton.subscribe(() => { + console.info('BACKPRESS SELECTMODE', this.selectMode) + if (this.selectMode) { + this.cancelSelect(true) + // give a bit time for backpress to fully propagate and then disable the backpress prevention + setTimeout(() => { + AppComponent.PREVENT_BACK_PRESS = false + }, 500) + } + }) + } + + async doOnNotificationClick(id: dashboardID, groupID: number, epoch: number, chainID: number): Promise { + const modal = await this.modalCtrl.create({ + component: NotificationDetailComponent, + componentProps: { + dashboardID: id, + groupID: groupID, + epoch: epoch, + chainID: chainID, + }, + }) + modal.present() + + await modal.onWillDismiss() + } + + ngOnInit() { + this.firebaseUtils.setNotificationClickCallback(this.doOnNotificationClick) + this.setup() + } + + async ionViewWillEnter() { + if (this.dashboardUtils.dashboardAwareListener.hasAndConsume(DASHBOARD_UPDATE)) { + await this.clearRequestCache() + await this.setup() + } + } + + /** + * Call when you need to clear the API request cache for all calls this view made. + * Note: when making calls in this view, always use the ASSOCIATED_CACHE_KEY + * @returns promise void + */ + clearRequestCache() { + return this.api.clearAllAssociatedCacheKeys(ASSOCIATED_CACHE_KEY) + } + + ionViewWillLeave() { + this.cancelSelect() + if (this.validatorSetAltered) { + this.validatorSetAltered = false + this.dashboardUtils.dashboardAwareListener.notifyAll() + } + } + + async setup() { + this.online = true + this.selectMode = false + AppComponent.PREVENT_BACK_PRESS = false + this.selected = new Map() + this.searchResult = null + this.searchResultMode = false + if (this.searchbarRef) { + this.searchbarRef.value = '' + } + + this.sort = await this.getDefaultSort() + this.isLoggedIn = await this.storage.isLoggedIn() + + await this.merchant.getUserInfo(false) + this.dashboardID.set(await this.dashboardUtils.initDashboard()) + if (!this.dashboardID) { + this.initialized = true + this.initialLoading = false + return + } + + const updateGroupsResult = await this.updateGroups() + if (updateGroupsResult && updateGroupsResult.error) { + Toast.show({ + text: 'Could not load groups', + }) + this.initialLoading = false + return + } + + if (!this.selectedGroup) { + // todo save selected group but reset when switching dashboard + // fall back to first group + + // todo test local only "all groups" - is it working? + this.selectedGroup = this.groups()?.[0] ? -1 : 0 //this.groups()?.[0]?.id ?? 0 + } + + await this.updateValidators() + } + + async getDefaultSort() { + return (await this.storage.getItem('validators_sort')) || 'index:asc' + } + + async setDefaultSort(sort: string) { + await this.storage.setItem('validators_sort', sort) + } + + selectSort() { + this.alerts.showSelect( + 'Sort by', + [ + { + name: 'sort', + label: 'Index Ascending', + value: 'index:asc', + type: 'radio', + checked: this.sort == 'index:asc', + }, + { + name: 'sort', + label: 'Index Descending', + value: 'index:desc', + type: 'radio', + checked: this.sort == 'index:desc', + }, + { + name: 'sort', + label: 'Online State (Offline first)', + value: 'status:asc', + type: 'radio', + checked: this.sort == 'status:asc', + }, + { + name: 'sort', + label: 'Online State (Online first)', + value: 'status:desc', + type: 'radio', + checked: this.sort == 'status:desc', + }, + { + name: 'sort', + label: 'Balance Ascending', + value: 'balance:asc', + type: 'radio', + checked: this.sort == 'balance:asc', + }, + { + name: 'sort', + label: 'Balance Descending', + value: 'balance:desc', + type: 'radio', + checked: this.sort == 'balance:desc', + }, + ], + async (data) => { + if (data) { + if (data != this.sort) { + await this.clearRequestCache() + this.sort = data as string + this.setDefaultSort(data as string) + this.updateValidators() + } + } + } + ) + } + + async openDashboardAndGroupSelect() { + const modal = await this.modalCtrl.create({ + component: DashboardAndGroupSelectComponent, + componentProps: { + dashboardChangedCallback: async () => { + const loading = await this.alerts.presentLoading('Loading...') + loading.present() + if (this.dashboardID() == (await this.storage.getDashboardID())) { + this.clearRequestCache() + } + await this.setup() + loading.dismiss() + }, + }, + }) + modal.present() + + await modal.onWillDismiss() + } + + private async updateGroups(recursiveMax: boolean = false): Promise | null> { + if (!this.isLoggedIn) { + return null + } + if (!this.dashboardID()) { + return null + } + const result = await this.api.set(new V2DashboardOverview(this.dashboardID()), this.dashboardData, ASSOCIATED_CACHE_KEY) + if (result.error) { + if (result.error instanceof APINotFoundError) { + if (recursiveMax) { + Toast.show({ + text: 'Dashboard not found', + }) + return + } + this.storage.setDashboardID(null) + // if dashboard is not available any more (maybe user deleted it) reinit and try again + this.dashboardID.set(await this.dashboardUtils.initDashboard()) + return this.updateGroups(true) + } else if (result.error instanceof APIError) { + if (this.dashboardUtils.defaultDashboardErrorHandler(result.error)) { + result.error = null + } else { + this.online = false + } + } else { + this.online = false + } + } + return result + } + + private async updateValidators(recursiveMax: boolean = false) { + this.initialLoading = true + this.reachedMaxValidators = false + this.validatorLoader = new ValidatorLoader(this.api, this.dashboardID(), this.selectedGroup, this.sort, async (error) => { + if (!(error instanceof APIUnauthorizedError)) { + // todo change to just if timeout? + this.online = false + } + if (error instanceof APINotFoundError) { + if (recursiveMax) { + Toast.show({ + text: 'Dashboard not found', + }) + return + } + this.storage.setDashboardID(null) + // if dashboard is not available any more (maybe user deleted it) reinit and try again + this.dashboardID.set(await this.dashboardUtils.initDashboard()) + return this.updateValidators(true) + } + }) + this.dataSource = new InfiniteScrollDataSource(PAGE_SIZE, this.getDefaultDataRetriever()) + + await this.dataSource.reset() + } + + private getDefaultDataRetriever(): loadMoreType { + return async (cursor) => { + const firstRun = !cursor && !this.initialized + if (firstRun) { + this.initialLoading = true + } + + this.loadMore = !!cursor + const result = await this.validatorLoader.getDefaultDataRetriever()(cursor) + this.loadMore = false + + if (this.initialLoading) { + this.initialLoading = false + this.initialized = true + } + return result + } + } + + async searchEvent(event: SearchbarCustomEvent, maxRecursive = false): Promise { + const searchString = event.target.value + if (!searchString || searchString.length < 0) return + if (this.platform.is('ios') || this.platform.is('android')) { + Keyboard.hide() + } + + this.searchResultMode = true + this.searchResult = null + const chainID = await this.api.getCurrentDashboardChainID() + const searchTypes = this.getFittingSearchTypes(searchString) + + const result = await this.api.execute(new V2SearchValidators(searchString, [chainID], searchTypes), ASSOCIATED_CACHE_KEY) + if (result.error) { + // If we get a cors forbidden error, try a get call and then retry + if (result.error instanceof APIForbiddenError && !maxRecursive) { + await this.api.getLatestState(true) + return this.searchEvent(event, true) + } + this.dashboardUtils.defaultDashboardErrorHandler(result.error) + + this.searchResultMode = false + this.online = false + Toast.show({ + text: 'Could not search for validators', + duration: 'long', + }) + return + } + + this.searchResult = result.data + } + + getFittingSearchTypes(searchString: string): searchType[] { + const isETH1Address = searchString.startsWith('0x') && searchString.length == 42 + const isWithdrawalCredential = searchString.startsWith('0x') && searchString.length == 66 + const isPubkey = searchString.startsWith('0x') && searchString.length == 98 + + const isAllHexadecimal = /^[0-9a-fA-F]+$/.test(searchString) && searchString.length % 2 == 0 && searchString.length > 10 + + const isIndexList = /^(\d+,)+\d+$/.test(searchString) + + // a bit of optimization so search is faster than just scanning for all types if we know input is a certain way + if (isETH1Address) { + return [searchType.validatorsByWithdrawalAddress, searchType.validatorsByDepositAddress] + } else if (isWithdrawalCredential) { + return [searchType.validatorsByWithdrawalCredential] + } else if (isPubkey) { + return [searchType.validatorByPublicKey] + } else if (isAllHexadecimal) { + return [ + searchType.validatorsByWithdrawalAddress, + searchType.validatorsByDepositAddress, + searchType.validatorsByWithdrawalCredential, + searchType.validatorByPublicKey, + ] + } else if (isIndexList) { + return [searchType.validatorList] + } + return [searchType.validatorByIndex, searchType.validatorsByDepositEnsName, searchType.validatorsByWithdrawalEns, searchType.validatorsByGraffiti] + } + + addSearchResult(item: SearchResultData) { + if (!this.merchant.canBulkAdd() && this.dashboardUtils.searchResultHandler.requiresPremium(item)) { + this.premiumInfo() + return + } + + const resultValidatorCount = this.dashboardUtils.searchResultHandler.resultCount(item) + if (resultValidatorCount + this.validatorCountAcrossAllGroups() > this.merchant.getCurrentPlanMaxValidator()) { + if (this.isLoggedIn && this.dashboardUtils.searchResultHandler.resultCount(item) > 1) { + this.alerts.confirmDialog( + 'Maximum validators reached', + 'Some of your validators can not be added since it exceeds your current plans limit.

You can add more validators by upgrading to a higher plan.

Do you want to add the remaining validators?', + 'Add', + () => { + this.addSearchResultRemoteDialog(item) + } + ) + return + } else { + this.alerts.showInfo( + 'Can not add validators', + 'You reached the maximum number of validators for your plan.

You can add more validators by upgrading to a higher plan.' + ) + return + } + } + + if (this.isLoggedIn) { + this.addSearchResultRemoteDialog(item) + } else { + this.confirmAddSearchResult(item, 0) + } + } + + addSearchResultRemoteDialog(item: SearchResultData) { + const addCount = this.dashboardUtils.searchResultHandler.resultCount(item) + let title = 'Add to Group' + if (addCount > 1) { + title = 'Add all to Group' + } + + const targetGroup = this.findGroupById(this.selectedGroup) || this.groups()[0] + + const maxGroupReached = this.groups().length >= this.merchant.userInfo().premium_perks.validator_groups_per_dashboard + const skipGroupSelectModal = this.groups().length == 1 && maxGroupReached // only default group anyway + + if (skipGroupSelectModal) { + this.confirmAddSearchResult(item, targetGroup.id) + return + } + + const allGroups = this.groups().map((g) => { + return { + name: 'group', + label: g.name + ' (' + g.count + ')', + value: g.id, + type: 'radio', + checked: g.id == targetGroup.id, + disabled: g.count + addCount >= this.merchant.getCurrentPlanMaxValidator(), + } + }) + + allGroups.push({ + name: 'group', + label: 'Create New Group' + (maxGroupReached ? ' (maxed)' : ''), + value: -1, + type: 'radio', + checked: false, + disabled: maxGroupReached, + }) + + const addSearchResultToGroup = async (groupID: number) => { + await this.confirmAddSearchResult(item, groupID) + if (groupID != targetGroup.id) { + this.selectedGroup = groupID + this.updateValidators() + } + } + + this.alerts.showSelectWithCancel(title, allGroups, async (groupID: number) => { + if (groupID == -1) { + // create new group + await this.addNewGroupDialog((newGroupID) => { + addSearchResultToGroup(newGroupID) + }) + return + } + addSearchResultToGroup(groupID) + }) + } + + async confirmAddSearchResult(item: SearchResultData, groupID: number) { + const loading = await this.alerts.presentLoading('Adding validators...') + loading.present() + + const ok = await this.dashboardUtils.addValidator(item, groupID) + if (!ok) { + Toast.show({ + text: 'Could not add validator to dashboard', + duration: 'long', + }) + } + this.validatorSetAltered = true + await this.clearRequestCache() + await this.setup() + + loading.dismiss() + } + + private clickBlocked = false + blockClick(forTime: number) { + this.clickBlocked = true + setTimeout(() => { + this.clickBlocked = false + }, forTime) + } + + selectValidator(item: MobileValidatorDashboardValidatorsTableRow) { + this.selectMode = !this.selectMode + AppComponent.PREVENT_BACK_PRESS = this.selectMode + if (!this.selectMode) { + this.cancelSelect() + } else { + this.blockClick(330) + this.enableSelectMode() + Haptics.selectionStart() + + if (item) { + this.selected.set(item.index, true) + Haptics.selectionChanged() + } + } + } + + enableSelectMode() { + if (!this.dataSource.hasItems()) { + Toast.show({ + text: 'Your validator list is empty.', + }) + return + } + this.selectMode = true + const color = getComputedStyle(document.body).getPropertyValue('--ion-color-primary') + this.themeUtils.setStatusBarColor(color) + } + + disableSelectMode() { + this.selectMode = false + this.selected = new Map() + this.themeUtils.revertStatusBarColor() + Haptics.selectionEnd() + } + + deleteSelected() { + if (this.selected.size <= 0) { + Toast.show({ + text: 'Select the validators you want to delete first.', + }) + return + } + + this.alerts.confirmDialog( + 'Remove validators', + 'Do you want to remove the selected validators from your dashboard?', + 'Delete', + () => { + this.alerts.confirmDialogReverse( + 'Are you really sure?', + 'Please note that this action can NOT be undone.

Delete: ' + this.selected.size + ' validators', + 'Delete', + () => this.deleteConfirm(Array.from(this.selected.keys())), + 'error-btn' + ) + }, + 'error-btn' + ) + } + + async deleteConfirm(index: number[]) { + const loading = await this.alerts.presentLoading('Removing validators...') + loading.present() + + const ok = await this.dashboardUtils.deleteValidator(index) + if (!ok) { + Toast.show({ + text: 'Could not remove validator from dashboard', + duration: 'long', + }) + return + } + + this.validatorSetAltered = true + await this.clearRequestCache() + this.disableSelectMode() + await this.setup() + loading.dismiss() + Toast.show({ + text: 'Validators removed from dashboard', + duration: 'short', + }) + } + + moveSelected() {} + + cancelSearch() { + if (this.searchResultMode) { + this.searchResultMode = false + this.updateValidators() + } + } + + private lastRefreshedTs: number = 0 + async doRefresh(event: { target: { complete: () => void } }) { + if (this.lastRefreshedTs + 15 * 1000 > new Date().getTime()) { + Toast.show({ + text: 'Nothing to update', + }) + if (event) event.target.complete() + return + } + this.lastRefreshedTs = new Date().getTime() + + this.initialLoading = true + await this.clearRequestCache() + await this.updateValidators().catch(() => { + if (event) event.target.complete() + }) + this.initialLoading = false + if (event) event.target.complete() + } + + async upgrade() { + const modal = await this.modalController.create({ + component: SubscribePage, + cssClass: 'my-custom-class', + }) + return await modal.present() + } + + clickValidator(item: MobileValidatorDashboardValidatorsTableRow) { + if (this.clickBlocked) return + if (this.selectMode) { + if (this.selected.get(item.index)) { + this.selected.delete(item.index) + } else { + this.selected.set(item.index, true) + } + Haptics.selectionChanged() + } else { + let syncText = '' + if (item.is_in_sync_committee) { + syncText = + "This validator is part of the current sync committee. You'll earn extra rewards during this period if you are online and attesting.

" + } else if (item.is_in_next_sync_committee) { + syncText = + "This validator is part of the next sync committee. You'll earn extra rewards during this period if you are online and attesting.

" + } + + let rocketPoolText = '' + if (item.rocket_pool) { + rocketPoolText = 'Rocket Pool
' + rocketPoolText += 'Deposit: ' + this.unit.weiToEth(item.rocket_pool.deposit_amount) + '
' + rocketPoolText += 'Commission: ' + (item.rocket_pool.commission * 100).toFixed(1) + '%
' + rocketPoolText += 'Status: ' + item.rocket_pool.status + '
' + rocketPoolText += 'Penalty Count: ' + item.rocket_pool.penalty_count + '
' + rocketPoolText += 'Smoothing Pool: ' + (item.rocket_pool.is_in_smoothing_pool ? 'Yes' : 'No') + '
' + } + + if (!item.rocket_pool && !syncText) { + this.alerts.showInfo('Validator Details', 'Nothing to show') + } else { + this.alerts.showInfo('Validator Details', syncText + rocketPoolText) + } + } + } + + cancelSelect(preventPreventBackPress = false) { + // cancelSelect is called when backpress is pressed, + // so it can lead to a scenario where prevent backpress is changed here to false + // while the backpress hasn't fully propagated yet. + // hence preventPreventBackPress = true in this scenario + if (!preventPreventBackPress) { + AppComponent.PREVENT_BACK_PRESS = false + } + + this.disableSelectMode() + } + + // ------------ GROUPS ------------ + + groups = computed(() => { + return this.dashboardUtils.getGroupList(this.dashboardData()?.groups) + }) + + validatorCountAcrossAllGroups = computed(() => { + if (this.isLoggedIn) { + return this.groups().reduce((acc, group) => acc + group.count, 0) + } else { + const id = this.dashboardID() + if (isLocalDashboard(id)) { + return id.length + } + return 0 + } + }) + + private opened = false + openAddGroupOnce() { + if (this.opened) return + this.opened = true + this.addNewGroupDialog() + setTimeout(() => { + this.opened = false + }, 300) + } + + ionSelectCompareWith = (a: number, b: number) => { + if (a >= this.NEW_GROUP_OFFSET) { + a -= this.NEW_GROUP_OFFSET + // special case for adding new group, it is current group id + NEW_GROUP_OFFSET + if (this.selectedGroup >= this.NEW_GROUP_OFFSET) { + this.selectedGroup -= this.NEW_GROUP_OFFSET // stay on last selected group + this.openAddGroupOnce() + } + } + if (b >= this.NEW_GROUP_OFFSET) { + b -= this.NEW_GROUP_OFFSET + } + + return a == b + } + + selectGroup() { + // special case for adding new group, it is current group id + NEW_GROUP_OFFSET + if (this.selectedGroup >= this.NEW_GROUP_OFFSET) { + return + } + this.updateValidators() + } + + findGroupById(id: number) { + return this.groups().find((group) => group.id == id) + } + + async renameGroupDialog() { + if (!this.notLoggedInGroupInfoDialog('Rename Group')) { + return + } + const renameGroup = this.findGroupById(this.selectedGroup) + + const alert = await this.alertController.create({ + cssClass: 'my-custom-class', + header: 'Rename Group', + inputs: [ + { + name: 'newName', + type: 'text', + value: renameGroup.realName, + placeholder: 'New group name', + }, + ], + buttons: [ + { + text: 'Cancel', + role: 'cancel', + cssClass: 'secondary', + handler: () => { + return + }, + }, + { + text: 'Rename', + handler: async (alertData) => { + if (alertData.newName.length < 1) { + Toast.show({ + text: 'Please enter a name', + }) + return false + } + + const loading = await this.alerts.presentLoading('Applying changes...') + loading.present() + + const result = await this.api.execute(new V2UpdateDashboardGroup(this.dashboardID(), renameGroup.id, alertData.newName)) + if (result.error) { + Toast.show({ + text: 'Error creating group, please try again later', + }) + } else { + Toast.show({ + text: 'Group renamed', + }) + await this.clearRequestCache() + const updateGroupsResult = await this.updateGroups() + if (updateGroupsResult.error) { + Toast.show({ + text: 'Could not load groups', + }) + loading.dismiss() + return + } + } + + loading.dismiss() + }, + }, + ], + }) + + await alert.present() + } + + removeGroupDialog() { + if (!this.notLoggedInGroupInfoDialog('Remove Group')) { + return + } + const deleteGroup = this.findGroupById(this.selectedGroup) + + if (deleteGroup.id == 0) { + this.alerts.showInfo('Default group', 'You can not delete the default group.') + return + } + + let extraText = '' + if (deleteGroup.count > 1) { + extraText = '

All ' + deleteGroup.count + ' associated validators with that group will be removed from your dashboard.' + } else if (deleteGroup.count == 1) { + extraText = '

The associated validator with that group will be removed from your from your dashboard.' + } + this.alerts.confirmDialog( + 'Remove Group', + 'Do you want to remove this group: "' + deleteGroup.name + '"?' + extraText, + 'Delete', + () => { + this.confirmRemoveGroup(deleteGroup) + }, + 'error-btn' + ) + } + + async confirmRemoveGroup(deleteGroup: VDBOverviewGroup) { + const loading = await this.alerts.presentLoading('Deleting group...') + loading.present() + + const result = await this.api.execute(new V2DeleteDashboardGroup(this.dashboardID(), deleteGroup.id)) + if (result.error) { + Toast.show({ + text: 'Error deleting group, please try again later', + }) + } else { + Toast.show({ + text: 'Group deleted', + }) + + this.validatorSetAltered = true + await this.clearRequestCache() + await this.api.clearSpecificCache(new V2MyDashboards()) // clear dashboard select view cache + const updateGroupsResult = await this.updateGroups() + if (updateGroupsResult.error) { + Toast.show({ + text: 'Could not load groups', + }) + loading.dismiss() + return + } + this.selectedGroup = this.groups()?.[0]?.id ?? 0 + this.updateValidators() + } + + loading.dismiss() + } + + notLoggedInGroupInfoDialog(title: string) { + if (!this.isLoggedIn) { + this.alerts.showInfo( + title, + 'Groups allow you to better manage your validators and get deep insight on how they perform against each other.

You need a beaconcha.in account and a premium subscription to use groups.' + ) + return false + } + return true + } + + async addNewGroupDialog(creationSuccessCallback: (id: number) => void = null) { + if (!this.notLoggedInGroupInfoDialog('Add Group')) { + return + } + if (this.merchant.userInfo()?.premium_perks?.validator_groups_per_dashboard == 1) { + this.alerts.showInfo('Upgrade', 'Groups are a premium feature. Please upgrade to Guppy or higher to use this feature.') + return + } + + if (this.groups().length >= this.merchant.highestPackageGroupsPerDashboardAllowed()) { + this.alerts.showInfo( + 'Maximum group reached', + 'You reached the highest possible number of groups we currently support.

If you feel like you need more, let us know!' + ) + return + } + + if (this.groups().length >= (this.merchant.userInfo()?.premium_perks?.validator_groups_per_dashboard ?? 0)) { + this.alerts.showInfo( + 'Upgrade to premium', + 'You have reached the maximum number of groups allowed for your plan.

You can create more groups by upgrading to a premium plan.' + ) + return + } + + const alert = await this.alertController.create({ + cssClass: 'my-custom-class', + header: 'New Group', + inputs: [ + { + name: 'newName', + type: 'text', + placeholder: 'Group name', + }, + ], + buttons: [ + { + text: 'Cancel', + role: 'cancel', + cssClass: 'secondary', + handler: () => { + return + }, + }, + { + text: 'Create', + handler: async (alertData) => { + if (alertData.newName.length < 1) { + Toast.show({ + text: 'Please enter a name', + }) + return false + } + + const loading = await this.alerts.presentLoading('Creating group...') + loading.present() + + const result = await this.api.execute(new V2AddDashboardGroup(this.dashboardID(), alertData.newName)) + if (result.error) { + console.log('error', result.error?.message) + if ((result.error.message?.indexOf('has incorrect format') || -1) > -1) { + Toast.show({ + text: 'Special characters are not allowed in group names.', + }) + } else { + Toast.show({ + text: 'Error creating group, please try again later', + }) + } + } else { + await this.api.clearSpecificCache(new V2MyDashboards()) // clear dashboard select view cache + if (creationSuccessCallback) { + loading.dismiss() + creationSuccessCallback(result.data.id) + return + } + Toast.show({ + text: 'Group created', + }) + await this.clearRequestCache() + const updateGroupsResult = await this.updateGroups() + if (updateGroupsResult.error) { + Toast.show({ + text: 'Could not load groups', + }) + loading.dismiss() + return + } + this.selectedGroup = result.data.id + + this.updateValidators() + } + + loading.dismiss() + }, + }, + ], + }) + + await alert.present() + } + + premiumInfo() { + this.alerts.showInfo( + 'Upgrade', + 'Adding multiple validators at once via ENS, deposit address or withdrawal address/credential requires a premium subscription.' + ) + } +} + +class ValidatorLoader { + constructor( + private api: ApiService, + private dashboard: dashboardID, + private groupID: number, + private sort: string, + private errorHandler: (error: Error) => Promise + ) {} + + public getDefaultDataRetriever(): loadMoreType { + return async (cursor) => { + if (!this.dashboard) { + return { + data: undefined, + next_cursor: null, + } + } + const result = await this.api.execute( + new V2GetValidatorFromDashboard(this.dashboard, this.groupID, cursor, PAGE_SIZE, this.sort), + ASSOCIATED_CACHE_KEY + ) + if (result.error) { + Toast.show({ + text: 'Could not load validators', + duration: 'long', + }) + if (this.errorHandler) { + await this.errorHandler(result.error) + } + return { + data: undefined, + next_cursor: null, + } + } + return { + data: result.data as MobileValidatorDashboardValidatorsTableRow[], + next_cursor: result.paging?.next_cursor, + } + } + } +} diff --git a/src/app/tabs/tabs-routing.module.ts b/src/app/tabs/tabs-routing.module.ts index 79a09a16..2d9fd8c3 100644 --- a/src/app/tabs/tabs-routing.module.ts +++ b/src/app/tabs/tabs-routing.module.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -29,23 +28,23 @@ const routes: Routes = [ children: [ { path: 'dashboard', - loadChildren: () => import('../tab-dashboard/tab-dashboard.module').then((m) => m.Tab1PageModule), + loadChildren: () => import('./tab-dashboard/tab-dashboard.module').then((m) => m.Tab1PageModule), }, { path: 'validators', - loadChildren: () => import('../tab-validators/tab-validators.module').then((m) => m.Tab2PageModule), + loadChildren: () => import('./tab-validators/tab-validators.module').then((m) => m.Tab2PageModule), }, { path: 'preferences', - loadChildren: () => import('../tab-preferences/tab-preferences.module').then((m) => m.Tab3PageModule), + loadChildren: () => import('./tab-preferences/tab-preferences.module').then((m) => m.Tab3PageModule), }, { path: 'machines', - loadChildren: () => import('../pages/machines/machines.module').then((m) => m.MachinesPageModule), + loadChildren: () => import('./tab-machines/machines.module').then((m) => m.MachinesPageModule), }, { path: 'blocks', - loadChildren: () => import('../tab-blocks/tab-blocks.module').then((m) => m.TabBlocksPageModule), + loadChildren: () => import('./tab-blocks/tab-blocks.module').then((m) => m.TabBlocksPageModule), }, { path: '', diff --git a/src/app/tabs/tabs.module.ts b/src/app/tabs/tabs.module.ts index 7f09f759..604d3426 100644 --- a/src/app/tabs/tabs.module.ts +++ b/src/app/tabs/tabs.module.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -26,9 +25,10 @@ import { FormsModule } from '@angular/forms' import { TabsPageRoutingModule } from './tabs-routing.module' import { TabsPage } from './tabs.page' +import { FirebaseUtilsModule } from '@utils/Firebase.module' @NgModule({ - imports: [IonicModule, CommonModule, FormsModule, TabsPageRoutingModule], + imports: [IonicModule, CommonModule, FormsModule, TabsPageRoutingModule, FirebaseUtilsModule], declarations: [TabsPage], }) export class TabsPageModule {} diff --git a/src/app/tabs/tabs.page.html b/src/app/tabs/tabs.page.html index 7588cdf6..27f4ac1e 100644 --- a/src/app/tabs/tabs.page.html +++ b/src/app/tabs/tabs.page.html @@ -1,5 +1,5 @@ - + @@ -36,7 +36,7 @@ - + @@ -45,6 +45,6 @@ - - + + diff --git a/src/app/tabs/tabs.page.scss b/src/app/tabs/tabs.page.scss index 99ecb501..79861479 100644 --- a/src/app/tabs/tabs.page.scss +++ b/src/app/tabs/tabs.page.scss @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -21,4 +20,22 @@ ion-tab-bar { --border-top: var(--tab-top-border); border-top: var(--tab-top-border); + + position: absolute; + z-index: 99; + width: 100%; + height: 50px; + bottom: -1px; +} + +@supports ((-webkit-backdrop-filter: blur(0)) or (backdrop-filter: blur(0))) { + ion-tab-bar { + --background: rgba(var(--ion-background-color-rgb, 255, 255, 255), var(--bar-transparency)); // Default (light mode) transparency + + //--background: rgba(var(--ion-background-color-rgb, 255, 255, 255), 0.9); + -webkit-backdrop-filter: saturate(180%) blur(5px); + backdrop-filter: saturate(180%) blur(5px); + will-change: transform; /* Create a new layer to avoid flickering */ + transform: translateZ(0); /* Forces the browser to create a new layer */ + } } diff --git a/src/app/tabs/tabs.page.spec.ts b/src/app/tabs/tabs.page.spec.ts deleted file mode 100644 index 7ebcdae6..00000000 --- a/src/app/tabs/tabs.page.spec.ts +++ /dev/null @@ -1,46 +0,0 @@ -/* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) - * // - * // This file is part of Beaconchain Dashboard. - * // - * // Beaconchain Dashboard is free software: you can redistribute it and/or modify - * // it under the terms of the GNU General Public License as published by - * // the Free Software Foundation, either version 3 of the License, or - * // (at your option) any later version. - * // - * // Beaconchain Dashboard is distributed in the hope that it will be useful, - * // but WITHOUT ANY WARRANTY; without even the implied warranty of - * // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * // GNU General Public License for more details. - * // - * // You should have received a copy of the GNU General Public License - * // along with Beaconchain Dashboard. If not, see . - */ - -import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core' -import { async, ComponentFixture, TestBed } from '@angular/core/testing' - -import { TabsPage } from './tabs.page' - -describe('TabsPage', () => { - let component: TabsPage - let fixture: ComponentFixture - - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [TabsPage], - schemas: [CUSTOM_ELEMENTS_SCHEMA], - }).compileComponents() - })) - - beforeEach(() => { - fixture = TestBed.createComponent(TabsPage) - component = fixture.componentInstance - fixture.detectChanges() - }) - - it('should create', () => { - expect(component).toBeTruthy() - }) -}) diff --git a/src/app/tabs/tabs.page.ts b/src/app/tabs/tabs.page.ts index 9dd73da5..e8838c62 100644 --- a/src/app/tabs/tabs.page.ts +++ b/src/app/tabs/tabs.page.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -19,24 +18,23 @@ */ import { Component } from '@angular/core' -import { StorageService } from '../services/storage.service' -import { SyncService } from '../services/sync.service' -import FirebaseUtils from '../utils/FirebaseUtils' -import { MerchantUtils } from '../utils/MerchantUtils' -import ThemeUtils from '../utils/ThemeUtils' -import { Toast } from '@capacitor/toast' +import FirebaseUtils, { pushLastTokenUpstream } from '@utils/FirebaseUtils' +import V2Migrator from '@utils/V2Migrator' +import { ApiService } from '@services/api.service' +import { StorageService } from '@services/storage.service' + @Component({ selector: 'app-tabs', templateUrl: 'tabs.page.html', styleUrls: ['tabs.page.scss'], + standalone: false, }) export class TabsPage { constructor( private firebaseUtils: FirebaseUtils, - private sync: SyncService, + private v2Migrator: V2Migrator, private storage: StorageService, - private merchant: MerchantUtils, - private theme: ThemeUtils + private api: ApiService ) {} ionViewDidEnter() { @@ -44,85 +42,18 @@ export class TabsPage { } private preload() { + setTimeout(() => { + this.v2Migrator.showDeprecationNotice() + }, 500) + // lazy initiating firebase token exchange this.firebaseUtils.registerPush() // just initialize the firebaseutils service // lazy sync & notification token update - setTimeout(async () => { - this.firebaseUtils.pushLastTokenUpstream(false) - await this.sync.mightSyncUpAndSyncDelete() - await this.sync.syncAllSettings() - }, 5000) - - // lazy ionic speed optimizations - setTimeout(() => { - this.hackyIonicPreloads() - }, 200) - - // Validate licence and reset theme accordingly setTimeout(() => { - this.validateTheming() - }, 600) - } - - private async validateTheming() { - const defaultTheme = await this.merchant.getDefaultTheme() - const stored = await this.storage.getItem('setting_default_theme') - if (defaultTheme != stored && defaultTheme != '') { - this.storage.setItem('setting_default_theme', defaultTheme) - this.theme.undoColor() - setTimeout(async () => { - this.theme.toggle(await this.theme.isDarkThemed(), true, defaultTheme) - Toast.show({ - text: 'Switched to Ethpool theme', - }) - }, 250) - } - - const hasTheming = await this.merchant.hasPremiumTheming() - if (!hasTheming && this.theme.currentThemeColor != 'gnosis') { - this.theme.resetTheming() - } - } - - private hackyIonicPreloads() { - // lazy preload some components needed by other tabs - const preloadArea: HTMLElement = document.getElementById('preload') - preloadArea.appendChild(document.createElement('ion-list-header')) - preloadArea.appendChild(document.createElement('app-message')) - preloadArea.appendChild(document.createElement('ion-select-option')) - preloadArea.appendChild(document.createElement('ion-toggle')) - preloadArea.appendChild(document.createElement('app-validator')) - preloadArea.appendChild(document.createElement('ion-searchbar')) - preloadArea.appendChild(document.createElement('app-offline')) - - // optimize ion-icon loading by preloading every icon used in preferences / validators page - const icons = document.createElement('div') - icons.innerHTML = - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' - preloadArea.appendChild(icons) + pushLastTokenUpstream(this.storage, this.api, false) + // await this.sync.mightSyncUpAndSyncDelete() + // await this.sync.syncAllSettings() + }, 5000) } } diff --git a/src/app/utils/AdUtils.ts b/src/app/utils/AdUtils.ts index 6e6286e0..56f226a7 100644 --- a/src/app/utils/AdUtils.ts +++ b/src/app/utils/AdUtils.ts @@ -1,4 +1,4 @@ -// Copyright (C) 2021 Bitfly GmbH +// Copyright (C) 2021 bitfly explorer GmbH // // This file is part of Beaconchain Dashboard. // @@ -15,9 +15,9 @@ // You should have received a copy of the GNU General Public License // along with Beaconchain Dashboard. If not, see . -import { ApiService } from '../services/api.service' +import { ApiService } from '@services/api.service' import { Injectable } from '@angular/core' -import { BitflyAdRequest, BitflyAdResponse } from '../requests/requests' +import { BitflyAdRequest, BitflyAdResponse } from '@requests/requests' import { MerchantUtils } from './MerchantUtils' export type AdLocation = 'dashboard' | 'validator' | 'machines' | 'blocks' | 'info' @@ -53,25 +53,25 @@ const LOGTAG = '[AdUtils] ' providedIn: 'root', }) export default class AdUtils { - constructor(private api: ApiService, private merchantUtils: MerchantUtils) {} + constructor( + private api: ApiService, + private merchantUtils: MerchantUtils + ) {} async get(location: AdLocation): Promise { - const adFree = await this.merchantUtils.hasAdFree() + await this.merchantUtils.initialize + const adFree = this.merchantUtils.userInfo()?.premium_perks.ad_free == true if (adFree) { console.info(LOGTAG + 'user is premium member, disabling ads') return null } const request = new BitflyAdRequest(map.get(location)) - const response = await this.api.execute(request).catch((err) => { - console.warn('error adUtils get', err) - return null - }) - const result = request.parse(response) + const result = await this.api.execute(request) console.log('Bitfly ad response', result) - if (result && result.length > 0 && result[0].height != '0') { - return result[0] + if (!result.error && result.data.length > 0 && result.data[0].height != '0') { + return result.data[0] } return { diff --git a/src/app/utils/AppUpdater.ts b/src/app/utils/AppUpdater.ts new file mode 100644 index 00000000..2a197477 --- /dev/null +++ b/src/app/utils/AppUpdater.ts @@ -0,0 +1,189 @@ +// Copyright (C) 2024 bitfly explorer GmbH +// +// This file is part of Beaconchain Dashboard. +// +// Beaconchain Dashboard is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Beaconchain Dashboard is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Beaconchain Dashboard. If not, see . + +import { Injectable } from '@angular/core' +import { CapacitorUpdater, DownloadOptions } from '@capgo/capacitor-updater' +import { ApiService } from '@services/api.service' +import { V2AckBundleUpdate, V2LatestAppBundle } from '@requests/v2-general' +import { AlertService } from '@services/alert.service' +import { AppUpdate, AppUpdateAvailability } from '@capawesome/capacitor-app-update' +import { App } from '@capacitor/app' +import versionInfo from '../../version.json' +import { Capacitor } from '@capacitor/core' +import { StorageService } from '@services/storage.service' + +@Injectable({ + providedIn: 'root', +}) +export class AppUpdater { + private loading: HTMLIonLoadingElement + + constructor( + private api: ApiService, + private alert: AlertService, + private storage: StorageService + ) {} + + async checkForNewNative() { + const currentNative = await this.getCurrentNativeVersionCode() + // New native version is always shipped with a new bundle + // if we don't reset it to the buildin bundle, the old bundle may still be used + const didBundleResetOnThisNative = await this.storage.getBooleanSetting('native_reset_' + currentNative, false) + if (!didBundleResetOnThisNative) { + await this.storage.setBooleanSetting('native_reset_' + currentNative, true) + CapacitorUpdater.reset({ + // back to native bundle + toLastSuccessful: false, + }) + } + } + + async check() { + const currentBundle = this.getCurrentBundleCode() + const currentNative = await this.getCurrentNativeVersionCode() + console.log('Current App Version', versionInfo.buildNumber, currentNative) + + if (!Capacitor.isNativePlatform()) { + console.info('non native, skipping updates') + return false + } + + this.ackCurrentBundle(currentBundle) + + const [hasNativeUpdate, latest] = await Promise.all([this.updateNative(), this.api.execute(new V2LatestAppBundle(currentBundle, currentNative))]) + + // Does it make sense to have a minimal api here so checking for updates still works even if + // an update breaks the api service? + // on the other hand needs api key, cloudflare handling and network specific handling as well... + + if (!hasNativeUpdate) { + if (latest.error) { + console.warn('Failed to check for updates', latest.error) + return + } + + if (latest.data.has_native_update_available) { + console.warn('new native is available on server but not yet on system app store, ignoring for now') + return + } + + if (latest.data.bundle_url) { + await this.updateBundle(latest.data.bundle_url) + } + } + } + + async ackCurrentBundle(currentBundle: number) { + const ackLocalKey = 'bundle_acknowledged_' + currentBundle + if (await this.storage.getBooleanSetting(ackLocalKey, false)) { + return + } + try { + await this.api.getLatestState() // get csrf token + const result = await this.api.execute(new V2AckBundleUpdate(currentBundle)) + if (result.error) { + console.warn('could not ack bundle', result.error) + return + } + await this.storage.setBooleanSetting(ackLocalKey, true) + console.log("update ack'd") + } catch (e) { + console.warn('could not ack bundle', e) + } + } + + private async updateNative(): Promise { + if (!Capacitor.isNativePlatform()) return false + const result = await AppUpdate.getAppUpdateInfo() + if (result.updateAvailability !== AppUpdateAvailability.UPDATE_AVAILABLE) { + return false + } + if (result.immediateUpdateAllowed) { + await AppUpdate.performImmediateUpdate() + } else { + await this.alert.confirmDialog('Update available', 'An update is available, would you like to update the app?', 'Update', async () => { + await AppUpdate.openAppStore() + }) + } + return true + } + + async updateBundle(bundleURL: string, allowHTTP = false) { + if (!allowHTTP && bundleURL.indexOf('http') < 0) { + console.warn('invalid bundle url', bundleURL) + return + } + this.loading = await this.alert.presentLoading('Updating...') + this.loading.present() + + await CapacitorUpdater.addListener('download', (event) => { + this.loading.message = 'Updating ' + event.percent + '%
Do not close the app.' + }) + + await CapacitorUpdater.addListener('downloadComplete', () => { + this.loading.message = 'Processing Update...' + }) + + await CapacitorUpdater.addListener('updateFailed', () => { + this.loading.dismiss() + this.alert.showInfo('Update failed', 'Could not update the app, please try again later') + }) + + await CapacitorUpdater.addListener('downloadFailed', () => { + this.loading.dismiss() + this.alert.showInfo('Download failed', 'Could not download the update, please try again later') + }) + + try { + const version = await CapacitorUpdater.download({ + url: bundleURL, + version: versionInfo.formattedVersion, // even though this is the current version, this just needs to be present for reasons + } as DownloadOptions) + CapacitorUpdater.removeAllListeners() + await CapacitorUpdater.set(version) + } catch (e) { + console.warn('could not update bundle', e) + this.loading.dismiss() + } + } + + getCurrentBundleCode() { + return versionInfo.buildNumber + } + + async getCurrentNativeVersionCode() { + try { + return parseInt((await App.getInfo()).build) + } catch (e) { + console.warn('could not get native version code', e) + return 0 + } + } + + /** + * Use to display the current app version to the user + * @returns current formatted bundle version + native versionCode in parentheses + */ + async getFormattedCurrentVersion() { + let nativeVersion = (await this.getCurrentNativeVersionCode()).toString() + if (!Capacitor.isNativePlatform()) { + nativeVersion = 'dev' + } + + return versionInfo.formattedVersion + ' (' + nativeVersion + ')' + } +} diff --git a/src/app/utils/BlockUtils.ts b/src/app/utils/BlockUtils.ts index 00ea5d0b..8db5790e 100644 --- a/src/app/utils/BlockUtils.ts +++ b/src/app/utils/BlockUtils.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -18,82 +17,5 @@ * // along with Beaconchain Dashboard. If not, see . */ -import { ApiService } from '../services/api.service' -import { Injectable } from '@angular/core' -import { BlockProducedByRequest, BlockResponse, DashboardRequest } from '../requests/requests' -import BigNumber from 'bignumber.js' -import { ValidatorUtils } from './ValidatorUtils' - export const ROCKETPOOL_SMOOTHING_POOL = '0xd4e96ef8eee8678dbff4d535e033ed1a4f7605b7' export const ETHPOOL = '0xb364e75b1189dcbbf7f0c856456c1ba8e4d6481b' - -const MONTH = 60 * 60 * 24 * 30 - -@Injectable({ - providedIn: 'root', -}) -export class BlockUtils { - constructor(public api: ApiService, public validatorUtils: ValidatorUtils) {} - - async getBlockRewardWithShare(block: BlockResponse): Promise { - const proposer = block.posConsensus.proposerIndex - const validator = await this.validatorUtils.getLocalValidatorByIndex(proposer) - if (validator == null || validator.execshare == null) return new BigNumber(block.producerReward) - return new BigNumber(block.producerReward).multipliedBy(validator.execshare) - } - - async getBlocksBy(validatorIndex: number[], offset: number): Promise { - const request = new BlockProducedByRequest(offset, 25, ...validatorIndex) - const response = await this.api.execute(request) - const result = request.parse(response) - return result - } - - async getMyBlocks(offset: number): Promise { - const valis = await this.validatorUtils.getAllValidatorsLocal() - if (valis.length == 0) return [] - - const request = new BlockProducedByRequest(offset, this.getLimit(valis.length), ...valis.map((vali) => vali.index)) - const response = await this.api.execute(request) - const result = request.parse(response) - return result - } - - public getLimit(validatorCount: number): number { - if (validatorCount <= 4) return 10 - else if (validatorCount <= 10) return 15 - else if (validatorCount <= 20) return 20 - else if (validatorCount <= 50) return 30 - else if (validatorCount <= 100) return 50 - else if (validatorCount <= 200) return 65 - else return 75 - } - - async getProposalLuck(): Promise { - const valis = await this.validatorUtils.getAllValidatorsLocal() - if (valis.length == 0) return null - - const request = new DashboardRequest(...valis.map((vali) => vali.index)) - const response = await this.api.execute(request) - const result = request.parse(response)[0] - if (result) { - const proposalLuckStats = result.proposal_luck_stats - return { - luckPercentage: proposalLuckStats.proposal_luck, - timeFrameName: proposalLuckStats.time_frame_name, - userValidators: valis.length, - expectedBlocksPerMonth: MONTH / (proposalLuckStats.average_proposal_interval * this.api.getNetwork().slotsTime), - nextBlockEstimate: proposalLuckStats.next_proposal_estimate_ts * 1000, - } as Luck - } - return null - } -} - -export interface Luck { - luckPercentage: number - timeFrameName: string - userValidators: number - expectedBlocksPerMonth: number - nextBlockEstimate: number -} diff --git a/src/app/utils/CacheModule.ts b/src/app/utils/CacheModule.ts index bdb96c32..a4de92cb 100644 --- a/src/app/utils/CacheModule.ts +++ b/src/app/utils/CacheModule.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -18,7 +17,7 @@ * // along with Beaconchain Dashboard. If not, see . */ -import { StorageService, replacer } from '../services/storage.service' +import { StorageService, replacer } from '@services/storage.service' import { Validator } from './ValidatorUtils' const LOGTAG = '[CacheModule]' @@ -29,7 +28,7 @@ interface CachedData { data: unknown } -export class CacheModule { +export abstract class CacheModule { private staleTime private keyPrefix = '' @@ -92,19 +91,18 @@ export class CacheModule { await this.clearHardCache() } } catch (e) { - console.warn('could not calculate cache size') + console.warn('could not calculate cache size', e) } } private getStoreForCacheKey(cacheKey: string): Map { // rationale: don't store big data objects in hardStorage due to severe performance impacts - const storeHard = - cacheKey.indexOf('app/dashboard') >= 0 || - cacheKey.indexOf('produced?offset=0') >= 0 || // first page of blocks page - (cacheKey.indexOf('beaconcha.in') < 0 && cacheKey.indexOf('gnosischa.in') < 0 && cacheKey.indexOf('ads.bitfly') < 0) + const storeHard = this.storeInHardCache(cacheKey) return storeHard ? this.cache : this.hotOnly } + abstract storeInHardCache(cachekey: string): boolean + public async deleteAllHardStorageCacheKeyContains(search: string) { if (!this.hardStorage) { return @@ -215,7 +213,7 @@ export class CacheModule { } protected invalidateCache(key: string) { - this.cache[this.getKey(key)] = null + this.cache.set(this.getKey(key), null) } public invalidateAllCache() { diff --git a/src/app/utils/ClientUpdateUtils.ts b/src/app/utils/ClientUpdateUtils.ts index d3196e02..2b9c5f4a 100644 --- a/src/app/utils/ClientUpdateUtils.ts +++ b/src/app/utils/ClientUpdateUtils.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -18,94 +17,138 @@ * // along with Beaconchain Dashboard. If not, see . */ -import { ApiService } from '../services/api.service' -import { StorageService } from '../services/storage.service' -import { Injectable } from '@angular/core' -import { GithubReleaseRequest, GithubReleaseResponse } from '../requests/requests' +import { ApiService } from '@services/api.service' +import { StorageService } from '@services/storage.service' +import { Injectable, OnInit } from '@angular/core' +import { GithubReleaseRequest, GithubReleaseResponse } from '@requests/requests' -interface ClientInfo { +export interface ClientInfo { key: string + remoteKey: string // remote uses different keys now, acts more as a name + remoteId?: number // used to subscribe/unsubscribe on remote name: string repo: string storageKey: string + type: 'cons' | 'exec' | '3rdparty' } export const Clients: ClientInfo[] = [ - // Execution + // Consensus { key: 'LIGHTHOUSE', + remoteKey: 'Lighthouse', name: 'Lighthouse', repo: 'sigp/lighthouse', storageKey: 'client_updates_lighthouse', + type: 'cons', }, { key: 'LODESTAR', + remoteKey: 'Lodestar', name: 'Lodestar', repo: 'chainsafe/lodestar', storageKey: 'client_updates_lodestar', + type: 'cons', }, { key: 'PRYSM', + remoteKey: 'Prysm', name: 'Prysm', repo: 'prysmaticlabs/prysm', storageKey: 'client_updates_prysm', + type: 'cons', }, { key: 'NIMBUS', + remoteKey: 'Nimbus', name: 'Nimbus', repo: 'status-im/nimbus-eth2', storageKey: 'client_updates_nimbus', + type: 'cons', }, { key: 'TEKU', + remoteKey: 'Teku', name: 'Teku', repo: 'ConsenSys/teku', storageKey: 'client_updates_teku', + type: 'cons', }, - // Consensus + + // { + // key: 'GRANDINE', + // remoteKey: 'Grandine', + // name: 'Grandine', + // repo: 'grandinetech/grandine', + // storageKey: 'client_updates_grandine', + // type: 'cons', + // }, + + // Execution { key: 'BESU', + remoteKey: 'Besu', name: 'Besu', repo: 'hyperledger/besu', storageKey: 'client_updates_besu', + type: 'exec', }, { key: 'ERIGON', + remoteKey: 'Erigon', name: 'Erigon', repo: 'erigontech/erigon', storageKey: 'client_updates_erigon', + type: 'exec', }, { key: 'GETH', + remoteKey: 'Geth', name: 'Geth', repo: 'ethereum/go-ethereum', storageKey: 'client_updates_geth', + type: 'exec', }, { key: 'NETHERMIND', + remoteKey: 'Nethermind', name: 'Nethermind', repo: 'NethermindEth/nethermind', storageKey: 'client_updates_nethermind', + type: 'exec', + }, + + { + key: 'RETH', + remoteKey: 'Reth', + name: 'Reth', + repo: 'paradigmxyz/reth', + storageKey: 'client_updates_reth', + type: 'exec', }, // Various { key: 'ROCKETPOOL', + remoteKey: 'Rocketpool Smart Node', name: 'Rocketpool', repo: 'rocket-pool/smartnode-install', storageKey: 'smart_node_updates', + type: '3rdparty', }, { key: 'MEV-BOOST', + remoteKey: 'MEV-Boost', name: 'MEV-Boost', repo: 'flashbots/mev-boost', storageKey: 'mev_boost_updates', + type: '3rdparty', }, ] @@ -115,13 +158,28 @@ const SETTINGS_UPDATECHANNEL = 'setting_client_updatechannel' @Injectable({ providedIn: 'root', }) -export default class ClientUpdateUtils { - private oldClientInfoConverted = false +export default class ClientUpdateUtils implements OnInit { updates: Release[] = null lastTry = 0 private locked = false - constructor(private api: ApiService, private storage: StorageService) {} + constructor( + private api: ApiService, + private storage: StorageService + ) {} + + ngOnInit() { + this.storage.getBooleanSetting('migrated_uu_5_0_0', false).then(async (migrated) => { + if (!migrated) { + const updateChannel = await this.getUpdateChannel() + if (updateChannel == 'PRERELEASE') { + this.setUpdateChannel('STABLE') + } + console.info('migrated update channel to stable') + this.storage.setBooleanSetting('migrated_uu_5_0_0', true) + } + }) + } getClientInfo(clientKey: string): ClientInfo { if (clientKey == null) { @@ -183,10 +241,6 @@ export default class ClientUpdateUtils { } } - private async isPreReleaseAllowed() { - return (await this.getUpdateChannel()) == 'PRERELEASE' - } - private append(info: Release) { const data = info if (!data) return @@ -294,47 +348,11 @@ export default class ClientUpdateUtils { } private async getReleases(client: ClientInfo): Promise { - const req = new GithubReleaseRequest(client.repo, !(await this.isPreReleaseAllowed())) - const response = await this.api.execute(req).catch((error) => { - console.warn('error getReleases', error) - return null - }) - const temp = req.parse(response) - if (temp.length <= 0) return null - console.log('Client updates data', response, temp) - return new Release(client, temp[0]) - } - - async convertOldToNewClientSettings() { - if (this.oldClientInfoConverted) { - return - } - - const oldEth1StorageKey = 'setting_client_eth1' - - let oldClient = await this.storage.getItem(oldEth1StorageKey) - if (oldClient != null) { - console.log('Old ETH1/ETH2 client settings found, converting them') - - if (oldClient != 'none') { - this.setClient(oldClient, oldClient) - } - this.storage.remove(oldEth1StorageKey) - - // both ETH1 and ETH2 clients where used simultaneously - // so only if the ETH1 client was != null, there was a possibility for an ETH2 client too - const oldEth2StorageKey = 'setting_client_eth2' - - oldClient = await this.storage.getItem(oldEth2StorageKey) - if (oldClient != null) { - if (oldClient != 'none') { - this.setClient(oldClient, oldClient) - } - this.storage.remove(oldEth2StorageKey) - } - } - - this.oldClientInfoConverted = true + const req = new GithubReleaseRequest(client.repo) + const temp = await this.api.execute(req) + if (temp.error) return null + console.log('Client updates data', temp) + return new Release(client, temp.data[0]) } } diff --git a/src/app/utils/ColorUtils.ts b/src/app/utils/ColorUtils.ts new file mode 100644 index 00000000..8ea431b8 --- /dev/null +++ b/src/app/utils/ColorUtils.ts @@ -0,0 +1,91 @@ +export function getSummaryChartGroupColors(theme: string) { + const colorsLight = [ + '#ffaa31', + '#7db5ec', + '#b2df27', + '#5d78dc', + '#ffdb58', + '#f067e9', + '#57bd64', + '#a448c0', + '#dc2a7f', + '#e6beff', + '#87ceeb', + '#438d61', + '#e7416a', + '#6be4d8', + '#fabebe', + '#90d9a5', + '#ff6a00', + '#ffbe7c', + '#bcb997', + '#deb244', + '#dda0dd', + '#fa8072', + '#d2b48c', + '#6b8e23', + '#0e8686', + '#9a6324', + '#932929', + '#808000', + '#30308e', + '#708090', + ] + const colorsDark = [ + '#ffaa31', + '#7db5ec', + '#c3f529', + '#5d78dc', + '#ffdb58', + '#f067e9', + '#57bd64', + '#a448c0', + '#dc2a7f', + '#e6beff', + '#87ceeb', + '#438d61', + '#e7416a', + '#6be4d8', + '#fabebe', + '#aaffc3', + '#ff6a00', + '#ffd8b1', + '#fffac8', + '#deb244', + '#dda0dd', + '#fa8072', + '#d2b48c', + '#6b8e23', + '#0e8686', + '#9a6324', + '#932929', + '#808000', + '#30308e', + '#708090', + ] + + return theme === 'light' ? colorsLight : colorsDark +} + +export function getChartTextColor(): null { + return null // keep default + // const styles = getComputedStyle(document.body) + // return styles.getPropertyValue('--ion-text-color-lighter') +} + +export function getChartTooltipBackgroundColor() { + const styles = window.getComputedStyle(document.body) + return styles.getPropertyValue('--ion-item-background') +} + +export function getRewardsChartLineColor() { + const styles = window.getComputedStyle(document.body) + return styles.getPropertyValue('--ion-text-color-lighter') +} + +export function getRewardChartColors() { + return { + cl: '#7DB5EC', + el: '#ffaa31', + } +} diff --git a/src/app/utils/CustomTimeAgoFormatter.ts b/src/app/utils/CustomTimeAgoFormatter.ts index 45110625..02a3a86e 100644 --- a/src/app/utils/CustomTimeAgoFormatter.ts +++ b/src/app/utils/CustomTimeAgoFormatter.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -44,16 +43,16 @@ const defaultFormattter = function (then: number): { value: number; unit: Unit; seconds < MINUTE ? [Math.round(seconds), 'second'] : seconds < HOUR - ? [Math.round(seconds / MINUTE), 'minute'] - : seconds < DAY - ? [Math.round(seconds / HOUR), 'hour'] - : seconds < WEEK - ? [Math.round(seconds / DAY), 'day'] - : seconds < MONTH - ? [Math.round(seconds / WEEK), 'week'] - : seconds < YEAR - ? [Math.round(seconds / MONTH), 'month'] - : [Math.round(seconds / YEAR), 'year'] + ? [Math.round(seconds / MINUTE), 'minute'] + : seconds < DAY + ? [Math.round(seconds / HOUR), 'hour'] + : seconds < WEEK + ? [Math.round(seconds / DAY), 'day'] + : seconds < MONTH + ? [Math.round(seconds / WEEK), 'week'] + : seconds < YEAR + ? [Math.round(seconds / MONTH), 'month'] + : [Math.round(seconds / YEAR), 'year'] return { value, unit, suffix } } diff --git a/src/app/utils/DashboardHelper.ts b/src/app/utils/DashboardHelper.ts new file mode 100644 index 00000000..ce0f003e --- /dev/null +++ b/src/app/utils/DashboardHelper.ts @@ -0,0 +1,22 @@ +// Copyright (C) 2024 bitfly explorer GmbH +// +// This file is part of Beaconchain Dashboard. +// +// Beaconchain Dashboard is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Beaconchain Dashboard is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Beaconchain Dashboard. If not, see . + +export function encodeDashboardID(validatorIDs: number[]): string { + const encodedString = validatorIDs.join(',') + const base64String = btoa(encodedString) + return base64String.replace(/=/g, '') +} diff --git a/src/app/utils/DashboardUtils.spec.ts b/src/app/utils/DashboardUtils.spec.ts new file mode 100644 index 00000000..e5de3a7e --- /dev/null +++ b/src/app/utils/DashboardUtils.spec.ts @@ -0,0 +1,350 @@ +/// +import { describe, it, expect, vi, beforeEach } from 'vitest' +import { DashboardUtils, initDashboard } from '@utils/DashboardUtils' +import { APIUnauthorizedError } from '@requests/requests' +import { SearchResultData } from '@requests/v2-search' +import { VDBOverviewGroup } from '@requests/types/validator_dashboard' +import * as DashboardUtilsModule from './DashboardUtils' + +// Redefine a local enum to match the union type string literals exactly. +enum SearchResponseType { + validator = 'validator', + validator_list = 'validator_list', + validators_by_deposit_address = 'validators_by_deposit_address', + validators_by_withdrawal_credential = 'validators_by_withdrawal_credential', + validators_by_graffiti = 'validators_by_graffiti', +} + +describe('DashboardUtils (service)', () => { + let dashboardUtils: DashboardUtils + let mockApi: any + let mockStorage: any + let mockAlerts: any + let mockOAuth: any + let mockMerchant: any + let mockUnit: any + + beforeEach(() => { + mockApi = { + execute: vi.fn(), + loadNetworkConfig: vi.fn().mockResolvedValue(undefined), + getCurrentDashboardChainID: vi.fn().mockResolvedValue(1), + clearSpecificCache: vi.fn(), + } + mockStorage = { + isLoggedIn: vi.fn().mockResolvedValue(true), + getDashboardID: vi.fn().mockResolvedValue([1, 2, 3]), + setDashboardID: vi.fn().mockResolvedValue(undefined), + setObject: vi.fn().mockResolvedValue(undefined), + } + mockAlerts = { + confirmDialog: vi.fn(), + showInfo: vi.fn(), + } + mockOAuth = { + login: vi.fn().mockResolvedValue(true), + } + mockMerchant = { + restartApp: vi.fn(), + } + mockUnit = { + loadCurrentChainNetwork: vi.fn(), + } + + // Construct a DashboardUtils instance. + dashboardUtils = new DashboardUtils(mockApi, mockStorage, mockAlerts, mockOAuth, mockMerchant, mockUnit) + }) + + describe('initDashboard (instance method)', () => { + it('should return a dashboard id when storage returns null and API returns dashboards', async () => { + // Simulate no dashboard stored yet, but user is logged in. + mockStorage.getDashboardID.mockResolvedValueOnce(null) + mockStorage.isLoggedIn.mockResolvedValueOnce(true) + // Simulate API returns a dashboard list with one entry (id 42) + const dashboards = { validator_dashboards: [{ id: 42 }] } + mockApi.execute.mockResolvedValueOnce({ error: false, data: dashboards }) + + const result = await dashboardUtils.initDashboard() + expect(result).toBe(42) + expect(mockStorage.setDashboardID).toHaveBeenCalledWith(42) + }) + }) + + describe('addValidator', () => { + // For a single validator, include index and public_key. + const dummyValidator: SearchResultData = { + type: SearchResponseType.validator, + chain_id: 1, + value: { index: 100, public_key: 'pubKey100' }, + } + it('should add a validator when logged in', async () => { + mockStorage.isLoggedIn.mockResolvedValue(true) + mockStorage.getDashboardID.mockResolvedValue([1, 2, 3]) + mockApi.execute.mockResolvedValue({ error: false }) + const result = await dashboardUtils.addValidator(dummyValidator, 0) + expect(mockApi.execute).toHaveBeenCalled() + expect(result).toBe(true) + }) + + it('should add a validator when not logged in', async () => { + mockStorage.isLoggedIn.mockResolvedValue(false) + mockStorage.getDashboardID.mockResolvedValue([1, 2, 3]) + // For validator_list, value must be an object with a "validators" array. + const dummyList: SearchResultData = { + type: SearchResponseType.validator_list, + chain_id: 1, + value: { validators: [100, 200] }, + } + const result = await dashboardUtils.addValidator(dummyList, 0) + expect(result).toBe(true) + expect(mockStorage.setDashboardID).toHaveBeenCalled() + }) + }) + + describe('addValidators', () => { + it('should return true immediately when index array is empty', async () => { + const result = await dashboardUtils.addValidators([], 0) + expect(result).toBe(true) + }) + + it('should add validators when logged in', async () => { + mockStorage.isLoggedIn.mockResolvedValue(true) + mockStorage.getDashboardID.mockResolvedValue([1, 2, 3]) + mockApi.execute.mockResolvedValue({ error: false }) + const result = await dashboardUtils.addValidators([100, 200, 300], 0) + expect(mockApi.execute).toHaveBeenCalled() + expect(result).toBe(true) + }) + + it('should add validators when not logged in (and truncate array to 20)', async () => { + mockStorage.isLoggedIn.mockResolvedValue(false) + mockStorage.getDashboardID.mockResolvedValue([1, 2, 3]) + const indices = Array.from({ length: 25 }, (_, i) => i + 100) + const result = await dashboardUtils.addValidators(indices, 0) + expect(mockStorage.setDashboardID).toHaveBeenCalled() + expect(result).toBe(true) + }) + }) + + describe('getGroupList', () => { + it('should return a default group list when null is passed', () => { + const groups = dashboardUtils.getGroupList(null) + expect(groups).toEqual([{ id: 0, count: 0, name: 'Default', realName: 'default' }]) + }) + + it('should sort groups and capitalize names', () => { + const originalCapitalize = (global as any).capitalize || ((s: string) => s) + ;(global as any).capitalize = (s: string) => s.charAt(0).toUpperCase() + s.slice(1) + const groupsInput: VDBOverviewGroup[] = [ + { id: 2, count: 5, name: 'group2' }, + { id: 1, count: 3, name: 'default' }, + { id: 0, count: 10, name: 'default' }, + ] + const result = dashboardUtils.getGroupList(groupsInput) + expect(result).toEqual([ + { id: 0, count: 10, name: 'Default', realName: 'default' }, + { id: 1, count: 3, name: 'Default', realName: 'default' }, + { id: 2, count: 5, name: 'Group2', realName: 'group2' }, + ]) + ;(global as any).capitalize = originalCapitalize + }) + }) + + describe('deleteValidator', () => { + it('should delete validator when logged in', async () => { + mockStorage.isLoggedIn.mockResolvedValue(true) + mockStorage.getDashboardID.mockResolvedValue([1, 2, 3, 4]) + mockApi.execute.mockResolvedValue({ error: false }) + const result = await dashboardUtils.deleteValidator([2, 4]) + expect(mockApi.execute).toHaveBeenCalled() + expect(result).toBe(true) + }) + + it('should update dashboard when not logged in and using a local dashboard', async () => { + mockStorage.isLoggedIn.mockResolvedValue(false) + mockStorage.getDashboardID.mockResolvedValue([1, 2, 3, 4]) + const result = await dashboardUtils.deleteValidator([2, 4]) + expect(mockStorage.setDashboardID).toHaveBeenCalled() + expect(result).toBe(true) + }) + }) + + describe('getLocalValidatorCount', () => { + it('should return the length if dashboard is local', async () => { + mockStorage.getDashboardID.mockResolvedValue([1, 2, 3]) + const count = await dashboardUtils.getLocalValidatorCount() + expect(count).toBe(3) + }) + + it('should return 0 if dashboard is not local', async () => { + mockStorage.getDashboardID.mockResolvedValue('not an array') + const count = await dashboardUtils.getLocalValidatorCount() + expect(count).toBe(0) + }) + }) + + describe('defaultDashboardErrorHandler', () => { + it('should do nothing for null or non-APIError errors', () => { + const res1 = dashboardUtils.defaultDashboardErrorHandler(null) + expect(res1).toBeUndefined() + const res2 = dashboardUtils.defaultDashboardErrorHandler(new Error('Test')) + expect(res2).toBeUndefined() + }) + + it('should handle APIUnauthorizedError by calling confirmDialog and return true', () => { + const unauthorizedError = new APIUnauthorizedError('Unauthorized', 401) + mockOAuth.login.mockResolvedValue(true) + const res = dashboardUtils.defaultDashboardErrorHandler(unauthorizedError) + expect(mockAlerts.confirmDialog).toHaveBeenCalled() + expect(res).toBe(true) + }) + }) +}) + +describe('mergeLocalDashboardToRemote (exported function)', () => { + let mockApi: any, mockStorage: any + beforeEach(() => { + mockApi = { execute: vi.fn() } + mockStorage = { + getDashboardID: vi.fn(), + setDashboardID: vi.fn().mockResolvedValue(undefined), + setObject: vi.fn().mockResolvedValue(undefined), + isLoggedIn: vi.fn().mockResolvedValue(true), + } + }) + + it('should merge a local dashboard when present', async () => { + const localDashboard = [1, 2, 3] + mockStorage.getDashboardID.mockResolvedValue(localDashboard) + mockApi.execute.mockResolvedValue({ error: false }) + vi.spyOn(DashboardUtilsModule, 'initDashboard').mockResolvedValue(42) + await DashboardUtilsModule.mergeLocalDashboardToRemote(mockApi, mockStorage) + expect(mockStorage.setObject).toHaveBeenCalledWith('local_dashboard_backup', null) + }) +}) + +afterEach(() => { + vi.restoreAllMocks() +}) + +describe('initDashboard (exported function)', () => { + let mockApi: any, mockStorage: any + beforeEach(() => { + mockApi = { + execute: vi.fn(), + getCurrentDashboardChainID: vi.fn().mockResolvedValue(1), + clearSpecificCache: vi.fn(), + } + mockStorage = { + getDashboardID: vi.fn(), + isLoggedIn: vi.fn(), + setDashboardID: vi.fn().mockResolvedValue(undefined), + } + }) + + it('should return existing dashID if present', async () => { + mockStorage.getDashboardID.mockResolvedValue(42) + mockStorage.isLoggedIn.mockResolvedValue(false) + const result = await initDashboard(mockApi, mockStorage) + expect(result).toBe(42) + }) + + it('should load dashboards when no dashID exists and user is logged in', async () => { + mockStorage.getDashboardID.mockResolvedValue(null) + mockStorage.isLoggedIn.mockResolvedValue(true) + const dashboards = { validator_dashboards: [{ id: 99 }] } + mockApi.execute.mockResolvedValue({ error: false, data: dashboards }) + const result = await initDashboard(mockApi, mockStorage) + expect(result).toBe(99) + expect(mockStorage.setDashboardID).toHaveBeenCalledWith(99) + }) + + it('should create a dashboard if no dashboards are found', async () => { + mockStorage.getDashboardID.mockResolvedValue(null) + mockStorage.isLoggedIn.mockResolvedValue(true) + mockApi.execute.mockResolvedValueOnce({ error: false, data: { validator_dashboards: [] } }) + const creationResult = { error: false, data: { id: 77 } } + mockApi.execute.mockResolvedValueOnce(creationResult) + const result = await initDashboard(mockApi, mockStorage) + expect(result).toBe(77) + }) +}) + +describe('SeachResultHandler (helper class)', () => { + let srHandler: any + beforeEach(() => { + // Create a dummy instance to access the searchResultHandler property. + srHandler = new DashboardUtils({} as any, {} as any, {} as any, {} as any, {} as any, {} as any).searchResultHandler + }) + + it('should format search type correctly', () => { + expect(srHandler.formatSearchType(SearchResponseType.validator_list)).toBe('Validator Indices') + expect(srHandler.formatSearchType(SearchResponseType.validator)).toBe('Validator Index') + expect(srHandler.formatSearchType(SearchResponseType.validators_by_deposit_address)).toBe('Deposit Address') + }) + + it('should correctly determine if item is index', () => { + const item: SearchResultData = { type: SearchResponseType.validator, chain_id: 1, value: { index: 100, public_key: 'pk' } } + expect(srHandler.isIndex(item)).toBe(true) + const item2: SearchResultData = { type: SearchResponseType.validator_list, chain_id: 1, value: { validators: [100, 200] } } + expect(srHandler.isIndex(item2)).toBe(false) + }) + + it('should return correct add-by index values', () => { + const item: SearchResultData = { type: SearchResponseType.validator_list, chain_id: 1, value: { validators: [1, 2, 3] } } + expect(srHandler.getAddByIndex(item)).toEqual([1, 2, 3]) + const item2: SearchResultData = { type: SearchResponseType.validator, chain_id: 1, value: { index: 42, public_key: 'pk' } } + expect(srHandler.getAddByIndex(item2)).toEqual([42]) + }) + + it('should return deposit address when applicable', () => { + const item: SearchResultData = { + type: SearchResponseType.validators_by_deposit_address, + chain_id: 1, + value: { deposit_address: 'addr', count: 1 }, + } + expect(srHandler.getAddByDepositAddress(item)).toBe('addr') + }) + + it('should return withdrawal credential when applicable', () => { + const item: SearchResultData = { + type: SearchResponseType.validators_by_withdrawal_credential, + chain_id: 1, + value: { withdrawal_credential: 'cred', count: 1 }, + } + expect(srHandler.getAddByWithdrawalCredential(item)).toBe('cred') + }) + + it('should return graffiti when applicable', () => { + const item: SearchResultData = { + type: SearchResponseType.validators_by_graffiti, + chain_id: 1, + value: { graffiti: 'graffiti', count: 1 }, + } + expect(srHandler.getAddByGraffiti(item)).toBe('graffiti') + }) + + it('should indicate premium requirement for deposit, withdrawal, and graffiti types', () => { + const item: SearchResultData = { + type: SearchResponseType.validators_by_graffiti, + chain_id: 1, + value: { graffiti: 'graffiti', count: 1 }, + } + expect(srHandler.requiresPremium(item)).toBe(true) + }) + + it('should return correct result count', () => { + const item: SearchResultData = { + type: SearchResponseType.validator_list, + chain_id: 1, + value: { validators: [1, 2, 3] }, + } + expect(srHandler.resultCount(item)).toBe(3) + const item2: SearchResultData = { + type: SearchResponseType.validator, + chain_id: 1, + value: { index: 42, public_key: 'pk' }, + } + expect(srHandler.resultCount(item2)).toBe(1) + }) +}) diff --git a/src/app/utils/DashboardUtils.ts b/src/app/utils/DashboardUtils.ts new file mode 100644 index 00000000..69a1cc9b --- /dev/null +++ b/src/app/utils/DashboardUtils.ts @@ -0,0 +1,389 @@ +// Copyright (C) 2024 bitfly explorer GmbH +// +// This file is part of Beaconchain Dashboard. +// +// Beaconchain Dashboard is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Beaconchain Dashboard is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Beaconchain Dashboard. If not, see . + +import { Injectable } from '@angular/core' +import { StorageService } from '@services/storage.service' +import { ApiService, capitalize } from '@services/api.service' +import { V2MyDashboards } from '@requests/v2-user' +import { + dashboardID, + V2AddValidatorToDashboard, + V2AddValidatorToDashboardData, + V2CreateDashboard, + V2DeleteValidatorFromDashboard, +} from '@requests/v2-dashboard' +import { Toast } from '@capacitor/toast' +import { AlertService } from '@services/alert.service' +import { OAuthUtils } from './OAuthUtils' +import { MerchantUtils } from './MerchantUtils' +import { SearchResponseType, SearchResultData } from '@requests/v2-search' +import { UnitconvService } from '@services/unitconv.service' +import { APIError, APIUnauthorizedError } from '@requests/requests' +import { VDBOverviewGroup } from '@requests/types/validator_dashboard' + +@Injectable({ + providedIn: 'root', +}) +export class DashboardUtils { + dashboardAwareListener: PullEventListener = new PullEventListener(() => { + this.unit.loadCurrentChainNetwork() + }) + searchResultHandler = new SeachResultHandler() + + constructor( + private api: ApiService, + private storage: StorageService, + private alerts: AlertService, + private oauth: OAuthUtils, + private merchant: MerchantUtils, + private unit: UnitconvService + ) {} + + public initDashboard() { + return initDashboard(this.api, this.storage, () => { + this.dashboardAwareListener.notifyAll() + }) + } + + async addValidator(item: SearchResultData, groupID: number): Promise { + const loggedIn = await this.storage.isLoggedIn() + const id = await this.storage.getDashboardID() + + if (loggedIn) { + const result = await this.api.execute( + new V2AddValidatorToDashboard(id, { + group_id: groupID, + validators: this.searchResultHandler.getAddByIndex(item), + deposit_address: this.searchResultHandler.getAddByDepositAddress(item), + withdrawal_address: this.searchResultHandler.getAddByWithdrawalCredential(item), + graffiti: this.searchResultHandler.getAddByGraffiti(item), + } as V2AddValidatorToDashboardData) + ) + return result && !result.error + } else { + // deprecated feature + const indexToAdd = this.searchResultHandler.getAddByIndex(item) + if (!indexToAdd || indexToAdd.length === 0) { + return false + } + + if (isLocalDashboard(id)) { + await this.storage.setDashboardID([...id, ...indexToAdd].slice(0, 20)) + } else { + await this.storage.setDashboardID(indexToAdd) + } + return true + } + } + + async addValidators(index: number[], groupID: number, dashID: dashboardID = undefined): Promise { + if (index.length === 0) { + return true + } + const loggedIn = await this.storage.isLoggedIn() + let id = await this.storage.getDashboardID() + if (dashID) { + id = dashID + } + + if (loggedIn) { + const result = await this.api.execute( + new V2AddValidatorToDashboard(id, { + group_id: groupID, + validators: index, + graffiti: undefined, + } as V2AddValidatorToDashboardData) + ) + return result && !result.error + } else { + index = index.slice(0, 20) // truncate as free tier is limited to 20 validators + + if (isLocalDashboard(id)) { + await this.storage.setDashboardID([...id, ...index].slice(0, 20)) + } else { + await this.storage.setDashboardID(index) + } + return true + } + } + + getGroupList(groups: VDBOverviewGroup[] | null): GroupEntries[] { + return ( + groups + ?.sort((a, b) => a.id - b.id) + .map((group) => { + return { + id: group.id, + count: group.count, + name: group.name == 'default' && group.id == 0 ? 'Default' : capitalize(group.name), + realName: group.name, + } + }) || [ + { + id: 0, + count: 0, + name: 'Default', + realName: 'default', + }, + ] + ) + } + + async deleteValidator(index: number[]) { + const loggedIn = await this.storage.isLoggedIn() + const id = await this.storage.getDashboardID() + + if (loggedIn) { + const result = await this.api.execute(new V2DeleteValidatorFromDashboard(id, index)) + return result && !result.error + } else { + if (isLocalDashboard(id)) { + const newDashboard = id.filter((element) => !index.includes(element)) + if (newDashboard.length === 0) { + await this.storage.setDashboardID(null) + return true + } + await this.storage.setDashboardID(newDashboard) + } else { + console.log('how did we end up here?') + return true + } + return true + } + } + + async getLocalValidatorCount() { + const id = await this.storage.getDashboardID() + if (isLocalDashboard(id)) { + return id.length + } + return 0 + } + + // @returns whether the error was handled + defaultDashboardErrorHandler(error: Error | null) { + if (!error || !(error instanceof APIError)) { + return + } + if (error instanceof APIUnauthorizedError) { + this.alerts.confirmDialog('Login expired', 'Please log back in to your beaconcha.in account to access your dashboards.', 'LOGIN', async () => { + const result = await this.oauth.login() + if (result) { + this.merchant.restartApp() + } else { + Toast.show({ + text: 'Login failed', + }) + } + }) + console.error('Unauthorized') + return true + } + + return false + } +} + +export interface GroupEntries { + id: number + count: number + name: string + realName: string +} + +export function isLocalDashboard(id: dashboardID): id is number[] { + return id && Array.isArray(id) && id.every((element) => typeof element === 'number') +} + +class PullEventListener { + private updateMap: Map = new Map() + + private push: () => void + constructor(push: () => void = null) { + this.push = push + } + + notifyAll() { + this.updateMap.forEach((_, key) => { + this.updateMap.set(key, true) + }) + if (this.push) this.push() + } + + register(key: string) { + this.updateMap.set(key, false) + } + + hasAndConsume(key: string): boolean { + const result = this.updateMap.get(key) + if (result) { + this.updateMap.set(key, false) + } + return result + } +} + +export async function mergeLocalDashboardToRemote(api: ApiService, storage: StorageService) { + const localDashboard = await storage.getDashboardID() + if (!isLocalDashboard(localDashboard)) { + await initDashboard(api, storage) + return + } + + // store local dashboard to inactive slot just in case something goes wrong + await storage.setObject('local_dashboard_backup', localDashboard) + console.log('merge do merge', localDashboard) + + storage.setDashboardID(null) // clear local dashboard + const remoteDashboard = await initDashboard(api, storage) + + const result = await api.execute( + new V2AddValidatorToDashboard(remoteDashboard, { + group_id: 0, + validators: localDashboard, + }) + ) + if (result.error) { + Toast.show({ + text: 'Error merging dashboards', + }) + return + } + await storage.setObject('local_dashboard_backup', null) // done +} + +// Call after login or when dashboard id is null +// will check if the user has dashboards and select the first one +// or else create a dashboard and select it +export async function initDashboard(api: ApiService, storage: StorageService, dashboardChangedListener: () => void = null) { + const dashID = await storage.getDashboardID() + const isLoggedIn = await storage.isLoggedIn() + + // check if user has dashboards + if (!dashID && isLoggedIn) { + const result = await api.execute(new V2MyDashboards()) + if (result.error) { + console.warn('dashboards can not be loaded', result.error) + Toast.show({ + text: 'Error loading dashboards', + }) + return + } + + let targetDashboard: dashboardID = null + // if user has a dashboard, pick the first one + if (result.data && result.data && result.data.validator_dashboards && result.data.validator_dashboards.length > 0) { + targetDashboard = result.data.validator_dashboards[0].id + // todo improve and pick the one on current network first - if user has multiple dashboards + console.log('found a user dashboard, picking first one') + } else { + console.log('user has no dashboards, creating default dashboard') + // create a new dashboard + const chainID = await api.getCurrentDashboardChainID() + const createResult = await api.execute(new V2CreateDashboard('Default Dashboard', chainID)) + if (createResult.error) { + Toast.show({ + text: 'Error renaming dashboard, please try again later', + }) + } else { + targetDashboard = createResult.data.id + api.clearSpecificCache(new V2MyDashboards()) + } + } + + await storage.setDashboardID(targetDashboard) + if (dashboardChangedListener) { + dashboardChangedListener() + } + return targetDashboard + } + return dashID +} + +class SeachResultHandler { + formatSearchType(type: SearchResponseType | string) { + switch (type) { + case SearchResponseType.validatorList: + return 'Validator Indices' + case SearchResponseType.validator: + return 'Validator Index' + case SearchResponseType.validatorsByDepositAddress: + return 'Deposit Address' + case SearchResponseType.validatorsByWithdrawalCredential: + return 'Withdrawal Credential' + } + } + + isIndex(item: SearchResultData) { + return item.type == SearchResponseType.validator + } + + getAddByIndex(searchResult: SearchResultData) { + if (searchResult.type == SearchResponseType.validatorList) { + return searchResult.value.validators + } + + if (searchResult.type == SearchResponseType.validator) { + return [searchResult.value.index] + } + return undefined + } + + getAddByDepositAddress(searchResult: SearchResultData) { + if (searchResult.type == SearchResponseType.validatorsByDepositAddress) { + return searchResult.value.deposit_address + } + return undefined + } + + getAddByWithdrawalCredential(searchResult: SearchResultData) { + if (searchResult.type == SearchResponseType.validatorsByWithdrawalCredential) { + return searchResult.value.withdrawal_credential + } + return undefined + } + + getAddByGraffiti(searchResult: SearchResultData) { + if (searchResult.type == SearchResponseType.validatorsByGraffiti) { + return searchResult.value.graffiti + } + return undefined + } + + requiresPremium(searchResult: SearchResultData) { + return ( + searchResult.type == SearchResponseType.validatorsByDepositAddress || + searchResult.type == SearchResponseType.validatorsByWithdrawalCredential || + searchResult.type == SearchResponseType.validatorsByGraffiti + ) + } + + resultCount(searchResult: SearchResultData) { + switch (searchResult.type) { + case SearchResponseType.validatorList: + return searchResult.value.validators.length + case SearchResponseType.validator: + return 1 + case SearchResponseType.validatorsByDepositAddress: + case SearchResponseType.validatorsByWithdrawalCredential: + case SearchResponseType.validatorsByGraffiti: + return searchResult.value.count + default: + return 0 + } + } +} diff --git a/src/app/utils/EthereumUnits.ts b/src/app/utils/EthereumUnits.ts index 110aa5d2..7e21ca40 100644 --- a/src/app/utils/EthereumUnits.ts +++ b/src/app/utils/EthereumUnits.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -42,7 +41,7 @@ export default class Unit { public static XDAI = new Unit('DAI', new BigNumber('1'), 4, 'XXX-DAI', 'xDAI') public static GNO = new Unit('GNO', new BigNumber('0.03125'), 5, 'XXX-GNO', 'GNO') - public static MGNO = new Unit('mGNO', new BigNumber('1'), 5, 'XXX-GNO', 'mGNO') + // public static MGNO = new Unit('mGNO', new BigNumber('1'), 5, 'XXX-GNO', 'mGNO') public static USDETH = new Unit('$', new BigNumber('1'), 2, 'XXX-USD', 'Dollar') public static EURETH = new Unit('€', new BigNumber('1'), 2, 'XXX-EUR', 'Euro') @@ -59,7 +58,7 @@ export default class Unit { public static NZDETH = new Unit('NZ$', new BigNumber('1'), 2, 'XXX-NZD', 'New Zealand Dollar') public static BTCETH = new Unit('₿', new BigNumber('1'), 6, 'XXX-BTC', 'Bitcoin') - private constructor(symbol: string, value: BigNumber, rounding = 2, coinbaseSpot = null, settingsName = null) { + private constructor(symbol: string, value: BigNumber, rounding = 2, coinbaseSpot: string = null, settingsName: string = null) { this.display = symbol this.value = value this.rounding = rounding @@ -105,7 +104,7 @@ export const MAPPING = new Map([ ['NO_CURRENCY', Unit.NO_CURRENCY], ['RETH', Unit.RETH], ['GNO', Unit.GNO], - ['mGNO', Unit.MGNO], + // ['mGNO', Unit.MGNO], ['xDAI', Unit.XDAI], ['RUBLE', Unit.RUBETH], diff --git a/src/app/utils/Firebase.module.ts b/src/app/utils/Firebase.module.ts new file mode 100644 index 00000000..3c942cc4 --- /dev/null +++ b/src/app/utils/Firebase.module.ts @@ -0,0 +1,11 @@ +import { NgModule } from '@angular/core' +import { IonicModule } from '@ionic/angular' +import { NotificationDetailComponent } from '@pages/notification-detail/notification-detail.component' +import FirebaseUtils from './FirebaseUtils' +import { CommonModule } from '@angular/common' + +@NgModule({ + imports: [IonicModule, CommonModule, NotificationDetailComponent], + providers: [FirebaseUtils], +}) +export class FirebaseUtilsModule {} diff --git a/src/app/utils/FirebaseUtils.ts b/src/app/utils/FirebaseUtils.ts index d5fa62f2..d8c8cb29 100644 --- a/src/app/utils/FirebaseUtils.ts +++ b/src/app/utils/FirebaseUtils.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -18,29 +17,35 @@ * // along with Beaconchain Dashboard. If not, see . */ -import { ApiService } from '../services/api.service' -import { StorageService } from '../services/storage.service' -import { UpdateTokenRequest } from '../requests/requests' +import { ApiService } from '@services/api.service' +import { StorageService } from '@services/storage.service' +import { APIRequest, UpdateTokenRequest } from '@requests/requests' import { Injectable } from '@angular/core' import { AlertController, Platform } from '@ionic/angular' -import { PushNotifications, PushNotificationSchema } from '@capacitor/push-notifications' +import { ActionPerformed, PushNotifications, PushNotificationSchema } from '@capacitor/push-notifications' import { LocalNotifications } from '@capacitor/local-notifications' import FlavorUtils from './FlavorUtils' import { Capacitor } from '@capacitor/core' +import { V2RegisterPushNotificationToken } from '@requests/v2-user' +import { dashboardID } from '@requests/v2-dashboard' const LOGTAG = '[FirebaseUtils]' export const CURRENT_TOKENKEY = 'firebase_token' const NOTIFICATION_CONSENT_KEY = 'notification_consent' +const firebaseTokenKey = 'last_firebase_token' + @Injectable({ providedIn: 'root', }) export default class FirebaseUtils { private alreadyRegistered = false + private clickCallback: (id: dashboardID, groupID: number, epoch: number, chainID: number) => Promise + constructor( private api: ApiService, private storage: StorageService, @@ -49,6 +54,10 @@ export default class FirebaseUtils { private flavor: FlavorUtils ) {} + setNotificationClickCallback(callback: (id: dashboardID, groupID: number, epoch: number, chainID: number) => Promise) { + this.clickCallback = callback + } + async hasSeenConsentScreenAndNotConsented() { const hasSeenConsent = await this.storage.getBooleanSetting(NOTIFICATION_CONSENT_KEY, false) @@ -117,7 +126,7 @@ export default class FirebaseUtils { PushNotifications.addListener('registration', async (token) => { console.log(LOGTAG + 'register token', token.value) await this.storage.setItem(CURRENT_TOKENKEY, token.value) - this.updateRemoteNotificationToken(token.value) + updateRemoteNotificationToken(this.storage, this.api, token.value) }) // Some issue with our setup and push will not work @@ -131,12 +140,44 @@ export default class FirebaseUtils { }) // Method called when tapping on a notification - /*PushNotifications.addListener('pushNotificationActionPerformed', (notification: ActionPerformed) => { + PushNotifications.addListener('pushNotificationActionPerformed', (notification: ActionPerformed) => { //alert("Push action performed: " + JSON.stringify(notification)); - })*/ + console.log(LOGTAG + 'Push action performed: ', notification) + if ( + notification && + notification.notification && + Object.prototype.hasOwnProperty.call(notification.notification.data, 'dashboard_id') && + Object.prototype.hasOwnProperty.call(notification.notification.data, 'group_id') && + Object.prototype.hasOwnProperty.call(notification.notification.data, 'epoch') + ) { + this.clickNotification( + notification.notification.data.dashboard_id, + notification.notification.data.group_id, + notification.notification.data.epoch, + Object.prototype.hasOwnProperty.call(notification.notification.data, 'chain_id') ? notification.notification.data.chain_id : 1 + ) + } + }) } - private async inAppNotification(title, message) { + clickNotification(id: dashboardID, groupID: number, epoch: number, chainID: number, count: number = 0) { + // clickCallback is provided in dashboard page. I was not able to find a way to open the modal here directly + // as any reference to NotificationDetailComponent here will break the entire app ¯⁠\⁠_⁠(⁠ツ⁠)⁠_⁠/⁠¯ + // Room for improvement here if you know a way + if (!this.clickCallback) { + if (count < 20) { + setTimeout(() => { + this.clickNotification(id, groupID, epoch, chainID, ++count) + }, 200) + } else { + console.error(LOGTAG + 'clickNotification failed after 20 tries') + } + return + } + this.clickCallback(id, groupID, epoch, chainID) + } + + private async inAppNotification(title: string, message: string) { const alert = await this.alertController.create({ header: title, message: message, @@ -181,31 +222,34 @@ export default class FirebaseUtils { await alert.present() } +} - async pushLastTokenUpstream(force: boolean) { - this.updateRemoteNotificationToken(await this.storage.getItem(CURRENT_TOKENKEY), force) - } +export async function pushLastTokenUpstream(storage: StorageService, api: ApiService, force: boolean) { + updateRemoteNotificationToken(storage, api, await storage.getItem(CURRENT_TOKENKEY), force) +} - private async updateRemoteNotificationToken(token: string, force = false) { - console.log(LOGTAG + ' updateRemoteNotificationToken called with token: ' + token) - - const firebaseTokenKey = 'last_firebase_token' - const loggedIn = await this.storage.isLoggedIn() - - if (loggedIn && token != null) { - const lastToken = await this.storage.getItem(firebaseTokenKey) - - console.log(LOGTAG + ' user is logged in, last local token was: ' + lastToken) - if (force || token != lastToken) { - const request = new UpdateTokenRequest(token) - const result = await this.api.execute(request).catch((error) => { - console.warn('error in updateRemoteNotificationToken execute', error) - return false - }) - if (request.wasSuccessful(result)) { - console.log(LOGTAG + ' update on remote was successful') - this.storage.setItem(firebaseTokenKey, token) - } +export async function updateRemoteNotificationToken(storage: StorageService, api: ApiService, token: string, force = false) { + console.log(LOGTAG + ' updateRemoteNotificationToken called with token: ' + token) + + const loggedIn = await storage.isLoggedIn() + + if (loggedIn && token != null) { + const lastToken = await storage.getItem(firebaseTokenKey) + + console.log(LOGTAG + ' user is logged in, last local token was: ' + lastToken) + if (force || token != lastToken) { + let request: APIRequest + if (await storage.isV2()) { + request = new V2RegisterPushNotificationToken(token, await storage.getDeviceID()) + } else { + request = new UpdateTokenRequest(token) + } + const result = await api.execute(request) + if (result.error) { + console.warn(LOGTAG + ' update on remote failed', result.error) + } else { + console.log(LOGTAG + ' update on remote was successful') + storage.setItem(firebaseTokenKey, token) } } } diff --git a/src/app/utils/Formatting.ts b/src/app/utils/Formatting.ts new file mode 100644 index 00000000..7cf0e38b --- /dev/null +++ b/src/app/utils/Formatting.ts @@ -0,0 +1,25 @@ +// Copyright (C) 2024 bitfly explorer GmbH +// +// This file is part of Beaconchain Dashboard. +// +// Beaconchain Dashboard is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Beaconchain Dashboard is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Beaconchain Dashboard. If not, see . + +import { Address } from '@requests/types/common' + +export function formatAddress(address: Address): string { + if (address.ens) { + return address.ens.substring(0, 6) + } + return address.hash.substring(0, 6) + '…' + address.hash.substring(address.hash.length - 4) +} diff --git a/src/app/utils/HighchartOptions.ts b/src/app/utils/HighchartOptions.ts index 7482d61e..999fb7b5 100644 --- a/src/app/utils/HighchartOptions.ts +++ b/src/app/utils/HighchartOptions.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -18,7 +17,11 @@ * // along with Beaconchain Dashboard. If not, see . */ -export function highChartOptions(where, hostName) { +/** + * + * @param where @deprecated replaced by echarts + */ +export function highChartOptions(where: { setOptions: (object: object) => void }, hostName: string) { where.setOptions({ time: { useUTC: false, diff --git a/src/app/utils/InfiniteScrollDataSource.spec.ts b/src/app/utils/InfiniteScrollDataSource.spec.ts new file mode 100644 index 00000000..e4a7013e --- /dev/null +++ b/src/app/utils/InfiniteScrollDataSource.spec.ts @@ -0,0 +1,153 @@ +import { describe, it, expect, vi, beforeEach } from 'vitest' +import { InfiniteScrollDataSource, sleep } from './InfiniteScrollDataSource' + +interface Range { + start: number + end: number +} + +import { Subject } from 'rxjs' + +class FakeCollectionViewer { + public viewChange = new Subject() +} +describe('InfiniteScrollDataSource', () => { + let fakeLoadMore: ReturnType + let dataSource: InfiniteScrollDataSource + let collectionViewer: FakeCollectionViewer + + beforeEach(() => { + // A fake loadMore function that returns different data based on the cursor. + fakeLoadMore = vi.fn((cursor: string) => { + if (!cursor) { + // First page + return Promise.resolve({ data: [1, 2, 3, 4, 5], next_cursor: 'cursor1' }) + } else if (cursor === 'cursor1') { + // Second page + return Promise.resolve({ data: [6, 7, 8, 9, 10], next_cursor: null }) + } + return Promise.resolve({ data: [], next_cursor: null }) + }) + + // Set pageSize = 5 for easier math + dataSource = new InfiniteScrollDataSource(5, fakeLoadMore) + collectionViewer = new FakeCollectionViewer() + }) + + it('should fetch the first page on connect when a viewChange event is emitted', async () => { + // Connect the datasource to our fake collection viewer. + const dataStream = dataSource.connect(collectionViewer) + // Emit a viewChange event that covers items 0-4 (page 0). + collectionViewer.viewChange.next({ start: 0, end: 4 }) + + // Allow any async operations to finish. + await sleep(10) + + // Verify that loadMore was called exactly once. + expect(fakeLoadMore).toHaveBeenCalledTimes(1) + + // Check that the cached data (accessible via the public API) is as expected. + expect(dataSource.getItems()).toEqual([1, 2, 3, 4, 5]) + + // Also, subscribe to the data stream and verify it emits the updated data. + let latestData: number[] | undefined + dataStream.subscribe((data) => (latestData = data)) + expect(latestData).toEqual([1, 2, 3, 4, 5]) + }) + + it('should fetch subsequent pages when the viewChange range spans multiple pages', async () => { + // Emit a range that spans from item 0 to 9. + // With a page size of 5, this covers pages 0 and 1. (A request for page 2 will be skipped because + // the second page marks the end.) + dataSource.connect(collectionViewer) + collectionViewer.viewChange.next({ start: 0, end: 9 }) + await sleep(10) + + // Expect two calls: + // - Page 0: loadMore(undefined) + // - Page 1: loadMore('cursor1') + expect(fakeLoadMore).toHaveBeenCalledTimes(2) + + // After page 0 and 1, cachedData should contain 10 items. + expect(dataSource.getItems()).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) + }) + + it('reset should clear the data and fetch the first page again', async () => { + // First, perform an initial fetch. + dataSource.connect(collectionViewer) + collectionViewer.viewChange.next({ start: 0, end: 4 }) + await sleep(10) + expect(dataSource.getItems()).toEqual([1, 2, 3, 4, 5]) + + // Call reset. This clears cachedData and fetchedPages, and then fetches page 0 again. + await dataSource.reset() + + // Since reset calls fetchPage(0) after clearing, loadMore should have been called one more time. + // (Depending on timing, the total calls count here is 2.) + expect(fakeLoadMore).toHaveBeenCalledTimes(2) + expect(dataSource.getItems()).toEqual([1, 2, 3, 4, 5]) + }) + + it('should have correct behavior for hasItems, length, and getItems', async () => { + // Initially, no items are loaded. + expect(dataSource.hasItems()).toBe(false) + expect(dataSource.length()).toBe(0) + expect(dataSource.getItems()).toEqual([]) + + // Trigger a load. + dataSource.connect(collectionViewer) + collectionViewer.viewChange.next({ start: 0, end: 4 }) + await sleep(10) + + // Now, items should be present. + expect(dataSource.hasItems()).toBe(true) + expect(dataSource.length()).toBe(5) + expect(dataSource.getItems()).toEqual([1, 2, 3, 4, 5]) + }) + + it('should mark reachedMax as true when loadMore returns no next_cursor', async () => { + // Connect and request a range that will fetch two pages. + dataSource.connect(collectionViewer) + collectionViewer.viewChange.next({ start: 0, end: 9 }) + await sleep(10) + collectionViewer.viewChange.next({ start: 9, end: 10 }) + await sleep(10) + + // The second page returns next_cursor as undefined. + expect(dataSource.hasReachedEnd()).toBe(true) + }) + + it('setLoadFrom should change the loadMore function used by the data source', async () => { + // Do an initial load with the original fakeLoadMore. + dataSource.connect(collectionViewer) + collectionViewer.viewChange.next({ start: 0, end: 4 }) + await sleep(10) + expect(dataSource.getItems()).toEqual([1, 2, 3, 4, 5]) + + // Define a new loadMore function. + const newLoadMore = vi.fn().mockResolvedValue({ data: [11, 12, 13], next_cursor: undefined }) + dataSource.setLoadFrom(newLoadMore) + + // Reset the datasource; it will now use newLoadMore for page 0. + await dataSource.reset() + expect(newLoadMore).toHaveBeenCalled() + expect(dataSource.getItems()).toEqual([11, 12, 13]) + }) + + it('disconnect should unsubscribe from viewChange events', async () => { + dataSource.connect(collectionViewer) + // Trigger a fetch. + collectionViewer.viewChange.next({ start: 0, end: 4 }) + await sleep(10) + expect(fakeLoadMore).toHaveBeenCalledTimes(1) + + // Disconnect the datasource. + dataSource.disconnect() + + // Emit a new viewChange event. Since the datasource is disconnected, + // no new loadMore call should be triggered. + collectionViewer.viewChange.next({ start: 5, end: 9 }) + await sleep(10) + expect(fakeLoadMore).toHaveBeenCalledTimes(1) + }) +}) diff --git a/src/app/utils/InfiniteScrollDataSource.ts b/src/app/utils/InfiniteScrollDataSource.ts index 94e4c36a..4994ea71 100644 --- a/src/app/utils/InfiniteScrollDataSource.ts +++ b/src/app/utils/InfiniteScrollDataSource.ts @@ -1,5 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -20,19 +20,22 @@ import { BehaviorSubject, Observable, Subscription } from 'rxjs' import { CollectionViewer, DataSource } from '@angular/cdk/collections' +export type loadMoreType = (cursor: string) => Promise<{ data: T[]; next_cursor: string }> export class InfiniteScrollDataSource extends DataSource { public static ALL_ITEMS_AT_ONCE = 0 private pageSize = 100 - private cachedData: T[] = [] + cachedData: T[] = [] private fetchedPages = new Set() private dataStream = new BehaviorSubject(this.cachedData) private subscription = new Subscription() - private loadMore: (offset: number) => Promise + private loadMore: loadMoreType private reachedMax = false - constructor(pageSize: number, loadMore: (offset: number) => Promise) { + private cursor: string = undefined + + constructor(pageSize: number, loadMore: loadMoreType) { super() this.pageSize = pageSize this.loadMore = loadMore @@ -40,11 +43,11 @@ export class InfiniteScrollDataSource extends DataSource { connect(collectionViewer: CollectionViewer): Observable { this.subscription.add( - collectionViewer.viewChange.subscribe((range) => { + collectionViewer.viewChange.subscribe(async (range) => { const startPage = this.getPageForIndex(range.start) - const endPage = this.getPageForIndex(range.end + 1) + const endPage = this.getPageForIndex(range.end) for (let i = startPage; i <= endPage; i++) { - this.fetchPage(i) + await this.fetchPage(i) } }) ) @@ -60,31 +63,39 @@ export class InfiniteScrollDataSource extends DataSource { return Math.floor(index / this.pageSize) } - private async fetchPage(page: number) { + protected async fetchPage(page: number) { if (this.fetchedPages.has(page) || this.reachedMax) { return } this.fetchedPages.add(page) - const newEntries = await this.loadMore(page * this.pageSize) + const newEntries = await this.loadMore(this.cursor) + if (!newEntries.data) { + return Promise.resolve() + } + this.cursor = newEntries.next_cursor + if (!this.cursor) { + this.reachedMax = true + } let deleteAmount = this.pageSize if (this.pageSize == InfiniteScrollDataSource.ALL_ITEMS_AT_ONCE) { deleteAmount = this.cachedData.length } - this.cachedData.splice(page * this.pageSize, deleteAmount, ...newEntries) + this.cachedData.splice(page * this.pageSize, deleteAmount, ...newEntries.data) this.dataStream.next(this.cachedData) - if (newEntries.length < this.pageSize) { - this.reachedMax = true - } + // if (newEntries.data.length < this.pageSize) { + // this.reachedMax = true + // } return Promise.resolve() } public async reset() { this.fetchedPages.clear() this.cachedData = [] + this.cursor = undefined this.dataStream.next(this.cachedData) this.reachedMax = false return await this.fetchPage(0) @@ -102,7 +113,11 @@ export class InfiniteScrollDataSource extends DataSource { return this.cachedData } - public setLoadFrom(loadMore: (offset: number) => Promise) { + public hasReachedEnd(): boolean { + return this.reachedMax + } + + public setLoadFrom(loadMore: loadMoreType) { this.loadMore = loadMore } } diff --git a/src/app/utils/MachineUtils.ts b/src/app/utils/MachineUtils.ts deleted file mode 100644 index 54e5900b..00000000 --- a/src/app/utils/MachineUtils.ts +++ /dev/null @@ -1,153 +0,0 @@ -// Copyright (C) 2021 Bitfly GmbH -// -// This file is part of Beaconchain Dashboard. -// -// Beaconchain Dashboard is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Beaconchain Dashboard is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Beaconchain Dashboard. If not, see . - -import { ApiService } from '../services/api.service' -import { Injectable } from '@angular/core' -import MachineController, { ProcessedStats, StatsResponse } from '../controllers/MachineController' -import { GetMyMachinesRequest } from '../requests/requests' -import { StorageService } from '../services/storage.service' -import { SyncService } from '../services/sync.service' -import { CacheModule } from './CacheModule' - -const LOGTAG = '[MachineUtils] ' -const MACHINES_STORAGE_KEY = 'stored_machine_names' -export const UNSUPPORTED_PRYSM = 'unsupported_prysm_version' - -const MACHINE_CACHE = 'machine_' - -@Injectable({ - providedIn: 'root', -}) -export default class MachineUtils extends CacheModule { - constructor(private api: ApiService, private storage: StorageService, private sync: SyncService) { - super('machine', 4 * 60 * 1000) - } - - /* - 2 Listen - -) Alle machine names - -) Neu ungesyncte machine names - */ - - // Call from notification screen when need a full list of machine names - async getAllMachineNames(): Promise { - const local = await this.getAllLocalMachineNames() - console.log('getAllMachineNames local', local) - if (!local || local.length == 0) { - const remote = await this.getAndProcessDataBase() - return this.getAllMachineNamesFrom(remote) - } - return local - } - - private async registerNewRemotesForSync(remote: string[]): Promise { - const local = await this.getAllLocalMachineNames() - let returnOK = true - for (let i = 0; i < remote.length; i++) { - const it = remote[i] // TODO think about default scenario - if (!local || !local.includes(it)) { - console.log(LOGTAG + 'found a new machine, applying your notification preferences...') - returnOK = (await this.sync.reapplyNotifyEvent('monitoring_machine_offline', it)) && returnOK - returnOK = (await this.sync.reapplyNotifyEvent('monitoring_hdd_almostfull', it)) && returnOK - returnOK = (await this.sync.reapplyNotifyEvent('monitoring_cpu_load', it)) && returnOK - returnOK = (await this.sync.reapplyNotifyEvent('monitoring_memory_usage', it)) && returnOK - } - } - this.sync.syncAllSettings() - return returnOK - } - - private registerAllLocalMachineNames(names: string[]) { - this.storage.setObject(MACHINES_STORAGE_KEY, names) - } - - private async getAllLocalMachineNames(): Promise { - return this.storage.getObject(MACHINES_STORAGE_KEY) as Promise - } - - private getAllMachineNamesFrom(data: ProcessedStats[]): string[] { - const result: string[] = [] - for (const key in data) { - result.push(key) - } - return result - } - - private unsupportedPrysmVersion(data: ProcessedStats[], machineController: MachineController): boolean { - let result = false - for (const key in data) { - const machine = data[key] - - if (machineController.isBuggyPrysmVersion(machine)) { - result = true - } - } - return result - } - - async getAndProcessData(timeslot = 180) { - const result = await this.getAndProcessDataBase(timeslot) - const machineNames = this.getAllMachineNamesFrom(result) - console.log(LOGTAG + ' machine names', machineNames) - - this.registerNewRemotesForSync(machineNames).then((remoteResult) => { - console.log(LOGTAG + ' registerNewRemotesForSync', remoteResult) - }) - - // Storing all machine names if - // Used for notification syncing - this.registerAllLocalMachineNames(machineNames) - - return result - } - - private async getAndProcessDataBase(timeslot = 180) { - const data = (await this.getData(timeslot).catch(() => { - return null - })) as StatsResponse - console.log('machine data', data) - if (data == null) { - return [] - } - - const machineController = new MachineController(this.storage) - - const result = machineController.combineByMachineName( - machineController.filterMachines(data.validator), - machineController.filterMachines(data.node), - machineController.filterMachines(data.system) - ) - - const unsupportedPrysm = this.unsupportedPrysmVersion(result, machineController) - this.storage.setBooleanSetting(UNSUPPORTED_PRYSM, unsupportedPrysm) - //machineController.isBuggyPrysmVersion(result) - - return result - } - - private async getData(timeslot: number): Promise { - const cached = (await this.getCache(MACHINE_CACHE + timeslot)) as StatsResponse - if (cached) return cached - const request = new GetMyMachinesRequest(0, timeslot) - const response = await this.api.execute(request) - const result = request.parse(response) - if (result && result[0]) { - this.putCache(MACHINE_CACHE + timeslot, result[0]) - } - return result[0] - } -} diff --git a/src/app/utils/MathUtils.spec.ts b/src/app/utils/MathUtils.spec.ts new file mode 100644 index 00000000..e4cfab45 --- /dev/null +++ b/src/app/utils/MathUtils.spec.ts @@ -0,0 +1,68 @@ +import { describe, it, expect } from 'vitest' +import { sumBigInt, findHighest, findLowest, slotToEpoch, startEpochSyncCommittee, endEpochSyncCommittee } from './MathUtils' +import BigNumber from 'bignumber.js' + +describe('MathUtils', () => { + describe('sumBigInt', () => { + it('should return the sum of BigNumber fields', () => { + const validators = [{ value: new BigNumber(10) }, { value: new BigNumber(20) }, { value: new BigNumber(30) }] + const result = sumBigInt(validators, (v) => v.value) + expect(result.toString()).toBe('60') + }) + + it('should return 0 for an empty array', () => { + const validators: { value: BigNumber }[] = [] + const result = sumBigInt(validators, (v) => v.value) + expect(result.toString()).toBe('0') + }) + }) + + describe('findHighest', () => { + it('should return the highest number', () => { + const validators = [{ value: 10 }, { value: 20 }, { value: 30 }] + const result = findHighest(validators, (v) => v.value) + expect(result).toBe(30) + }) + + it('should return MIN_SAFE_INTEGER for an empty array', () => { + const validators: { value: number }[] = [] + const result = findHighest(validators, (v) => v.value) + expect(result).toBe(Number.MIN_SAFE_INTEGER) + }) + }) + + describe('findLowest', () => { + it('should return the lowest number', () => { + const validators = [{ value: 10 }, { value: 20 }, { value: 30 }] + const result = findLowest(validators, (v) => v.value) + expect(result).toBe(10) + }) + + it('should return MAX_SAFE_INTEGER for an empty array', () => { + const validators: { value: number }[] = [] + const result = findLowest(validators, (v) => v.value) + expect(result).toBe(Number.MAX_SAFE_INTEGER) + }) + }) + + describe('slotToEpoch', () => { + it('should convert slot to epoch correctly', () => { + const result = slotToEpoch(1, 64) + expect(result).toBe(2) + }) + }) + + describe('startEpochSyncCommittee', () => { + it('should return the correct start epoch of the sync committee', () => { + const result = startEpochSyncCommittee(1, 256) + expect(result).toBe(0) + }) + }) + + describe('endEpochSyncCommittee', () => { + it('should return the correct end epoch of the sync committee', () => { + const result = endEpochSyncCommittee(1, 256) + expect(result).toBe(256) + }) + }) +}) diff --git a/src/app/utils/MathUtils.ts b/src/app/utils/MathUtils.ts index a93705d0..675136a2 100644 --- a/src/app/utils/MathUtils.ts +++ b/src/app/utils/MathUtils.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -19,6 +18,7 @@ */ import BigNumber from 'bignumber.js' +import { findChainNetworkById } from './NetworkData' export function sumBigInt(validators: T[], field: (cur: T) => BigNumber) { let sum = new BigNumber('0') @@ -50,4 +50,26 @@ export function findLowest(validators: T[], field: (cur: T) => number): numbe return lowest } +export function slotToEpoch(chainID: number, slot: number): number { + const network = findChainNetworkById(chainID) + return Math.floor(slot / network.slotPerEpoch) +} + +/** + * @returns the epoch at which the sync committee started, inclusive + */ +export function startEpochSyncCommittee(chainID: number, currentSlot: number): number { + const network = findChainNetworkById(chainID) + const period = Math.floor(slotToEpoch(chainID, currentSlot) / network.epochsPerSyncPeriod) + return period * network.epochsPerSyncPeriod +} + +/** + * @returns the epoch at which the sync committee ended, exclusive + */ +export function endEpochSyncCommittee(chainID: number, currentSlot: number): number { + const network = findChainNetworkById(chainID) + return startEpochSyncCommittee(chainID, currentSlot) + network.epochsPerSyncPeriod +} + export default class {} diff --git a/src/app/utils/MerchantUtils.ts b/src/app/utils/MerchantUtils.ts index 782bfc8d..e18a0da4 100644 --- a/src/app/utils/MerchantUtils.ts +++ b/src/app/utils/MerchantUtils.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -18,100 +17,296 @@ * // along with Beaconchain Dashboard. If not, see . */ -import { Injectable } from '@angular/core' -import 'cordova-plugin-purchase/www/store.d' +import { computed, effect, Injectable, OnInit, Signal, signal, WritableSignal } from '@angular/core' +import 'cordova-plugin-purchase' import { Platform } from '@ionic/angular' -import { PostMobileSubscription, SubscriptionData } from '../requests/requests' -import { AlertService, PURCHASEUTILS } from '../services/alert.service' -import { ApiService } from '../services/api.service' -import { DEBUG_SETTING_OVERRIDE_PACKAGE, StorageService } from '../services/storage.service' +import { AlertService, PURCHASEUTILS } from '@services/alert.service' +import { ApiService } from '@services/api.service' +import { DEBUG_SETTING_OVERRIDE_PACKAGE, StorageService } from '@services/storage.service' import { SplashScreen } from '@capacitor/splash-screen' +import { SubscriptionData, V2Me, V2PurchaseValidation } from '@requests/v2-user' +import { UserInfo, UserSubscription } from '@requests/types/user' +import { Aggregation } from '@requests/v2-dashboard' +import { ONE_DAY, ONE_HOUR } from './TimeUtils' +import ThemeUtils from './ThemeUtils' +import { ApiResult } from '@requests/requests' export const PRODUCT_STANDARD = 'standard' -const MAX_PRODUCT = 'whale' + +export const AggregationTimeframes: Aggregation[] = [Aggregation.Epoch, Aggregation.Hourly, Aggregation.Daily, Aggregation.Weekly] @Injectable({ providedIn: 'root', }) -export class MerchantUtils { - DEPRECATED_PACKAGES = [ +export class MerchantUtils implements OnInit { + store?: CdvPurchase.Store + + DEPRECATED_PACKAGES: Package[] = [ { name: 'Plankton', price: '$1.99', - maxValidators: 100, - maxTestnetValidators: 100, - maxBeaconNodes: 1, - deviceMonitoringHours: 30 * 24, - deviceMonitorAlerts: true, - noAds: true, - widgets: false, - customTheme: false, - supportUs: true, + priceMicros: 1990000, + currency: 'USD', purchaseKey: 'plankton', + renewFrame: null, }, ] - PACKAGES: Package[] = [ - { - name: 'Free', - price: '$0.00', - maxValidators: 100, - maxTestnetValidators: 100, - maxBeaconNodes: 1, - deviceMonitoringHours: 3, - deviceMonitorAlerts: false, - noAds: false, - widgets: false, - customTheme: false, - supportUs: false, - purchaseKey: null, - }, - { - name: 'Goldfish', - price: '$4.99', - maxValidators: 100, - maxTestnetValidators: 100, - maxBeaconNodes: 2, - deviceMonitoringHours: 30 * 24, - deviceMonitorAlerts: true, - noAds: true, - widgets: true, - customTheme: true, - supportUs: true, - purchaseKey: 'goldfish', - }, - { - name: 'Whale', - price: '$19.99', - maxValidators: 280, - maxTestnetValidators: 280, - maxBeaconNodes: 10, - deviceMonitoringHours: 30 * 24, - deviceMonitorAlerts: true, - noAds: true, - widgets: true, - customTheme: true, - supportUs: true, - purchaseKey: 'whale', - }, - ] - - currentPlan = PRODUCT_STANDARD // use getCurrentPlanConfirmed instead + PACKAGES: Package[] purchaseIntent = '' // temp workaround until new api is live - constructor(private alertService: AlertService, private api: ApiService, private platform: Platform, private storage: StorageService) { + userInfo: WritableSignal = signal(null) + + userAllowedChartAggregations = computed(() => { + function add(list: Aggregation[], value: number, aggregation: Aggregation) { + if (value === 0) return + list.push(aggregation) + } + + const result: Aggregation[] = [] + add(result, this.userInfo()?.premium_perks?.chart_history_seconds?.epoch ?? 0, Aggregation.Epoch) + add(result, this.userInfo()?.premium_perks?.chart_history_seconds?.daily ?? 0, Aggregation.Daily) + add(result, this.userInfo()?.premium_perks?.chart_history_seconds?.hourly ?? 43200, Aggregation.Hourly) + add(result, this.userInfo()?.premium_perks?.chart_history_seconds?.weekly ?? 0, Aggregation.Weekly) + + return result + }) + + initialize: Promise + + constructor( + private alertService: AlertService, + private api: ApiService, + private platform: Platform, + private storage: StorageService, + private theme: ThemeUtils + ) { + effect(() => { + if (this.userInfo()) { + const hasTheming = this.userInfo()?.premium_perks?.mobile_app_custom_themes == true + if (!hasTheming && this.theme.currentThemeColor != 'gnosis') { + this.theme.resetTheming() + } + } + }) + this.initPackages() if (!this.platform.is('ios') && !this.platform.is('android')) { console.info('merchant is not supported on this platform') return } + this.platform.ready().then(() => { + console.log('store initialized') + // MUST WAIT for Cordova to initialize before referencing CdvPurchase namespace + this.store = CdvPurchase.store + }) + } + + initPackages(appendix: string = '') { + this.PACKAGES = [ + { + name: 'Free', + price: '€0.00', + priceMicros: 0, + currency: 'EUR', + purchaseKey: null, + renewFrame: null, + }, + { + name: 'Guppy', + price: '€9.99', + priceMicros: 9990000, + currency: 'EUR', + purchaseKey: 'guppy' + appendix, + renewFrame: 'monthly', + }, + { + name: 'Guppy', + price: '€107.88', + priceMicros: 107880000, + currency: 'EUR', + purchaseKey: 'guppy.yearly' + appendix, + renewFrame: 'yearly', + }, + { + name: 'Dolphin', + price: '€29.99', + priceMicros: 29990000, + currency: 'EUR', + purchaseKey: 'dolphin' + appendix, + renewFrame: 'monthly', + }, + { + name: 'Dolphin', + price: '€311.88', + priceMicros: 311880000, + currency: 'EUR', + purchaseKey: 'dolphin.yearly' + appendix, + renewFrame: 'yearly', + }, + { + name: 'Orca', + price: '€49.99', + priceMicros: 49990000, + currency: 'EUR', + purchaseKey: 'orca' + appendix, + renewFrame: 'monthly', + }, + { + name: 'Orca', + price: '€479.88', + priceMicros: 479880000, + currency: 'EUR', + purchaseKey: 'orca.yearly' + appendix, + renewFrame: 'yearly', + }, + ] + } + + ngOnInit() { + this.initialize = this.init() + } + + public async getUserInfoOnNetwork(chainID: number, forceRefresh: boolean): Promise> { + if (await this.storage.getAuthUserv2()) { + const result = await this.api.executeOnChainID(new V2Me().withAllowedCacheResponse(!forceRefresh), null, chainID) + if (result.error) { + console.warn('failed to get user info', result.error) + return result + } + + const override = (await this.storage.getSetting(DEBUG_SETTING_OVERRIDE_PACKAGE, 'default')) as string + if (override != 'default') { + return { + data: this.overridePerks(result.data, override), + error: undefined, + } as ApiResult + } + return result + } else { + return { + data: this.overridePerks(undefined, 'standard'), + error: undefined, + } as ApiResult + } + } - this.init() + public async getUserInfo(forceRefresh: boolean = false, errHandler: (err: Error) => void = () => {}) { + if (await this.storage.getAuthUserv2()) { + if (!forceRefresh) { + this.userInfo.set(await (this.storage.getObject('userInfo') as Promise)) + } + const result = await this.api.set(new V2Me().withAllowedCacheResponse(!forceRefresh), this.userInfo) + if (result.error) { + console.warn('failed to get user info', result.error) + errHandler(result.error) + return + } + + if (this.userInfo()) { + this.storage.setObject('userInfo', this.userInfo()) + if (this.userInfo().api_keys && this.userInfo().api_keys.length > 0) { + this.api.setApiKey(this.userInfo().api_keys[0]) + } + } + } else { + this.userInfo.set(this.overridePerks(this.userInfo(), 'standard')) + } + // check for override + const override = (await this.storage.getSetting(DEBUG_SETTING_OVERRIDE_PACKAGE, 'default')) as string + if (override != 'default') { + this.userInfo.set(this.overridePerks(this.userInfo(), override)) + } + } + + // debug + private overridePerks(sourcePerks: UserInfo, target: string) { + const userInfoShadow = + sourcePerks || + ({ + premium_perks: { + ad_free: false, + validator_dashboards: 1, + validators_per_dashboard: 20, + validator_groups_per_dashboard: 1, + chart_history_seconds: { + epoch: 0, + hourly: 12 * ONE_HOUR, + daily: 0, + weekly: 0, + }, + }, + subscriptions: [], + } as UserInfo) + switch (target) { + case 'standard': + userInfoShadow.premium_perks.ad_free = false + userInfoShadow.premium_perks.validator_dashboards = 1 + userInfoShadow.premium_perks.validators_per_dashboard = 20 + userInfoShadow.premium_perks.validator_groups_per_dashboard = 1 + userInfoShadow.premium_perks.chart_history_seconds = { + epoch: 0, + hourly: 12 * ONE_HOUR, + daily: 0, + weekly: 0, + } + break + case 'guppy': + userInfoShadow.premium_perks.ad_free = true + userInfoShadow.premium_perks.validator_dashboards = 1 + userInfoShadow.premium_perks.validators_per_dashboard = 100 + userInfoShadow.premium_perks.validator_groups_per_dashboard = 3 + userInfoShadow.premium_perks.chart_history_seconds = { + epoch: 1 * ONE_DAY, + hourly: 7 * ONE_DAY, + daily: 30 * ONE_DAY, + weekly: 0, + } + break + case 'dolphin': + userInfoShadow.premium_perks.ad_free = true + userInfoShadow.premium_perks.validator_dashboards = 2 + userInfoShadow.premium_perks.validators_per_dashboard = 300 + userInfoShadow.premium_perks.validator_groups_per_dashboard = 10 + userInfoShadow.premium_perks.chart_history_seconds = { + epoch: 5 * ONE_DAY, + hourly: 30 * ONE_DAY, + daily: 60 * ONE_DAY, + weekly: 56 * ONE_DAY, // todo + } + break + case 'orca': + userInfoShadow.premium_perks.ad_free = true + userInfoShadow.premium_perks.validator_dashboards = 2 + userInfoShadow.premium_perks.validators_per_dashboard = 1000 + userInfoShadow.premium_perks.validator_groups_per_dashboard = 30 + userInfoShadow.premium_perks.chart_history_seconds = { + epoch: 21 * ONE_DAY, + hourly: 180 * ONE_DAY, + daily: 360 * ONE_DAY, + weekly: 999 * ONE_DAY, + } + break + } + return userInfoShadow + } + + clearTempUserInfo() { + return this.storage.setObject('userInfo', this.userInfo()) + } + + public getMonthlyBilledPackages(): Package[] { + return this.PACKAGES.filter((pkg) => pkg.renewFrame == null || pkg.renewFrame == 'monthly') + } + + public getYearlyBilledPackages(): Package[] { + return this.PACKAGES.filter((pkg) => pkg.renewFrame == null || pkg.renewFrame == 'yearly') } private async init() { try { + await this.getUserInfo() await this.initProducts() this.initCustomValidator() this.setupListeners() @@ -125,7 +320,7 @@ export class MerchantUtils { } private initCustomValidator() { - CdvPurchase.store.validator = async ( + this.store.validator = async ( product: CdvPurchase.Validator.Request.Body, callback: CdvPurchase.Callback ) => { @@ -152,67 +347,57 @@ export class MerchantUtils { window.location.reload() } - async refreshToken() { - let refreshSuccess = (await this.api.refreshToken()) != null - if (!refreshSuccess) { - console.log('refreshing token after purchase failed, scheduling retry') - const loading = await this.alertService.presentLoading('This can take a minute') - loading.present() - await this.sleep(35000) - refreshSuccess = (await this.api.refreshToken()) != null - if (!refreshSuccess) { - this.alertService.showError( - 'Purchase Error', - 'We could not confirm your purchase. Please try again later or contact us if this problem persists.', - PURCHASEUTILS + 2 - ) - } - loading.dismiss() - } - } - private async registerPurchaseOnRemote(data: SubscriptionData): Promise { - const request = new PostMobileSubscription(data) - const response = await this.api.execute(request) - const result = request.wasSuccessful(response, false) + const result = await this.api.execute(new V2PurchaseValidation(data)) - if (!result) { - console.log('registering purchase receipt failed', response) + if (result.error) { + console.log('registering purchase receipt failed', result) } - return result + return result.error == null } private async initProducts() { let platform = CdvPurchase.Platform.GOOGLE_PLAY + let appendix = '' if (this.platform.is('ios')) { platform = CdvPurchase.Platform.APPLE_APPSTORE + appendix = '.apple' } + for (let i = 0; i < this.PACKAGES.length; i++) { if (this.PACKAGES[i].purchaseKey) { - CdvPurchase.store.register({ - id: this.PACKAGES[i].purchaseKey, + this.store.register({ + id: this.PACKAGES[i].purchaseKey + appendix, platform: platform, type: CdvPurchase.ProductType.PAID_SUBSCRIPTION, } as CdvPurchase.IRegisterProduct) } } - await CdvPurchase.store.initialize() - for (let i = 0; i < CdvPurchase.store.products.length; i++) { - const lastIndex = CdvPurchase.store.products[i].offers[0].pricingPhases.length - 1 + await this.store.initialize() + for (let i = 0; i < this.store.products.length; i++) { + const lastIndex = this.store.products[i].offers[0].pricingPhases.length - 1 if (lastIndex < 0) { - console.warn('no pricingphases found', CdvPurchase.store.products[i]) + console.warn('no pricingphases found', this.store.products[i]) continue } - this.updatePrice(CdvPurchase.store.products[i].id, CdvPurchase.store.products[i].offers[0].pricingPhases[lastIndex].price) + this.updatePrice(this.store.products[i].id, this.store.products[i].offers[0].pricingPhases[lastIndex]) } } - private updatePrice(id, price) { + private updatePrice(id: string, prices: CdvPurchase.PricingPhase) { + if (this.platform.is('ios')) { + id = id.replace('.apple', '') + } + for (let i = 0; i < this.PACKAGES.length; i++) { - if (this.PACKAGES[i].purchaseKey == id) this.PACKAGES[i].price = price + if (this.PACKAGES[i].purchaseKey == id) { + this.PACKAGES[i].price = prices.price + this.PACKAGES[i].priceMicros = prices.priceMicros + this.PACKAGES[i].currency = prices.currency + } } } @@ -220,11 +405,11 @@ export class MerchantUtils { private setupListeners() { // General query to all products - CdvPurchase.store + this.store .when() .approved((p: CdvPurchase.Transaction) => { // Handle the product deliverable - this.currentPlan = p.products[0].id + //this.currentPlan = p.products[0].id //this.ref.detectChanges(); return p.verify() @@ -235,27 +420,39 @@ export class MerchantUtils { // }) } - sleep(ms) { + sleep(ms: number) { return new Promise((resolve) => setTimeout(resolve, ms)) } manageSubscriptions() { - CdvPurchase.store.manageSubscriptions() + this.store.manageSubscriptions() } async restore(product: string) { this.restorePurchase = true this.purchaseIntent = product - await CdvPurchase.store.restorePurchases() + await this.store.restorePurchases() } async purchase(product: string) { - const offer = CdvPurchase.store.get(product).getOffer() + if (this.platform.is('ios')) { + // you don't wanna know :) + product += '.apple' + } + console.log('purchasing product', product) + const storeProduct = this.store.get(product) + if (storeProduct == null) { + console.log('store', this.store) + this.alertService.showError('Purchase failed', `Product ${product} can not be purchased at the moment, please try again later.`, PURCHASEUTILS) + return + } + + const offer = storeProduct.getOffer() const loading = await this.alertService.presentLoading('') loading.present() this.restorePurchase = true this.purchaseIntent = product - CdvPurchase.store.order(offer).then( + this.store.order(offer).then( () => { setTimeout(() => { loading.dismiss() @@ -265,12 +462,12 @@ export class MerchantUtils { loading.dismiss() this.alertService.showError('Purchase failed', `Failed to purchase: ${e}`, PURCHASEUTILS + 1) console.warn('purchase error', e) - this.currentPlan = PRODUCT_STANDARD + //this.currentPlan = PRODUCT_STANDARD } ) } - private async confirmPurchaseOnRemote(product) { + private async confirmPurchaseOnRemote(product: CdvPurchase.Validator.Request.Body) { const isIOS = this.platform.is('ios') // TODO in the future replace isIOS ? product.transaction.appStoreReceipt : product.transaction.purchaseToken @@ -279,10 +476,12 @@ export class MerchantUtils { currency: product.currency, id: isIOS ? this.purchaseIntent : product.id, priceMicros: product.priceMicros, - valid: product.valid, + valid: true, transaction: { id: product.id, - receipt: isIOS ? product.transaction.id : product.transaction.purchaseToken, + receipt: isIOS + ? (product.transaction as CdvPurchase.Validator.Request.ApiValidatorBodyTransactionApple).id + : (product.transaction as CdvPurchase.Validator.Request.ApiValidatorBodyTransactionGoogle).purchaseToken, type: product.transaction.type, }, } @@ -308,7 +507,15 @@ export class MerchantUtils { loading.dismiss() } - if (result) await this.refreshToken() + if (result) { + await this.getUserInfo(true, () => { + this.alertService.showError( + 'Purchase Error', + 'We could not confirm your purchase. Please try again later or contact us if this problem persists.', + PURCHASEUTILS + 2 + ) + }) + } loading.dismiss() @@ -333,46 +540,17 @@ export class MerchantUtils { } ) } - - async getCurrentPlanConfirmed(): Promise { - if (this.api.debug) { - const debugPackage = await this.storage.getSetting(DEBUG_SETTING_OVERRIDE_PACKAGE, 'default') - if (debugPackage != 'default') { - return debugPackage as string - } - } - - const authUser = await this.storage.getAuthUser() - if (!authUser || !authUser.accessToken) return PRODUCT_STANDARD - const jwtParts = authUser.accessToken.split('.') - const claims: ClaimParts = JSON.parse(atob(jwtParts[1])) - if (claims && claims.package) { - return claims.package - } - return PRODUCT_STANDARD - } - - async getDefaultTheme(): Promise { - const authUser = await this.storage.getAuthUser() - if (!authUser || !authUser.accessToken) return '' - const jwtParts = authUser.accessToken.split('.') - const claims: ClaimParts = JSON.parse(atob(jwtParts[1])) - if (claims && Object.prototype.hasOwnProperty.call(claims, 'theme') && claims.theme) { - return claims.theme - } - return '' - } - findProduct(name: string): Package { + console.log('find product', name, this.PACKAGES) for (let i = 0; i < this.PACKAGES.length; i++) { const current = this.PACKAGES[i] - if (current.purchaseKey == name) { + if (current.purchaseKey == name || this.mapv2Tov1(current.purchaseKey) == name) { return current } } for (let i = 0; i < this.DEPRECATED_PACKAGES.length; i++) { const current = this.DEPRECATED_PACKAGES[i] - if (current.purchaseKey == name) { + if (current.purchaseKey == name || this.mapv2Tov1(current.purchaseKey) == name) { return current } } @@ -380,69 +558,84 @@ export class MerchantUtils { return null } - private async isNotFreeTier() { - const currentPlan = await this.getCurrentPlanConfirmed() - return currentPlan != PRODUCT_STANDARD && currentPlan != '' + isPremium = computed(() => { + if (!this.userInfo()) return false + return this.userInfo().premium_perks.ad_free + }) + + canBulkAdd = computed(() => { + if (!this.userInfo()) return false + return this.userInfo().premium_perks.bulk_adding + }) + + getCurrentPlanMaxValidator = computed(() => { + if (!this.isPremium()) return 20 + return this.userInfo().premium_perks.validators_per_dashboard + }) + + getCurrentPlanMaxGroups = computed(() => { + if (!this.isPremium()) return 1 + return this.userInfo().premium_perks.validator_groups_per_dashboard + }) + + highestPackageDashboardsAllowed = computed(() => { + return 2 // todo + }) + + highestPackageGroupsPerDashboardAllowed = computed(() => { + return 30 // todo + }) + + mapv2Tov1(name: string): string { + if (name == null) return null + if (name.indexOf('guppy') >= 0) return 'plankton' + if (name.indexOf('dolphin') >= 0) return 'goldfish' + if (name.indexOf('orca') >= 0) return 'whale' + return name } - async hasPremiumTheming() { - const currentPlan = await this.getCurrentPlanConfirmed() - return currentPlan != PRODUCT_STANDARD && currentPlan != '' && currentPlan != 'plankton' + mapv1Tov2(name: string): string { + if (name == null) return null + if (name.indexOf('plankton') >= 0) return 'guppy' + if (name.indexOf('goldfish') >= 0) return 'dolphin' + if (name.indexOf('whale') >= 0) return 'orca' + return name } - async hasCustomizableNotifications() { - return await this.isNotFreeTier() - } - - async hasAdFree() { - return await this.isNotFreeTier() - } - - async hasMachineHistoryPremium() { - return await this.isNotFreeTier() - } - - async getCurrentPlanMaxValidator(): Promise { - const currentPlan = await this.getCurrentPlanConfirmed() - const currentProduct = this.findProduct(currentPlan) - if (currentProduct == null) return 100 - - const notMainnet = this.api.isNotEthereumMainnet() - if (notMainnet) return currentProduct.maxTestnetValidators - return currentProduct.maxValidators - } - - getHighestPackageValidator(): number { - const currentProduct = this.findProduct(MAX_PRODUCT) - if (currentProduct == null) return 100 - - const notMainnet = this.api.isNotEthereumMainnet() - if (notMainnet) return currentProduct.maxTestnetValidators - return currentProduct.maxValidators + removeApplePrefix(name: string): string { + if (name == null) return null + if (name.indexOf('.apple')) { + name = name.replace('.apple', '') + } + return name } -} -interface ClaimParts { - userID: number - appID: number - deviceID: number - package: string - exp: number - iss: string - theme: string + hasMachineMonitoringPremium = computed(() => { + if (!this.isPremium()) return false + return this.userInfo().premium_perks.machine_monitoring_history_seconds > 10800 + }) + + getUsersSubscription: Signal = computed(() => { + const none = { + product_id: '', + product_name: '', + product_category: '', + product_store: '', + start: 0, + end: 0, + } + if (!this.userInfo()) return none + const appSubs = this.userInfo().subscriptions.filter((sub) => sub.product_category == 'premium') + if (appSubs.length == 0) return none + return appSubs[0] + }) } export interface Package { name: string price: string - maxValidators: number - maxTestnetValidators: number - maxBeaconNodes: number - deviceMonitoringHours: number - deviceMonitorAlerts: boolean - noAds: boolean - widgets: boolean - customTheme: boolean - supportUs: boolean + priceMicros: number + currency: string purchaseKey: string + renewFrame: 'monthly' | 'yearly' | null } diff --git a/src/app/utils/NetworkData.ts b/src/app/utils/NetworkData.ts index 2376b16b..28882214 100644 --- a/src/app/utils/NetworkData.ts +++ b/src/app/utils/NetworkData.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -30,15 +29,24 @@ export const MAP: ApiNetwork[] = [ version: 'v1', onlyDebug: false, active: true, - genesisTs: 1606824023, - clCurrency: NetworkMainCurrency.ETH, - elCurrency: NetworkMainCurrency.ETH, - slotPerEpoch: 32, - slotsTime: 12, - epochsPerSyncPeriod: 256, + supportedChainIds: 1, name: 'Ethereum', + v2NetworkConfigKey: 'main_v2_prod', }, { + key: 'main_v2_prod', + protocol: 'https', + host: 'v2-staging-mainnet.beaconcha.in', + net: '', + endpoint: '/api/', + version: 'i', + onlyDebug: true, + active: true, + supportedChainIds: 1, + name: 'Ethereum', + }, + { + // todo change key: 'gnosis', protocol: 'https', host: 'gnosischa.in', @@ -47,30 +55,22 @@ export const MAP: ApiNetwork[] = [ version: 'v1', onlyDebug: false, active: true, - genesisTs: 1638993340, - clCurrency: NetworkMainCurrency.GNO, - elCurrency: NetworkMainCurrency.xDAI, - slotPerEpoch: 16, - slotsTime: 5, - epochsPerSyncPeriod: 512, + supportedChainIds: 100, name: 'Gnosis', + v2NetworkConfigKey: 'gnosis_v2_prod', }, { - key: 'prater', + // todo change + key: 'gnosis_v2_prod', protocol: 'https', - host: 'beaconcha.in', - net: 'prater.', + host: 'v2-staging-gnosis.beaconcha.in', + net: '', endpoint: '/api/', - version: 'v1', - onlyDebug: false, + version: 'i', + onlyDebug: true, active: true, - genesisTs: 1616508000, - clCurrency: NetworkMainCurrency.ETH, - elCurrency: NetworkMainCurrency.ETH, - slotPerEpoch: 32, - slotsTime: 12, - epochsPerSyncPeriod: 256, - name: 'Ethereum', + supportedChainIds: 100, + name: 'Gnosis', }, { key: 'sepolia', @@ -81,12 +81,7 @@ export const MAP: ApiNetwork[] = [ version: 'v1', onlyDebug: false, active: true, - genesisTs: 1655733600, - clCurrency: NetworkMainCurrency.ETH, - elCurrency: NetworkMainCurrency.ETH, - slotPerEpoch: 32, - slotsTime: 12, - epochsPerSyncPeriod: 256, + supportedChainIds: 11155111, name: 'Ethereum', }, { @@ -98,29 +93,44 @@ export const MAP: ApiNetwork[] = [ version: 'v1', onlyDebug: false, active: true, - genesisTs: 1695902400, - clCurrency: NetworkMainCurrency.ETH, - elCurrency: NetworkMainCurrency.ETH, - slotPerEpoch: 32, - slotsTime: 12, - epochsPerSyncPeriod: 256, + supportedChainIds: 17000, name: 'Ethereum', + v2NetworkConfigKey: 'holesky_v2_prod', }, { - key: 'local dev', + key: 'main_v2', protocol: 'http', - host: '192.168.103.224:3333', + host: 'local.beaconcha.in:8083', net: '', endpoint: '/api/', - version: 'v1', + version: 'i', onlyDebug: true, active: true, - genesisTs: 1606824023, - clCurrency: NetworkMainCurrency.ETH, - elCurrency: NetworkMainCurrency.ETH, - slotPerEpoch: 32, - slotsTime: 12, - epochsPerSyncPeriod: 256, + supportedChainIds: 1, + name: 'Ethereum', + }, + { + key: 'holesky_v2', + protocol: 'http', + host: 'local.beaconcha.in:8083', + net: '', + endpoint: '/api/', + version: 'i', + onlyDebug: true, + active: true, + supportedChainIds: 17000, + name: 'Ethereum', + }, + { + key: 'holesky_v2_prod', + protocol: 'https', + host: 'jkihuwegfsgjkhsdgf.beaconcha.in', + net: '', + endpoint: '/api/', + version: 'i', + onlyDebug: true, + active: true, + supportedChainIds: 17000, name: 'Ethereum', }, { @@ -132,12 +142,7 @@ export const MAP: ApiNetwork[] = [ version: 'v1', onlyDebug: true, active: true, - genesisTs: 1606824023, - clCurrency: NetworkMainCurrency.ETH, - elCurrency: NetworkMainCurrency.ETH, - slotPerEpoch: 32, - slotsTime: 12, - epochsPerSyncPeriod: 256, + supportedChainIds: 17000, name: 'Ethereum', }, ] @@ -151,3 +156,85 @@ export function findConfigForKey(key: string): ApiNetwork { console.log('config for ' + key + ' not found, using mainnet instead', key) return MAP[0] } + +export const CHAIN_NETWORKS: ChainNetwork[] = [ + { + id: 1, + name: 'ethereum', + legacyKey: 'main', + genesisTs: 1606824023, + clCurrency: NetworkMainCurrency.ETH, + elCurrency: NetworkMainCurrency.ETH, + slotPerEpoch: 32, + slotsTime: 12, + epochsPerSyncPeriod: 256, + testnet: false, + }, + { + id: 17000, + name: 'holesky', + legacyKey: 'holesky', + genesisTs: 1695902400, + clCurrency: NetworkMainCurrency.ETH, + elCurrency: NetworkMainCurrency.ETH, + slotPerEpoch: 32, + slotsTime: 12, + epochsPerSyncPeriod: 256, + testnet: true, + }, + { + id: 100, + name: 'gnosis', + legacyKey: 'gnosis', + genesisTs: 1638993340, + clCurrency: NetworkMainCurrency.GNO, + elCurrency: NetworkMainCurrency.xDAI, + slotPerEpoch: 16, + slotsTime: 5, + epochsPerSyncPeriod: 512, + testnet: false, + }, + { + id: 11155111, + name: 'sepolia', + legacyKey: 'sepolia', + genesisTs: 1655733600, + clCurrency: NetworkMainCurrency.ETH, + elCurrency: NetworkMainCurrency.ETH, + slotPerEpoch: 32, + slotsTime: 12, + epochsPerSyncPeriod: 256, + testnet: true, + }, +] + +export function findChainNetworkById(id: number): ChainNetwork | null { + for (const entry of CHAIN_NETWORKS) { + if (entry.id == id) { + return entry + } + } + return CHAIN_NETWORKS[0] +} + +export function findChainNetworkByName(name: string): ChainNetwork | null { + for (const entry of CHAIN_NETWORKS) { + if (entry.name == name) { + return entry + } + } + return CHAIN_NETWORKS[0] +} + +export interface ChainNetwork { + id: number + name: string // do not change once set + legacyKey: string // pre 5.0.0 network key associated with that chain + genesisTs: number + elCurrency: NetworkMainCurrency + clCurrency: NetworkMainCurrency + slotPerEpoch: number + slotsTime: number + epochsPerSyncPeriod: number + testnet: boolean +} diff --git a/src/app/utils/OAuthUtils.ts b/src/app/utils/OAuthUtils.ts index 70d07201..583e67ad 100644 --- a/src/app/utils/OAuthUtils.ts +++ b/src/app/utils/OAuthUtils.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -18,19 +17,21 @@ * // along with Beaconchain Dashboard. If not, see . */ -import { ApiService } from '../services/api.service' +import { ApiService } from '@services/api.service' import { Injectable } from '@angular/core' -import { StorageService } from '../services/storage.service' -import FirebaseUtils from './FirebaseUtils' -import { ValidatorUtils } from './ValidatorUtils' +import { StorageService } from '@services/storage.service' +import { pushLastTokenUpstream } from './FirebaseUtils' import { LoadingController, Platform } from '@ionic/angular' -import { SyncService } from '../services/sync.service' import { MerchantUtils } from './MerchantUtils' import { Toast } from '@capacitor/toast' import { Device } from '@capacitor/device' -import { OAuth2Client } from '@byteowls/capacitor-oauth2' +import { OAuth2AuthenticateOptions, OAuth2Client } from '@byteowls/capacitor-oauth2' import FlavorUtils from './FlavorUtils' +import { mergeLocalDashboardToRemote } from './DashboardUtils' +import { getProperty } from '@requests/requests' +import { AlertService } from '@services/alert.service' +import { NotificationBase } from '../tabs/tab-preferences/notification-base' @Injectable({ providedIn: 'root', @@ -39,47 +40,76 @@ export class OAuthUtils { constructor( private api: ApiService, private storage: StorageService, - private firebaseUtils: FirebaseUtils, - private validatorUtils: ValidatorUtils, private loadingController: LoadingController, - private sync: SyncService, private merchantUtils: MerchantUtils, private flavor: FlavorUtils, - private platform: Platform + private platform: Platform, + private alert: AlertService, + private notificationBase: NotificationBase ) { //registerWebPlugin(OAuth2Client); } async login(statusCallback: (finished: boolean) => void = null) { - return OAuth2Client.authenticate(await this.getOAuthOptions()) - .then(async (response: AccessTokenResponse) => { + let authOptions: OAuth2AuthenticateOptions = await this.getOAuthOptionsv1() + const isV2 = await this.storage.isV2() + if (isV2) { + authOptions = await this.getOAuthOptionsv2() + } + return OAuth2Client.authenticate(authOptions) + .then(async (response: unknown) => { const loadingScreen = await this.presentLoading() loadingScreen.present() - let result = response.access_token_response - if (typeof result === 'string') { - result = JSON.parse(response.access_token_response as string) + let obj = response + if (typeof response === 'string') { + obj = JSON.parse(response as string) + } + + // different responses based on the platform yay + let accessToken = getProperty(obj, 'access_token') + if (!accessToken) { + accessToken = getProperty(obj, 'access_token_response') + ? getProperty(getProperty(obj, 'access_token_response'), 'access_token') + : getProperty(obj, 'authorization_response') + ? getProperty(getProperty(obj, 'authorization_response'), 'access_token') + : undefined + } + let refreshToken = getProperty(obj, 'refresh_token') + if (!refreshToken) { + refreshToken = getProperty(obj, 'access_token_response') + ? getProperty(getProperty(obj, 'access_token_response'), 'refresh_token') + : getProperty(obj, 'authorization_response') + ? getProperty(getProperty(obj, 'authorization_response'), 'refresh_token') + : undefined + } + + if (!accessToken) { + throw new Error('invalid access token') } - result = result as Token - const accessToken = result.access_token - const refreshToken = result.refresh_token - // inconsistent on ios, just assume a 10min lifetime for first token and then just refresh it - // and kick off real expiration times - const expiresIn = Date.now() + 10 * 60 * 1000 + if (isV2) { + console.log('successful v2 auth') - console.log('successful', accessToken, refreshToken, expiresIn) - await this.storage.setAuthUser({ - accessToken: accessToken, - refreshToken: refreshToken, - expiresIn: expiresIn, - }) + await this.storage.setAuthUserv2({ + Session: accessToken as string, + }) - this.validatorUtils.clearDeletedSet() - await this.firebaseUtils.pushLastTokenUpstream(true) - await this.sync.fullSync() + await this.api.initV2Cookies() + } else { + // inconsistent on ios, just assume a 10min lifetime for first token and then just refresh it + // and kick off real expiration times + const expiresIn = Date.now() + 10 * 60 * 1000 + + await this.storage.setAuthUser({ + accessToken: accessToken as string, + refreshToken: refreshToken as string, + expiresIn: expiresIn, + }) + } - const isPremium = await this.merchantUtils.hasMachineHistoryPremium() + await this.postLogin() + const isPremium = this.merchantUtils.isPremium() loadingScreen.dismiss() if (isPremium) { @@ -95,13 +125,31 @@ export class OAuthUtils { .catch((reason: unknown) => { if (statusCallback) statusCallback(true) console.error('OAuth rejected', reason) - Toast.show({ - text: 'Could not log in, please try again later.', - }) + this.alert.showError( + 'Login Failed', + 'Your credentials are correct but there has been a problem signing you in at this moment. Please try again in 20min. If this error persists please reach out to us.', + 100 + ) return false }) } + async postLogin() { + await pushLastTokenUpstream(this.storage, this.api, true) + //await this.sync.fullSync() + + await this.merchantUtils.getUserInfo(true, () => { + console.warn('can not get user info') + Toast.show({ + text: 'Could not log in, please try again later.', + }) + }) + + await mergeLocalDashboardToRemote(this.api, this.storage) + + await this.notificationBase.syncClientUpdates() + } + private async presentLoading() { return await this.loadingController.create({ cssClass: 'my-custom-class', @@ -120,7 +168,7 @@ export class OAuthUtils { return hash.toString(16) } - private async getOAuthOptions() { + private async getOAuthOptionsv1() { const api = this.api const endpointUrl = api.getResourceUrl('user/token') @@ -141,8 +189,10 @@ export class OAuthUtils { } } + const oAuthURL = api.getBaseUrl() + '/user/authorize' + return { - authorizationBaseUrl: api.getBaseUrl() + '/user/authorize', + authorizationBaseUrl: oAuthURL, accessTokenEndpoint: endpointUrl, web: { appId: clientID, @@ -164,13 +214,42 @@ export class OAuthUtils { }, } } -} -interface AccessTokenResponse { - access_token_response: Token | string -} + private async getOAuthOptionsv2() { + const responseType = 'token' + const clientName = await this.storage.getDeviceName() -interface Token { - access_token: string - refresh_token: string + let callback = 'beaconchainmobile://callback' + if (this.platform.is('ios') || this.platform.is('android')) { + if (await this.flavor.isBetaFlavor()) { + callback = 'beaconchainmobilebeta://callback' + } + } + + const oAuthURL = this.api.getBaseUrl() + '/login' + + const clientID = await this.storage.getDeviceID() + + return { + authorizationBaseUrl: oAuthURL, + web: { + appId: clientID + ':' + clientName, + responseType: responseType, + redirectUrl: callback, + windowOptions: 'height=600,left=0,top=0', + }, + android: { + appId: clientID + ':' + clientName, + responseType: responseType, + redirectUrl: callback, + handleResultOnNewIntent: true, + handleResultOnActivityResult: true, + }, + ios: { + appId: clientID + ':' + clientName, + responseType: responseType, + redirectUrl: callback, + }, + } + } } diff --git a/src/app/utils/ThemeUtils.ts b/src/app/utils/ThemeUtils.ts index eb694330..96e8891d 100644 --- a/src/app/utils/ThemeUtils.ts +++ b/src/app/utils/ThemeUtils.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -18,12 +17,11 @@ * // along with Beaconchain Dashboard. If not, see . */ -import { StorageService } from '../services/storage.service' +import { StorageService } from '@services/storage.service' import { Injectable } from '@angular/core' import { NavigationBarPlugin } from 'capacitor-navigationbarnx' import { Capacitor, Plugins } from '@capacitor/core' import { Platform } from '@ionic/angular' -import * as Snowflakes from 'magic-snowflakes' import confetti from 'canvas-confetti' import { StatusBar, Style } from '@capacitor/status-bar' @@ -48,11 +46,14 @@ export default class ThemeUtils { currentThemeColor = '' private lock: Promise - private snowFlakes + private snowFlakes: { destroy: () => void } - private currentStatusBarColor = null + private currentStatusBarColor: string = null - constructor(private storage: StorageService, private platform: Platform) {} + constructor( + private storage: StorageService, + private platform: Platform + ) {} init(splashScreenCallback: () => void) { this.lock = this.storage.getObject(STORAGE_KEY).then((preferenceDarkMode) => { @@ -81,7 +82,7 @@ export default class ThemeUtils { ) // fade out duration = 200ms } - private internalInit(preferenceDarkMode) { + private internalInit(preferenceDarkMode: StoredTheme) { const prefersDark = window.matchMedia('(prefers-color-scheme: dark)') if (preferenceDarkMode) { this.userPreference = preferenceDarkMode.theme @@ -103,7 +104,7 @@ export default class ThemeUtils { if (themeColor && themeColor != '') document.body.classList.remove(themeColor) } - async toggle(darkModeEnabled: boolean, setColorHandler = true, themeColor: string = this.currentThemeColor) { + toggle(darkModeEnabled: boolean, setColorHandler = true, themeColor: string = this.currentThemeColor) { document.body.classList.toggle('dark', darkModeEnabled) if (themeColor && themeColor != '') document.body.classList.toggle(themeColor, true) if (setColorHandler) this.colorHandler() @@ -111,7 +112,6 @@ export default class ThemeUtils { this.storage.setObject(STORAGE_KEY, { theme: themeString, themeColor: themeColor } as StoredTheme) this.userPreference = themeString this.currentThemeColor = themeColor - this.toggleWinter(await this.isWinterEnabled(), false) } resetTheming() { @@ -120,17 +120,6 @@ export default class ThemeUtils { this.storage.setObject(STORAGE_KEY, { theme: this.userPreference, themeColor: '' } as StoredTheme) } - async isWinterEnabled() { - if (!this.isWinterSeason()) return false - const temp = await this.storage.getBooleanSetting('snow_enabled', true) - return temp - } - - isWinterSeason() { - const d = new Date() - return d.getMonth() == 11 && d.getDate() >= 24 && d.getDate() <= 24 - } - isSilvester() { const d = new Date() const silvesterday = d.getMonth() == 11 && d.getDate() == 31 && d.getHours() == 23 @@ -144,7 +133,7 @@ export default class ThemeUtils { const animationEnd = Date.now() + duration const defaults = { startVelocity: 30, spread: 100, ticks: 70, zIndex: 0 } - function randomInRange(min, max) { + function randomInRange(min: number, max: number) { return Math.random() * (max - min) + min } @@ -162,14 +151,6 @@ export default class ThemeUtils { }, 350) } - toggleWinter(enabled, saveWinterSetting = true) { - this.stopSnow(this.snowFlakes) - if (this.isWinterSeason() && saveWinterSetting) this.storage.setBooleanSetting('snow_enabled', enabled) - - if (!enabled) return - this.snowFlakes = this.winterSeason(this.userPreference == Theme.DARK) - } - async getThemeColor() { await this.lock return this.currentThemeColor @@ -192,7 +173,7 @@ export default class ThemeUtils { * @param isDarkThemed Android bottom button bar * @returns */ - private async changeNavigationBarColor(isDarkThemed) { + private async changeNavigationBarColor(isDarkThemed: boolean) { if (!Capacitor.isPluginAvailable('StatusBar')) return try { const themeColor = await this.getThemeColor() @@ -211,7 +192,7 @@ export default class ThemeUtils { } } - private async changeStatusBarColor(color: string, isDarkThemed) { + private async changeStatusBarColor(color: string, isDarkThemed: boolean) { let darker = isDarkThemed ? '#000000' : color.trim() //this.shadeColor(color, -12) if (this.platform.is('android')) { const themeColor = await this.getThemeColor() @@ -227,7 +208,8 @@ export default class ThemeUtils { } } - setStatusBarColor(color) { + setStatusBarColor(color: string, recursiveCount = 0) { + if (recursiveCount > 5) return try { if (Capacitor.isPluginAvailable('StatusBar')) { StatusBar.setStyle({ @@ -236,6 +218,9 @@ export default class ThemeUtils { StatusBar.setBackgroundColor({ color: color, }) + setTimeout(() => { + this.setStatusBarColor(color, ++recursiveCount) + }, 40) } else { console.info('Statusbar is not available on this platform') } @@ -247,39 +232,6 @@ export default class ThemeUtils { revertStatusBarColor() { this.setStatusBarColor(this.currentStatusBarColor) } - - private getSnowFlakeColor(darkTheme: boolean) { - return darkTheme ? '#fff' : '#5ECDEF' - } - - private winterSeason(darkTheme: boolean) { - if (!this.isWinterSeason()) return false - return this.snow(darkTheme) - } - - public snow(darkTheme: boolean = this.userPreference == Theme.DARK) { - return Snowflakes({ - color: this.getSnowFlakeColor(darkTheme), // Default: "#5ECDEF" - count: 14, // 100 snowflakes. Default: 50 - minOpacity: 0.1, // From 0 to 1. Default: 0.6 - maxOpacity: 0.95, // From 0 to 1. Default: 1 - minSize: 8, // Default: 8 - maxSize: 15, // Default: 18 - rotation: true, // Default: true - speed: 1, // The property affects the speed of falling. Default: 1 - wind: false, // Without wind. Default: true - }) - } - - public stopSnow(snow) { - if (snow) { - try { - snow.destroy() - } catch (error) { - console.warn('error in stopSnow()', error) - } - } - } } interface StoredTheme { diff --git a/src/app/utils/TimeUtils.spec.ts b/src/app/utils/TimeUtils.spec.ts new file mode 100644 index 00000000..18e29672 --- /dev/null +++ b/src/app/utils/TimeUtils.spec.ts @@ -0,0 +1,85 @@ +import { describe, it, expect } from 'vitest' +import { + epochToTimestamp, + formatMonthLong, + formatMonthShort, + formatTsToRelative, + getEndTs, + ONE_DAY, + ONE_HOUR, + ONE_WEEK, + relativeTs, + slotToSecondsTimestamp, + timestampToEpoch, + timestampToSlot, + timeUntilNextSlot, + toDateTime, +} from './TimeUtils' + +describe('TimeUtils', () => { + const chainID = 1 + const epoch = 12345 + const slot = 123456 + const ts = 1609459200 // January 1, 2021 00:00:00 UTC in seconds + const genesisMainnet = 1606824023000 + + it('should convert epoch to timestamp', () => { + const result = epochToTimestamp(chainID, epoch) + expect(result).toBe(genesisMainnet + epoch * 32 * 12 * 1000) + }) + + it('should convert timestamp to epoch', () => { + expect(timestampToEpoch(chainID, genesisMainnet)).toBe(0) + expect(timestampToEpoch(chainID, genesisMainnet + 12 * 32 * 1000)).toBe(1) + }) + + it('should convert timestamp to slot', () => { + expect(timestampToSlot(chainID, genesisMainnet)).toBe(0) + expect(timestampToSlot(chainID, genesisMainnet + 36000)).toBe(3) + }) + + it('should calculate time until next slot', () => { + expect(timeUntilNextSlot(chainID, genesisMainnet)).toBe(12000) + }) + + it('should calculate time until next slot offset', () => { + expect(timeUntilNextSlot(chainID, genesisMainnet + 2000)).toBe(10000) + }) + + it('should convert slot to seconds timestamp', () => { + expect(slotToSecondsTimestamp(chainID, slot)).toBe(genesisMainnet / 1000 + slot * 12) + }) + + it('should convert seconds to Date object', () => { + expect(toDateTime(ts)).toEqual(new Date(1970, 0, 1, 0, 0, ts)) + }) + + it('should get end timestamp based on aggregation', () => { + const startTs = 1609459200 + expect(getEndTs('hourly', startTs)).toBe(startTs + ONE_HOUR) + expect(getEndTs('weekly', startTs)).toBe(startTs + ONE_WEEK) + expect(getEndTs('daily', startTs)).toBe(startTs + ONE_DAY) + }) + + it('should format timestamp to relative time', () => { + const result = formatTsToRelative(Date.now() + 100, undefined, 'narrow', 'en-US') + expect(result).toBe('in 0 sec.') + }) + + it('should return relative time string', () => { + expect(relativeTs(3600)).toBe('hour') + expect(relativeTs(7200)).toBe('2 hours') + expect(relativeTs(86400)).toBe('day') + expect(relativeTs(172800)).toBe('2 days') + }) + + it('should format month short', () => { + expect(formatMonthShort(0)).toBe('Jan') + expect(formatMonthShort(11)).toBe('Dec') + }) + + it('should format month long', () => { + expect(formatMonthLong(0)).toBe('January') + expect(formatMonthLong(11)).toBe('December') + }) +}) diff --git a/src/app/utils/TimeUtils.ts b/src/app/utils/TimeUtils.ts new file mode 100644 index 00000000..048397ee --- /dev/null +++ b/src/app/utils/TimeUtils.ts @@ -0,0 +1,203 @@ +// Copyright (C) 2024 bitfly explorer GmbH +// +// This file is part of Beaconchain Dashboard. +// +// Beaconchain Dashboard is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Beaconchain Dashboard is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Beaconchain Dashboard. If not, see . + +import { DateTime, type StringUnitLength } from 'luxon' +import { findChainNetworkById } from './NetworkData' + +export type AgeFormat = 'absolute' | 'relative' + +export const ONE_MINUTE = 60 +export const ONE_HOUR = ONE_MINUTE * 60 +export const ONE_DAY = ONE_HOUR * 24 +export const ONE_WEEK = ONE_DAY * 7 +export const ONE_YEAR = ONE_DAY * 365 + +export function epochToTimestamp(chainID: number, epoch: number) { + const network = findChainNetworkById(chainID) + return (network.genesisTs + epoch * network.slotPerEpoch * network.slotsTime) * 1000 +} + +export function timestampToEpoch(chainID: number, ts: number) { + const network = findChainNetworkById(chainID) + return Math.floor((ts / 1000 - network.genesisTs) / network.slotPerEpoch / network.slotsTime) +} + +export function timestampToSlot(chainID: number, ts: number) { + const network = findChainNetworkById(chainID) + return Math.floor((ts / 1000 - network.genesisTs) / network.slotsTime) +} + +export function timeUntilNextSlot(chainID: number, ts: number) { + const slot = timestampToSlot(chainID, ts) + const nextSlot = slot + 1 + const nextSlotTs = slotToSecondsTimestamp(chainID, nextSlot) * 1000 + return nextSlotTs - ts +} + +export function slotToSecondsTimestamp(chainID: number, slot: number) { + const network = findChainNetworkById(chainID) + return network.genesisTs + slot * network.slotsTime +} + +export function getLocale() { + return navigator.languages && navigator.languages.length ? navigator.languages[0] : navigator.language +} + +export function formatTsToDateTime(ts: number, locales: string): string { + const options: Intl.DateTimeFormatOptions = { + month: 'short', + day: 'numeric', + year: 'numeric', + hour: 'numeric', + minute: 'numeric', + } + + const date = new Date(ts * 1000) + return date.toLocaleDateString(locales, options) +} + +export function formatTsToTime(ts: number, locales: string): string { + const options: Intl.DateTimeFormatOptions = { + hour: 'numeric', + minute: 'numeric', + } + const date = new Date(ts * 1000) + return date.toLocaleTimeString(locales, options) +} + +export function toDateTime(secs: number): Date { + if (secs > 100000000000) secs /= 1000000000 // backwards compatibility, server returned nanoseconds pre v2 launch, can be removed later + const t = new Date(1970, 0, 1) + t.setSeconds(secs) + return t +} + +export function getEndTs(aggregation: string, startTs: number): number { + if (!startTs) { + return + } + switch (aggregation) { + case 'epoch': + return + case 'hourly': + return startTs + ONE_HOUR + case 'weekly': + return startTs + ONE_WEEK + case 'daily': + default: + return startTs + ONE_DAY + } +} + +export function formatGoTimestamp( + timestamp: string | number, + compareTimestamp?: number, + format?: AgeFormat, + style?: StringUnitLength, + locales?: string, + withTime?: boolean +) { + if (typeof timestamp === 'number') { + timestamp *= 1000 + } + const dateTime = new Date(timestamp).getTime() + return formatTs(dateTime / 1000, compareTimestamp, format, style, locales, withTime) +} + +function formatTs( + ts?: number, + timestamp?: number, + format: AgeFormat = 'relative', + style: StringUnitLength = 'narrow', + locales: string = 'en-US', + withTime = true +) { + if (ts === undefined) { + return undefined + } + + if (format === 'relative') { + return formatTsToRelative(ts * 1000, timestamp, style, locales) + } else { + return formatTsToAbsolute(ts, locales, withTime) + } +} + +export function formatTsToRelative( + targetTimestamp?: number, + baseTimestamp?: number, + style: StringUnitLength = 'narrow', + locales: string = 'en-US' +): string | null | undefined { + if (!targetTimestamp) { + return undefined + } + + const date = baseTimestamp ? DateTime.fromMillis(baseTimestamp) : DateTime.now() + return DateTime.fromMillis(targetTimestamp).setLocale(locales).toRelative({ base: date, style }) +} + +export function formatTsToAbsolute(ts: number, locales: string, includeTime?: boolean): string { + const timeOptions: Intl.DateTimeFormatOptions = includeTime ? { hour: 'numeric', minute: 'numeric' } : {} + const options: Intl.DateTimeFormatOptions = { + month: 'short', + day: 'numeric', + year: 'numeric', + ...timeOptions, + } + const date = new Date(ts * 1000) + return includeTime ? date.toLocaleString(locales, options) : date.toLocaleDateString(locales, options) +} + +export function relativeTs(seconds: number) { + const minutes = Math.floor(seconds / 60) + const hours = Math.floor(minutes / 60) + const days = Math.floor(hours / 24) + + if (days > 0) { + return days > 1 ? `${days} days` : 'day' + } else if (hours > 0) { + return hours > 1 ? `${hours} hours` : 'hour' + } else if (minutes > 0) { + return minutes > 1 ? `${minutes} minutes` : 'minute' + } else { + return seconds > 1 ? `${seconds} seconds` : 'second' + } +} + +export function shortTimeFormatLocale(): string { + const lang = getLang() + if (lang === 'en-US') { + return 'M/d/yy, h:mm a' + } + return 'dd.MM.yyyy, hh:mm' +} + +function getLang() { + if (navigator.languages != undefined) return navigator.languages[0] + return navigator.language +} + +export function formatMonthShort(month: number): string { + const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] + return months[month] +} + +export function formatMonthLong(month: number): string { + const months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'] + return months[month] +} diff --git a/src/app/utils/V2Migrator.spec.ts b/src/app/utils/V2Migrator.spec.ts new file mode 100644 index 00000000..58b97acb --- /dev/null +++ b/src/app/utils/V2Migrator.spec.ts @@ -0,0 +1,201 @@ +/// +import V2Migrator from '@utils/V2Migrator' + +describe('V2Migrator', () => { + let migrator: V2Migrator + let mockApi: any + let mockStorage: any + let mockValidatorUtils: any + let mockDashboardUtils: any + let mockAlert: any + let mockMerchant: any + + beforeEach(() => { + mockApi = { + loadNetworkConfig: vi.fn().mockResolvedValue(undefined), + refreshToken: vi.fn().mockResolvedValue(true), + getLatestState: vi.fn().mockResolvedValue(undefined), + execute: vi.fn(), + initialize: vi.fn().mockResolvedValue(undefined), + } + mockStorage = { + setV2: vi.fn().mockResolvedValue(undefined), + getBooleanSetting: vi.fn().mockResolvedValue(false), + setBooleanSetting: vi.fn().mockResolvedValue(undefined), + getAuthUser: vi.fn().mockResolvedValue(null), + isV2: vi.fn().mockResolvedValue(false), + getAuthUserv2: vi.fn().mockResolvedValue(null), + setAuthUser: vi.fn().mockResolvedValue(undefined), + setAuthUserv2: vi.fn().mockResolvedValue(undefined), + getDeviceID: vi.fn().mockResolvedValue('device123'), + getDeviceName: vi.fn().mockResolvedValue('MyDevice'), + } + mockValidatorUtils = { + wasStakeShareUser: vi.fn().mockResolvedValue(false), + getMyLocalValidators: vi.fn().mockResolvedValue([]), + } + mockDashboardUtils = { + initDashboard: vi.fn().mockResolvedValue(undefined), + addValidators: vi.fn().mockResolvedValue(true), + } + mockAlert = { + showInfo: vi.fn(), + presentLoading: vi.fn().mockReturnValue({ + present: vi.fn(), + dismiss: vi.fn(), + }), + noChoiceDialog: vi.fn(), + } + mockMerchant = { + restartApp: vi.fn(), + } + + migrator = new V2Migrator(mockApi, mockStorage, mockValidatorUtils, mockDashboardUtils, mockAlert, mockMerchant) + }) + + describe('switchToV2', () => { + it('should set V2 flag and load network config', async () => { + await migrator.switchToV2(true) + expect(mockStorage.setV2).toHaveBeenCalledWith(true) + expect(mockApi.loadNetworkConfig).toHaveBeenCalled() + }) + }) + + describe('showDeprecationNotice', () => { + it('should do nothing if deprecation notice already seen', async () => { + mockStorage.getBooleanSetting.mockResolvedValueOnce(true) + await migrator.showDeprecationNotice() + expect(mockStorage.getBooleanSetting).toHaveBeenCalledWith('deprecation_info_seen', false) + // showInfo should not be called if notice was already seen + expect(mockAlert.showInfo).not.toHaveBeenCalled() + }) + + it('should not show notice if not a stake share user', async () => { + mockStorage.getBooleanSetting.mockResolvedValueOnce(false) + mockValidatorUtils.wasStakeShareUser.mockResolvedValueOnce(false) + await migrator.showDeprecationNotice() + expect(mockStorage.setBooleanSetting).toHaveBeenCalledWith('deprecation_info_seen', true) + expect(mockAlert.showInfo).not.toHaveBeenCalled() + }) + + it('should show deprecation notice if stake share user', async () => { + mockStorage.getBooleanSetting.mockResolvedValueOnce(false) + mockValidatorUtils.wasStakeShareUser.mockResolvedValueOnce(true) + await migrator.showDeprecationNotice() + expect(mockStorage.setBooleanSetting).toHaveBeenCalledWith('deprecation_info_seen', true) + expect(mockAlert.showInfo).toHaveBeenCalledWith('Deprecation Notice', expect.stringContaining('Stake Share')) + }) + }) + + describe('migrate', () => { + it('should do nothing if migration already completed', async () => { + // Simulate that migration is already completed. + mockStorage.getBooleanSetting.mockResolvedValueOnce(true) + await migrator.migrate() + // Expect no migration actions to be performed. + expect(mockApi.refreshToken).not.toHaveBeenCalled() + // We assume that if migration is completed, setBooleanSetting for migration_completed is not re‑set. + expect(mockStorage.setBooleanSetting).not.toHaveBeenCalledWith('migration_completed', true) + }) + + it('should switch to v2 and mark migration completed if nothing to migrate', async () => { + // Simulate no v1 dashboards and no v1 user. + mockValidatorUtils.getMyLocalValidators.mockResolvedValueOnce([]) + mockStorage.getAuthUser.mockResolvedValueOnce(null) + // Simulate migration not completed. + mockStorage.getBooleanSetting.mockResolvedValueOnce(false) + await migrator.migrate() + // Expect switchToV2 to be called internally. + expect(mockStorage.setV2).toHaveBeenCalledWith(true) + // Migration flag should be set. + expect(mockStorage.setBooleanSetting).toHaveBeenCalledWith('migration_completed', true) + }) + + it('should perform migration when v1 user or dashboards are found', async () => { + // Simulate that v1 dashboards exist. + mockValidatorUtils.getMyLocalValidators.mockResolvedValueOnce([{ id: 1 }]) + // Simulate that a v1 user is found. + mockStorage.getAuthUser.mockResolvedValueOnce({ accessToken: 'token', refreshToken: 'rToken' }) + // Ensure migration is not already completed. + mockStorage.getBooleanSetting.mockResolvedValueOnce(false) + // Simulate that we're not on v2. + mockStorage.isV2.mockResolvedValueOnce(false) + // Simulate refresh token failing so that user gets logged out. + mockApi.refreshToken.mockResolvedValueOnce(false) + // Simulate v1SessionToV2 failing. + vi.spyOn(migrator as any, 'v1SessionToV2').mockResolvedValue(false) + // Simulate dashboard migration failure. + mockDashboardUtils.addValidators.mockResolvedValueOnce(false) + // Simulate that v2 user is not present. + mockStorage.getAuthUserv2.mockResolvedValueOnce(null) + + await migrator.migrate() + + // Expect that switchToV2 is called to switch to v2. + expect(mockStorage.setV2).toHaveBeenCalledWith(true) + // Expect that api.getLatestState is called with true. + expect(mockApi.getLatestState).toHaveBeenCalledWith(true) + // Expect that the v1 session is cleared. + expect(mockStorage.setAuthUser).toHaveBeenCalledWith(null) + // Verify that a dialog is shown. + expect(mockAlert.noChoiceDialog).toHaveBeenCalled() + // Simulate the dialog callback execution. + const dialogCallback = (mockAlert.noChoiceDialog as vi.Mock).mock.calls[0][2] + dialogCallback() + expect(mockMerchant.restartApp).toHaveBeenCalled() + // Finally, the migration_completed flag should be set. + expect(mockStorage.setBooleanSetting).toHaveBeenCalledWith('migration_completed', true) + }) + }) + + describe('isMigrationCompleted', () => { + it('should return the migration completed status from storage', async () => { + mockStorage.getBooleanSetting.mockResolvedValueOnce(true) + const result = await migrator.isMigrationCompleted() + expect(result).toBe(true) + expect(mockStorage.getBooleanSetting).toHaveBeenCalledWith('migration_completed', false) + }) + }) + + describe('v1SessionToV2', () => { + // Test v1SessionToV2 by accessing it via bracket notation. + it('should return false if no user is found', async () => { + mockStorage.getAuthUser.mockResolvedValueOnce(null) + const result = await (migrator as any).v1SessionToV2() + expect(result).toBe(false) + }) + + it('should return false if user has no refreshToken', async () => { + mockStorage.getAuthUser.mockResolvedValueOnce({ accessToken: 'token' }) + const result = await (migrator as any).v1SessionToV2() + expect(result).toBe(false) + }) + + it('should return false if api.execute returns error', async () => { + const user = { accessToken: 'token', refreshToken: 'rToken' } + mockStorage.getAuthUser.mockResolvedValueOnce(user) + mockApi.execute.mockResolvedValueOnce({ error: true }) + const result = await (migrator as any).v1SessionToV2() + expect(result).toBe(false) + }) + + it('should return false if no session is found in api.execute response', async () => { + const user = { accessToken: 'token', refreshToken: 'rToken' } + mockStorage.getAuthUser.mockResolvedValueOnce(user) + mockApi.execute.mockResolvedValueOnce({ data: {} }) + const result = await (migrator as any).v1SessionToV2() + expect(result).toBe(false) + }) + + it('should migrate successfully if api.execute returns a valid session', async () => { + const user = { accessToken: 'token', refreshToken: 'rToken' } + const sessionData = { Session: { token: 'v2Token' } } + mockStorage.getAuthUser.mockResolvedValueOnce(user) + mockApi.execute.mockResolvedValueOnce({ data: sessionData }) + const result = await (migrator as any).v1SessionToV2() + expect(result).toBe(true) + expect(mockStorage.setAuthUserv2).toHaveBeenCalledWith({ Session: sessionData.Session }) + expect(mockApi.initialize).toHaveBeenCalled() + }) + }) +}) diff --git a/src/app/utils/V2Migrator.ts b/src/app/utils/V2Migrator.ts new file mode 100644 index 00000000..74fc496a --- /dev/null +++ b/src/app/utils/V2Migrator.ts @@ -0,0 +1,217 @@ +// Copyright (C) 2021 bitfly explorer GmbH +// Copyright (C) 2021 bitfly explorer GmbH +// +// This file is part of Beaconchain Dashboard. +// +// Beaconchain Dashboard is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Beaconchain Dashboard is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Beaconchain Dashboard. If not, see . + +import { ApiService } from '@services/api.service' +import { Injectable } from '@angular/core' +import { StorageService } from '@services/storage.service' +import { MigrateV1AuthToV2 } from '@requests/v2-auth' +import * as StorageTypes from '../models/StorageTypes' +import { ValidatorUtils } from './ValidatorUtils' +import { DashboardUtils } from './DashboardUtils' +import { AlertService } from '@services/alert.service' +import { MerchantUtils } from './MerchantUtils' + +const SETTING_MIGRATION_COMPLETED = 'migration_completed' + +@Injectable({ + providedIn: 'root', +}) +export default class V2Migrator { + constructor( + private api: ApiService, + private storage: StorageService, + private validatorUtils: ValidatorUtils, + private dashboardUtils: DashboardUtils, + private alert: AlertService, + private merchant: MerchantUtils + ) {} + + async switchToV2(useV2: boolean) { + await this.storage.setV2(useV2) + await this.api.loadNetworkConfig() + } + + async showDeprecationNotice() { + const deprecationNoiceKey = 'deprecation_info_seen' + if (await this.storage.getBooleanSetting(deprecationNoiceKey, false)) { + return + } + this.storage.setBooleanSetting(deprecationNoiceKey, true) + + let deprecationList = '' + const stakeShareUser = await this.validatorUtils.wasStakeShareUser() + + if (!stakeShareUser) { + return + } + + if (stakeShareUser) { + deprecationList += `

- Stake Share, the partial validator ownership feature, has been removed. + We value your privacy and specifically made this app without any trackers, but this also means that we have no insight into how much this feature was actually used. + We rely on your feedback, so please let us know if you miss this feature and whether we should spend our resources on bringing it back.` + } + + this.alert.showInfo( + 'Deprecation Notice', + `Thank you for using Beaconchain Dashboard, we hope you enjoy the update!

+ Unfortunately, some features of the old app version did not make it to the new version:` + deprecationList + ) + } + + async migrate() { + // TODO migrate other networks as well + if (await this.storage.getBooleanSetting(SETTING_MIGRATION_COMPLETED, false)) { + return + } + + let v1UserFound = false + let v1DashboardsFound = false + + // Pre-Stage 1: check if we have local v1 dashboards + const localValidatorIndex = await this.validatorUtils.getMyLocalValidators() + if (localValidatorIndex.length > 0) { + console.log('migrator, found local validators', localValidatorIndex) + v1DashboardsFound = true + } + + // Pre-Stage 2: check if we have a v1 user session + const v1User = await this.storage.getAuthUser() + if (v1User && v1User.accessToken) { + v1UserFound = true + } + + // early exit, nothing to migrate + if (!v1DashboardsFound && !v1UserFound) { + console.info('migrator, nothing to migrate') + await this.switchToV2(true) + await this.storage.setBooleanSetting(SETTING_MIGRATION_COMPLETED, true) + return + } + + // ----- Actual migration ----- + + let userHasBeenLoggedOut = false + let notAllValidatorsMigrated = false + + const loading = await this.alert.presentLoading('Updating app...') + loading.present() + + // -- Happens on v1 api -- + + // Stage 1: Start at v1 api, check if user is present, try to refresh token and switch to v2 + // or just switch to v2 + if (!(await this.storage.isV2())) { + console.log('migrator, not on v2 api, running v1 checks') + if (v1UserFound) { + console.log('migrator, v1 user found, refreshing token') + const result = await this.api.refreshToken() + if (!result) { + console.warn('migrator, could refresh v1 session, logging user out', result) + userHasBeenLoggedOut = true + } + } + } + + // -- Happens on v2 api -- + await this.switchToV2(true) + await this.api.getLatestState(true) // get csrf token + console.log('migrator, switched to v2 api') + + // Stage 2: migrate v1 user session to v2 user session + const v2User = await this.storage.getAuthUserv2() + if (v1UserFound && !v2User && !v2User?.Session) { + console.log('migrator, unmigrated v1 session found, migrating to v2') + const sessionMigrated = await this.v1SessionToV2() + if (!sessionMigrated) { + console.warn('migrator, could not migrate v1 session to v2, logging user out') + userHasBeenLoggedOut = true + } + } + this.storage.setAuthUser(null) + + // Stage 3: migrate v1 dashboards to v2 dashboards + if (v1DashboardsFound) { + console.log('migrator, v1 dashboards found, migrating to v2') + // init dashboards: load dashboards or create a default one if not present + await this.dashboardUtils.initDashboard() + + // adds v1 validators to v2 dashboard + // note: if user has more validators than free limit, we add the first 20 validators + // todo: do I need to truncate or does the api? todo: correctly set notAllValidatorsMigrated + const ok = await this.dashboardUtils.addValidators(localValidatorIndex, 0) + if (!ok) { + console.warn('migrator, not all validators or none could be migrated') + notAllValidatorsMigrated = true + } + } + + loading.dismiss() + + let additional = '' + if (userHasBeenLoggedOut || notAllValidatorsMigrated) { + additional += '

Some data could not be migrated:' + } + if (userHasBeenLoggedOut) { + additional += '

- You have been logged out.' + } + if (notAllValidatorsMigrated) { + additional += `

- We couldn't take all your validators with us. You'll find a full backup of your validators in the new 'Manage Dashboards' section.` + } + + this.alert.noChoiceDialog('Update Completed', 'The app will restart itself.' + additional, () => { + this.merchant.restartApp() + }) + + console.info('migrator, migration completed') + this.storage.setBooleanSetting(SETTING_MIGRATION_COMPLETED, true) + } + + isMigrationCompleted() { + return this.storage.getBooleanSetting(SETTING_MIGRATION_COMPLETED, false) + } + + private async v1SessionToV2() { + const user = await this.storage.getAuthUser() + if (!user || !user.refreshToken) { + console.warn('migrator, no refreshtoken, cannot refresh token') + return false + } + + const loginRequest = new MigrateV1AuthToV2(user.refreshToken, await this.storage.getDeviceID(), await this.storage.getDeviceName()) + const result = await this.api.execute(loginRequest) + console.log('migrator, v1SessionToV2 eq exchange', result) // todo remove + + if (result.error) { + console.warn('migrator, invalid response', result) + return false + } + + if (!result.data.Session) { + console.warn('migrator, no session found', result) + return false + } + + await this.storage.setAuthUserv2({ + Session: result.data.Session, + } as StorageTypes.AuthUserv2) + await this.api.initialize() + console.info('migrator, v1 session successfully migrated to v2') + + return true + } +} diff --git a/src/app/utils/ValidatorSyncUtils.ts b/src/app/utils/ValidatorSyncUtils.ts deleted file mode 100644 index a3c5870f..00000000 --- a/src/app/utils/ValidatorSyncUtils.ts +++ /dev/null @@ -1,226 +0,0 @@ -/* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) - * // - * // This file is part of Beaconchain Dashboard. - * // - * // Beaconchain Dashboard is free software: you can redistribute it and/or modify - * // it under the terms of the GNU General Public License as published by - * // the Free Software Foundation, either version 3 of the License, or - * // (at your option) any later version. - * // - * // Beaconchain Dashboard is distributed in the hope that it will be useful, - * // but WITHOUT ANY WARRANTY; without even the implied warranty of - * // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * // GNU General Public License for more details. - * // - * // You should have received a copy of the GNU General Public License - * // along with Beaconchain Dashboard. If not, see . - */ - -import { ApiService } from '../services/api.service' -import { StorageService, StoredTimestamp } from '../services/storage.service' -import { Injectable } from '@angular/core' -import { MyValidatorResponse, AddMyValidatorsRequest } from '../requests/requests' -import { Mutex } from 'async-mutex' -import { ValidatorUtils, LAST_TIME_ADDED_KEY, LAST_TIME_REMOVED_KEY } from './ValidatorUtils' - -const LAST_TIME_UPSYNCED_KEY = 'last_time_upsynced' -const LAST_TIME_UPDELETED_KEY = 'last_time_updeleted' - -@Injectable({ - providedIn: 'root', -}) -export class ValidatorSyncUtils { - constructor(private validator: ValidatorUtils, private storage: StorageService, private api: ApiService) {} - - public async mightSyncUpAndSyncDelete(syncNotificationsForNewValidators: () => void) { - this.mayDeleteUp() - await this.maySyncUp(syncNotificationsForNewValidators) - } - - // Use only when you really need to sync both ways - // Otherwise use syncDown or maySyncUp - public async fullSync(syncNotificationsForNewValidators: () => void) { - await this.syncDown() - await this.mightSyncUpAndSyncDelete(syncNotificationsForNewValidators) - } - - public async syncDown() { - const loggedIn = await this.storage.isLoggedIn() - if (!loggedIn) return - console.log('[SYNC] syncing down') - - const myRemotes = await this.validator.getMyRemoteValidators() - if (!myRemotes || myRemotes.length <= 0) return - - const newValidatorIndizes = await this.validator.getAllNewIndicesOnly(myRemotes) - console.log('newValidatorIndizes', newValidatorIndizes) - - this.syncRemoteRemovals(myRemotes) - - if (newValidatorIndizes.length <= 0) { - this.validator.notifyListeners() - return - } - - const newValidators = await this.validator.getRemoteValidatorInfo(...newValidatorIndizes).catch((err) => { - console.warn('error in syncDown getRemoteValidatorInfo', err) - return null - }) - if (newValidators == null) return - - this.validator.convertToValidatorModelsAndSaveLocal(true, newValidators) - } - - private upSyncLastTry = 0 - - private async maySyncUp(syncNotificationsForNewValidators: () => void) { - const loggedIn = await this.storage.isLoggedIn() - if (!loggedIn) return - - if (this.upSyncLastTry + 2 * 60 * 1000 > Date.now()) { - console.log('maySyncUp canceled, last try was under 2minutes ago') - return - } - - const lastTimeUpSynced = (await this.storage.getObject(LAST_TIME_UPSYNCED_KEY)) as StoredTimestamp - - // Upload only when new validators were added locally - const lastTimeAdded = (await this.storage.getObject(LAST_TIME_ADDED_KEY)) as StoredTimestamp - if (lastTimeAdded && (!lastTimeUpSynced || lastTimeAdded.timestamp > lastTimeUpSynced.timestamp)) { - this.upSyncLastTry = Date.now() - const success = await this.syncUp(syncNotificationsForNewValidators) - if (success) { - this.storage.setObject(LAST_TIME_UPSYNCED_KEY, { timestamp: Date.now() } as StoredTimestamp) - } - } - } - - private upDeleteSyncLastTry = 0 - private deleteSyncLock = new Mutex() - private async mayDeleteUp() { - const loggedIn = await this.storage.isLoggedIn() - if (!loggedIn) return - - if (this.upDeleteSyncLastTry + 5 * 60 * 1000 > Date.now()) { - console.log('mayDeleteUp canceled, last try was under 2minutes ago') - return - } - - if (this.deleteSyncLock.isLocked()) { - console.log('delete sync already locked by other async chain') - return - } - - const lastTimeUpDeleted = (await this.storage.getObject(LAST_TIME_UPDELETED_KEY)) as StoredTimestamp - const lastTimeRemoved = (await this.storage.getObject(LAST_TIME_REMOVED_KEY)) as StoredTimestamp - - console.log('mayDeleteUp', lastTimeRemoved, lastTimeUpDeleted) - - if (lastTimeRemoved && (!lastTimeUpDeleted || lastTimeRemoved.timestamp > lastTimeUpDeleted.timestamp)) { - console.log('Starting deleteUp') - const unlock = await this.deleteSyncLock.acquire() - const success = await this.deleteUp() - unlock() - if (success) { - this.validator.clearDeletedSet() - this.storage.setObject(LAST_TIME_UPDELETED_KEY, { timestamp: Date.now() }) - } - } else { - this.validator.clearDeletedSet() - } - } - - private async deleteUp(): Promise { - const storageKey = this.validator.getStorageKey() - const deletedSet = await this.validator.getDeletedSet(storageKey) - - console.log('delete queue', deletedSet) - if (deletedSet.size <= 0) return true - this.upDeleteSyncLastTry = Date.now() - console.log('== starting delete sync queue ==') - - let count = 0 - let finished = true - for (const value of deletedSet) { - const success = await this.validator.removeValidatorRemote(value.toString()) - if (success) { - console.log('== deleted ' + value + ' ==') - count++ - - const temp = await this.validator.getDeletedSet(storageKey) - temp.delete(value) - this.validator.setDeleteSet(storageKey, temp) - - await this.delay(10000 + (count > 3 ? 15000 : 0)) - } else { - console.log('== failed to delete ' + value + ' ==') - finished = false - await this.delay(35000) - } - } - - return finished - } - - private delay(ms: number) { - return new Promise((resolve) => setTimeout(resolve, ms)) - } - - private async syncUp(syncNotificationsForNewValidators: () => void) { - console.log('[SYNC] syncing up') - - const storageKey = this.validator.getStorageKey() - const current = await this.validator.getMap(storageKey) - - const syncUpList: string[] = [] - current.forEach((validator) => { - if (!validator.synced) syncUpList.push(validator.index + '') - }) - - if (syncUpList.length <= 0) return true - const success = await this.addValidatorsRemote(syncUpList) - - if (success) { - syncNotificationsForNewValidators() - - current.forEach((validator) => { - if (!validator.synced) validator.synced = true - }) - } - - await this.storage.setObject(storageKey, current) - return success - } - - private async syncRemoteRemovals(myRemotes: MyValidatorResponse[]) { - const storageKey = this.validator.getStorageKey() - const current = await this.validator.getMap(storageKey) - - const existsSynced: Set = new Set() - myRemotes.forEach((remote) => { - if (current.has(remote.PubKey)) { - existsSynced.add(remote.PubKey) - } - }) - console.log('syncRemoteRemovals existsSynced', existsSynced) - - current.forEach((oldValidator) => { - if (!existsSynced.has(oldValidator.pubkey) && oldValidator.synced) { - console.log('syncRemoteRemovals remove', oldValidator) - current.delete(oldValidator.pubkey) - } - }) - - await this.storage.setObject(storageKey, current) - } - - private async addValidatorsRemote(indices: string[]): Promise { - const request = new AddMyValidatorsRequest(indices) - const response = await this.api.execute(request) - const result = request.parse(response) - console.log('add validators remote', response, result) - return request.wasSuccessful(response) - } -} diff --git a/src/app/utils/ValidatorUtils.ts b/src/app/utils/ValidatorUtils.ts index eac75edb..a3f87222 100644 --- a/src/app/utils/ValidatorUtils.ts +++ b/src/app/utils/ValidatorUtils.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -18,49 +17,31 @@ * // along with Beaconchain Dashboard. If not, see . */ -import { ApiService } from '../services/api.service' -import { StorageService, StoredShare, StoredTimestamp } from '../services/storage.service' +import { ApiService } from '@services/api.service' +import { StorageService, StoredShare } from '@services/storage.service' import { Injectable } from '@angular/core' -import { - EpochResponse, - RemoveMyValidatorsRequest, - AttestationPerformanceResponse, - ValidatorRequest, - ValidatorResponse, - GetMyValidatorsRequest, - MyValidatorResponse, - DashboardRequest, - RocketPoolResponse, - RocketPoolNetworkStats, - ExecutionResponse, - SyncCommitteeResponse, - ETH1ValidatorResponse, - SyncCommitteesStatisticsResponse, - ProposalLuckResponse, - ValidatorViaDepositAddress, - ValidatorViaWithdrawalAddress, -} from '../requests/requests' -import { MerchantUtils } from './MerchantUtils' import BigNumber from 'bignumber.js' -import { UnitconvService } from '../services/unitconv.service' +import { UnitconvService } from '@services/unitconv.service' +import { VDBManageValidatorsTableRow } from '@requests/types/validator_dashboard' export const SAVED = 0 // stored locally export const MEMORY = 1 // Search results etc -const VERSION = 1 - const KEYPREFIX = 'validators_' export const LAST_TIME_ADDED_KEY = 'last_time_added' export const LAST_TIME_REMOVED_KEY = 'last_time_removed' export enum ValidatorState { - ACTIVE, - OFFLINE, - SLASHED, - WAITING, - ELIGABLE, - EXITED, - UNKNOWN, + SLASHED = 'slashed', + EXITED = 'exited', + DEPOSITED = 'deposited', + PENDING = 'pending', + SLASHING_ONLINE = 'slashing_online', + SLASHING_OFFLINE = 'slashing_offline', + EXITING_ONLINE = 'exiting_online', + EXITING_OFFLINE = 'exiting_offline', + ACTIVE_ONLINE = 'active_online', + ACTIVE_OFFLINE = 'active_offline', } export interface Validator { @@ -70,77 +51,47 @@ export interface Validator { storage: typeof SAVED | typeof MEMORY synced: boolean version: number - data: ValidatorResponse + // state: ValidatorState attrEffectiveness: number - rocketpool: RocketPoolResponse - execution: ExecutionResponse share: number rplshare: number execshare: number - currentSyncCommittee: SyncCommitteeResponse - nextSyncCommittee: SyncCommitteeResponse } @Injectable({ providedIn: 'root', }) export class ValidatorUtils { - private listeners: (() => void)[] = [] - - private currentEpoch: EpochResponse - private olderEpoch: EpochResponse - rocketpoolStats: RocketPoolNetworkStats - syncCommitteesStatsResponse: SyncCommitteesStatisticsResponse - proposalLuckResponse: ProposalLuckResponse - constructor( private api: ApiService, private storage: StorageService, - private merchantUtils: MerchantUtils, private unitConversion: UnitconvService ) {} - notifyListeners() { - this.listeners.forEach((callback) => callback()) - } - - registerListener(listener: () => void) { - this.listeners.push(listener) - } - - async hasLocalValdiators() { - return (await this.getMap(this.getStorageKey())).size > 0 - } - + /**@deprecated */ async localValidatorCount() { return (await this.getMap(this.getStorageKey())).size } + /**@deprecated */ public getStorageKey(): string { return KEYPREFIX + this.api.getNetworkName() } - async migrateTo3Dot2() { - const share = await this.storage.getStakingShare() - const valis = await this.getAllValidatorsLocal() - if (valis) { - for (let i = 0; i < valis.length; i++) { - if (share) { - valis[i].share = share.toNumber() - } - } - this.saveValidatorsLocal(valis) - } - } - + /** + * @deprecated replaced in v2 with new v2 storage object + */ public async getMap(storageKey: string): Promise> { const erg = await this.storage.getObject(storageKey) if (erg && erg instanceof Map) return erg return new Map() } - private async getMapWithoutDeleted(storageKey): Promise> { + /** + * @deprecated with v2 we don't need complex syncing logic any more + */ + private async getMapWithoutDeleted(storageKey: string): Promise> { const local = await this.getMap(storageKey) const deleted = await this.getDeletedSet(storageKey) if (await this.storage.isLoggedIn()) { @@ -151,24 +102,25 @@ export class ValidatorUtils { return local } + /**@deprecated */ public async getDeletedSet(storageKey: string): Promise> { const erg = await this.storage.getObject(storageKey + '_deleted') if (erg && Array.isArray(erg)) return new Set(erg) return new Set() } + /**@deprecated */ public async setDeleteSet(storageKey: string, list: Set) { if (!(await this.storage.isLoggedIn())) return this.storage.setObject(storageKey + '_deleted', [...list]) } - clearDeletedSet() { - const storageKey = this.getStorageKey() - this.setDeleteSet(storageKey, new Set()) - } - - async deleteAll() { - const storageKey = this.getStorageKey() + /**@deprecated */ + async deleteAll(networkName: string = undefined) { + let storageKey = this.getStorageKey() + if (networkName) { + storageKey = KEYPREFIX + networkName + } const current = await this.getMap(storageKey) this.storage.setObject(storageKey, new Map()) @@ -180,467 +132,88 @@ export class ValidatorUtils { this.setDeleteSet(storageKey, deletedList) this.storage.setObject(LAST_TIME_REMOVED_KEY, { timestamp: Date.now() }) - this.notifyListeners() - } - - private deletedWithoutNotifying: boolean = false - - async deleteValidatorLocal(validator: ValidatorResponse, notifyListeners: boolean = true) { - const storageKey = this.getStorageKey() - const current = await this.getMap(storageKey) - current.delete(validator.pubkey) - this.storage.setObject(storageKey, current) - - const deletedList = await this.getDeletedSet(storageKey) - deletedList.add(validator.pubkey) - this.setDeleteSet(storageKey, deletedList) - console.log('delete set', deletedList) - - this.storage.setObject(LAST_TIME_REMOVED_KEY, { timestamp: Date.now() }) - if (notifyListeners) this.notifyListeners() - else this.deletedWithoutNotifying = true - } - - notifyListenersIfDeletedWithoutNotifying() { - if (this.deletedWithoutNotifying) { - this.notifyListeners() - this.deletedWithoutNotifying = false - } - } - - async saveValidatorsLocal(validators: Validator[]) { - const storageKey = this.getStorageKey() - - const current = await this.getMap(storageKey) - const newMap = new Map() - - validators.forEach((validator) => { - newMap.set(validator.pubkey, validator) - }) - - current.forEach((value, key) => { - if (!newMap.has(key)) newMap.set(key, value) - }) - - this.storage.setObject(storageKey, newMap) - this.notifyListeners() } + /**@deprecated */ async saveRocketpoolCollateralShare(nodeAddress: string, sharePercent: number) { await this.storage.setObject('rpl_share_' + nodeAddress, { share: sharePercent } as StoredShare) } + /**@deprecated */ async getRocketpoolCollateralShare(nodeAddress: string): Promise { const temp = (await this.storage.getObject('rpl_share_' + nodeAddress)) as StoredShare if (!temp) return null return temp.share } - async getValidatorLocal(pubkey: string): Promise { - const current = await this.getMapWithoutDeleted(this.getStorageKey()) - return current.get(pubkey) - } - - async getAllValidatorsLocal(): Promise { - const current = await this.getMap(this.getStorageKey()) + /**@deprecated */ + async getAllValidatorsLocal(networkName: string = undefined): Promise { + let storageKey = this.getStorageKey() + if (networkName) { + storageKey = KEYPREFIX + networkName + } + const current = await this.getMap(storageKey) const erg: Validator[] = [...current.values()] return erg } - async getLocalValidatorByIndex(index: number): Promise { - const localValidators = await this.getAllValidatorsLocal() - for (const vali of localValidators) { - if (vali.index == index) { - return vali - } + async getMyLocalValidators(networkName: string = undefined): Promise { + let storageKey = this.getStorageKey() + if (networkName) { + storageKey = KEYPREFIX + networkName } - return null - } - - async getAllMyValidators(): Promise { - const storageKey = this.getStorageKey() const local = await this.getMapWithoutDeleted(storageKey) if (local.size == 0) return [] - - const validatorString = getValidatorQueryString([...local.values()], 2000, (await this.merchantUtils.getCurrentPlanMaxValidator()) - 1) - - const remoteUpdatesPromise = this.getDashboardDataValidators(SAVED, validatorString).catch((err) => { - console.warn('error getAllMyValidators getDashboardDataValidators', err) - return [] + return [...local.values()].map((item) => item.index) + } + + async debugSetMyLocalValidators(networkName: string = undefined, validators: number[]) { + let storageKey = this.getStorageKey() + if (networkName) { + storageKey = KEYPREFIX + networkName + } + const mappedToValidators = validators.map((v) => { + return { + index: v, + pubkey: '', + name: '', + storage: SAVED, + synced: false, + version: 0, + data: null, + state: null, + attrEffectiveness: 0, + rocketpool: null, + execution: null, + share: 0, + rplshare: 0, + execshare: 0, + currentSyncCommittee: null, + nextSyncCommittee: null, + } as Validator }) - if (remoteUpdatesPromise == null) return null - - const remoteUpdates = await remoteUpdatesPromise - - remoteUpdates.forEach((item) => { - local.set(item.pubkey, item) + const map = new Map() + mappedToValidators.forEach((v) => { + map.set(v.index.toString(), v) }) - - // update local info - this.storage.setObject(storageKey, local) - - const result = [...local.values()] - - return result + await this.storage.setObject(storageKey, map) } - async areRocketpoolValidatorsSubscribed(): Promise { - const validators = await this.getAllMyValidators() - for (const v of validators) { - if (v.rocketpool) { - return true - } + async wasStakeShareUser() { + const hasStakeShareEnabled = async (network: string) => { + return !!(await this.getAllValidatorsLocal(network)).find((v) => { + return !!v.share || !!v.execshare || !!v.rplshare + }) } - return false - } - - updateValidatorStates(validators: Validator[]) { - validators.forEach((item) => { - item.state = this.getValidatorState(item) - }) - } - - // checks if remote validators are already known locally. - // If not, return all indizes of non locally known validators - public async getAllNewIndicesOnly(myRemotes: MyValidatorResponse[]): Promise { - const storageKey = this.getStorageKey() - const current = await this.getMap(storageKey) - - const result: number[] = [] - myRemotes.forEach((remote) => { - if (!current.has(remote.PubKey)) { - result.push(remote.Index) - } - }) - - return result - } - - getValidatorState(item: Validator): ValidatorState { - if (item.data.slashed) return ValidatorState.SLASHED - if (item.data.status == 'exited') return ValidatorState.EXITED - if (item.data.status == 'deposited') return ValidatorState.ELIGABLE - if (item.data.status == 'pending') return ValidatorState.WAITING - if (item.data.slashed == false && item.data.status.indexOf('online') > 0) { - return ValidatorState.ACTIVE - } - - // default case - return ValidatorState.OFFLINE - } - - public async removeValidatorRemote(pubKey: string) { - const request = new RemoveMyValidatorsRequest(pubKey) - const response = await this.api.execute(request).catch((error) => { - console.warn('error in removeValidatorRemote', error) - return false - }) - if (!response) return false - return request.wasSuccessful(response) - } - - async getMyRemoteValidators(): Promise { - const request = new GetMyValidatorsRequest() - const response = await this.api.execute(request) - const result = request.parse(response) - console.log('My remote validators', result, response) - return result - } - - private async getDashboardDataValidators(storage: 0 | 1, ...validators): Promise { - const request = new DashboardRequest(...validators) - const response = await this.api.execute(request) - if (!request.wasSuccessful(response)) { - if (response && response.data && response.data.status && response.data.status.indexOf('only a maximum of') >= 0) { - throw new Error(response.data.status) - } - this.api.clearSpecificCache(request) - return [] - } - - const result = request.parse(response)[0] - if (!result) { - console.warn('error getDashboardDataValidators', response, result) - return [] - } - - if (result.currentEpoch && result.currentEpoch.length > 0) { - this.currentEpoch = result.currentEpoch[0] - } else { - console.warn('no current epoch information!', result) - } - if (result.olderEpoch && result.olderEpoch.length > 0) { - this.olderEpoch = result.olderEpoch[0] - } else { - console.warn('no older epoch information!', result) - } - - if (result.rocketpool_network_stats && result.rocketpool_network_stats.length > 0) { - this.rocketpoolStats = result.rocketpool_network_stats[0] - } - const validatorEffectivenessResponse = result.effectiveness - const validatorsResponse = result.validators - - this.syncCommitteesStatsResponse = result.sync_committees_stats - this.proposalLuckResponse = result.proposal_luck_stats - - this.updateRplAndRethPrice() - - if (response.cached != true) { - await this.storage.setLastEpochRequestTime(Date.now()) - } else { - const lastCachedTime = await this.storage.getLastEpochRequestTime() - if (this.currentEpoch) { - this.currentEpoch.lastCachedTimestamp = lastCachedTime - } - } - - let local = null - if (storage == SAVED) { - local = await this.getMapWithoutDeleted(this.getStorageKey()) - } - - const temp = this.convertToValidatorModel({ synced: false, storage: storage, validatorResponse: validatorsResponse }) - this.updateValidatorStates(temp) - for (const vali of temp) { - vali.attrEffectiveness = this.findAttributionEffectiveness(validatorEffectivenessResponse, vali.index) - vali.rocketpool = this.findRocketpoolResponse(result.rocketpool_validators, vali.index) - vali.execution = this.findExecutionResponse(result.execution_performance, vali.index) - if (local) { - const found = local.get(vali.pubkey) - if (found) { - vali.share = found.share - vali.execshare = found.execshare == null || found.execshare == undefined ? found.share : found.execshare - } - } - if (vali.rocketpool) { - vali.rplshare = await this.getRocketpoolCollateralShare(vali.rocketpool.node_address) - } - - if (result.current_sync_committee && result.current_sync_committee.length >= 1) { - vali.currentSyncCommittee = this.findSyncCommitteeDuty(result.current_sync_committee[0], vali.index) - } - if (result.next_sync_committee && result.next_sync_committee.length >= 1) { - vali.nextSyncCommittee = this.findSyncCommitteeDuty(result.next_sync_committee[0], vali.index) - } - } - - return temp - } - - private findSyncCommitteeDuty(committee: SyncCommitteeResponse, index: number): SyncCommitteeResponse { - for (const vali of committee.validators) { - if (vali == index) { - return committee - } - } - return null + return (await hasStakeShareEnabled('main')) || (await hasStakeShareEnabled('holesky')) || (await hasStakeShareEnabled('gnosis')) } private updateRplAndRethPrice() { - if (!this.rocketpoolStats) return - this.unitConversion.setRPLPrice(new BigNumber(this.rocketpoolStats.rpl_price.toString())) - //this.unitConversion.setRETHPrice(new BigNumber(this.rocketpoolStats.reth_exchange_rate.toString())) - } - - private findExecutionResponse(list: ExecutionResponse[], index: number): ExecutionResponse { - if (list == null || list.length == 0) return null - for (const attr of list) { - if (attr.validatorindex == index) { - return attr - } - } - return null - } - - private findRocketpoolResponse(list: RocketPoolResponse[], index: number): RocketPoolResponse { - for (const attr of list) { - if (attr.index == index) { - return attr - } - } - return null - } - - private findAttributionEffectiveness(list: AttestationPerformanceResponse[], index: number): number { - for (const attr of list) { - if (attr.validatorindex == index && attr.attestation_efficiency) { - return new BigNumber(1).dividedBy(attr.attestation_efficiency).multipliedBy(100).decimalPlaces(1).toNumber() - } - } - return -1 - } - - getOlderEpoch(): EpochResponse { - return this.olderEpoch - } - - async getRemoteCurrentEpoch(): Promise { - const result = this.currentEpoch - if (result == null) { - await this.getAllMyValidators() - return this.currentEpoch - } - - return result - } - - async getRemoteValidatorInfo(...args: number[]): Promise { - if (!args || !args[0]) return [] - const request = new ValidatorRequest(...args) - const response = await this.api.execute(request) - if (request.wasSuccessful(response)) { - return request.parse(response) - } else { - return this.apiStatusHandler(response) - } - } - - async getRemoteValidatorViaETHAddress(arg: string, enforceMax = -1): Promise { - if (!arg) return [] - const viaDeposit = new ValidatorViaDepositAddress(arg) - const viaDepositPromise = this.api.execute(viaDeposit) - - const viaWithdrawal = new ValidatorViaWithdrawalAddress(arg) - const viaWithdrawalPromise = this.api.execute(viaWithdrawal) - - const response = await Promise.all([viaDepositPromise, viaWithdrawalPromise]) - let result: ETH1ValidatorResponse[] = [] - - for (const resp of response) { - if (viaDeposit.wasSuccessful(resp)) { - // since both results are identical we can use any of the requests for parsing - const temp = viaDeposit.parse(resp) - if (temp) { - if (result.length > 0) { - result = Array.from(new Map([...result, ...temp].map((item) => [item.validatorindex, item])).values()) - } else { - result = temp - } - } - } else { - return this.apiStatusHandler(response) - } - } - - const queryString = getValidatorQueryString(result, 2000, enforceMax) - return await this.getDashboardDataValidators(MEMORY, queryString) - } - - private async apiStatusHandler(response) { - if (response && response.data && response.data.status) { - return Promise.reject(new Error(response.data.status)) - } - return Promise.reject(new Error('Response is invalid')) - } - - // single - async convertToValidatorModelAndSaveValidatorLocal(synced: boolean, validator: ValidatorResponse) { - await this.convertToValidatorModelsAndSaveLocal(synced, [validator]) - } - - // multiple - async convertToValidatorModelsAndSaveLocal(synced: boolean, validator: ValidatorResponse[]) { - await this.saveValidatorsLocal(this.convertToValidatorModel({ synced, storage: SAVED, validatorResponse: validator })) - if (!synced) { - await this.storage.setObject(LAST_TIME_ADDED_KEY, { timestamp: Date.now() } as StoredTimestamp) - } - } - - private convertToValidatorModel({ - synced, - storage, - validatorResponse, - }: { - synced: boolean - storage: 0 | 1 - validatorResponse: ValidatorResponse[] - }): Validator[] { - const erg: Validator[] = [] - validatorResponse.forEach((validator) => { - const temp = { - index: validator.validatorindex, - pubkey: validator.pubkey, - name: this.getName(validator), - storage: storage, - synced: synced, - version: VERSION, - data: validator, - state: ValidatorState.UNKNOWN, - share: null, - rplshare: null, - } as Validator - - erg.push(temp) - }) - return erg + this.unitConversion.setRPLPrice(new BigNumber(''.toString())) // todo rpl price } - - async searchValidators(search: string): Promise { - const result = await this.getDashboardDataValidators(MEMORY, search).catch((err) => { - console.warn('error in searchValidators', err) - return null - }) - if (result == null) return [] - return result - } - - async searchValidatorsViaETHAddress(search: string, enforceMax = -1): Promise { - const result = await this.getRemoteValidatorViaETHAddress(search, enforceMax) - if (result == null) return [] - return result - } - - private getName(validator: ValidatorResponse): string { - if (!validator || !validator.name || validator.name.length <= 0) { - return 'Validator ' + validator.validatorindex - } else { - return validator.name - } - } -} - -export function getValidatorQueryString(validators: Validator[] | ETH1ValidatorResponse[], getParamMaxLimit: number, maxValLimit = -1) { - // Validator - let erg = '' - let count = 0 - validators.forEach((item) => { - let temp = '' - - if (item.validatorindex !== undefined && item.validatorindex != null) { - temp = item.validatorindex + ',' - } else if (item.index !== undefined && item.index != null) { - temp = item.index + ',' - } else if (item.pubkey !== undefined && item.pubkey != null) { - temp = item.pubkey + ',' - } else if (item.publickey !== undefined && item.publickey != null) { - temp = item.publickey + ',' - } - - const isNotMaxed = maxValLimit == -1 || count <= maxValLimit - const doesNotExceedGetMaxLimit = erg.length + temp.length < getParamMaxLimit - - if (isNotMaxed && doesNotExceedGetMaxLimit) { - erg += temp - count++ - } - }) - - if (erg.length > 1) { - return erg.substring(0, erg.length - 1) - } - - return erg } -export function getDisplayName(validator: Validator): string { - if (validator.name && validator.name.length >= 0) { - return validator.name - } - if (validator.data.name.length <= 0) { - return 'Validator ' + validator.data.validatorindex - } else { - return validator.data.name - } +export function getDisplayName(validator: VDBManageValidatorsTableRow): string { + return 'Validator ' + validator.index } diff --git a/src/cordova-plugin-purchase-wrapper.ts b/src/cordova-plugin-purchase-wrapper.ts new file mode 100644 index 00000000..78a3544a --- /dev/null +++ b/src/cordova-plugin-purchase-wrapper.ts @@ -0,0 +1,11 @@ +// src/cordova-plugin-purchase-wrapper.ts +// Import the default export from our ambient module. +import CdvPurchase from 'cordova-plugin-purchase' + +const cdvPurchase = (window as any).CdvPurchase as typeof CdvPurchase | undefined + +if (!cdvPurchase) { + console.warn('CdvPurchase global is not available. Ensure the plugin is loaded.') +} + +export default cdvPurchase diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts deleted file mode 100644 index f07b6642..00000000 --- a/src/environments/environment.prod.ts +++ /dev/null @@ -1,23 +0,0 @@ -/* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) - * // - * // This file is part of Beaconchain Dashboard. - * // - * // Beaconchain Dashboard is free software: you can redistribute it and/or modify - * // it under the terms of the GNU General Public License as published by - * // the Free Software Foundation, either version 3 of the License, or - * // (at your option) any later version. - * // - * // Beaconchain Dashboard is distributed in the hope that it will be useful, - * // but WITHOUT ANY WARRANTY; without even the implied warranty of - * // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * // GNU General Public License for more details. - * // - * // You should have received a copy of the GNU General Public License - * // along with Beaconchain Dashboard. If not, see . - */ - -export const environment = { - production: true, -} diff --git a/src/environments/environment.ts b/src/environments/environment.ts index 63cf605d..c4c3da99 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -24,6 +23,11 @@ export const environment = { production: false, + API_ACCESS_KEY: null as string, // Cloudflare API access key, needed for PROD builds(!). Available in Bitwarden "App Cloudflare Key" + mock_combine_machines: false, // Debug flag: Combines all machines when talking to the mock API into a single one - kind of a workaround, sometime in the future API mock should better mock this. Should be false in prod + debug_set_default_network: '', // Debug flag: change default network of the app. Defaults to eth mainnet unless set otherwise. Should be empty in prod + debug: false, // Debug flag: Enabled access to the developer menu. Should be false in prod(!) + dangerousCookiePassing: true, } /* diff --git a/src/global.scss b/src/global.scss index 5c368cbf..ec3e1c1f 100644 --- a/src/global.scss +++ b/src/global.scss @@ -1,6 +1,5 @@ /* - * // Copyright (C) 2020 - 2021 Bitfly GmbH - * // Manuel Caspari (manuel@bitfly.at) + * // Copyright (C) 2020 - 2024 bitfly explorer GmbH * // * // This file is part of Beaconchain Dashboard. * // @@ -30,20 +29,20 @@ */ /* Core CSS required for Ionic components to work properly */ -@import '~@ionic/angular/css/core.css'; +@import '@ionic/angular/css/core.css'; /* Basic CSS for apps built with Ionic */ -@import '~@ionic/angular/css/normalize.css'; -@import '~@ionic/angular/css/structure.css'; -@import '~@ionic/angular/css/typography.css'; -@import '~@ionic/angular/css/display.css'; +@import '@ionic/angular/css/normalize.css'; +@import '@ionic/angular/css/structure.css'; +@import '@ionic/angular/css/typography.css'; +@import '@ionic/angular/css/display.css'; /* Optional CSS utils that can be commented out */ -@import '~@ionic/angular/css/padding.css'; -@import '~@ionic/angular/css/float-elements.css'; -@import '~@ionic/angular/css/text-alignment.css'; -@import '~@ionic/angular/css/text-transformation.css'; -@import '~@ionic/angular/css/flex-utils.css'; +@import '@ionic/angular/css/padding.css'; +@import '@ionic/angular/css/float-elements.css'; +@import '@ionic/angular/css/text-alignment.css'; +@import '@ionic/angular/css/text-transformation.css'; +@import '@ionic/angular/css/flex-utils.css'; @font-face { font-family: 'Varela'; @@ -56,6 +55,10 @@ ion-button { --box-shadow: none; } +.error-btn span { + color: var(--ion-color-danger) !important; +} + .bigger-alert { .alert-message.sc-ion-alert-md { max-height: 335px !important; @@ -91,6 +94,32 @@ ion-button { border-color: transparent var(--tooltip-background) transparent transparent !important; } +.header-background { + -webkit-backdrop-filter: none !important; +} + +ion-popover .popover-viewport { + border-radius: 10px; +} + +body.dark ion-popover ion-content ion-list ion-item { + --background: #222 !important; +} + +body.dark ion-popover ion-select-popover ion-list ion-item { + --background: #222 !important; +} + +ion-popover ion-content ion-list ion-item { + padding: 0px !important; + margin: 0px !important; +} + +ion-popover ion-select-popover ion-list ion-item { + padding: 0px !important; + margin: 0px !important; +} + ion-header { background: var(--ion-toolbar-background) !important; --background: var(--ion-toolbar-background) !important; @@ -125,10 +154,51 @@ cdk-virtual-scroll-viewport { background: var(--ion-background-color); } +ion-list-header { + padding-left: 0px; + text-align: center; +} +ion-list-header ion-label { + font-size: 0.79rem; + //font-weight: 600 !important; + font-weight: 400 !important; + text-shadow: 0.65px 0 0 currentcolor; + font-family: 'Varela'; + letter-spacing: 0.5px; + color: var(--ion-text-color-lighter); +} + +ion-segment-button { + color: var(--x-toolbar-title-color); + + --indicator-height: 0px !important; + text-transform: none !important; + --ripple-color: transparent !important; + //transition: color 0.15s ease; + opacity: 0.65; +} + +ion-segment-button ion-label { + text-shadow: 0.65px 0 0 currentcolor; + font-weight: 400 !important; + font-family: 'Varela'; + font-size: 0.68rem; + letter-spacing: 0.5px; +} + .header-md::after { display: none; } +ion-popover { + &::part(content) { + min-width: 230px; + } +} +.popover-viewport ion-content ion-list ion-item { + margin: 0px 10px 0px 0px; +} + .header-md { -webkit-box-shadow: none !important; box-shadow: none !important; @@ -141,6 +211,13 @@ h3 { --font-family: 'Varela'; } +.center { + width: 100%; + display: flex; + justify-content: center; + text-align: center; +} + ion-modal { --width: 100% !important; --height: 100% !important; @@ -234,6 +311,11 @@ ion-tab-button.tab-selected { } } +mark { + color: #ee7112; + background-color: transparent; +} + body.dark { ion-tab-button.tab-selected { .opacity-icon { @@ -253,6 +335,10 @@ body.dark { opacity: 0.6; } } + + .popover { + background: #222222; + } } ion-tab-button { @@ -286,6 +372,19 @@ ion-toolbar { border-style: none !important; } +ion-toolbar.top { + padding: 0px 10px; +} + +.modal-buttons { + margin: 0px !important; +} + +ion-item, +ion-buttons { + margin: var(--edge-padding); +} + .fade-in { -webkit-animation: fadein 0.7s; -moz-animation: fadein 0.7s; @@ -299,7 +398,7 @@ ion-toolbar { } .bottomFiller { - height: 40px; + height: 80px; } @keyframes fadein { @@ -344,3 +443,105 @@ ion-toolbar { opacity: 1; } } + +.smaller-info { + font-size: var(--smaller-info-size) !important; + //color: var(--ion-text-color-secondary) !important; + opacity: var(--default-secondary-transparency); + font-weight: var(--smaller-label-weight) !important; +} + +.smallest-info { + font-size: var(--smallest-info-size) !important; + //color: var(--ion-text-color-secondary) !important; + opacity: var(--default-secondary-transparency); + font-weight: var(--smaller-label-weight) !important; +} + +.smaller-pad { + padding: 2px 0px 0px 0px; +} + +.touch-icon-padding { + padding: 9px 0px 9px 9px; +} + +.top-bar { + padding-bottom: 0px !important; + margin-bottom: 0px !important; + margin-left: 0px; + margin-right: 0px; +} + +.top-bar-inner { + margin: var(--edge-padding); +} + +.infi-item-blockie { + position: absolute; + left: 16px; + margin-left: 5px; + border-radius: 20%; + height: 40px; + width: 40px; + image-rendering: pixelated; +} + +.infi-item-container { + padding: 3px 0px 3px 0px; + margin: var(--edge-padding-left-minus-5px); // blockie is shifted 5px to the right so text can be centered +} + +.infi-item-container-below-blockie { + text-align: center; + padding-top: var(--text-below-blockie-margin); + width: 50px; +} + +.infi-item-middle-container { + margin-left: 5px; + padding-bottom: 8px; +} + +.infi-item-first { + padding-top: 13px; +} + +.infi-item-last-padding { + padding-bottom: 120px; + background: var(--ion-background-color); +} + +@-moz-keyframes spin { + 100% { + -moz-transform: rotate(360deg); + } +} +@-webkit-keyframes spin { + 100% { + -webkit-transform: rotate(360deg); + } +} +@keyframes spin { + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + } +} + +:root { + --blink-animation: blink 1.2s infinite; +} + +// Keyframes for the blink animation +@keyframes blink { + 0% { + opacity: 0.8; + } + 50% { + opacity: 0.4; + } + 100% { + opacity: 0.8; + } +} diff --git a/src/index.html b/src/index.html index 14ef0496..1e234d24 100644 --- a/src/index.html +++ b/src/index.html @@ -1,4 +1,4 @@ - + @@ -14,7 +14,7 @@ - +