diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..0792692 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,16 @@ +# Editor configuration, see https://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 4 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.ts] +quote_type = single + +[*.md] +max_line_length = off +trim_trailing_whitespace = false diff --git a/.eslintrc.json b/.eslintrc.json index 108bcd3..817ca67 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,14 +1,46 @@ { - "extends": ["next/core-web-vitals", "next/typescript", "prettier"], - "rules": { - "@typescript-eslint/no-unused-vars": [ - "warn", - { - "argsIgnorePattern": "^_", - "varsIgnorePattern": "^_", - "caughtErrorsIgnorePattern": "^_", - "destructuredArrayIgnorePattern": "^_" - } + "root": true, + "ignorePatterns": [ + "projects/**/*" + ], + "overrides": [{ + "files": [ + "*.ts" + ], + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "plugin:@angular-eslint/recommended", + "plugin:@angular-eslint/template/process-inline-templates" + ], + "rules": { + "@angular-eslint/directive-selector": [ + "error", + { + "type": "attribute", + "prefix": "app", + "style": "camelCase" + } + ], + "@angular-eslint/component-selector": [ + "error", + { + "type": "element", + "prefix": "app", + "style": "kebab-case" + } + ] + } + }, + { + "files": [ + "*.html" + ], + "extends": [ + "plugin:@angular-eslint/template/recommended", + "plugin:@angular-eslint/template/accessibility" + ], + "rules": {} + } ] - } } diff --git a/.gitignore b/.gitignore index c25534b..83db789 100644 --- a/.gitignore +++ b/.gitignore @@ -6,36 +6,10 @@ /out-tsc /bazel-out -# dependencies +# Node /node_modules -/.pnp -.pnp.js - -# debug -npm-debug.log* -yarn-debug.log* -yarn-error.log* -.pnpm-debug.log* - -# local env files -.env*.local - -# production -/build - -# testing -/coverage - -# next.js -/.next/ -/out/ - -# vercel -.vercel - -# typescript -*.tsbuildinfo -next-env.d.ts +npm-debug.log +yarn-error.log # IDEs and editors .idea/ @@ -59,10 +33,10 @@ next-env.d.ts .nx/ .sass-cache/ /connect.lock +/coverage /libpeerconnection.log testem.log /typings -*.pem # e2e /e2e/*.js @@ -80,4 +54,5 @@ sonar.properties **/*.copy.scss **/*.copy.html -certificates \ No newline at end of file +.next/ +next-env.d.ts \ No newline at end of file diff --git a/.husky/pre-commit b/.husky/pre-commit index 6be6160..ada238b 100644 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,3 +1,3 @@ -npm test +# npm test -- --watch=false #prettier $(git diff --cached --name-only --diff-filter=ACMR | sed 's| |\\ |g') --write --ignore-unknown #git update-index --again \ No newline at end of file diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..a301716 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,72 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Commands + +- `npm start` — dev server (production config) on port 4200 +- `npm run dev` — dev server with `APP_ENV=development` on port 4300, uses `environment.development.ts` +- `npm run local` — dev server with `APP_ENV=local` on port 4400, uses `environment.local.ts` +- `npm run serve` — alias for local config on port 4201 +- `npm run build` — production build to `dist/adastra_angular/` +- `npm run watch` — incremental build in development configuration +- `npm run lint` — angular-eslint over `src/**/*.ts` and `src/**/*.html` +- `npm test` — Karma + Jasmine (single spec: `ng test --include src/path/to/file.spec.ts`) + +Node engines: `^18.19.1 || ^20.11.1`. Angular 18, TypeScript 5.5, strict mode with `strictTemplates`. + +## Environments + +`src/environments/environment.ts` is the default (production). `environment.development.ts` and `environment.local.ts` are swapped in via `fileReplacements` in `angular.json` for their respective configurations. `environment.example.ts` documents the expected shape (`apiBaseUrl`, `apiKey`, `useApiKey`, `refreshInterval`, `googleMapApiKey`). Never commit real keys to the development/local files — the production `environment.ts` currently has real keys checked in; be mindful. + +## Architecture + +Standalone Angular 18 app (no NgModules) wired up in [src/app/app.config.ts](src/app/app.config.ts). It provides the router with `withViewTransitions()`, three HTTP interceptors, charts, French locale (`fr-FR`), and an `APP_INITIALIZER` that eagerly fetches the current user when a JWT is present in localStorage. + +### Routing split + +Routes are composed in [src/app/app.routes.ts](src/app/app.routes.ts) from two arrays: +- [src/app/routes/auth.routes.ts](src/app/routes/auth.routes.ts) — `authGuard`-protected routes. Skydive admin sections (`aeronefs`, `canopies`, `dashboard`, `dropzones`, `jumps`) additionally require `adminGuard`. +- [src/app/routes/noauth.routes.ts](src/app/routes/noauth.routes.ts) — public pages and auth-entry routes (`login`, `register`) gated by `noauthGuard` (blocks entry when already authenticated). + +Resolvers under [src/app/core/resolvers/](src/app/core/resolvers/) pre-fetch data for each route — new route components should generally follow this pattern rather than fetching in `ngOnInit`. + +### HTTP pipeline + +Three interceptors chained in order ([src/app/core/interceptors/](src/app/core/interceptors/)): +1. `apiInterceptor` — prepends `environment.apiBaseUrl` to every request URL. **Consequence:** services call relative paths like `/cms/user`, never absolute URLs. +2. `tokenInterceptor` — attaches `Authorization: Token ` when a token exists. +3. `errorInterceptor` — unwraps `err.error` and rethrows. + +`ApiService` ([api.service.ts](src/app/core/services/api.service.ts)) is a thin `HttpClient` wrapper; most feature services call it with a versioned prefix (e.g., `_apiDomain = '/skydive'` or `/cms`). The API version is per-service, not global. + +### Auth flow + +`JwtService` stores the token in `localStorage['jwtToken']`. `UserService` exposes `currentUser` (BehaviorSubject) and `isAuthenticated` (ReplaySubject) observables consumed by guards and the layout. The `APP_INITIALIZER` in `app.config.ts` calls `userService.getCurrentUser()` if a token exists, so guards can rely on `isAuthenticated` being populated on first navigation. Admin role check is `currentUser.role === 'Admin'`. + +### Layout + +[AppComponent](src/app/app.component.ts) renders only `FullComponent` ([src/app/components/shared/layout/full.component.ts](src/app/components/shared/layout/full.component.ts)), which owns the Material sidenav + toolbar shell and swaps menu items between `MENUITEMS` and `MENUITEMSADMIN` defined in [src/app/components/shared/menu-items.ts](src/app/components/shared/menu-items.ts) based on role. Route changes render inside its ``. + +### Feature areas + +The app spans four mostly-independent feature domains, mirroring the backend's route grouping: +- **E-commerce** — `products`, `product/:slug`, `products/:category` (public + auth variants). Categories are baked into menu items, not dynamic. Backend counterpart: `/api/ecommerce/*`. +- **CMS** — `pages`, `page/:slug`, `home`, profiles, articles. Backend counterpart: `/api/cms/*`. +- **Skydive** — `skydive/*` routes, services in [src/app/core/services/skydive/](src/app/core/services/skydive/), QCM exam data in `src/app/components/qcm/*.json` and `src/qcm-bpa.json`. Backend counterpart: `/api/skydive/*`. +- **Hero Wars** — analytics for a game guild, services in [src/app/core/services/herowars/](src/app/core/services/herowars/), weekly data snapshots in [src/files-data/](src/files-data/) (`Week_XX` folders and `hw-*.json` files are static data shipped as assets). Backend counterpart: `/api/herowars/*`. + +### Path aliases + +Configured in [tsconfig.json](tsconfig.json) and used everywhere — prefer them over relative paths: +`@components`, `@services`, `@models`, `@guards`, `@interceptors`, `@resolvers`, `@viewmodels`, `@interfaces`, `@constants`, `@core/*`, `@environments/*`, `@data/*` (→ `src/files-data/*`), `@assets/*`, `@styles/*`. + +Each alias points at an `index.ts` barrel — when adding a new component/service/model, also export it from the appropriate barrel or it won't be importable via the alias. + +### Styling + +SCSS with `includePaths: ["src/styles"]` so imports like `@use 'variables'` resolve. Global Chartist styles are registered in `angular.json` build options. Material 18 with French date locale and `DD/MM/YYYY` format configured in `AppComponent`'s providers. + +## Related service + +The backend API lives in a sibling repo at `/Users/julien/Sites/adastra_api` (Express + Sequelize, additional working directory). Routes are grouped under `src/routes/api/` into the same four domains as the frontend: `skydive`, `cms`, `ecommerce`, `herowars`. The `v1`, `v2`, `v3` folders alongside them are legacy backups slated for removal — ignore them. When a task spans both repos (e.g., adding an endpoint + consumer), check there as well. diff --git a/README.md b/README.md index 913f13f..15317b2 100644 --- a/README.md +++ b/README.md @@ -1,42 +1,27 @@ -# AdAstra_App +# Ad Astra -## Libraries and Frameworks +This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 17.2.2. -| Name | | -| --------------------------------------------- | ---------------------------------- | -| [TypeScript](https://www.typescriptlang.org/) | v5.5.x | -| [Next.js](https://nextjs.org/) | v15.x | -| [React](https://react.dev/) | v18.x | -| [Conform](https://conform.guide/) | form validation library | -| [Zod](https://zod.dev/) | schema validation library | -| [unified](https://unifiedjs.com/) | markdown to html converter | -| [OpenAPI TypeScript](https://openapi-ts.dev/) | type generator from OpenAPI schema | +## Development server -## Getting Started +Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The application will automatically reload if you change any of the source files. -```bash -# copy env -cp .env.example .env.local +## Code scaffolding -# set API_BASE_URL variable in .env.local to your backend api endpoint +Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. -# run app -npm run dev -``` +## Build -## Directory structure +Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. -```plaintext -. -├── api/ # api schema -├── public/ # static assets -└── src/ - ├── app/ # web routes - ├── config/ # global configuration and constants - ├── generated/ # automatically generated codes - ├── modules/ - │ ├── common/ # common (feature-independent) components - │ └── features/ # feature-specific components - ├── styles/ # global style sheets - └── utils/ # utilities -``` +## Running unit tests + +Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). + +## Running end-to-end tests + +Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities. + +## Further help + +To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page. diff --git a/angular.json b/angular.json new file mode 100644 index 0000000..d38f09a --- /dev/null +++ b/angular.json @@ -0,0 +1,179 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "cli": { + "packageManager": "npm", + "analytics": false, + "schematicCollections": [ + "@angular-eslint/schematics" + ] + }, + "newProjectRoot": "projects", + "projects": { + "adastra_angular": { + "projectType": "application", + "schematics": { + "@schematics/angular:component": { + "style": "scss" + } + }, + "i18n": { + "sourceLocale": "fr" + }, + "root": "", + "sourceRoot": "src", + "prefix": "app", + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:application", + "options": { + "outputPath": { + "base": "dist/adastra_angular" + }, + "index": "src/index.html", + "tsConfig": "tsconfig.app.json", + "polyfills": [ + "@angular/localize/init", + "zone.js" + ], + "inlineStyleLanguage": "scss", + "assets": [ + "src/favicon.ico", + "src/assets", + "src/manifest.webmanifest", + { + "glob": "_redirects", + "input": "src", + "output": "/" + } + ], + "styles": [ + "node_modules/chartist/dist/index.scss", + "src/styles/styles.scss" + ], + "stylePreprocessorOptions": { + "includePaths": [ + "src/styles" + ] + }, + "scripts": [], + "browser": "src/main.ts" + }, + "configurations": { + "production": { + "extractLicenses": true, + "namedChunks": false, + "optimization": true, + "outputHashing": "all", + "sourceMap": false, + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ] + }, + "development": { + "extractLicenses": false, + "namedChunks": true, + "optimization": false, + "sourceMap": true, + "budgets": [ + { + "type": "anyComponentStyle", + "maximumWarning": "6kb" + } + ], + "fileReplacements": [ + { + "replace": "src/environments/environment.ts", + "with": "src/environments/environment.development.ts" + } + ] + }, + "local": { + "extractLicenses": false, + "namedChunks": true, + "optimization": false, + "sourceMap": true, + "budgets": [ + { + "type": "anyComponentStyle", + "maximumWarning": "6kb" + } + ], + "fileReplacements": [ + { + "replace": "src/environments/environment.ts", + "with": "src/environments/environment.local.ts" + } + ] + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "builder": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "adastra_angular:build:production" + }, + "development": { + "buildTarget": "adastra_angular:build:development" + }, + "local": { + "buildTarget": "adastra_angular:build:local" + } + }, + "defaultConfiguration": "development" + }, + "extract-i18n": { + "builder": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "adastra_angular:build" + } + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "polyfills": [ + "zone.js", + "zone.js/testing" + ], + "tsConfig": "tsconfig.spec.json", + "inlineStyleLanguage": "scss", + "assets": [ + "src/favicon.ico", + "src/assets", + "src/manifest.webmanifest" + ], + "styles": [ + "src/styles/styles.scss" + ], + "scripts": [], + "stylePreprocessorOptions": { + "includePaths": [ + "src/styles" + ] + } + } + }, + "lint": { + "builder": "@angular-eslint/builder:lint", + "options": { + "lintFilePatterns": [ + "src/**/*.ts", + "src/**/*.html" + ] + } + } + } + } + } +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 6dd7474..1406b25 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,49 +1,932 @@ { - "name": "adastra-nextjs", - "version": "0.1.0", + "name": "adastra-app", + "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "adastra-nextjs", - "version": "0.1.0", + "name": "adastra-app", + "version": "1.0.0", "dependencies": { - "@conform-to/react": "^1.2.2", - "@conform-to/zod": "^1.2.2", + "@angular/animations": "^18.2.14", + "@angular/cdk": "^18.2.14", + "@angular/common": "^18.2.14", + "@angular/compiler": "^18.2.14", + "@angular/core": "^18.2.14", + "@angular/forms": "^18.2.14", + "@angular/google-maps": "^17.3.8", + "@angular/localize": "^18.2.14", + "@angular/material": "^18.2.14", + "@angular/platform-browser": "^18.2.14", + "@angular/platform-browser-dynamic": "^18.2.14", + "@angular/router": "^18.2.14", "bootstrap": "^5.3.7", - "clsx": "^2.1.1", - "next": "^15.4.5", - "react": "^19.1.1", - "react-bootstrap": "^2.10.10", - "react-dom": "^19.1.1", - "rehype-stringify": "^10.0.1", - "remark-parse": "^11.0.0", - "remark-rehype": "^11.1.1", - "unified": "^11.0.5", - "zod": "^3.23.8" + "chart.js": "^4.4.2", + "chartist": "^1.3.0", + "ng-chartist": "^8.2.0", + "ng2-charts": "^6.0.1", + "ngx-skeleton-loader": "^9.0.0", + "rxjs": "~7.8.0", + "tslib": "^2.3.0", + "zone.js": "^0.14.10" }, "devDependencies": { - "@types/node": "^24.1.0", - "@types/react": "^19.1.9", - "@types/react-dom": "^19.1.7", - "eslint": "^9.32.0", - "eslint-config-next": "^15.4.5", - "eslint-config-prettier": "^9.1.0", - "husky": "^9.1.6", - "lint-staged": "^15.2.10", - "openapi-typescript": "^7.4.1", - "prettier": "^3.3.3", - "sass": "^1.89.2", - "typescript": "^5.9.2" + "@angular-devkit/build-angular": "^18.2.21", + "@angular-eslint/builder": "18.4.3", + "@angular-eslint/eslint-plugin": "18.4.3", + "@angular-eslint/eslint-plugin-template": "18.4.3", + "@angular-eslint/schematics": "18.4.3", + "@angular-eslint/template-parser": "18.4.3", + "@angular/cli": "^18.2.21", + "@angular/compiler-cli": "^18.2.14", + "@types/jasmine": "~5.1.0", + "@typescript-eslint/eslint-plugin": "7.2.0", + "@typescript-eslint/parser": "7.2.0", + "eslint": "^8.57.0", + "jasmine-core": "~5.1.0", + "karma": "~6.4.0", + "karma-chrome-launcher": "~3.2.0", + "karma-coverage": "~2.2.0", + "karma-jasmine": "~5.1.0", + "karma-jasmine-html-reporter": "~2.1.0", + "typescript": "~5.5.4" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@angular-devkit/architect": { + "version": "0.1802.21", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1802.21.tgz", + "integrity": "sha512-+Ll+xtpKwZ3iLWN/YypvnCZV/F0MVbP+/7ZpMR+Xv/uB0OmribhBVj9WGaCd9I/bGgoYBw8wBV/NFNCKkf0k3Q==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "18.2.21", + "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/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@angular-devkit/build-angular": { + "version": "18.2.21", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-18.2.21.tgz", + "integrity": "sha512-0pJfURFpEUV2USgZ2TL3nNAaJmF9bICx9OVddBoC+F9FeOpVKxkcVIb+c8Km5zHFo1iyVtPZ6Rb25vFk9Zm/ug==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "2.3.0", + "@angular-devkit/architect": "0.1802.21", + "@angular-devkit/build-webpack": "0.1802.21", + "@angular-devkit/core": "18.2.21", + "@angular/build": "18.2.21", + "@babel/core": "7.26.10", + "@babel/generator": "7.26.10", + "@babel/helper-annotate-as-pure": "7.25.9", + "@babel/helper-split-export-declaration": "7.24.7", + "@babel/plugin-transform-async-generator-functions": "7.26.8", + "@babel/plugin-transform-async-to-generator": "7.25.9", + "@babel/plugin-transform-runtime": "7.26.10", + "@babel/preset-env": "7.26.9", + "@babel/runtime": "7.26.10", + "@discoveryjs/json-ext": "0.6.1", + "@ngtools/webpack": "18.2.21", + "ansi-colors": "4.1.3", + "autoprefixer": "10.4.20", + "babel-loader": "9.1.3", + "browserslist": "^4.21.5", + "copy-webpack-plugin": "12.0.2", + "critters": "0.0.24", + "css-loader": "7.1.2", + "esbuild-wasm": "0.23.0", + "fast-glob": "3.3.2", + "http-proxy-middleware": "3.0.5", + "https-proxy-agent": "7.0.5", + "istanbul-lib-instrument": "6.0.3", + "jsonc-parser": "3.3.1", + "karma-source-map-support": "1.4.0", + "less": "4.2.0", + "less-loader": "12.2.0", + "license-webpack-plugin": "4.0.2", + "loader-utils": "3.3.1", + "magic-string": "0.30.11", + "mini-css-extract-plugin": "2.9.0", + "mrmime": "2.0.0", + "open": "10.1.0", + "ora": "5.4.1", + "parse5-html-rewriting-stream": "7.0.0", + "picomatch": "4.0.2", + "piscina": "4.6.1", + "postcss": "8.4.41", + "postcss-loader": "8.1.1", + "resolve-url-loader": "5.0.0", + "rxjs": "7.8.1", + "sass": "1.77.6", + "sass-loader": "16.0.0", + "semver": "7.6.3", + "source-map-loader": "5.0.0", + "source-map-support": "0.5.21", + "terser": "5.31.6", + "tree-kill": "1.2.2", + "tslib": "2.6.3", + "watchpack": "2.4.1", + "webpack": "5.94.0", + "webpack-dev-middleware": "7.4.2", + "webpack-dev-server": "5.2.2", + "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.23.0" + }, + "peerDependencies": { + "@angular/compiler-cli": "^18.0.0", + "@angular/localize": "^18.0.0", + "@angular/platform-server": "^18.0.0", + "@angular/service-worker": "^18.0.0", + "@web/test-runner": "^0.18.0", + "browser-sync": "^3.0.2", + "jest": "^29.5.0", + "jest-environment-jsdom": "^29.5.0", + "karma": "^6.3.0", + "ng-packagr": "^18.0.0", + "protractor": "^7.0.0", + "tailwindcss": "^2.0.0 || ^3.0.0", + "typescript": ">=5.4 <5.6" + }, + "peerDependenciesMeta": { + "@angular/localize": { + "optional": true + }, + "@angular/platform-server": { + "optional": true + }, + "@angular/service-worker": { + "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/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", + "dev": true + }, + "node_modules/@angular-devkit/build-webpack": { + "version": "0.1802.21", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1802.21.tgz", + "integrity": "sha512-2jSVRhA3N4Elg8OLcBktgi+CMSjlAm/bBQJE6TQYbdQWnniuT7JAWUHA/iPf7MYlQE5qj4rnAni1CI/c1Bk4HQ==", + "dev": true, + "dependencies": { + "@angular-devkit/architect": "0.1802.21", + "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/build-webpack/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==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@angular-devkit/core": { + "version": "18.2.21", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.2.21.tgz", + "integrity": "sha512-Lno6GNbJME85wpc/uqn+wamBxvfZJZFYSH8+oAkkyjU/hk8r5+X8DuyqsKAa0m8t46zSTUsonHsQhVe5vgrZeQ==", + "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": "^3.5.2" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/core/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==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@angular-devkit/schematics": { + "version": "18.2.21", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-18.2.21.tgz", + "integrity": "sha512-yuC2vN4VL48JhnsaOa9J/o0Jl+cxOklRNQp5J2/ypMuRROaVCrZAPiX+ChSHh++kHYMpj8+ggNrrUwRNfMKACQ==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "18.2.21", + "jsonc-parser": "3.3.1", + "magic-string": "0.30.11", + "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/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@angular-eslint/builder": { + "version": "18.4.3", + "resolved": "https://registry.npmjs.org/@angular-eslint/builder/-/builder-18.4.3.tgz", + "integrity": "sha512-NzmrXlr7GFE+cjwipY/CxBscZXNqnuK0us1mO6Z2T6MeH6m+rRcdlY/rZyKoRniyNNvuzl6vpEsfMIMmnfebrA==", + "dev": true, + "dependencies": { + "@angular-devkit/architect": ">= 0.1800.0 < 0.1900.0", + "@angular-devkit/core": ">= 18.0.0 < 19.0.0" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": "*" + } + }, + "node_modules/@angular-eslint/bundled-angular-compiler": { + "version": "18.4.3", + "resolved": "https://registry.npmjs.org/@angular-eslint/bundled-angular-compiler/-/bundled-angular-compiler-18.4.3.tgz", + "integrity": "sha512-zdrA8mR98X+U4YgHzUKmivRU+PxzwOL/j8G7eTOvBuq8GPzsP+hvak+tyxlgeGm9HsvpFj9ERHLtJ0xDUPs8fg==", + "dev": true + }, + "node_modules/@angular-eslint/eslint-plugin": { + "version": "18.4.3", + "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin/-/eslint-plugin-18.4.3.tgz", + "integrity": "sha512-AyJbupiwTBR81P6T59v+aULEnPpZBCBxL2S5QFWfAhNCwWhcof4GihvdK2Z87yhvzDGeAzUFSWl/beJfeFa+PA==", + "dev": true, + "dependencies": { + "@angular-eslint/bundled-angular-compiler": "18.4.3", + "@angular-eslint/utils": "18.4.3" + }, + "peerDependencies": { + "@typescript-eslint/utils": "^7.11.0 || ^8.0.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": "*" + } + }, + "node_modules/@angular-eslint/eslint-plugin-template": { + "version": "18.4.3", + "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin-template/-/eslint-plugin-template-18.4.3.tgz", + "integrity": "sha512-ijGlX2N01ayMXTpeQivOA31AszO8OEbu9ZQUCxnu9AyMMhxyi2q50bujRChAvN9YXQfdQtbxuajxV6+aiWb5BQ==", + "dev": true, + "dependencies": { + "@angular-eslint/bundled-angular-compiler": "18.4.3", + "@angular-eslint/utils": "18.4.3", + "aria-query": "5.3.2", + "axobject-query": "4.1.0" + }, + "peerDependencies": { + "@typescript-eslint/types": "^7.11.0 || ^8.0.0", + "@typescript-eslint/utils": "^7.11.0 || ^8.0.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": "*" + } + }, + "node_modules/@angular-eslint/schematics": { + "version": "18.4.3", + "resolved": "https://registry.npmjs.org/@angular-eslint/schematics/-/schematics-18.4.3.tgz", + "integrity": "sha512-D5maKn5e6n58+8n7jLFLD4g+RGPOPeDSsvPc1sqial5tEKLxAJQJS9WZ28oef3bhkob6C60D+1H0mMmEEVvyVA==", + "dev": true, + "dependencies": { + "@angular-devkit/core": ">= 18.0.0 < 19.0.0", + "@angular-devkit/schematics": ">= 18.0.0 < 19.0.0", + "@angular-eslint/eslint-plugin": "18.4.3", + "@angular-eslint/eslint-plugin-template": "18.4.3", + "ignore": "6.0.2", + "semver": "7.6.3", + "strip-json-comments": "3.1.1" + } + }, + "node_modules/@angular-eslint/template-parser": { + "version": "18.4.3", + "resolved": "https://registry.npmjs.org/@angular-eslint/template-parser/-/template-parser-18.4.3.tgz", + "integrity": "sha512-JZMPtEB8yNip3kg4WDEWQyObSo2Hwf+opq2ElYuwe85GQkGhfJSJ2CQYo4FSwd+c5MUQAqESNRg9QqGYauDsiw==", + "dev": true, + "dependencies": { + "@angular-eslint/bundled-angular-compiler": "18.4.3", + "eslint-scope": "^8.0.2" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": "*" + } + }, + "node_modules/@angular-eslint/utils": { + "version": "18.4.3", + "resolved": "https://registry.npmjs.org/@angular-eslint/utils/-/utils-18.4.3.tgz", + "integrity": "sha512-w0bJ9+ELAEiPBSTPPm9bvDngfu1d8JbzUhvs2vU+z7sIz/HMwUZT5S4naypj2kNN0gZYGYrW0lt+HIbW87zTAQ==", + "dev": true, + "dependencies": { + "@angular-eslint/bundled-angular-compiler": "18.4.3" + }, + "peerDependencies": { + "@typescript-eslint/utils": "^7.11.0 || ^8.0.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": "*" + } + }, + "node_modules/@angular/animations": { + "version": "18.2.14", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-18.2.14.tgz", + "integrity": "sha512-Kp/MWShoYYO+R3lrrZbZgszbbLGVXHB+39mdJZwnIuZMDkeL3JsIBlSOzyJRTnpS1vITc+9jgHvP/6uKbMrW1Q==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/core": "18.2.14" + } + }, + "node_modules/@angular/build": { + "version": "18.2.21", + "resolved": "https://registry.npmjs.org/@angular/build/-/build-18.2.21.tgz", + "integrity": "sha512-uvq3qP4cByJrUkV1ri0v3x6LxOFt4fDKiQdNwbQAqdxtfRs3ssEIoCGns4t89sTWXv6VZWBNDcDIKK9/Fa9mmg==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "2.3.0", + "@angular-devkit/architect": "0.1802.21", + "@babel/core": "7.25.2", + "@babel/helper-annotate-as-pure": "7.24.7", + "@babel/helper-split-export-declaration": "7.24.7", + "@babel/plugin-syntax-import-attributes": "7.24.7", + "@inquirer/confirm": "3.1.22", + "@vitejs/plugin-basic-ssl": "1.1.0", + "browserslist": "^4.23.0", + "critters": "0.0.24", + "esbuild": "0.23.0", + "fast-glob": "3.3.2", + "https-proxy-agent": "7.0.5", + "listr2": "8.2.4", + "lmdb": "3.0.13", + "magic-string": "0.30.11", + "mrmime": "2.0.0", + "parse5-html-rewriting-stream": "7.0.0", + "picomatch": "4.0.2", + "piscina": "4.6.1", + "rollup": "4.22.4", + "sass": "1.77.6", + "semver": "7.6.3", + "vite": "~5.4.17", + "watchpack": "2.4.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": { + "@angular/compiler-cli": "^18.0.0", + "@angular/localize": "^18.0.0", + "@angular/platform-server": "^18.0.0", + "@angular/service-worker": "^18.0.0", + "less": "^4.2.0", + "postcss": "^8.4.0", + "tailwindcss": "^2.0.0 || ^3.0.0", + "typescript": ">=5.4 <5.6" + }, + "peerDependenciesMeta": { + "@angular/localize": { + "optional": true + }, + "@angular/platform-server": { + "optional": true + }, + "@angular/service-worker": { + "optional": true + }, + "less": { + "optional": true + }, + "postcss": { + "optional": true + }, + "tailwindcss": { + "optional": true + } + } + }, + "node_modules/@angular/build/node_modules/@babel/core": { + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz", + "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.25.0", + "@babel/helper-compilation-targets": "^7.25.2", + "@babel/helper-module-transforms": "^7.25.2", + "@babel/helpers": "^7.25.0", + "@babel/parser": "^7.25.0", + "@babel/template": "^7.25.0", + "@babel/traverse": "^7.25.2", + "@babel/types": "^7.25.2", + "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/build/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/build/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/@angular/build/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/cdk": { + "version": "18.2.14", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-18.2.14.tgz", + "integrity": "sha512-vDyOh1lwjfVk9OqoroZAP8pf3xxKUvyl+TVR8nJxL4c5fOfUFkD7l94HaanqKSRwJcI2xiztuu92IVoHn8T33Q==", + "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": "18.2.21", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-18.2.21.tgz", + "integrity": "sha512-efweY4p8awRTbHs+HKdg6s44hl7Y0gdVlXYi3HeY8Z5JDC0abbka0K6sA/MrV9AXvn/5ovxYbxiL3AsOApjTpg==", + "dev": true, + "dependencies": { + "@angular-devkit/architect": "0.1802.21", + "@angular-devkit/core": "18.2.21", + "@angular-devkit/schematics": "18.2.21", + "@inquirer/prompts": "5.3.8", + "@listr2/prompt-adapter-inquirer": "2.0.15", + "@schematics/angular": "18.2.21", + "@yarnpkg/lockfile": "1.1.0", + "ini": "4.1.3", + "jsonc-parser": "3.3.1", + "listr2": "8.2.4", + "npm-package-arg": "11.0.3", + "npm-pick-manifest": "9.1.0", + "pacote": "18.0.6", + "resolve": "1.22.8", + "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/common": { + "version": "18.2.14", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-18.2.14.tgz", + "integrity": "sha512-ZPRswzaVRiqcfZoowuAM22Hr2/z10ajWOUoFDoQ9tWqz/fH/773kJv2F9VvePIekgNPCzaizqv9gF6tGNqaAwg==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/core": "18.2.14", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/compiler": { + "version": "18.2.14", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-18.2.14.tgz", + "integrity": "sha512-Mpq3v/mztQzGAQAAFV+wAI1hlXxZ0m8eDBgaN2kD3Ue+r4S6bLm1Vlryw0iyUnt05PcFIdxPT6xkcphq5pl6lw==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/core": "18.2.14" + }, + "peerDependenciesMeta": { + "@angular/core": { + "optional": true + } + } + }, + "node_modules/@angular/compiler-cli": { + "version": "18.2.14", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-18.2.14.tgz", + "integrity": "sha512-BmmjyrFSBSYkm0tBSqpu4cwnJX/b/XvhM36mj2k8jah3tNS5zLDDx5w6tyHmaPJa/1D95MlXx2h6u7K9D+Mhew==", + "dependencies": { + "@babel/core": "7.25.2", + "@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": "18.2.14", + "typescript": ">=5.4 <5.6" + } + }, + "node_modules/@angular/compiler-cli/node_modules/@babel/core": { + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz", + "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.25.0", + "@babel/helper-compilation-targets": "^7.25.2", + "@babel/helper-module-transforms": "^7.25.2", + "@babel/helpers": "^7.25.0", + "@babel/parser": "^7.25.0", + "@babel/template": "^7.25.0", + "@babel/traverse": "^7.25.2", + "@babel/types": "^7.25.2", + "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==" + }, + "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==", + "bin": { + "semver": "bin/semver.js" + } + }, + "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==", + "license": "MIT", + "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.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular/core": { + "version": "18.2.14", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-18.2.14.tgz", + "integrity": "sha512-BIPrCs93ZZTY9ym7yfoTgAQ5rs706yoYeAdrgc8kh/bDbM9DawxKlgeKBx2FLt09Y0YQ1bFhKVp0cV4gDEaMxQ==", + "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.14.10" + } + }, + "node_modules/@angular/forms": { + "version": "18.2.14", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-18.2.14.tgz", + "integrity": "sha512-fZVwXctmBJa5VdopJae/T9MYKPXNd04+6j4k/6X819y+9fiyWLJt2QicSc5Rc+YD9mmhXag3xaljlrnotf9VGA==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/common": "18.2.14", + "@angular/core": "18.2.14", + "@angular/platform-browser": "18.2.14", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/google-maps": { + "version": "17.3.10", + "resolved": "https://registry.npmjs.org/@angular/google-maps/-/google-maps-17.3.10.tgz", + "integrity": "sha512-QqBdXgMcA7xMwEh7ZPdFKsU4clbK+ZX6IqYdaY7hpZkkbO3Us7jnuIL8xCA0bskuYIKOSDijZqgqnDJig/SNDg==", + "dependencies": { + "@types/google.maps": "^3.54.10", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/common": "^17.0.0 || ^18.0.0", + "@angular/core": "^17.0.0 || ^18.0.0", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/localize": { + "version": "18.2.14", + "resolved": "https://registry.npmjs.org/@angular/localize/-/localize-18.2.14.tgz", + "integrity": "sha512-VRe169SRSKxJfxJ+oZONwph0llTQHGrH9MhMjoej7XqTH3EVzrYJBNcS9j7Jhd0O/aKSfPY/wIJBeKUn+4O4gQ==", + "dependencies": { + "@babel/core": "7.25.2", + "@types/babel__core": "7.20.5", + "fast-glob": "3.3.2", + "yargs": "^17.2.1" + }, + "bin": { + "localize-extract": "tools/bundles/src/extract/cli.js", + "localize-migrate": "tools/bundles/src/migrate/cli.js", + "localize-translate": "tools/bundles/src/translate/cli.js" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/compiler": "18.2.14", + "@angular/compiler-cli": "18.2.14" + } + }, + "node_modules/@angular/localize/node_modules/@babel/core": { + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz", + "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.25.0", + "@babel/helper-compilation-targets": "^7.25.2", + "@babel/helper-module-transforms": "^7.25.2", + "@babel/helpers": "^7.25.0", + "@babel/parser": "^7.25.0", + "@babel/template": "^7.25.0", + "@babel/traverse": "^7.25.2", + "@babel/types": "^7.25.2", + "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/localize/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==" + }, + "node_modules/@angular/localize/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@angular/material": { + "version": "18.2.14", + "resolved": "https://registry.npmjs.org/@angular/material/-/material-18.2.14.tgz", + "integrity": "sha512-28pxzJP49Mymt664WnCtPkKeg7kXUsQKTKGf/Kl95rNTEdTJLbnlcc8wV0rT0yQNR7kXgpfBnG7h0ETLv/iu5Q==", + "dependencies": { + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/animations": "^18.0.0 || ^19.0.0", + "@angular/cdk": "18.2.14", + "@angular/common": "^18.0.0 || ^19.0.0", + "@angular/core": "^18.0.0 || ^19.0.0", + "@angular/forms": "^18.0.0 || ^19.0.0", + "@angular/platform-browser": "^18.0.0 || ^19.0.0", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/platform-browser": { + "version": "18.2.14", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-18.2.14.tgz", + "integrity": "sha512-W+JTxI25su3RiZVZT3Yrw6KNUCmOIy7OZIZ+612skPgYK2f2qil7VclnW1oCwG896h50cMJU/lnAfxZxefQgyQ==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/animations": "18.2.14", + "@angular/common": "18.2.14", + "@angular/core": "18.2.14" + }, + "peerDependenciesMeta": { + "@angular/animations": { + "optional": true + } + } + }, + "node_modules/@angular/platform-browser-dynamic": { + "version": "18.2.14", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-18.2.14.tgz", + "integrity": "sha512-QOv+o89u8HLN0LG8faTIVHKBxfkOBHVDB0UuXy19+HJofWZGGvho+vGjV0/IAkhZnMC4Sxdoy/mOHP2ytALX3A==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/common": "18.2.14", + "@angular/compiler": "18.2.14", + "@angular/core": "18.2.14", + "@angular/platform-browser": "18.2.14" + } + }, + "node_modules/@angular/router": { + "version": "18.2.14", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-18.2.14.tgz", + "integrity": "sha512-v/gweh8MBjjDfh1QssuyjISa+6SVVIvIZox7MaMs81RkaoVHwS9grDtPud1pTKHzms2KxSVpvwwyvkRJQplueg==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/common": "18.2.14", + "@angular/core": "18.2.14", + "@angular/platform-browser": "18.2.14", + "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@babel/code-frame": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", - "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", - "dev": true, + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", "dependencies": { - "@babel/helper-validator-identifier": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" }, @@ -51,84 +934,2002 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-validator-identifier": { + "node_modules/@babel/compat-data": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz", + "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.10.tgz", + "integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.10", + "@babel/helper-compilation-targets": "^7.26.5", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.10", + "@babel/parser": "^7.26.10", + "@babel/template": "^7.26.9", + "@babel/traverse": "^7.26.10", + "@babel/types": "^7.26.10", + "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==" + }, + "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==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.10.tgz", + "integrity": "sha512-rRHT8siFIXQrAYOYqZQVsAr8vJ+cBNqcVAY6m5V8/4QqzaPl+zDBe6cLEPRDuNOUf3ww8RfJVlOyQMoSI+5Ang==", + "dependencies": { + "@babel/parser": "^7.26.10", + "@babel/types": "^7.26.10", + "@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.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", + "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", + "dependencies": { + "@babel/compat-data": "^7.28.6", + "@babel/helper-validator-option": "^7.27.1", + "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==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.6.tgz", + "integrity": "sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-member-expression-to-functions": "^7.28.5", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/helper-replace-supers": "^7.28.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/traverse": "^7.28.6", + "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.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", + "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.27.3" + }, + "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.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.28.5.tgz", + "integrity": "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "regexpu-core": "^6.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.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", + "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.27.3" + }, + "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.8", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.8.tgz", + "integrity": "sha512-47UwBLPpQi1NoWzLuHNjRoHlYXMwIJoBf7MFou6viC/sIHWYygpvr0B6IAyh5sBdA2nr2LPIRww8lfaUVQINBA==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "debug": "^4.4.3", + "lodash.debounce": "^4.0.8", + "resolve": "^1.22.11" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-define-polyfill-provider/node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "dev": true, + "dependencies": { + "is-core-module": "^2.16.1", + "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/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz", + "integrity": "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.28.5", + "@babel/types": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", + "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", + "dependencies": { + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", + "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", + "dependencies": { + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", - "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", + "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", + "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", "dev": true, "engines": { "node": ">=6.9.0" } }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz", + "integrity": "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-wrap-function": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "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.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", + "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.28.6.tgz", + "integrity": "sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==", + "dev": true, + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.28.5", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", + "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "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.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.28.6.tgz", + "integrity": "sha512-z+PwLziMNBeSQJonizz2AGnndLsP2DeGHIxDAn+wdHOGuo4Fo1x1HBPPXeE9TAOPHNNWQKCSlA2VZyYyyibDnQ==", + "dev": true, + "dependencies": { + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.2.tgz", + "integrity": "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==", + "dependencies": { + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz", + "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==", + "dependencies": { + "@babel/types": "^7.29.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.28.5.tgz", + "integrity": "sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.27.1.tgz", + "integrity": "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "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.27.1", + "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.27.1.tgz", + "integrity": "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz", + "integrity": "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/plugin-transform-optional-chaining": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.28.6.tgz", + "integrity": "sha512-a0aBScVTlNaiUe35UtfxAN7A/tehvvG4/ByO6+46VPKTRSlfnAFsgKy0FUh+qAkQrDTmhDkT+IBOKlOoMUxQ0g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.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-import-assertions": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.28.6.tgz", + "integrity": "sha512-pSJUpFHdx9z5nqTSirOCMtYVP2wFgoWhP0p3g8ONK/4IHhLIBd0B9NYqAvIUAhq+OkhO4VM1tENCt0cjlsNShw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "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-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.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz", + "integrity": "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.26.8.tgz", + "integrity": "sha512-He9Ej2X7tNf2zdKMAGOsmg2MrFc+hfoAhd3po4cWfo/NWjzEAKa0oQruj1ROVUdl0e6fb6/kE/G3SSxE0lRJOg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.26.5", + "@babel/helper-remap-async-to-generator": "^7.25.9", + "@babel/traverse": "^7.26.8" + }, + "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.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.27.1.tgz", + "integrity": "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.6.tgz", + "integrity": "sha512-tt/7wOtBmwHPNMPu7ax4pdPz6shjFrmHDghvNC+FG9Qvj7D6mJcoRQIF5dy4njmxR941l6rgtvfSB2zX3VlUIw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.28.6.tgz", + "integrity": "sha512-dY2wS3I2G7D697VHndN91TJr8/AAfXQNt5ynCTI/MpxMsSzHp+52uNivYT5wCPax3whc47DR8Ba7cmlQMg24bw==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.6.tgz", + "integrity": "sha512-rfQ++ghVwTWTqQ7w8qyDxL1XGihjBss4CmTgGRCTAC9RIbhVpyp4fOeZtta0Lbf+dTNIVJer6ych2ibHwkZqsQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.6.tgz", + "integrity": "sha512-EF5KONAqC5zAqT783iMGuM2ZtmEBy+mJMOKl2BCvPZ2lVrwvXnB6o+OBWCS+CoeCCpVRF2sA2RBKUxvT8tQT5Q==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-globals": "^7.28.0", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-replace-supers": "^7.28.6", + "@babel/traverse": "^7.28.6" + }, + "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.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", + "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.28.6.tgz", + "integrity": "sha512-bcc3k0ijhHbc2lEfpFHgx7eYw9KNXqOerKWfzbxEHUGKnS3sz9C4CNL9OiFN1297bDNfUiSO7DaLzbvHQQQ1BQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/template": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.5.tgz", + "integrity": "sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.28.6.tgz", + "integrity": "sha512-SljjowuNKB7q5Oayv4FoPzeB74g3QgLt8IVJw9ADvWy3QnUb/01aw8I4AVv8wYnPvQz2GDDZ/g3GhcNyDBI4Bg==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.27.1.tgz", + "integrity": "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.29.0.tgz", + "integrity": "sha512-zBPcW2lFGxdiD8PUnPwJjag2J9otbcLQzvbiOzDxpYXyCuYX9agOwMPGn1prVH0a4qzhCKu24rlH4c1f7yA8rw==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.27.1.tgz", + "integrity": "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.28.6.tgz", + "integrity": "sha512-WitabqiGjV/vJ0aPOLSFfNY1u9U3R7W36B03r5I2KoNix+a3sOhJ3pKFB3R5It9/UiK78NiO0KE9P21cMhlPkw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz", + "integrity": "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz", + "integrity": "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz", + "integrity": "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.28.6.tgz", + "integrity": "sha512-Nr+hEN+0geQkzhbdgQVPoqr47lZbm+5fCUmO70722xJZd0Mvb59+33QLImGj6F+DkK3xgDi1YVysP8whD6FQAw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz", + "integrity": "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.6.tgz", + "integrity": "sha512-+anKKair6gpi8VsM/95kmomGNMD0eLz1NQ8+Pfw5sAwWH9fGYXT50E55ZpV0pHUHWf6IUTWPM+f/7AAff+wr9A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.27.1.tgz", + "integrity": "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.27.1.tgz", + "integrity": "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.28.6.tgz", + "integrity": "sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.29.0.tgz", + "integrity": "sha512-PrujnVFbOdUpw4UHiVwKvKRLMMic8+eC0CuNlxjsyZUiBjhFdPsewdXCkveh2KqBA9/waD0W1b4hXSOBQJezpQ==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.29.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.27.1.tgz", + "integrity": "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.29.0.tgz", + "integrity": "sha512-1CZQA5KNAD6ZYQLPw7oi5ewtDNxH/2vuCh+6SmvgDfhumForvs8a1o9n0UrEoBD8HU4djO2yWngTQlXl1NDVEQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.27.1.tgz", + "integrity": "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.28.6.tgz", + "integrity": "sha512-3wKbRgmzYbw24mDJXT7N+ADXw8BC/imU9yo9c9X9NKaLF1fW+e5H1U5QjMUBe4Qo4Ox/o++IyUkl1sVCLgevKg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.28.6.tgz", + "integrity": "sha512-SJR8hPynj8outz+SlStQSwvziMN4+Bq99it4tMIf5/Caq+3iOc0JtKyse8puvyXkk3eFRIA5ID/XfunGgO5i6w==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.6.tgz", + "integrity": "sha512-5rh+JR4JBC4pGkXLAcYdLHZjXudVxWMXbB6u6+E9lRL5TrGVbHt1TjxGbZ8CkmYw9zjkB7jutzOROArsqtncEA==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/plugin-transform-destructuring": "^7.28.5", + "@babel/plugin-transform-parameters": "^7.27.7", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.27.1.tgz", + "integrity": "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.28.6.tgz", + "integrity": "sha512-R8ja/Pyrv0OGAvAXQhSTmWyPJPml+0TMqXlO5w+AsMEiwb2fg3WkOvob7UxFSL3OIttFSGSRFKQsOhJ/X6HQdQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.6.tgz", + "integrity": "sha512-A4zobikRGJTsX9uqVFdafzGkqD30t26ck2LmOzAuLL8b2x6k3TIqRiT2xVvA9fNmFeTX484VpsdgmKNA0bS23w==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.27.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz", + "integrity": "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.28.6.tgz", + "integrity": "sha512-piiuapX9CRv7+0st8lmuUlRSmX6mBcVeNQ1b4AYzJxfCMuBfB0vBXDiGSmm03pKJw1v6cZ8KSeM+oUnM6yAExg==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.28.6.tgz", + "integrity": "sha512-b97jvNSOb5+ehyQmBpmhOCiUC5oVK4PMnpRvO7+ymFBoqYjeDHIU9jnrNUuwHOiL9RpGDoKBpSViarV+BU+eVA==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "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.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", + "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.27.1.tgz", + "integrity": "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.29.0.tgz", + "integrity": "sha512-FijqlqMA7DmRdg/aINBSs04y8XNTYw/lr1gJ2WsmBnnaNw1iS43EPkJW+zK7z65auG3AWRFXWj+NcTQwYptUog==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regexp-modifiers": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.28.6.tgz", + "integrity": "sha512-QGWAepm9qxpaIs7UM9FvUSnCGlb8Ua1RhyM4/veAxLwt3gMat/LSGrZixyuj4I6+Kn9iwvqCyPTtbdxanYoWYg==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.27.1.tgz", + "integrity": "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.26.10.tgz", + "integrity": "sha512-NWaL2qG6HRpONTnj4JvDU6th4jYeZOJgu3QhmFTCihib0ermtOJqktA5BduGm3suhhVe9EMP9c9+mfJ/I9slqw==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.26.5", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.11.0", + "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.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz", + "integrity": "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.28.6.tgz", + "integrity": "sha512-9U4QObUC0FtJl05AsUcodau/RWDytrU6uKgkxu09mLR9HLDAtUMoPuuskm5huQsoktmsYpI+bGmq+iapDcriKA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz", + "integrity": "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz", + "integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.1.tgz", + "integrity": "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.27.1.tgz", + "integrity": "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.28.6.tgz", + "integrity": "sha512-4Wlbdl/sIZjzi/8St0evF0gEZrgOswVO6aOzqxh1kDZOl9WmLrHq2HtGhnOJZmHZYKP8WZ1MDLCt5DAWwRo57A==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz", + "integrity": "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.28.6.tgz", + "integrity": "sha512-/wHc/paTUmsDYN7SZkpWxogTOBNnlx7nBQYfy6JJlCT7G3mVhltk3e++N7zV0XfgGsrqBxd4rJQt9H16I21Y1Q==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.9.tgz", + "integrity": "sha512-vX3qPGE8sEKEAZCWk05k3cpTAE3/nOYca++JA+Rd0z2NCNzabmYvEiSShKzm10zdquOIAVXsy2Ei/DTW34KlKQ==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.26.8", + "@babel/helper-compilation-targets": "^7.26.5", + "@babel/helper-plugin-utils": "^7.26.5", + "@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.26.8", + "@babel/plugin-transform-async-to-generator": "^7.25.9", + "@babel/plugin-transform-block-scoped-functions": "^7.26.5", + "@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.26.3", + "@babel/plugin-transform-export-namespace-from": "^7.25.9", + "@babel/plugin-transform-for-of": "^7.26.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.26.3", + "@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.26.6", + "@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.26.8", + "@babel/plugin-transform-typeof-symbol": "^7.26.7", + "@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.11.0", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "core-js-compat": "^3.40.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.28.6.tgz", + "integrity": "sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "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/runtime": { - "version": "7.28.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.2.tgz", - "integrity": "sha512-KHp2IflsnGywDjBWDkR9iEqiWSpc8GIi0lgTT3mOElT0PP1tG26P4tmFI2YvAdzgq9RGyoHZQEIEdZy6Ec5xCA==", + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.10.tgz", + "integrity": "sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw==", + "dev": true, + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@conform-to/dom": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/@conform-to/dom/-/dom-1.8.2.tgz", - "integrity": "sha512-5eDqI9366+23Fl/E5zxebuy2FCebJKpSrdE/c6PZQ5Ul59BYQ17pBmkLkvxAKjPXW+Qq77BJyjGjuklwmqN08A==" - }, - "node_modules/@conform-to/react": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/@conform-to/react/-/react-1.8.2.tgz", - "integrity": "sha512-AJuHH4YY64o+VP3qsXd7bqlqCJYefTcEVj6mOiQr/m9iQV785gPtGE31jdmipvQ3ZHQE0Lp4e4th7kN/xo46qg==", + "node_modules/@babel/template": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", "dependencies": { - "@conform-to/dom": "1.8.2" + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" }, - "peerDependencies": { - "react": ">=18" + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@conform-to/zod": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/@conform-to/zod/-/zod-1.8.2.tgz", - "integrity": "sha512-uYipAoNByusRji7j84o40r9IvYmsV84utfCfvqr2b746/8JnBuoO6C90yltan5D9OVAJMIKejXW4T1XfOsaMWg==", + "node_modules/@babel/traverse": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", "dependencies": { - "@conform-to/dom": "1.8.2" + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0", + "debug": "^4.3.1" }, - "peerDependencies": { - "zod": "^3.21.0 || ^4.0.0" + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@emnapi/core": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.4.5.tgz", - "integrity": "sha512-XsLw1dEOpkSX/WucdqUhPWP7hDxSvZiY+fsUC14h+FtQ2Ifni4znbBt8punRX+Uj2JG/uDb8nEHVKvrVlvdZ5Q==", + "node_modules/@babel/traverse/node_modules/@babel/generator": { + "version": "7.29.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", + "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", + "dependencies": { + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.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.6.1", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.6.1.tgz", + "integrity": "sha512-boghen8F0Q8D+0/Q1/1r6DUEieUJ8w2a1gIknExMSHBsJFOr2+0KUfHiVYBvucPwl3+RU5PFBK833FjFCh3BhA==", + "dev": true, + "engines": { + "node": ">=14.17.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.23.0.tgz", + "integrity": "sha512-3sG8Zwa5fMcA9bgqB8AfWPQ+HFke6uD3h1s3RIwUNK8EG7a4buxvuFTs3j1IMs2NXAk9F30C/FF4vxRgQCcmoQ==", + "cpu": [ + "ppc64" + ], "dev": true, "optional": true, - "dependencies": { - "@emnapi/wasi-threads": "1.0.4", - "tslib": "^2.4.0" + "os": [ + "aix" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@emnapi/runtime": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.5.tgz", - "integrity": "sha512-++LApOtY0pEEz1zrd9vy1/zXVaVJJ/EbAF3u0fXIzPJEDtnITsBGbbK0EkM72amhl/R5b+5xx0Y/QhcVOpuulg==", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/wasi-threads": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.0.4.tgz", - "integrity": "sha512-PJR+bOmMOPH8AtcTGAyYNiuJ3/Fcoj2XN/gBEWzDIKh254XO+mM9XoXHk5GNEhodxeMznbg7BlRojVbKN+gC6g==", + "node_modules/@esbuild/android-arm": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.23.0.tgz", + "integrity": "sha512-+KuOHTKKyIKgEEqKbGTK8W7mPp+hKinbMBeEnNzjJGyFcWsfrXjSTNluJHCY1RqhxFurdD8uNXQDei7qDlR6+g==", + "cpu": [ + "arm" + ], "dev": true, "optional": true, - "dependencies": { - "tslib": "^2.4.0" + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.23.0.tgz", + "integrity": "sha512-EuHFUYkAVfU4qBdyivULuu03FhJO4IJN9PGuABGrFy4vUuzk91P2d+npxHcFdpUnfYKy0PuV+n6bKIpHOB3prQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.23.0.tgz", + "integrity": "sha512-WRrmKidLoKDl56LsbBMhzTTBxrsVwTKdNbKDalbEZr0tcsBgCLbEtoNthOW6PX942YiYq8HzEnb4yWQMLQuipQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.23.0.tgz", + "integrity": "sha512-YLntie/IdS31H54Ogdn+v50NuoWF5BDkEUFpiOChVa9UnKpftgwzZRrI4J132ETIi+D8n6xh9IviFV3eXdxfow==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.23.0.tgz", + "integrity": "sha512-IMQ6eme4AfznElesHUPDZ+teuGwoRmVuuixu7sv92ZkdQcPbsNHzutd+rAfaBKo8YK3IrBEi9SLLKWJdEvJniQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.0.tgz", + "integrity": "sha512-0muYWCng5vqaxobq6LB3YNtevDFSAZGlgtLoAc81PjUfiFz36n4KMpwhtAd4he8ToSI3TGyuhyx5xmiWNYZFyw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.23.0.tgz", + "integrity": "sha512-XKDVu8IsD0/q3foBzsXGt/KjD/yTKBCIwOHE1XwiXmrRwrX6Hbnd5Eqn/WvDekddK21tfszBSrE/WMaZh+1buQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.23.0.tgz", + "integrity": "sha512-SEELSTEtOFu5LPykzA395Mc+54RMg1EUgXP+iw2SJ72+ooMwVsgfuwXo5Fn0wXNgWZsTVHwY2cg4Vi/bOD88qw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.23.0.tgz", + "integrity": "sha512-j1t5iG8jE7BhonbsEg5d9qOYcVZv/Rv6tghaXM/Ug9xahM0nX/H2gfu6X6z11QRTMT6+aywOMA8TDkhPo8aCGw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.23.0.tgz", + "integrity": "sha512-P7O5Tkh2NbgIm2R6x1zGJJsnacDzTFcRWZyTTMgFdVit6E98LTxO+v8LCCLWRvPrjdzXHx9FEOA8oAZPyApWUA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.23.0.tgz", + "integrity": "sha512-InQwepswq6urikQiIC/kkx412fqUZudBO4SYKu0N+tGhXRWUqAx+Q+341tFV6QdBifpjYgUndV1hhMq3WeJi7A==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.23.0.tgz", + "integrity": "sha512-J9rflLtqdYrxHv2FqXE2i1ELgNjT+JFURt/uDMoPQLcjWQA5wDKgQA4t/dTqGa88ZVECKaD0TctwsUfHbVoi4w==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.23.0.tgz", + "integrity": "sha512-cShCXtEOVc5GxU0fM+dsFD10qZ5UpcQ8AM22bYj0u/yaAykWnqXJDpd77ublcX6vdDsWLuweeuSNZk4yUxZwtw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.23.0.tgz", + "integrity": "sha512-HEtaN7Y5UB4tZPeQmgz/UhzoEyYftbMXrBCUjINGjh3uil+rB/QzzpMshz3cNUxqXN7Vr93zzVtpIDL99t9aRw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.23.0.tgz", + "integrity": "sha512-WDi3+NVAuyjg/Wxi+o5KPqRbZY0QhI9TjrEEm+8dmpY9Xir8+HE/HNx2JoLckhKbFopW0RdO2D72w8trZOV+Wg==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.23.0.tgz", + "integrity": "sha512-a3pMQhUEJkITgAw6e0bWA+F+vFtCciMjW/LPtoj99MhVt+Mfb6bbL9hu2wmTZgNd994qTAEw+U/r6k3qHWWaOQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.23.0.tgz", + "integrity": "sha512-cRK+YDem7lFTs2Q5nEv/HHc4LnrfBCbH5+JHu6wm2eP+d8OZNoSMYgPZJq78vqQ9g+9+nMuIsAO7skzphRXHyw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.0.tgz", + "integrity": "sha512-suXjq53gERueVWu0OKxzWqk7NxiUWSUlrxoZK7usiF50C6ipColGR5qie2496iKGYNLhDZkPxBI3erbnYkU0rQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.23.0.tgz", + "integrity": "sha512-6p3nHpby0DM/v15IFKMjAaayFhqnXV52aEmv1whZHX56pdkK+MEaLoQWj+H42ssFarP1PcomVhbsR4pkz09qBg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.23.0.tgz", + "integrity": "sha512-BFelBGfrBwk6LVrmFzCq1u1dZbG4zy/Kp93w2+y83Q5UGYF1d8sCzeLI9NXjKyujjBBniQa8R8PzLFAUrSM9OA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.23.0.tgz", + "integrity": "sha512-lY6AC8p4Cnb7xYHuIxQ6iYPe6MfO2CC43XXKo9nBXDb35krYt7KGhQnOkRGar5psxYkircpCqfbNDB4uJbS2jQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.23.0.tgz", + "integrity": "sha512-7L1bHlOTcO4ByvI7OXVI5pNN6HSu6pUQq9yodga8izeuB1KcT2UkHaH6118QJwopExPn0rMHIseCTx1CRo/uNA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.23.0.tgz", + "integrity": "sha512-Arm+WgUFLUATuoxCJcahGuk6Yj9Pzxd6l11Zb/2aAuv5kWWvvfhLFo2fni4uSK5vzlUdCGZ/BdV5tH8klj8p8g==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", - "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", "dev": true, "dependencies": { "eslint-visitor-keys": "^3.4.3" @@ -143,72 +2944,25 @@ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, - "node_modules/@eslint-community/eslint-utils/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-community/regexpp": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", - "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, - "node_modules/@eslint/config-array": { - "version": "0.21.0", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.0.tgz", - "integrity": "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==", - "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-helpers": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.0.tgz", - "integrity": "sha512-ViuymvFmcJi04qdZeDc2whTHryouGcDlaxPqarTD0ZE10ISpxGUVZGZDx4w01upyIynL3iu6IXH2bS1NhclQMw==", - "dev": true, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/core": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.1.tgz", - "integrity": "sha512-bkOp+iumZCCbt1K1CmWf0R9pM5yKpDv+ZXtvSyQpudrI9kuFLp+bM2WOPXImuD/ceQuaa8f5pj93Y7zyECIGNA==", - "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.3.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", - "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", + "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": "^10.0.1", - "globals": "^14.0.0", + "espree": "^9.6.0", + "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -216,79 +2970,109 @@ "strip-json-comments": "^3.1.1" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, - "node_modules/@eslint/js": { - "version": "9.32.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.32.0.tgz", - "integrity": "sha512-BBpRFZK3eX6uMLKz8WxFOBIFFcGFJ/g8XuwjTHCqHROSIsopI+ddn/d5Cfh36+7+e5edVS8dbSHnBNhrLEX0zg==", - "dev": true, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://eslint.org/donate" - } - }, - "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.3.4", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.4.tgz", - "integrity": "sha512-Ul5l+lHEcw3L5+k8POx6r74mxEYKG5kOb6Xpy2gCRW6zweT6TEhAf8vhxGgjhqrd/VO/Dirhsb+1hNpD1ue9hw==", + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", "dev": true, "dependencies": { - "@eslint/core": "^0.15.1", - "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" + "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/nzakas" + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/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/@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.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", + "deprecated": "Use @eslint/config-array instead", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.3", + "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.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" } }, "node_modules/@humanwhocodes/module-importer": { @@ -304,566 +3088,989 @@ "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@humanwhocodes/retry": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", - "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "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/@inquirer/checkbox": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-2.5.0.tgz", + "integrity": "sha512-sMgdETOfi2dUHT8r7TT1BTKOwNvdDGFDXYWtQ2J69SvlYNntk9I/gJe7r5yvMwwsuKnYbuRs3pNhx4tgNck5aA==", + "dev": true, + "dependencies": { + "@inquirer/core": "^9.1.0", + "@inquirer/figures": "^1.0.5", + "@inquirer/type": "^1.5.3", + "ansi-escapes": "^4.3.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/confirm": { + "version": "3.1.22", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-3.1.22.tgz", + "integrity": "sha512-gsAKIOWBm2Q87CDfs9fEo7wJT3fwWIJfnDGMn9Qy74gBnNFOACDNfhUzovubbJjWnKLGBln7/NcSmZwj5DuEXg==", + "dev": true, + "dependencies": { + "@inquirer/core": "^9.0.10", + "@inquirer/type": "^1.5.2" + }, + "engines": { + "node": ">=18" + } + }, + "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, + "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/core/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, + "dependencies": { + "mute-stream": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/editor": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-2.2.0.tgz", + "integrity": "sha512-9KHOpJ+dIL5SZli8lJ6xdaYLPPzB8xB9GZItg39MBybzhxA16vxmszmQFrRwbOA918WA2rvu8xhDEg/p6LXKbw==", + "dev": true, + "dependencies": { + "@inquirer/core": "^9.1.0", + "@inquirer/type": "^1.5.3", + "external-editor": "^3.1.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/expand": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-2.3.0.tgz", + "integrity": "sha512-qnJsUcOGCSG1e5DTOErmv2BPQqrtT6uzqn1vI/aYGiPKq+FgslGZmtdnXbhuI7IlT7OByDoEEqdnhUnVR2hhLw==", + "dev": true, + "dependencies": { + "@inquirer/core": "^9.1.0", + "@inquirer/type": "^1.5.3", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/figures": { + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.15.tgz", + "integrity": "sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==", "dev": true, "engines": { - "node": ">=18.18" + "node": ">=18" + } + }, + "node_modules/@inquirer/input": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-2.3.0.tgz", + "integrity": "sha512-XfnpCStx2xgh1LIRqPXrTNEEByqQWoxsWYzNRSEUxJ5c6EQlhMogJ3vHKu8aXuTacebtaZzMAHwEL0kAflKOBw==", + "dev": true, + "dependencies": { + "@inquirer/core": "^9.1.0", + "@inquirer/type": "^1.5.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/number": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-1.1.0.tgz", + "integrity": "sha512-ilUnia/GZUtfSZy3YEErXLJ2Sljo/mf9fiKc08n18DdwdmDbOzRcTv65H1jjDvlsAuvdFXf4Sa/aL7iw/NanVA==", + "dev": true, + "dependencies": { + "@inquirer/core": "^9.1.0", + "@inquirer/type": "^1.5.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/password": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-2.2.0.tgz", + "integrity": "sha512-5otqIpgsPYIshqhgtEwSspBQE40etouR8VIxzpJkv9i0dVHIpyhiivbkH9/dGiMLdyamT54YRdGJLfl8TFnLHg==", + "dev": true, + "dependencies": { + "@inquirer/core": "^9.1.0", + "@inquirer/type": "^1.5.3", + "ansi-escapes": "^4.3.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/prompts": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-5.3.8.tgz", + "integrity": "sha512-b2BudQY/Si4Y2a0PdZZL6BeJtl8llgeZa7U2j47aaJSCeAl1e4UI7y8a9bSkO3o/ZbZrgT5muy/34JbsjfIWxA==", + "dev": true, + "dependencies": { + "@inquirer/checkbox": "^2.4.7", + "@inquirer/confirm": "^3.1.22", + "@inquirer/editor": "^2.1.22", + "@inquirer/expand": "^2.1.22", + "@inquirer/input": "^2.2.9", + "@inquirer/number": "^1.0.10", + "@inquirer/password": "^2.1.22", + "@inquirer/rawlist": "^2.2.4", + "@inquirer/search": "^1.0.7", + "@inquirer/select": "^2.4.7" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/rawlist": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-2.3.0.tgz", + "integrity": "sha512-zzfNuINhFF7OLAtGHfhwOW2TlYJyli7lOUoJUXw/uyklcwalV6WRXBXtFIicN8rTRK1XTiPWB4UY+YuW8dsnLQ==", + "dev": true, + "dependencies": { + "@inquirer/core": "^9.1.0", + "@inquirer/type": "^1.5.3", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/search": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-1.1.0.tgz", + "integrity": "sha512-h+/5LSj51dx7hp5xOn4QFnUaKeARwUCLs6mIhtkJ0JYPBLmEYjdHSYh7I6GrLg9LwpJ3xeX0FZgAG1q0QdCpVQ==", + "dev": true, + "dependencies": { + "@inquirer/core": "^9.1.0", + "@inquirer/figures": "^1.0.5", + "@inquirer/type": "^1.5.3", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/select": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-2.5.0.tgz", + "integrity": "sha512-YmDobTItPP3WcEI86GvPo+T2sRHkxxOq/kXmsBjHS5BVXUgvgZ5AfJjkvQvZr03T81NnI3KrrRuMzeuYUQRFOA==", + "dev": true, + "dependencies": { + "@inquirer/core": "^9.1.0", + "@inquirer/figures": "^1.0.5", + "@inquirer/type": "^1.5.3", + "ansi-escapes": "^4.3.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "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/@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.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "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.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "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.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "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/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.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "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==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "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/nzakas" + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" } }, - "node_modules/@img/sharp-darwin-arm64": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.3.tgz", - "integrity": "sha512-ryFMfvxxpQRsgZJqBd4wsttYQbCxsJksrv9Lw/v798JcQ8+w84mBWuXwl+TT0WJ/WrYOLaYpwQXi3sA9nTIaIg==", + "node_modules/@jsonjoy.com/buffers": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-17.67.0.tgz", + "integrity": "sha512-tfExRpYxBvi32vPs9ZHaTjSP4fHAfzSmcahOfNxtvGHcyJel+aibkPlGeBB+7AoC6hL7lXIE++8okecBxx7lcw==", + "dev": true, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/codegen": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/codegen/-/codegen-1.0.0.tgz", + "integrity": "sha512-E8Oy+08cmCf0EK/NMxpaJZmOxPqM+6iSe2S4nlSBrPZOORoDJILxtbSUEDKQyTamm/BVAhIGllOBNU79/dwf0g==", + "dev": true, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-core": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-core/-/fs-core-4.57.1.tgz", + "integrity": "sha512-YrEi/ZPmgc+GfdO0esBF04qv8boK9Dg9WpRQw/+vM8Qt3nnVIJWIa8HwZ/LXVZ0DB11XUROM8El/7yYTJX+WtA==", + "dev": true, + "dependencies": { + "@jsonjoy.com/fs-node-builtins": "4.57.1", + "@jsonjoy.com/fs-node-utils": "4.57.1", + "thingies": "^2.5.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-fsa": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-fsa/-/fs-fsa-4.57.1.tgz", + "integrity": "sha512-ooEPvSW/HQDivPDPZMibHGKZf/QS4WRir1czGZmXmp3MsQqLECZEpN0JobrD8iV9BzsuwdIv+PxtWX9WpPLsIA==", + "dev": true, + "dependencies": { + "@jsonjoy.com/fs-core": "4.57.1", + "@jsonjoy.com/fs-node-builtins": "4.57.1", + "@jsonjoy.com/fs-node-utils": "4.57.1", + "thingies": "^2.5.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-node": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node/-/fs-node-4.57.1.tgz", + "integrity": "sha512-3YaKhP8gXEKN+2O49GLNfNb5l2gbnCFHyAaybbA2JkkbQP3dpdef7WcUaHAulg/c5Dg4VncHsA3NWAUSZMR5KQ==", + "dev": true, + "dependencies": { + "@jsonjoy.com/fs-core": "4.57.1", + "@jsonjoy.com/fs-node-builtins": "4.57.1", + "@jsonjoy.com/fs-node-utils": "4.57.1", + "@jsonjoy.com/fs-print": "4.57.1", + "@jsonjoy.com/fs-snapshot": "4.57.1", + "glob-to-regex.js": "^1.0.0", + "thingies": "^2.5.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-node-builtins": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-builtins/-/fs-node-builtins-4.57.1.tgz", + "integrity": "sha512-XHkFKQ5GSH3uxm8c3ZYXVrexGdscpWKIcMWKFQpMpMJc8gA3AwOMBJXJlgpdJqmrhPyQXxaY9nbkNeYpacC0Og==", + "dev": true, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-node-to-fsa": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-to-fsa/-/fs-node-to-fsa-4.57.1.tgz", + "integrity": "sha512-pqGHyWWzNck4jRfaGV39hkqpY5QjRUQ/nRbNT7FYbBa0xf4bDG+TE1Gt2KWZrSkrkZZDE3qZUjYMbjwSliX6pg==", + "dev": true, + "dependencies": { + "@jsonjoy.com/fs-fsa": "4.57.1", + "@jsonjoy.com/fs-node-builtins": "4.57.1", + "@jsonjoy.com/fs-node-utils": "4.57.1" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-node-utils": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-utils/-/fs-node-utils-4.57.1.tgz", + "integrity": "sha512-vp+7ZzIB8v43G+GLXTS4oDUSQmhAsRz532QmmWBbdYA20s465JvwhkSFvX9cVTqRRAQg+vZ7zWDaIEh0lFe2gw==", + "dev": true, + "dependencies": { + "@jsonjoy.com/fs-node-builtins": "4.57.1" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-print": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-print/-/fs-print-4.57.1.tgz", + "integrity": "sha512-Ynct7ZJmfk6qoXDOKfpovNA36ITUx8rChLmRQtW08J73VOiuNsU8PB6d/Xs7fxJC2ohWR3a5AqyjmLojfrw5yw==", + "dev": true, + "dependencies": { + "@jsonjoy.com/fs-node-utils": "4.57.1", + "tree-dump": "^1.1.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-snapshot/-/fs-snapshot-4.57.1.tgz", + "integrity": "sha512-/oG8xBNFMbDXTq9J7vepSA1kerS5vpgd3p5QZSPd+nX59uwodGJftI51gDYyHRpP57P3WCQf7LHtBYPqwUg2Bg==", + "dev": true, + "dependencies": { + "@jsonjoy.com/buffers": "^17.65.0", + "@jsonjoy.com/fs-node-utils": "4.57.1", + "@jsonjoy.com/json-pack": "^17.65.0", + "@jsonjoy.com/util": "^17.65.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/base64": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-17.67.0.tgz", + "integrity": "sha512-5SEsJGsm15aP8TQGkDfJvz9axgPwAEm98S5DxOuYe8e1EbfajcDmgeXXzccEjh+mLnjqEKrkBdjHWS5vFNwDdw==", + "dev": true, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/codegen": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/codegen/-/codegen-17.67.0.tgz", + "integrity": "sha512-idnkUplROpdBOV0HMcwhsCUS5TRUi9poagdGs70A6S4ux9+/aPuKbh8+UYRTLYQHtXvAdNfQWXDqZEx5k4Dj2Q==", + "dev": true, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/json-pack": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-17.67.0.tgz", + "integrity": "sha512-t0ejURcGaZsn1ClbJ/3kFqSOjlryd92eQY465IYrezsXmPcfHPE/av4twRSxf6WE+TkZgLY+71vCZbiIiFKA/w==", + "dev": true, + "dependencies": { + "@jsonjoy.com/base64": "17.67.0", + "@jsonjoy.com/buffers": "17.67.0", + "@jsonjoy.com/codegen": "17.67.0", + "@jsonjoy.com/json-pointer": "17.67.0", + "@jsonjoy.com/util": "17.67.0", + "hyperdyperid": "^1.2.0", + "thingies": "^2.5.0", + "tree-dump": "^1.1.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/json-pointer": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pointer/-/json-pointer-17.67.0.tgz", + "integrity": "sha512-+iqOFInH+QZGmSuaybBUNdh7yvNrXvqR+h3wjXm0N/3JK1EyyFAeGJvqnmQL61d1ARLlk/wJdFKSL+LHJ1eaUA==", + "dev": true, + "dependencies": { + "@jsonjoy.com/util": "17.67.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/util": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-17.67.0.tgz", + "integrity": "sha512-6+8xBaz1rLSohlGh68D1pdw3AwDi9xydm8QNlAFkvnavCJYSze+pxoW2VKP8p308jtlMRLs5NTHfPlZLd4w7ew==", + "dev": true, + "dependencies": { + "@jsonjoy.com/buffers": "17.67.0", + "@jsonjoy.com/codegen": "17.67.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/json-pack": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.21.0.tgz", + "integrity": "sha512-+AKG+R2cfZMShzrF2uQw34v3zbeDYUqnQ+jg7ORic3BGtfw9p/+N6RJbq/kkV8JmYZaINknaEQ2m0/f693ZPpg==", + "dev": true, + "dependencies": { + "@jsonjoy.com/base64": "^1.1.2", + "@jsonjoy.com/buffers": "^1.2.0", + "@jsonjoy.com/codegen": "^1.0.0", + "@jsonjoy.com/json-pointer": "^1.0.2", + "@jsonjoy.com/util": "^1.9.0", + "hyperdyperid": "^1.2.0", + "thingies": "^2.5.0", + "tree-dump": "^1.1.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/json-pack/node_modules/@jsonjoy.com/buffers": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-1.2.1.tgz", + "integrity": "sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==", + "dev": true, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/json-pointer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pointer/-/json-pointer-1.0.2.tgz", + "integrity": "sha512-Fsn6wM2zlDzY1U+v4Nc8bo3bVqgfNTGcn6dMgs6FjrEnt4ZCe60o6ByKRjOGlI2gow0aE/Q41QOigdTqkyK5fg==", + "dev": true, + "dependencies": { + "@jsonjoy.com/codegen": "^1.0.0", + "@jsonjoy.com/util": "^1.9.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/util": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.9.0.tgz", + "integrity": "sha512-pLuQo+VPRnN8hfPqUTLTHk126wuYdXVxE6aDmjSeV4NCAgyxWbiOIeNJVtID3h1Vzpoi9m4jXezf73I6LgabgQ==", + "dev": true, + "dependencies": { + "@jsonjoy.com/buffers": "^1.0.0", + "@jsonjoy.com/codegen": "^1.0.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/util/node_modules/@jsonjoy.com/buffers": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-1.2.1.tgz", + "integrity": "sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==", + "dev": true, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@kurkle/color": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.4.tgz", + "integrity": "sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==" + }, + "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.15", + "resolved": "https://registry.npmjs.org/@listr2/prompt-adapter-inquirer/-/prompt-adapter-inquirer-2.0.15.tgz", + "integrity": "sha512-MZrGem/Ujjd4cPTLYDfCZK2iKKeiO/8OX13S6jqxldLs0Prf2aGqVlJ77nMBqMv7fzqgXEgjrNHLXcKR8l9lOg==", + "dev": true, + "dependencies": { + "@inquirer/type": "^1.5.1" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@inquirer/prompts": ">= 3 < 6" + } + }, + "node_modules/@lmdb/lmdb-darwin-arm64": { + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-3.0.13.tgz", + "integrity": "sha512-uiKPB0Fv6WEEOZjruu9a6wnW/8jrjzlZbxXscMB8kuCJ1k6kHpcBnuvaAWcqhbI7rqX5GKziwWEdD+wi2gNLfA==", "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "darwin" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-darwin-arm64": "1.2.0" - } + ] }, - "node_modules/@img/sharp-darwin-x64": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.3.tgz", - "integrity": "sha512-yHpJYynROAj12TA6qil58hmPmAwxKKC7reUqtGLzsOHfP7/rniNGTL8tjWX6L3CTV4+5P4ypcS7Pp+7OB+8ihA==", + "node_modules/@lmdb/lmdb-darwin-x64": { + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-3.0.13.tgz", + "integrity": "sha512-bEVIIfK5mSQoG1R19qA+fJOvCB+0wVGGnXHT3smchBVahYBdlPn2OsZZKzlHWfb1E+PhLBmYfqB5zQXFP7hJig==", "cpu": [ "x64" ], + "dev": true, "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.2.0" - } + ] }, - "node_modules/@img/sharp-libvips-darwin-arm64": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.0.tgz", - "integrity": "sha512-sBZmpwmxqwlqG9ueWFXtockhsxefaV6O84BMOrhtg/YqbTaRdqDE7hxraVE3y6gVM4eExmfzW4a8el9ArLeEiQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-darwin-x64": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.0.tgz", - "integrity": "sha512-M64XVuL94OgiNHa5/m2YvEQI5q2cl9d/wk0qFTDVXcYzi43lxuiFTftMR1tOnFQovVXNZJ5TURSDK2pNe9Yzqg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-arm": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.0.tgz", - "integrity": "sha512-mWd2uWvDtL/nvIzThLq3fr2nnGfyr/XMXlq8ZJ9WMR6PXijHlC3ksp0IpuhK6bougvQrchUAfzRLnbsen0Cqvw==", + "node_modules/@lmdb/lmdb-linux-arm": { + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-3.0.13.tgz", + "integrity": "sha512-Yml1KlMzOnXj/tnW7yX8U78iAzTk39aILYvCPbqeewAq1kSzl+w59k/fiVkTBfvDi/oW/5YRxL+Fq+Y1Fr1r2Q==", "cpu": [ "arm" ], + "dev": true, "optional": true, "os": [ "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } + ] }, - "node_modules/@img/sharp-libvips-linux-arm64": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.0.tgz", - "integrity": "sha512-RXwd0CgG+uPRX5YYrkzKyalt2OJYRiJQ8ED/fi1tq9WQW2jsQIn0tqrlR5l5dr/rjqq6AHAxURhj2DVjyQWSOA==", + "node_modules/@lmdb/lmdb-linux-arm64": { + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-3.0.13.tgz", + "integrity": "sha512-afbVrsMgZ9dUTNUchFpj5VkmJRxvht/u335jUJ7o23YTbNbnpmXif3VKQGCtnjSh+CZaqm6N3CPG8KO3zwyZ1Q==", "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } + ] }, - "node_modules/@img/sharp-libvips-linux-ppc64": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.0.tgz", - "integrity": "sha512-Xod/7KaDDHkYu2phxxfeEPXfVXFKx70EAFZ0qyUdOjCcxbjqyJOEUpDe6RIyaunGxT34Anf9ue/wuWOqBW2WcQ==", - "cpu": [ - "ppc64" - ], - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-s390x": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.0.tgz", - "integrity": "sha512-eMKfzDxLGT8mnmPJTNMcjfO33fLiTDsrMlUVcp6b96ETbnJmd4uvZxVJSKPQfS+odwfVaGifhsB07J1LynFehw==", - "cpu": [ - "s390x" - ], - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-x64": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.0.tgz", - "integrity": "sha512-ZW3FPWIc7K1sH9E3nxIGB3y3dZkpJlMnkk7z5tu1nSkBoCgw2nSRTFHI5pB/3CQaJM0pdzMF3paf9ckKMSE9Tg==", + "node_modules/@lmdb/lmdb-linux-x64": { + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-3.0.13.tgz", + "integrity": "sha512-vOtxu0xC0SLdQ2WRXg8Qgd8T32ak4SPqk5zjItRszrJk2BdeXqfGxBJbP7o4aOvSPSmSSv46Lr1EP4HXU8v7Kg==", "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } + ] }, - "node_modules/@img/sharp-libvips-linuxmusl-arm64": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.0.tgz", - "integrity": "sha512-UG+LqQJbf5VJ8NWJ5Z3tdIe/HXjuIdo4JeVNADXBFuG7z9zjoegpzzGIyV5zQKi4zaJjnAd2+g2nna8TZvuW9Q==", + "node_modules/@lmdb/lmdb-win32-x64": { + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-3.0.13.tgz", + "integrity": "sha512-UCrMJQY/gJnOl3XgbWRZZUvGGBuKy6i0YNSptgMzHBjs+QYDYR1Mt/RLTOPy4fzzves65O1EDmlL//OzEqoLlA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "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": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } + "darwin" + ] }, - "node_modules/@img/sharp-libvips-linuxmusl-x64": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.0.tgz", - "integrity": "sha512-SRYOLR7CXPgNze8akZwjoGBoN1ThNZoqpOgfnOxmWsklTGVfJiGJoC/Lod7aNMGA1jSsKWM1+HRX43OP6p9+6Q==", + "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": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } + "darwin" + ] }, - "node_modules/@img/sharp-linux-arm": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.3.tgz", - "integrity": "sha512-oBK9l+h6KBN0i3dC8rYntLiVfW8D8wH+NPNT3O/WBHeW0OQWCjfWksLUaPidsrDKpJgXp3G3/hkmhptAW0I3+A==", + "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" ], - "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.2.0" - } - }, - "node_modules/@img/sharp-linux-arm64": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.3.tgz", - "integrity": "sha512-QdrKe3EvQrqwkDrtuTIjI0bu6YEJHTgEeqdzI3uWJOH6G1O8Nl1iEeVYRGdj1h5I21CqxSvQp1Yv7xeU3ZewbA==", - "cpu": [ - "arm64" - ], - "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.2.0" - } - }, - "node_modules/@img/sharp-linux-ppc64": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.3.tgz", - "integrity": "sha512-GLtbLQMCNC5nxuImPR2+RgrviwKwVql28FWZIW1zWruy6zLgA5/x2ZXk3mxj58X/tszVF69KK0Is83V8YgWhLA==", - "cpu": [ - "ppc64" - ], - "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-ppc64": "1.2.0" - } - }, - "node_modules/@img/sharp-linux-s390x": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.3.tgz", - "integrity": "sha512-3gahT+A6c4cdc2edhsLHmIOXMb17ltffJlxR0aC2VPZfwKoTGZec6u5GrFgdR7ciJSsHT27BD3TIuGcuRT0KmQ==", - "cpu": [ - "s390x" - ], - "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.2.0" - } - }, - "node_modules/@img/sharp-linux-x64": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.3.tgz", - "integrity": "sha512-8kYso8d806ypnSq3/Ly0QEw90V5ZoHh10yH0HnrzOCr6DKAPI6QVHvwleqMkVQ0m+fc7EH8ah0BB0QPuWY6zJQ==", - "cpu": [ - "x64" - ], - "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.2.0" - } - }, - "node_modules/@img/sharp-linuxmusl-arm64": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.3.tgz", - "integrity": "sha512-vAjbHDlr4izEiXM1OTggpCcPg9tn4YriK5vAjowJsHwdBIdx0fYRsURkxLG2RLm9gyBq66gwtWI8Gx0/ov+JKQ==", - "cpu": [ - "arm64" - ], - "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.2.0" - } - }, - "node_modules/@img/sharp-linuxmusl-x64": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.3.tgz", - "integrity": "sha512-gCWUn9547K5bwvOn9l5XGAEjVTTRji4aPTqLzGXHvIr6bIDZKNTA34seMPgM0WmSf+RYBH411VavCejp3PkOeQ==", - "cpu": [ - "x64" - ], - "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.2.0" - } - }, - "node_modules/@img/sharp-wasm32": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.3.tgz", - "integrity": "sha512-+CyRcpagHMGteySaWos8IbnXcHgfDn7pO2fiC2slJxvNq9gDipYBN42/RagzctVRKgxATmfqOSulgZv5e1RdMg==", - "cpu": [ - "wasm32" - ], - "optional": true, - "dependencies": { - "@emnapi/runtime": "^1.4.4" - }, - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-win32-arm64": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.3.tgz", - "integrity": "sha512-MjnHPnbqMXNC2UgeLJtX4XqoVHHlZNd+nPt1kRPmj63wURegwBhZlApELdtxM2OIZDRv/DFtLcNhVbd1z8GYXQ==", - "cpu": [ - "arm64" - ], - "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-ia32": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.3.tgz", - "integrity": "sha512-xuCdhH44WxuXgOM714hn4amodJMZl3OEvf0GVTm0BEyMeA2to+8HEdRPShH0SLYptJY1uBw+SCFP9WVQi1Q/cw==", - "cpu": [ - "ia32" - ], - "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.34.3", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.3.tgz", - "integrity": "sha512-OWwz05d++TxzLEv4VnsTz5CmZ6mI6S05sfQGEMrNrQcOEERbX46332IvE7pO/EUiw7jUrrS40z/M7kPyjfl04g==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@napi-rs/wasm-runtime": { - "version": "0.2.12", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", - "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", "dev": true, "optional": true, - "dependencies": { - "@emnapi/core": "^1.4.3", - "@emnapi/runtime": "^1.4.3", - "@tybys/wasm-util": "^0.10.0" - } + "os": [ + "linux" + ] }, - "node_modules/@next/env": { - "version": "15.4.5", - "resolved": "https://registry.npmjs.org/@next/env/-/env-15.4.5.tgz", - "integrity": "sha512-ruM+q2SCOVCepUiERoxOmZY9ZVoecR3gcXNwCYZRvQQWRjhOiPJGmQ2fAiLR6YKWXcSAh7G79KEFxN3rwhs4LQ==" - }, - "node_modules/@next/eslint-plugin-next": { - "version": "15.4.5", - "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-15.4.5.tgz", - "integrity": "sha512-YhbrlbEt0m4jJnXHMY/cCUDBAWgd5SaTa5mJjzOt82QwflAFfW/h3+COp2TfVSzhmscIZ5sg2WXt3MLziqCSCw==", + "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, - "dependencies": { - "fast-glob": "3.3.1" - } - }, - "node_modules/@next/swc-darwin-arm64": { - "version": "15.4.5", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.4.5.tgz", - "integrity": "sha512-84dAN4fkfdC7nX6udDLz9GzQlMUwEMKD7zsseXrl7FTeIItF8vpk1lhLEnsotiiDt+QFu3O1FVWnqwcRD2U3KA==", - "cpu": [ - "arm64" - ], "optional": true, "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } + "linux" + ] }, - "node_modules/@next/swc-darwin-x64": { - "version": "15.4.5", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.4.5.tgz", - "integrity": "sha512-CL6mfGsKuFSyQjx36p2ftwMNSb8PQog8y0HO/ONLdQqDql7x3aJb/wB+LA651r4we2pp/Ck+qoRVUeZZEvSurA==", + "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" ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-arm64-gnu": { - "version": "15.4.5", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.4.5.tgz", - "integrity": "sha512-1hTVd9n6jpM/thnDc5kYHD1OjjWYpUJrJxY4DlEacT7L5SEOXIifIdTye6SQNNn8JDZrcN+n8AWOmeJ8u3KlvQ==", - "cpu": [ - "arm64" - ], + "dev": true, "optional": true, "os": [ "linux" - ], - "engines": { - "node": ">= 10" - } + ] }, - "node_modules/@next/swc-linux-arm64-musl": { - "version": "15.4.5", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.4.5.tgz", - "integrity": "sha512-4W+D/nw3RpIwGrqpFi7greZ0hjrCaioGErI7XHgkcTeWdZd146NNu1s4HnaHonLeNTguKnL2Urqvj28UJj6Gqw==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-x64-gnu": { - "version": "15.4.5", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.4.5.tgz", - "integrity": "sha512-N6Mgdxe/Cn2K1yMHge6pclffkxzbSGOydXVKYOjYqQXZYjLCfN/CuFkaYDeDHY2VBwSHyM2fUjYBiQCIlxIKDA==", + "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" ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-x64-musl": { - "version": "15.4.5", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.4.5.tgz", - "integrity": "sha512-YZ3bNDrS8v5KiqgWE0xZQgtXgCTUacgFtnEgI4ccotAASwSvcMPDLua7BWLuTfucoRv6mPidXkITJLd8IdJplQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-arm64-msvc": { - "version": "15.4.5", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.4.5.tgz", - "integrity": "sha512-9Wr4t9GkZmMNcTVvSloFtjzbH4vtT4a8+UHqDoVnxA5QyfWe6c5flTH1BIWPGNWSUlofc8dVJAE7j84FQgskvQ==", - "cpu": [ - "arm64" - ], + "dev": true, "optional": true, "os": [ "win32" - ], - "engines": { - "node": ">= 10" - } + ] }, - "node_modules/@next/swc-win32-x64-msvc": { - "version": "15.4.5", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.4.5.tgz", - "integrity": "sha512-voWk7XtGvlsP+w8VBz7lqp8Y+dYw/MTI4KeS0gTVtfdhdJ5QwhXLmNrndFOin/MDoCvUaLWMkYKATaCoUkt2/A==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ], + "node_modules/@ngtools/webpack": { + "version": "18.2.21", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-18.2.21.tgz", + "integrity": "sha512-mfLT7lXbyJRlsazuPyuF5AGsMcgzRJRwsDlgxFbiy1DBlaF1chRFsXrKYj1gQ/WXQWNcEd11aedU0Rt+iCNDVw==", + "dev": true, "engines": { - "node": ">= 10" + "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": "^18.0.0", + "typescript": ">=5.4 <5.6", + "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" @@ -876,7 +4083,6 @@ "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" } @@ -885,7 +4091,6 @@ "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" @@ -894,55 +4099,292 @@ "node": ">= 8" } }, - "node_modules/@nolyfill/is-core-module": { - "version": "1.0.39", - "resolved": "https://registry.npmjs.org/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz", - "integrity": "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==", + "node_modules/@npmcli/agent": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-2.2.2.tgz", + "integrity": "sha512-OrcNPXdpSl9UX7qPVRWbmWMCSXrcDa2M9DvrbOTj7ao1S4PlqVFYv9/yLKMkrJKZ/V5A/kDBC690or307i26Og==", "dev": true, - "engines": { - "node": ">=12.4.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, - "optional": true, "dependencies": { - "detect-libc": "^1.0.3", - "is-glob": "^4.0.3", - "micromatch": "^4.0.5", - "node-addon-api": "^7.0.0" + "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": ">= 10.0.0" + "node": "^16.14.0 || >=18.0.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": "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": "5.0.8", + "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-5.0.8.tgz", + "integrity": "sha512-liASfw5cqhjNW9UFd+ruwwdEf/lbOAQjLL2XY2dFW/bkJheXDYZgOyul/4gVvEV4BWkTXjYGmDqMw9uegdbJNQ==", + "dev": true, + "dependencies": { + "@npmcli/promise-spawn": "^7.0.0", + "ini": "^4.1.3", + "lru-cache": "^10.0.1", + "npm-pick-manifest": "^9.0.0", + "proc-log": "^4.0.0", + "promise-inflight": "^1.0.1", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^4.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/git/node_modules/isexe": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.5.tgz", + "integrity": "sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "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": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "dev": true, + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^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/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/package-json": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-5.2.1.tgz", + "integrity": "sha512-f7zYC6kQautXHvNbLEWgD/uGu1+xCn9izgqBfgItWSx22U0ZDekxN08A1vM8cTxj/cRVe0Q94Ode+tdoYmIOOQ==", + "dev": true, + "dependencies": { + "@npmcli/git": "^5.0.0", + "glob": "^10.2.2", + "hosted-git-info": "^7.0.0", + "json-parse-even-better-errors": "^3.0.0", + "normalize-package-data": "^6.0.0", + "proc-log": "^4.0.0", + "semver": "^7.5.3" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/package-json/node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "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": { - "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" + "url": "https://github.com/sponsors/isaacs" } }, - "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==", + "node_modules/@npmcli/package-json/node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@npmcli/promise-spawn": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-7.0.2.tgz", + "integrity": "sha512-xhfYPXoV5Dy4UkY0D+v2KkwvnDfiA/8Mt3sWCGI/hM03NsYIH8ZaG6QzS9x7pje5vHZBZJ2v6VRFVTWACnqcmQ==", + "dev": true, + "dependencies": { + "which": "^4.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/promise-spawn/node_modules/isexe": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.5.tgz", + "integrity": "sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@npmcli/promise-spawn/node_modules/which": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "dev": true, + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/redact": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@npmcli/redact/-/redact-2.0.1.tgz", + "integrity": "sha512-YgsR5jCQZhVmTJvjduTOIHph0L73pK8xwMVaDY0PatySqVM9AZj93jpoXYSJqfHFxFkN9dmqTw6OiqExsS3LPw==", + "dev": true, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/run-script": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-8.1.0.tgz", + "integrity": "sha512-y7efHHwghQfk28G2z3tlZ67pLG0XdfYbcVG26r7YIXALRsrVQcTq4/tdenSmdOrEsNahIYA/eh8aEVROWGFUDg==", + "dev": true, + "dependencies": { + "@npmcli/node-gyp": "^3.0.0", + "@npmcli/package-json": "^5.0.0", + "@npmcli/promise-spawn": "^7.0.0", + "node-gyp": "^10.0.0", + "proc-log": "^4.0.0", + "which": "^4.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/run-script/node_modules/isexe": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.5.tgz", + "integrity": "sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@npmcli/run-script/node_modules/which": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "dev": true, + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^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/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "peer": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.4.tgz", + "integrity": "sha512-Fxamp4aEZnfPOcGA8KSNEohV8hX7zVHOemC8jVBoBUHu5zpJK/Eu3uJwt6BMgy9fkvzxDaurgj96F/NiLukF2w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.4.tgz", + "integrity": "sha512-VXoK5UMrgECLYaMuGuVTOx5kcuap1Jm8g/M83RnCHBKOqvPPmROFJGQaZhGccnsFtfXQ3XYa4/jMCJvZnbJBdA==", "cpu": [ "arm64" ], @@ -950,19 +4392,12 @@ "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==", + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.4.tgz", + "integrity": "sha512-xMM9ORBqu81jyMKCDP+SZDhnX2QEVQzTcC6G18KlTQEzWK8r/oNZtKuZaCcHhnsa6fEeOBionoyl5JsAbE/36Q==", "cpu": [ "arm64" ], @@ -970,19 +4405,12 @@ "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==", + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.4.tgz", + "integrity": "sha512-aJJyYKQwbHuhTUrjWjxEvGnNNBCnmpHDvrb8JFDbeSH3m2XdHcxDd3jthAzvmoI8w/kSjd2y0udT+4okADsZIw==", "cpu": [ "x64" ], @@ -990,39 +4418,12 @@ "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==", + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.4.tgz", + "integrity": "sha512-j63YtCIRAzbO+gC2L9dWXRh5BFetsv0j0va0Wi9epXDgU/XUi5dJKo4USTttVyK7fGw2nPWK0PbAvyliz50SCQ==", "cpu": [ "arm" ], @@ -1030,19 +4431,12 @@ "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==", + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.4.tgz", + "integrity": "sha512-dJnWUgwWBX1YBRsuKKMOlXCzh2Wu1mlHzv20TpqEsfdZLb3WoJW2kIEsGwLkroYf24IrPAvOT/ZQ2OYMV6vlrg==", "cpu": [ "arm" ], @@ -1050,19 +4444,12 @@ "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==", + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.4.tgz", + "integrity": "sha512-AdPRoNi3NKVLolCN/Sp4F4N1d98c4SBnHMKoLuiG6RXgoZ4sllseuGioszumnPGmPM2O7qaAX/IJdeDU8f26Aw==", "cpu": [ "arm64" ], @@ -1070,19 +4457,12 @@ "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==", + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.4.tgz", + "integrity": "sha512-Gl0AxBtDg8uoAn5CCqQDMqAx22Wx22pjDOjBdmG0VIWX3qUBHzYmOKh8KXHL4UpogfJ14G4wk16EQogF+v8hmA==", "cpu": [ "arm64" ], @@ -1090,19 +4470,51 @@ "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==", + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.4.tgz", + "integrity": "sha512-3aVCK9xfWW1oGQpTsYJJPF6bfpWfhbRnhdlyhak2ZiyFLDaayz0EP5j9V1RVLAAxlmWKTDfS9wyRyY3hvhPoOg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.4.tgz", + "integrity": "sha512-ePYIir6VYnhgv2C5Xe9u+ico4t8sZWXschR6fMgoPUK31yQu7hTEJb7bCqivHECwIClJfKgE7zYsh1qTP3WHUA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.4.tgz", + "integrity": "sha512-GqFJ9wLlbB9daxhVlrTe61vJtEY99/xB3C8e4ULVsVfflcpmR6c8UZXjtkMA6FhNONhj2eA5Tk9uAVw5orEs4Q==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.4.tgz", + "integrity": "sha512-87v0ol2sH9GE3cLQLNEy0K/R0pz1nvg76o8M5nhMR0+Q+BBGLnb35P0fVz4CQxHYXaAOhE8HhlkaZfsdUOlHwg==", "cpu": [ "x64" ], @@ -1110,19 +4522,12 @@ "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==", + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.4.tgz", + "integrity": "sha512-UV6FZMUgePDZrFjrNGIWzDo/vABebuXBhJEqrHxrGiU6HikPy0Z3LfdtciIttEUQfuDdCn8fqh7wiFJjCNwO+g==", "cpu": [ "x64" ], @@ -1130,19 +4535,12 @@ "optional": true, "os": [ "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } + ] }, - "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==", + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.4.tgz", + "integrity": "sha512-BjI+NVVEGAXjGWYHz/vv0pBqfGoUH0IGZ0cICTn7kB9PyjrATSkX+8WkguNjWoj2qSr1im/+tTGRaY+4/PdcQw==", "cpu": [ "arm64" ], @@ -1150,19 +4548,12 @@ "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==", + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.4.tgz", + "integrity": "sha512-SiWG/1TuUdPvYmzmYnmd3IEifzR61Tragkbx9D3+R8mzQqDBz8v+BvZNDlkiTtI9T15KYZhP0ehn3Dld4n9J5g==", "cpu": [ "ia32" ], @@ -1170,19 +4561,12 @@ "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==", + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.4.tgz", + "integrity": "sha512-j8pPKp53/lq9lMXN57S8cFz0MynJk8OWNuUnXct/9KCpKU7DgU3bYMJhwWmcqC0UU29p8Lr0/7KEVcaM6bf47Q==", "cpu": [ "x64" ], @@ -1190,361 +4574,552 @@ "optional": true, "os": [ "win32" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } + ] }, - "node_modules/@popperjs/core": { - "version": "2.11.8", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", - "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/popperjs" - } - }, - "node_modules/@react-aria/ssr": { - "version": "3.9.10", - "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.10.tgz", - "integrity": "sha512-hvTm77Pf+pMBhuBm760Li0BVIO38jv1IBws1xFm1NoL26PU+fe+FMW5+VZWyANR6nYL65joaJKZqOdTQMkO9IQ==", - "dependencies": { - "@swc/helpers": "^0.5.0" - }, - "engines": { - "node": ">= 12" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@redocly/ajv": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/@redocly/ajv/-/ajv-8.11.3.tgz", - "integrity": "sha512-4P3iZse91TkBiY+Dx5DUgxQ9GXkVJf++cmI0MOyLDxV9b5MUBI4II6ES8zA5JCbO72nKAJxWrw4PUPW+YP3ZDQ==", + "node_modules/@schematics/angular": { + "version": "18.2.21", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-18.2.21.tgz", + "integrity": "sha512-5Ai+NEflQZi67y4NsQ3o04iEp7zT0/BUFVCrJ3CueU3uYQGs8jrN1Lk6tvQ9c5HzGcTDrMXuTrCswyR9o6ecpA==", "dev": true, "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/ajv/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/@redocly/config": { - "version": "0.22.2", - "resolved": "https://registry.npmjs.org/@redocly/config/-/config-0.22.2.tgz", - "integrity": "sha512-roRDai8/zr2S9YfmzUfNhKjOF0NdcOIqF7bhf4MVC5UxpjIysDjyudvlAiVbpPHp3eDRWbdzUgtkK1a7YiDNyQ==", - "dev": true - }, - "node_modules/@redocly/openapi-core": { - "version": "1.34.5", - "resolved": "https://registry.npmjs.org/@redocly/openapi-core/-/openapi-core-1.34.5.tgz", - "integrity": "sha512-0EbE8LRbkogtcCXU7liAyC00n9uNG9hJ+eMyHFdUsy9lB/WGqnEBgwjA9q2cyzAVcdTkQqTBBU1XePNnN3OijA==", - "dev": true, - "dependencies": { - "@redocly/ajv": "^8.11.2", - "@redocly/config": "^0.22.0", - "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" + "@angular-devkit/core": "18.2.21", + "@angular-devkit/schematics": "18.2.21", + "jsonc-parser": "3.3.1" }, "engines": { - "node": ">=18.17.0", - "npm": ">=9.5.0" + "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/@redocly/openapi-core/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "node_modules/@sigstore/bundle": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-2.3.2.tgz", + "integrity": "sha512-wueKWDk70QixNLB363yHc2D2ItTgYiMTdPwK8D9dKQMR3ZQ0c35IxP5xnwQ8cNLoCgCRcHf14kE+CLIvNX1zmA==", "dev": true, "dependencies": { - "balanced-match": "^1.0.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 - }, - "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, - "dependencies": { - "brace-expansion": "^2.0.1" + "@sigstore/protobuf-specs": "^0.3.2" }, "engines": { - "node": ">=10" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@restart/hooks": { - "version": "0.4.16", - "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.16.tgz", - "integrity": "sha512-f7aCv7c+nU/3mF7NWLtVVr0Ra80RqsO89hO72r+Y/nvQr5+q0UFGkocElTH6MJApvReVh6JHUFYn2cw1WdHF3w==", - "dependencies": { - "dequal": "^2.0.3" - }, - "peerDependencies": { - "react": ">=16.8.0" - } - }, - "node_modules/@restart/ui": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@restart/ui/-/ui-1.9.4.tgz", - "integrity": "sha512-N4C7haUc3vn4LTwVUPlkJN8Ach/+yIMvRuTVIhjilNHqegY60SGLrzud6errOMNJwSnmYFnt1J0H/k8FE3A4KA==", - "dependencies": { - "@babel/runtime": "^7.26.0", - "@popperjs/core": "^2.11.8", - "@react-aria/ssr": "^3.5.0", - "@restart/hooks": "^0.5.0", - "@types/warning": "^3.0.3", - "dequal": "^2.0.3", - "dom-helpers": "^5.2.0", - "uncontrollable": "^8.0.4", - "warning": "^4.0.3" - }, - "peerDependencies": { - "react": ">=16.14.0", - "react-dom": ">=16.14.0" - } - }, - "node_modules/@restart/ui/node_modules/@restart/hooks": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.5.1.tgz", - "integrity": "sha512-EMoH04NHS1pbn07iLTjIjgttuqb7qu4+/EyhAx27MHpoENcB2ZdSsLTNxmKD+WEPnZigo62Qc8zjGnNxoSE/5Q==", - "dependencies": { - "dequal": "^2.0.3" - }, - "peerDependencies": { - "react": ">=16.8.0" - } - }, - "node_modules/@restart/ui/node_modules/uncontrollable": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-8.0.4.tgz", - "integrity": "sha512-ulRWYWHvscPFc0QQXvyJjY6LIXU56f0h8pQFvhxiKk5V1fcI8gp9Ht9leVAhrVjzqMw0BgjspBINx9r6oyJUvQ==", - "peerDependencies": { - "react": ">=16.14.0" - } - }, - "node_modules/@rtsao/scc": { + "node_modules/@sigstore/core": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", - "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", - "dev": true - }, - "node_modules/@rushstack/eslint-patch": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.12.0.tgz", - "integrity": "sha512-5EwMtOqvJMMa3HbmxLlF74e+3/HhwBTMcvt3nqVJgGCozO6hzIPOBlwm8mGVNR9SN2IJpxSnlxczyDjcn7qIyw==", - "dev": true - }, - "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==", - "dependencies": { - "tslib": "^2.8.0" - } - }, - "node_modules/@tybys/wasm-util": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.0.tgz", - "integrity": "sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ==", + "resolved": "https://registry.npmjs.org/@sigstore/core/-/core-1.1.0.tgz", + "integrity": "sha512-JzBqdVIyqm2FRQCulY6nbQzMpJJpSiJ8XXWMhtOX9eKgaXXpfNOF53lzQEjIydlStnd/eFtuC1dW4VYdD93oRg==", "dev": true, - "optional": true, - "dependencies": { - "tslib": "^2.4.0" + "engines": { + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@types/debug": { - "version": "4.1.12", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", - "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "node_modules/@sigstore/protobuf-specs": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.3.3.tgz", + "integrity": "sha512-RpacQhBlwpBWd7KEJsRKcBQalbV28fvkxwTOJIqhIuDysMMaJW47V4OqW30iJB9uRpqOSxxEAQFdr8tTattReQ==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/sign": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-2.3.2.tgz", + "integrity": "sha512-5Vz5dPVuunIIvC5vBb0APwo7qKA4G9yM48kPWJT+OEERs40md5GoUR1yedwpekWZ4m0Hhw44m6zU+ObsON+iDA==", + "dev": true, "dependencies": { - "@types/ms": "*" + "@sigstore/bundle": "^2.3.2", + "@sigstore/core": "^1.0.0", + "@sigstore/protobuf-specs": "^0.3.2", + "make-fetch-happen": "^13.0.1", + "proc-log": "^4.2.0", + "promise-retry": "^2.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/tuf": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-2.3.4.tgz", + "integrity": "sha512-44vtsveTPUpqhm9NCrbU8CWLe3Vck2HO1PNLw7RIajbB7xhtn5RBPm1VNSCMwqGYHhDsBJG8gDF0q4lgydsJvw==", + "dev": true, + "dependencies": { + "@sigstore/protobuf-specs": "^0.3.2", + "tuf-js": "^2.2.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/verify": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@sigstore/verify/-/verify-1.2.1.tgz", + "integrity": "sha512-8iKx79/F73DKbGfRf7+t4dqrc0bRr0thdPrxAtCKWRm/F0tG71i6O1rvlnScncJLLBZHn3h8M3c1BSUAb9yu8g==", + "dev": true, + "dependencies": { + "@sigstore/bundle": "^2.3.2", + "@sigstore/core": "^1.1.0", + "@sigstore/protobuf-specs": "^0.3.2" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "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/@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/@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": "2.0.1", + "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-2.0.1.tgz", + "integrity": "sha512-92F7/SFyufn4DXsha9+QfKnN03JGqtMFMXgSHbZOo8JG59WkTni7UzAouNQDf7AuP9OAMxVOPQcqG3sB7w+kkg==", + "dev": true, + "dependencies": { + "@tufjs/canonical-json": "2.0.0", + "minimatch": "^9.0.4" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@tufjs/models/node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.6", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", + "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", + "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/cors": { + "version": "2.8.19", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.19.tgz", + "integrity": "sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==", + "dev": true, + "dependencies": { + "@types/node": "*" } }, "node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "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/hast": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", - "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "node_modules/@types/express": { + "version": "4.17.25", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.25.tgz", + "integrity": "sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==", + "dev": true, "dependencies": { - "@types/unist": "*" + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "^1" } }, + "node_modules/@types/express-serve-static-core": { + "version": "4.19.8", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.8.tgz", + "integrity": "sha512-02S5fmqeoKzVZCHPZid4b8JH2eM5HzQLZWN2FohQEy/0eXTq8VXZfSN6Pcr3F6N9R/vNrj7cpgbhjie6m/1tCA==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/google.maps": { + "version": "3.58.1", + "resolved": "https://registry.npmjs.org/@types/google.maps/-/google.maps-3.58.1.tgz", + "integrity": "sha512-X9QTSvGJ0nCfMzYOnaVs/k6/4L+7F5uCS+4iUmkLEls6J9S/Phv+m/i3mDeyc49ZBgwab3EFO1HEoBY7k98EGQ==" + }, + "node_modules/@types/http-errors": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", + "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", + "dev": true + }, + "node_modules/@types/http-proxy": { + "version": "1.17.17", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.17.tgz", + "integrity": "sha512-ED6LB+Z1AVylNTu7hdzuBqOgMnvG/ld6wGCG8wFnAzKX5uyW2K3WD52v0gnLCTK/VLpXtKckgWuyScYK6cSPaw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/jasmine": { + "version": "5.1.15", + "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-5.1.15.tgz", + "integrity": "sha512-ZAC8KjmV2MJxbNTrwXFN+HKeajpXQZp6KpPiR6Aa4XvaEnjP6qh23lL/Rqb7AYzlp3h/rcwDrQ7Gg7q28cQTQg==", + "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==", + "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/mdast": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", - "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "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, "dependencies": { - "@types/unist": "*" + "@types/node": "*" } }, - "node_modules/@types/ms": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", - "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==" - }, "node_modules/@types/node": { - "version": "24.2.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.2.0.tgz", - "integrity": "sha512-3xyG3pMCq3oYCNg7/ZP+E1ooTaGB4cG8JWRsqqOYQdbWNY4zbaV0Ennrd7stjiJEFZCaybcIgpTjJWHRfBSIDw==", + "version": "22.19.15", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.15.tgz", + "integrity": "sha512-F0R/h2+dsy5wJAUe3tAU6oqa2qbWY5TpNfL/RGmo1y38hiyO1w3x2jPtt76wmuaJI4DQnOBu21cNXQ2STIUUWg==", "dev": true, "dependencies": { - "undici-types": "~7.10.0" + "undici-types": "~6.21.0" } }, - "node_modules/@types/prop-types": { - "version": "15.7.15", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", - "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==" - }, - "node_modules/@types/react": { - "version": "19.1.9", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.9.tgz", - "integrity": "sha512-WmdoynAX8Stew/36uTSVMcLJJ1KRh6L3IZRx1PZ7qJtBqT3dYTgyDTx8H1qoRghErydW7xw9mSJ3wS//tCRpFA==", - "dependencies": { - "csstype": "^3.0.2" - } - }, - "node_modules/@types/react-dom": { - "version": "19.1.7", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.7.tgz", - "integrity": "sha512-i5ZzwYpqjmrKenzkoLM2Ibzt6mAsM7pxB6BCIouEVVmgiqaMj1TjaK7hnA36hbW5aZv20kx7Lw6hWzPWg0Rurw==", + "node_modules/@types/node-forge": { + "version": "1.3.14", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.14.tgz", + "integrity": "sha512-mhVF2BnD4BO+jtOp7z1CdzaK4mbuK0LLQYAvdOLqHTavxFNq4zA1EmYkpnFjP8HOUzedfQkRnp0E2ulSAYSzAw==", "dev": true, - "peerDependencies": { - "@types/react": "^19.0.0" + "dependencies": { + "@types/node": "*" } }, - "node_modules/@types/react-transition-group": { - "version": "4.4.12", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.12.tgz", - "integrity": "sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==", - "peerDependencies": { - "@types/react": "*" + "node_modules/@types/qs": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.15.0.tgz", + "integrity": "sha512-JawvT8iBVWpzTrz3EGw9BTQFg3BQNmwERdKE22vlTxawwtbyUSlMppvZYKLZzB5zgACXdXxbD3m1bXaMqP/9ow==", + "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.2", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz", + "integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==", + "dev": true + }, + "node_modules/@types/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==", + "dev": true + }, + "node_modules/@types/send": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@types/send/-/send-1.2.1.tgz", + "integrity": "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==", + "dev": true, + "dependencies": { + "@types/node": "*" } }, - "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==" + "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/warning": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.3.tgz", - "integrity": "sha512-D1XC7WK8K+zZEveUPY+cf4+kgauk8N4eHr/XIHXGlGYkHLud6hK9lYfZk1ry1TNh798cZUCgb6MqGEG8DkJt6Q==" + "node_modules/@types/serve-static": { + "version": "1.15.10", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.10.tgz", + "integrity": "sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==", + "dev": true, + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "<1" + } + }, + "node_modules/@types/serve-static/node_modules/@types/send": { + "version": "0.17.6", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.6.tgz", + "integrity": "sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==", + "dev": true, + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "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/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 + }, + "node_modules/@types/ws": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.39.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.39.0.tgz", - "integrity": "sha512-bhEz6OZeUR+O/6yx9Jk6ohX6H9JSFTaiY0v9/PuKT3oGK0rn0jNplLmyFUGV+a9gfYnVNwGDwS/UkLIuXNb2Rw==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.2.0.tgz", + "integrity": "sha512-mdekAHOqS9UjlmyF/LSs6AIEvfceV749GFxoBAjwAv0nkevfKHWQFDMcBZWUiIC5ft6ePWivXoS36aKQ0Cy3sw==", "dev": true, "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.39.0", - "@typescript-eslint/type-utils": "8.39.0", - "@typescript-eslint/utils": "8.39.0", - "@typescript-eslint/visitor-keys": "8.39.0", + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "7.2.0", + "@typescript-eslint/type-utils": "7.2.0", + "@typescript-eslint/utils": "7.2.0", + "@typescript-eslint/visitor-keys": "7.2.0", + "debug": "^4.3.4", "graphemer": "^1.4.0", - "ignore": "^7.0.0", + "ignore": "^5.2.4", "natural-compare": "^1.4.0", - "ts-api-utils": "^2.1.0" + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.39.0", - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" + "@typescript-eslint/parser": "^7.0.0", + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.2.0.tgz", + "integrity": "sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.2.0.tgz", + "integrity": "sha512-YfHpnMAGb1Eekpm3XRK8hcMwGLGsnT6L+7b2XyRv6ouDuJU1tZir1GS2i0+VXRatMwSI1/UfcyPe53ADkU+IuA==", + "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": "7.2.0", + "@typescript-eslint/types": "7.2.0", + "@typescript-eslint/typescript-estree": "7.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", - "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "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/@typescript-eslint/parser": { - "version": "8.39.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.39.0.tgz", - "integrity": "sha512-g3WpVQHngx0aLXn6kfIYCZxM6rRJlWzEkVpqEFLT3SgEDsp9cpCbxxgwnE504q4H+ruSDh/VGS6nqZIDynP+vg==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.2.0.tgz", + "integrity": "sha512-5FKsVcHTk6TafQKQbuIVkXq58Fnbkd2wDL4LB7AURN7RUOu1utVP+G8+6u3ZhEroW3DF6hyo3ZEXxgKgp4KeCg==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "8.39.0", - "@typescript-eslint/types": "8.39.0", - "@typescript-eslint/typescript-estree": "8.39.0", - "@typescript-eslint/visitor-keys": "8.39.0", + "@typescript-eslint/scope-manager": "7.2.0", + "@typescript-eslint/types": "7.2.0", + "@typescript-eslint/typescript-estree": "7.2.0", + "@typescript-eslint/visitor-keys": "7.2.0", "debug": "^4.3.4" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.2.0.tgz", + "integrity": "sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.39.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.39.0.tgz", - "integrity": "sha512-CTzJqaSq30V/Z2Og9jogzZt8lJRR5TKlAdXmWgdu4hgcC9Kww5flQ+xFvMxIBWVNdxJO7OifgdOK4PokMIWPew==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.57.2.tgz", + "integrity": "sha512-FuH0wipFywXRTHf+bTTjNyuNQQsQC3qh/dYzaM4I4W0jrCqjCVuUh99+xd9KamUfmCGPvbO8NDngo/vsnNVqgw==", "dev": true, + "peer": true, "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.39.0", - "@typescript-eslint/types": "^8.39.0", - "debug": "^4.3.4" + "@typescript-eslint/tsconfig-utils": "^8.57.2", + "@typescript-eslint/types": "^8.57.2", + "debug": "^4.4.3" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1558,16 +5133,29 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.39.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.39.0.tgz", - "integrity": "sha512-8QOzff9UKxOh6npZQ/4FQu4mjdOCGSdO3p44ww0hk8Vu+IGbg0tB/H1LcTARRDzGCC8pDGbh2rissBuuoPgH8A==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.2.0.tgz", + "integrity": "sha512-Qh976RbQM/fYtjx9hs4XkayYujB/aPwglw2choHmf3zBjB4qOywWSdt9+KLRdHubGcoSwBnXUH2sR3hkyaERRg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.39.0", - "@typescript-eslint/visitor-keys": "8.39.0" + "@typescript-eslint/types": "7.2.0", + "@typescript-eslint/visitor-keys": "7.2.0" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/scope-manager/node_modules/@typescript-eslint/types": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.2.0.tgz", + "integrity": "sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", @@ -1575,10 +5163,11 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.39.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.39.0.tgz", - "integrity": "sha512-Fd3/QjmFV2sKmvv3Mrj8r6N8CryYiCS8Wdb/6/rgOXAWGcFuc+VkQuG28uk/4kVNVZBQuuDHEDUpo/pQ32zsIQ==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.57.2.tgz", + "integrity": "sha512-3Lm5DSM+DCowsUOJC+YqHHnKEfFh5CoGkj5Z31NQSNF4l5wdOwqGn99wmwN/LImhfY3KJnmordBq/4+VDe2eKw==", "dev": true, + "peer": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -1591,34 +5180,76 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.39.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.39.0.tgz", - "integrity": "sha512-6B3z0c1DXVT2vYA9+z9axjtc09rqKUPRmijD5m9iv8iQpHBRYRMBcgxSiKTZKm6FwWw1/cI4v6em35OsKCiN5Q==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.2.0.tgz", + "integrity": "sha512-xHi51adBHo9O9330J8GQYQwrKBqbIPJGZZVQTHHmy200hvkLZFWJIFtAG/7IYTWUyun6DE6w5InDReePJYJlJA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.39.0", - "@typescript-eslint/typescript-estree": "8.39.0", - "@typescript-eslint/utils": "8.39.0", + "@typescript-eslint/typescript-estree": "7.2.0", + "@typescript-eslint/utils": "7.2.0", "debug": "^4.3.4", - "ts-api-utils": "^2.1.0" + "ts-api-utils": "^1.0.1" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.2.0.tgz", + "integrity": "sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.2.0.tgz", + "integrity": "sha512-YfHpnMAGb1Eekpm3XRK8hcMwGLGsnT6L+7b2XyRv6ouDuJU1tZir1GS2i0+VXRatMwSI1/UfcyPe53ADkU+IuA==", + "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": "7.2.0", + "@typescript-eslint/types": "7.2.0", + "@typescript-eslint/typescript-estree": "7.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" } }, "node_modules/@typescript-eslint/types": { - "version": "8.39.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.39.0.tgz", - "integrity": "sha512-ArDdaOllnCj3yn/lzKn9s0pBQYmmyme/v1HbGIGB0GB/knFI3fWMHloC+oYTJW46tVbYnGKTMDK4ah1sC2v0Kg==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.57.2.tgz", + "integrity": "sha512-/iZM6FnM4tnx9csuTxspMW4BOSegshwX5oBDznJ7S4WggL7Vczz5d2W11ecc4vRrQMQHXRSxzrCsyG5EsPPTbA==", "dev": true, + "peer": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -1628,21 +5259,104 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.39.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.39.0.tgz", - "integrity": "sha512-ndWdiflRMvfIgQRpckQQLiB5qAKQ7w++V4LlCHwp62eym1HLB/kw7D9f2e8ytONls/jt89TEasgvb+VwnRprsw==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.2.0.tgz", + "integrity": "sha512-cyxS5WQQCoBwSakpMrvMXuMDEbhOo9bNHHrNcEWis6XHx6KF518tkF1wBvKIn/tpq5ZpUYK7Bdklu8qY0MsFIA==", "dev": true, "dependencies": { - "@typescript-eslint/project-service": "8.39.0", - "@typescript-eslint/tsconfig-utils": "8.39.0", - "@typescript-eslint/types": "8.39.0", - "@typescript-eslint/visitor-keys": "8.39.0", + "@typescript-eslint/types": "7.2.0", + "@typescript-eslint/visitor-keys": "7.2.0", "debug": "^4.3.4", - "fast-glob": "^3.3.2", + "globby": "^11.1.0", "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^2.1.0" + "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/typescript-estree/node_modules/@typescript-eslint/types": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.2.0.tgz", + "integrity": "sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.57.2.tgz", + "integrity": "sha512-krRIbvPK1ju1WBKIefiX+bngPs+odIQUtR7kymzPfo1POVw3jlF+nLkmexdSSd4UCbDcQn+wMBATOOmpBbqgKg==", + "dev": true, + "peer": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.57.2", + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/typescript-estree": "8.57.2" + }, + "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 || ^10.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.57.2.tgz", + "integrity": "sha512-snZKH+W4WbWkrBqj4gUNRIGb/jipDW3qMqVJ4C9rzdFc+wLwruxk+2a5D+uoFcKPAqyqEnSb4l2ULuZf95eSkw==", + "dev": true, + "peer": true, + "dependencies": { + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/visitor-keys": "8.57.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.57.2.tgz", + "integrity": "sha512-2MKM+I6g8tJxfSmFKOnHv2t8Sk3T6rF20A1Puk0svLK+uVapDZB/4pfAeB7nE83uAZrU6OxW+HmOd5wHVdXwXA==", + "dev": true, + "peer": true, + "dependencies": { + "@typescript-eslint/project-service": "8.57.2", + "@typescript-eslint/tsconfig-utils": "8.57.2", + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/visitor-keys": "8.57.2", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.4.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1655,92 +5369,126 @@ "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.57.2.tgz", + "integrity": "sha512-zhahknjobV2FiD6Ee9iLbS7OV9zi10rG26odsQdfBO/hjSzUQbkIYgda+iNKK1zNiW2ey+Lf8MU5btN17V3dUw==", "dev": true, + "peer": true, "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@typescript-eslint/typescript-estree/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" + "@typescript-eslint/types": "8.57.2", + "eslint-visitor-keys": "^5.0.0" }, "engines": { - "node": ">=8.6.0" + "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/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==", + "node_modules/@typescript-eslint/utils/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, + "peer": true, "engines": { - "node": ">= 6" + "node": "18 || 20 || >=22" } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "node_modules/@typescript-eslint/utils/node_modules/brace-expansion": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", "dev": true, + "peer": true, "dependencies": { - "brace-expansion": "^2.0.1" + "balanced-match": "^4.0.2" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "18 || 20 || >=22" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "peer": true, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/minimatch": { + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "dev": true, + "peer": true, + "dependencies": { + "brace-expansion": "^5.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@typescript-eslint/utils": { - "version": "8.39.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.39.0.tgz", - "integrity": "sha512-4GVSvNA0Vx1Ktwvf4sFE+exxJ3QGUorQG1/A5mRfRNZtkBT2xrA/BCO2H0eALx/PnvCS6/vmYwRdDA41EoffkQ==", + "node_modules/@typescript-eslint/utils/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.39.0", - "@typescript-eslint/types": "8.39.0", - "@typescript-eslint/typescript-estree": "8.39.0" + "peer": true, + "bin": { + "semver": "bin/semver.js" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/ts-api-utils": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", + "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.2.0.tgz", + "integrity": "sha512-c6EIQRHhcpl6+tO8EMR+kjkkV+ugUNXOmeASA1rlzkd8EPIriavpWoiEz1HR/VLhbVIdhqnV6E7JZm00cBDx2A==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.2.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.39.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.39.0.tgz", - "integrity": "sha512-ldgiJ+VAhQCfIjeOgu8Kj5nSxds0ktPOSO9p4+0VDH2R2pLvQraaM5Oen2d7NxzMCm+Sn/vJT+mv2H5u6b/3fA==", + "node_modules/@typescript-eslint/visitor-keys/node_modules/@typescript-eslint/types": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.2.0.tgz", + "integrity": "sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA==", "dev": true, - "dependencies": { - "@typescript-eslint/types": "8.39.0", - "eslint-visitor-keys": "^4.2.1" - }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", @@ -1750,262 +5498,220 @@ "node_modules/@ungap/structured-clone": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", - "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==" + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "dev": true }, - "node_modules/@unrs/resolver-binding-android-arm-eabi": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz", - "integrity": "sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==", - "cpu": [ - "arm" - ], + "node_modules/@vitejs/plugin-basic-ssl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-1.1.0.tgz", + "integrity": "sha512-wO4Dk/rm8u7RNhOf95ZzcEmC9rYOncYgvq4z3duaJrCgjN8BxAnDVyndanfcJZ0O6XZzHz6Q0hTimxTg8Y9g/A==", "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@unrs/resolver-binding-android-arm64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.11.1.tgz", - "integrity": "sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@unrs/resolver-binding-darwin-arm64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.11.1.tgz", - "integrity": "sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@unrs/resolver-binding-darwin-x64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.11.1.tgz", - "integrity": "sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@unrs/resolver-binding-freebsd-x64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.11.1.tgz", - "integrity": "sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.11.1.tgz", - "integrity": "sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.11.1.tgz", - "integrity": "sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.11.1.tgz", - "integrity": "sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm64-musl": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.11.1.tgz", - "integrity": "sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.11.1.tgz", - "integrity": "sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.11.1.tgz", - "integrity": "sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.11.1.tgz", - "integrity": "sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.11.1.tgz", - "integrity": "sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-x64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.1.tgz", - "integrity": "sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-x64-musl": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.1.tgz", - "integrity": "sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-wasm32-wasi": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.11.1.tgz", - "integrity": "sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==", - "cpu": [ - "wasm32" - ], - "dev": true, - "optional": true, - "dependencies": { - "@napi-rs/wasm-runtime": "^0.2.11" - }, "engines": { - "node": ">=14.0.0" + "node": ">=14.6.0" + }, + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" } }, - "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.1.tgz", - "integrity": "sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==", - "cpu": [ - "arm64" - ], + "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, - "optional": true, - "os": [ - "win32" - ] + "dependencies": { + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" + } }, - "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.11.1.tgz", - "integrity": "sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] + "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/@unrs/resolver-binding-win32-x64-msvc": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz", - "integrity": "sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==", - "cpu": [ - "x64" - ], + "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, - "optional": true, - "os": [ - "win32" - ] + "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/@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/abbrev": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz", + "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "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/accepts/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/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -2014,6 +5720,15 @@ "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, + "peerDependencies": { + "acorn": "^8" + } + }, "node_modules/acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", @@ -2023,6 +5738,33 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.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/agent-base": { "version": "7.1.4", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", @@ -2032,22 +5774,64 @@ "node": ">= 14" } }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "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": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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", @@ -2058,37 +5842,44 @@ } }, "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==", + "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": { - "environment": "^1.0.0" + "type-fest": "^0.21.3" }, "engines": { - "node": ">=18" + "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "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": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" + "node": ">=8" } }, "node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -2099,6 +5890,31 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "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.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -2114,195 +5930,56 @@ "node": ">= 0.4" } }, - "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-includes": { - "version": "3.1.9", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", - "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.4", - "define-properties": "^1.2.1", - "es-abstract": "^1.24.0", - "es-object-atoms": "^1.1.1", - "get-intrinsic": "^1.3.0", - "is-string": "^1.1.1", - "math-intrinsics": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.findlast": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", - "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", - "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.findlastindex": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", - "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.4", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.9", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "es-shim-unscopables": "^1.1.0" - }, - "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/array.prototype.tosorted": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", - "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.3", - "es-errors": "^1.3.0", - "es-shim-unscopables": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "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/ast-types-flow": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", - "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", + "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/async-function": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", - "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "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": ">= 0.4" + "node": ">=8" } }, - "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==", + "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": { - "possible-typed-array-names": "^1.0.0" + "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": ">= 0.4" + "node": "^10 || ^12 || >=14" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/axe-core": { - "version": "4.10.3", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.3.tgz", - "integrity": "sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==", - "dev": true, - "engines": { - "node": ">=4" + "peerDependencies": { + "postcss": "^8.1.0" } }, "node_modules/axobject-query": { @@ -2314,13 +5991,69 @@ "node": ">= 0.4" } }, - "node_modules/bail": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", - "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "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-polyfill-corejs2": { + "version": "0.4.17", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.17.tgz", + "integrity": "sha512-aTyf30K/rqAsNwN76zYrdtx8obu0E4KoUME29B1xj+B3WxgvWkp943vYQ+z8Mv3lw9xHXMHpvSPOBxzAkIa94w==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.28.6", + "@babel/helper-define-polyfill-provider": "^0.6.8", + "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.11.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.11.1.tgz", + "integrity": "sha512-yGCqvBT4rwMczo28xkH/noxJ6MZ4nJfkVYdoDaC/utLtWrXxv27HVrzAeSbqR8SxDsp46n0YF47EbHoixy6rXQ==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.3", + "core-js-compat": "^3.40.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.8.tgz", + "integrity": "sha512-M762rNHfSF1EV3SLtnCJXFoQbbIIz0OyRwnCmV0KPC7qosSfCO0QLTSuJX3ayAebubhE6oYBAYPrBA5ljowaZg==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.8" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/balanced-match": { @@ -2329,10 +6062,143 @@ "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==", + "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/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/baseline-browser-mapping": { + "version": "2.10.12", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.12.tgz", + "integrity": "sha512-qyq26DxfY4awP2gIRXhhLWfwzwI+N5Nxk6iQi8EFizIaWIjqicQTE4sLnZZVdeKPRcVNoJOkkpfzoIYuvCKaIQ==", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.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/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/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==", + "dev": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/body-parser": { + "version": "1.20.4", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.4.tgz", + "integrity": "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==", + "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.1", + "iconv-lite": "~0.4.24", + "on-finished": "~2.4.1", + "qs": "~6.14.0", + "raw-body": "~2.5.3", + "type-is": "~1.6.18", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/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/bootstrap": { - "version": "5.3.7", - "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.7.tgz", - "integrity": "sha512-7KgiD8UHjfcPBHEpDNg+zGz8L3LqR3GVwqZiBRFX04a1BCArZOz1r2kjly2HQ0WokqTO0v1nF+QAt8dsW4lKlw==", + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.8.tgz", + "integrity": "sha512-HP1SZDqaLDPwsNiqRqi5NcP0SSXciX2s9E+RyqJIIqGo+vJeN5AJVM98CXmW/Wux0nQ5L7jeWUdplCEf0Ee+tg==", "funding": [ { "type": "github", @@ -2348,20 +6214,18 @@ } }, "node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", + "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", "dev": true, "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "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" }, @@ -2369,22 +6233,155 @@ "node": ">=8" } }, - "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, + "node_modules/browserslist": { + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", + "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": { - "call-bind-apply-helpers": "^1.0.0", - "es-define-property": "^1.0.0", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.2" + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" + }, + "bin": { + "browserslist": "cli.js" }, "engines": { - "node": ">= 0.4" + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "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.1.13" + } + }, + "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/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/ljharb" + "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/cacache": { + "version": "18.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-18.0.4.tgz", + "integrity": "sha512-B+L5iIa9mgcjLbliir2th36yEwPftrzteHYujzsx3dFP/31GCHcIeS8f5MGd80odLOjaOvSpU3EEAmRQptkxLQ==", + "dev": true, + "dependencies": { + "@npmcli/fs": "^3.1.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": "^4.0.0", + "ssri": "^10.0.0", + "tar": "^6.1.11", + "unique-filename": "^3.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/cacache/node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "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/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/call-bind-apply-helpers": { @@ -2426,9 +6423,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001731", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001731.tgz", - "integrity": "sha512-lDdp2/wrOmTRWuoB5DpfNkC0rJDU8DqRa6nYL6HK6sytw70QMopt/NIc/9SM7ylItlBWfACXk0tEn37UWM/+mg==", + "version": "1.0.30001782", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001782.tgz", + "integrity": "sha512-dZcaJLJeDMh4rELYFw1tvSn1bhZWYFOt468FcbHHxx/Z/dFidd1I6ciyFdi3iwfQCyOjqo9upF6lGQYtMiJWxw==", "funding": [ { "type": "opencollective", @@ -2444,15 +6441,6 @@ } ] }, - "node_modules/ccount": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", - "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -2469,58 +6457,95 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "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==", + "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/character-entities": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", - "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "node_modules/chart.js": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.5.1.tgz", + "integrity": "sha512-GIjfiT9dbmHRiYi6Nl2yFCq7kkwdkp1W/lp2J99rX0yo9tgJGn3lKQATztIjb5tVtevcBtIdICNWqlq5+E8/Pw==", + "dependencies": { + "@kurkle/color": "^0.3.0" + }, + "engines": { + "pnpm": ">=8" } }, - "node_modules/character-entities-html4": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", - "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-entities-legacy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", - "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "node_modules/chartist": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/chartist/-/chartist-1.5.0.tgz", + "integrity": "sha512-mcCJuWHpNqkJucuWEeHxymQCQEeAOkamGypqCV5+C+uI2NF4I3BOn/tjIuZaowJVNAcrY9BG3janLaCWSNVPDw==", + "engines": { + "node": ">=14" } }, "node_modules/chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "devOptional": true, + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", "dependencies": { - "readdirp": "^4.0.1" + "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": ">= 14.16.0" + "node": ">= 8.10.0" }, "funding": { "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" } }, - "node_modules/classnames": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", - "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==" + "node_modules/chokidar/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, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "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": "5.0.0", @@ -2537,6 +6562,18 @@ "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", @@ -2553,37 +6590,109 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/client-only": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", - "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" + "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/clsx": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", - "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "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/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/cliui/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/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==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "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/color": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", - "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", - "optional": true, + "node_modules/clone-deep/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": { - "color-convert": "^2.0.1", - "color-string": "^1.9.0" + "isobject": "^3.0.1" }, "engines": { - "node": ">=12.5.0" + "node": ">=0.10.0" } }, "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==", - "devOptional": true, "dependencies": { "color-name": "~1.1.4" }, @@ -2594,18 +6703,7 @@ "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==", - "devOptional": true - }, - "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==", - "optional": true, - "dependencies": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/colorette": { "version": "2.0.20", @@ -2613,30 +6711,344 @@ "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", "dev": true }, - "node_modules/comma-separated-tokens": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", - "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "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/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/commander": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz", - "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==", + "node_modules/compression": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz", + "integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==", "dev": true, + "dependencies": { + "bytes": "3.1.2", + "compressible": "~2.0.18", + "debug": "2.6.9", + "negotiator": "~0.6.4", + "on-headers": "~1.1.0", + "safe-buffer": "5.2.1", + "vary": "~1.1.2" + }, "engines": { - "node": ">=18" + "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/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/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/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==" + }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz", + "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==", + "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/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/copy-webpack-plugin/node_modules/fast-glob/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/copy-webpack-plugin/node_modules/globby": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.1.0.tgz", + "integrity": "sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==", + "dev": true, + "dependencies": { + "@sindresorhus/merge-streams": "^2.1.0", + "fast-glob": "^3.3.3", + "ignore": "^7.0.3", + "path-type": "^6.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/copy-webpack-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/copy-webpack-plugin/node_modules/path-type": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-6.0.0.tgz", + "integrity": "sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/copy-webpack-plugin/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/core-js-compat": { + "version": "3.49.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.49.0.tgz", + "integrity": "sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==", + "dev": true, + "dependencies": { + "browserslist": "^4.28.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "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 + }, + "node_modules/cors": { + "version": "2.8.6", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", + "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==", + "dev": true, + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/cosmiconfig": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.1.tgz", + "integrity": "sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ==", + "dev": true, + "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/critters": { + "version": "0.0.24", + "resolved": "https://registry.npmjs.org/critters/-/critters-0.0.24.tgz", + "integrity": "sha512-Oyqew0FGM0wYUSNqR0L6AteO5MpMoUU0rhKRieXeiKs+PmRTxiJMyaunYB2KF6fQ3dzChXKCpbFOEJx3OQ1v/Q==", + "deprecated": "Ownership of Critters has moved to the Nuxt team, who will be maintaining the project going forward. If you'd like to keep using Critters, please switch to the actively-maintained fork at https://github.com/danielroe/beasties", + "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", + "postcss-media-query-parser": "^0.2.3" + } + }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -2651,72 +7063,100 @@ "node": ">= 8" } }, - "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + "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/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==", + "node_modules/css-select": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", + "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", + "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-what": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", + "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", + "dev": true, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "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/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/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==", + "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, - "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": ">=4.0" } }, "node_modules/debug": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dependencies": { "ms": "^2.1.3" }, @@ -2729,110 +7169,205 @@ } } }, - "node_modules/decode-named-character-reference": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.2.0.tgz", - "integrity": "sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==", - "dependencies": { - "character-entities": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "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/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==", + "node_modules/default-browser": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.5.0.tgz", + "integrity": "sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==", "dev": true, "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=18" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "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==", + "node_modules/default-browser-id": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.1.tgz", + "integrity": "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==", + "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": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" + "clone": "^1.0.2" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "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/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": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "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/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/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, - "optional": true, - "bin": { - "detect-libc": "bin/detect-libc.js" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/devlop": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", - "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", - "dependencies": { - "dequal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "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": ">=0.10.0" + "node": ">=6.0.0" } }, - "node_modules/dom-helpers": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", - "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "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": { - "@babel/runtime": "^7.8.7", - "csstype": "^3.0.2" + "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/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/dunder-proto": { @@ -2849,12 +7384,149 @@ "node": ">= 0.4" } }, - "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==", + "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/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.5.328", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.328.tgz", + "integrity": "sha512-QNQ5l45DzYytThO21403XN3FvK0hOkWDG8viNf6jqS42msJ8I4tGDSpBCgvDRRPnkffafiwAym2X2eHeGD2V0w==" + }, + "node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "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/engine.io": { + "version": "6.6.6", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.6.tgz", + "integrity": "sha512-U2SN0w3OpjFRVlrc17E6TMDmH58Xl9rai1MblNjAdwWp07Kk+llmzX0hjDpQdrDGzwmvOtgM5yI+meYX6iZ2xA==", + "dev": true, + "dependencies": { + "@types/cors": "^2.8.12", + "@types/node": ">=10.0.0", + "@types/ws": "^8.5.12", + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.7.2", + "cors": "~2.8.5", + "debug": "~4.4.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.18.3" + }, + "engines": { + "node": ">=10.2.0" + } + }, + "node_modules/engine.io-parser": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", + "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.20.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.20.1.tgz", + "integrity": "sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.3.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/ent": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.2.tgz", + "integrity": "sha512-kKvD1tO6BM+oK9HzCPpUdRb4vKFQY/FPTFmurMvh6LlN68VMrdj77w8yp51/kDbpkFOS9J8w5W6zIzgM2H8/hw==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "punycode": "^1.4.1", + "safe-regex-test": "^1.1.0" + }, + "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==", + "dev": 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/environment": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", @@ -2867,72 +7539,32 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/es-abstract": { - "version": "1.24.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz", - "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==", + "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.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", "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.4", - "data-view-buffer": "^1.0.2", - "data-view-byte-length": "^1.0.2", - "data-view-byte-offset": "^1.0.1", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "es-set-tostringtag": "^2.1.0", - "es-to-primitive": "^1.3.0", - "function.prototype.name": "^1.1.8", - "get-intrinsic": "^1.3.0", - "get-proto": "^1.0.1", - "get-symbol-description": "^1.1.0", - "globalthis": "^1.0.4", - "gopd": "^1.2.0", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "internal-slot": "^1.1.0", - "is-array-buffer": "^3.0.5", - "is-callable": "^1.2.7", - "is-data-view": "^1.0.2", - "is-negative-zero": "^2.0.3", - "is-regex": "^1.2.1", - "is-set": "^2.0.3", - "is-shared-array-buffer": "^1.0.4", - "is-string": "^1.1.1", - "is-typed-array": "^1.1.15", - "is-weakref": "^1.1.1", - "math-intrinsics": "^1.1.0", - "object-inspect": "^1.13.4", - "object-keys": "^1.1.1", - "object.assign": "^4.1.7", - "own-keys": "^1.0.1", - "regexp.prototype.flags": "^1.5.4", - "safe-array-concat": "^1.1.3", - "safe-push-apply": "^1.0.0", - "safe-regex-test": "^1.1.0", - "set-proto": "^1.0.0", - "stop-iteration-iterator": "^1.1.0", - "string.prototype.trim": "^1.2.10", - "string.prototype.trimend": "^1.0.9", - "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.3", - "typed-array-byte-length": "^1.0.3", - "typed-array-byte-offset": "^1.0.4", - "typed-array-length": "^1.0.7", - "unbox-primitive": "^1.1.0", - "which-typed-array": "^1.1.19" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "is-arrayish": "^0.2.1" } }, "node_modules/es-define-property": { @@ -2953,32 +7585,11 @@ "node": ">= 0.4" } }, - "node_modules/es-iterator-helpers": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz", - "integrity": "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.6", - "es-errors": "^1.3.0", - "es-set-tostringtag": "^2.0.3", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.6", - "globalthis": "^1.0.4", - "gopd": "^1.2.0", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.2.0", - "has-symbols": "^1.1.0", - "internal-slot": "^1.1.0", - "iterator.prototype": "^1.1.4", - "safe-array-concat": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - } + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "dev": true }, "node_modules/es-object-atoms": { "version": "1.1.1", @@ -2992,50 +7603,71 @@ "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==", + "node_modules/esbuild": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.0.tgz", + "integrity": "sha512-1lvV17H2bMYda/WaFb2jLPeHU3zml2k4/yagNMG8Q/YtfMjCwEUZa2eXXMgZTVSL5q1n4H7sQ0X6CdJDqqeCFA==", "dev": true, - "dependencies": { - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" }, "engines": { - "node": ">= 0.4" + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.23.0", + "@esbuild/android-arm": "0.23.0", + "@esbuild/android-arm64": "0.23.0", + "@esbuild/android-x64": "0.23.0", + "@esbuild/darwin-arm64": "0.23.0", + "@esbuild/darwin-x64": "0.23.0", + "@esbuild/freebsd-arm64": "0.23.0", + "@esbuild/freebsd-x64": "0.23.0", + "@esbuild/linux-arm": "0.23.0", + "@esbuild/linux-arm64": "0.23.0", + "@esbuild/linux-ia32": "0.23.0", + "@esbuild/linux-loong64": "0.23.0", + "@esbuild/linux-mips64el": "0.23.0", + "@esbuild/linux-ppc64": "0.23.0", + "@esbuild/linux-riscv64": "0.23.0", + "@esbuild/linux-s390x": "0.23.0", + "@esbuild/linux-x64": "0.23.0", + "@esbuild/netbsd-x64": "0.23.0", + "@esbuild/openbsd-arm64": "0.23.0", + "@esbuild/openbsd-x64": "0.23.0", + "@esbuild/sunos-x64": "0.23.0", + "@esbuild/win32-arm64": "0.23.0", + "@esbuild/win32-ia32": "0.23.0", + "@esbuild/win32-x64": "0.23.0" } }, - "node_modules/es-shim-unscopables": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", - "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", + "node_modules/esbuild-wasm": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.23.0.tgz", + "integrity": "sha512-6jP8UmWy6R6TUUV8bMuC3ZyZ6lZKI56x0tkxyCIqWwRRJ/DgeQKneh/Oid5EoGoPFLrGNkz47ZEtWAYuiY/u9g==", "dev": true, - "dependencies": { - "hasown": "^2.0.2" + "bin": { + "esbuild": "bin/esbuild" }, "engines": { - "node": ">= 0.4" + "node": ">=18" } }, - "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" - }, + "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": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "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": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -3049,332 +7681,59 @@ } }, "node_modules/eslint": { - "version": "9.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.32.0.tgz", - "integrity": "sha512-LSehfdpgMeWcTZkWZVIJl+tkZ2nuSkyyB9C27MZqFWXuph7DvaowgcTvKqxvpLW1JZIk8PN7hFY3Rj9LQ7m7lg==", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.21.0", - "@eslint/config-helpers": "^0.3.0", - "@eslint/core": "^0.15.0", - "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.32.0", - "@eslint/plugin-kit": "^0.3.4", - "@humanfs/node": "^0.16.6", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.4.2", - "@types/estree": "^1.0.6", - "@types/json-schema": "^7.0.15", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", "ajv": "^6.12.4", "chalk": "^4.0.0", - "cross-spawn": "^7.0.6", + "cross-spawn": "^7.0.2", "debug": "^4.3.2", + "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.4.0", - "eslint-visitor-keys": "^4.2.1", - "espree": "^10.4.0", - "esquery": "^1.5.0", + "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": "^8.0.0", + "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" + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" }, "bin": { "eslint": "bin/eslint.js" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { - "url": "https://eslint.org/donate" - }, - "peerDependencies": { - "jiti": "*" - }, - "peerDependenciesMeta": { - "jiti": { - "optional": true - } - } - }, - "node_modules/eslint-config-next": { - "version": "15.4.5", - "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-15.4.5.tgz", - "integrity": "sha512-IMijiXaZ43qFB+Gcpnb374ipTKD8JIyVNR+6VsifFQ/LHyx+A9wgcgSIhCX5PYSjwOoSYD5LtNHKlM5uc23eww==", - "dev": true, - "dependencies": { - "@next/eslint-plugin-next": "15.4.5", - "@rushstack/eslint-patch": "^1.10.3", - "@typescript-eslint/eslint-plugin": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", - "@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-import-resolver-typescript": "^3.5.2", - "eslint-plugin-import": "^2.31.0", - "eslint-plugin-jsx-a11y": "^6.10.0", - "eslint-plugin-react": "^7.37.0", - "eslint-plugin-react-hooks": "^5.0.0" - }, - "peerDependencies": { - "eslint": "^7.23.0 || ^8.0.0 || ^9.0.0", - "typescript": ">=3.3.1" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/eslint-config-prettier": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.2.tgz", - "integrity": "sha512-iI1f+D2ViGn+uvv5HuHVUamg8ll4tN+JRHGc6IJi4TP9Kl976C57fzPXgseXNs8v0iA8aSJpHsTWjDb9QJamGQ==", - "dev": true, - "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-import-resolver-typescript": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.10.1.tgz", - "integrity": "sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ==", - "dev": true, - "dependencies": { - "@nolyfill/is-core-module": "1.0.39", - "debug": "^4.4.0", - "get-tsconfig": "^4.10.0", - "is-bun-module": "^2.0.0", - "stable-hash": "^0.0.5", - "tinyglobby": "^0.2.13", - "unrs-resolver": "^1.6.2" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint-import-resolver-typescript" - }, - "peerDependencies": { - "eslint": "*", - "eslint-plugin-import": "*", - "eslint-plugin-import-x": "*" - }, - "peerDependenciesMeta": { - "eslint-plugin-import": { - "optional": true - }, - "eslint-plugin-import-x": { - "optional": true - } - } - }, - "node_modules/eslint-module-utils": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz", - "integrity": "sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==", - "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.32.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz", - "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", - "dev": true, - "dependencies": { - "@rtsao/scc": "^1.1.0", - "array-includes": "^3.1.9", - "array.prototype.findlastindex": "^1.2.6", - "array.prototype.flat": "^1.3.3", - "array.prototype.flatmap": "^1.3.3", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.12.1", - "hasown": "^2.0.2", - "is-core-module": "^2.16.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.8", - "object.groupby": "^1.0.3", - "object.values": "^1.2.1", - "semver": "^6.3.1", - "string.prototype.trimend": "^1.0.9", - "tsconfig-paths": "^3.15.0" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" - } - }, - "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/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-jsx-a11y": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.2.tgz", - "integrity": "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==", - "dev": true, - "dependencies": { - "aria-query": "^5.3.2", - "array-includes": "^3.1.8", - "array.prototype.flatmap": "^1.3.2", - "ast-types-flow": "^0.0.8", - "axe-core": "^4.10.0", - "axobject-query": "^4.1.0", - "damerau-levenshtein": "^1.0.8", - "emoji-regex": "^9.2.2", - "hasown": "^2.0.2", - "jsx-ast-utils": "^3.3.5", - "language-tags": "^1.0.9", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.8", - "safe-regex-test": "^1.0.3", - "string.prototype.includes": "^2.0.1" - }, - "engines": { - "node": ">=4.0" - }, - "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" - } - }, - "node_modules/eslint-plugin-react": { - "version": "7.37.5", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz", - "integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==", - "dev": true, - "dependencies": { - "array-includes": "^3.1.8", - "array.prototype.findlast": "^1.2.5", - "array.prototype.flatmap": "^1.3.3", - "array.prototype.tosorted": "^1.1.4", - "doctrine": "^2.1.0", - "es-iterator-helpers": "^1.2.1", - "estraverse": "^5.3.0", - "hasown": "^2.0.2", - "jsx-ast-utils": "^2.4.1 || ^3.0.0", - "minimatch": "^3.1.2", - "object.entries": "^1.1.9", - "object.fromentries": "^2.0.8", - "object.values": "^1.2.1", - "prop-types": "^15.8.1", - "resolve": "^2.0.0-next.5", - "semver": "^6.3.1", - "string.prototype.matchall": "^4.0.12", - "string.prototype.repeat": "^1.0.0" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" - } - }, - "node_modules/eslint-plugin-react-hooks": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.2.0.tgz", - "integrity": "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==", - "dev": true, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" - } - }, - "node_modules/eslint-plugin-react/node_modules/resolve": { - "version": "2.0.0-next.5", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", - "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", - "dev": true, - "dependencies": { - "is-core-module": "^2.13.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/eslint-plugin-react/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" + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-scope": { @@ -3394,38 +7753,107 @@ } }, "node_modules/eslint-visitor-keys": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", - "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "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": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, - "node_modules/espree": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", - "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "node_modules/eslint/node_modules/ajv": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", "dev": true, "dependencies": { - "acorn": "^8.15.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.2.1" + "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/brace-expansion": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/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": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/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/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.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "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/esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", "dev": true, "dependencies": { "estraverse": "^5.1.0" @@ -3464,39 +7892,152 @@ "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/eventemitter3": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", "dev": true }, - "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==", + "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/exponential-backoff": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.3.tgz", + "integrity": "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==", + "dev": true + }, + "node_modules/express": { + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.22.1.tgz", + "integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==", "dev": true, "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" + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "~1.20.3", + "content-disposition": "~0.5.4", + "content-type": "~1.0.4", + "cookie": "~0.7.1", + "cookie-signature": "~1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.3.1", + "fresh": "~0.5.2", + "http-errors": "~2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "~2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "~0.1.12", + "proxy-addr": "~2.0.7", + "qs": "~6.14.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "~0.19.0", + "serve-static": "~1.16.2", + "setprototypeof": "1.2.0", + "statuses": "~2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" }, "engines": { - "node": ">=16.17" + "node": ">= 0.10.0" }, "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "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.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz", + "integrity": "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==", + "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.2", + "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.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "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==" + "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/fast-deep-equal": { "version": "3.1.3", @@ -3505,10 +8046,9 @@ "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, + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -3524,7 +8064,6 @@ "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" }, @@ -3544,32 +8083,76 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, - "node_modules/fastq": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", - "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ] + }, + "node_modules/fastq": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", "dependencies": { "reusify": "^1.0.4" } }, - "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==", + "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": { - "flat-cache": "^4.0.0" + "websocket-driver": ">=0.5.1" }, "engines": { - "node": ">=16.0.0" + "node": ">=0.8.0" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "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" }, @@ -3577,6 +8160,67 @@ "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": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -3593,38 +8237,146 @@ "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==", + "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.4" + "keyv": "^4.5.3", + "rimraf": "^3.0.2" }, "engines": { - "node": ">=16" + "node": "^10.12.0 || >=12.0.0" } }, "node_modules/flatted": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", - "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", "dev": true }, - "node_modules/for-each": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", - "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "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.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", "dev": true, "dependencies": { - "is-callable": "^1.2.7" + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" }, "engines": { - "node": ">= 0.4" + "node": ">=14" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/isaacs" + } + }, + "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-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/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/function-bind": { @@ -3636,39 +8388,26 @@ "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" - }, + "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==", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=6.9.0" } }, - "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/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==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.5.0.tgz", + "integrity": "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==", "dev": true, "engines": { "node": ">=18" @@ -3714,45 +8453,25 @@ "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, - "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==", + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "dev": true, "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6" + "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": ">= 0.4" + "node": "*" }, "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-tsconfig": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.1.tgz", - "integrity": "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==", - "dev": true, - "dependencies": { - "resolve-pkg-maps": "^1.0.0" - }, - "funding": { - "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/glob-parent": { @@ -3767,32 +8486,104 @@ "node": ">=10.13.0" } }, - "node_modules/globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "node_modules/glob-to-regex.js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/glob-to-regex.js/-/glob-to-regex.js-1.2.0.tgz", + "integrity": "sha512-QMwlOQKU/IzqMUOAZWubUOT8Qft+Y0KQWnX9nK3ch0CJg0tTp4TvGZsTfudYKv2NzoQSyPcnA6TYeIQ3jGichQ==", "dev": true, "engines": { - "node": ">=18" + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "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.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "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/globalthis": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", - "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "node_modules/globals/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, - "dependencies": { - "define-properties": "^1.2.1", - "gopd": "^1.0.1" - }, "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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/globby/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/gopd": { @@ -3807,23 +8598,23 @@ "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==", + "dev": true + }, "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/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/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/has-flag": { "version": "4.0.0", @@ -3834,33 +8625,6 @@ "node": ">=8" } }, - "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", @@ -3900,100 +8664,287 @@ "node": ">= 0.4" } }, - "node_modules/hast-util-to-html": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz", - "integrity": "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==", + "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, "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "ccount": "^2.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-whitespace": "^3.0.0", - "html-void-elements": "^3.0.0", - "mdast-util-to-hast": "^13.0.0", - "property-information": "^7.0.0", - "space-separated-tokens": "^2.0.0", - "stringify-entities": "^4.0.0", - "zwitch": "^2.0.4" + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.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-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.2.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", + "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.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "dev": true, + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/unified" + "url": "https://opencollective.com/express" } }, - "node_modules/hast-util-whitespace": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", - "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "node_modules/http-errors/node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.10.tgz", + "integrity": "sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==", + "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": { - "@types/hast": "^3.0.0" + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "engines": { + "node": ">=8.0.0" } }, - "node_modules/html-void-elements": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", - "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "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==", + "dev": true, + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/http-proxy-middleware": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-3.0.5.tgz", + "integrity": "sha512-GLZZm1X38BPY4lkXA01jhwxvDoOkkXqjgVyUzVxiEK4iuRu03PZoYHhHRwxnfhQMDuaxi3vVri0YgSro/1oWqg==", + "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/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==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", "dev": true, "dependencies": { - "agent-base": "^7.1.2", + "agent-base": "^7.0.2", "debug": "4" }, "engines": { "node": ">= 14" } }, - "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==", + "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": ">=16.17.0" + "node": ">=10.18" } }, - "node_modules/husky": { - "version": "9.1.7", - "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", - "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==", + "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, - "bin": { - "husky": "bin.js" + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" }, "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/typicode" + "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==", + "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/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-6.0.2.tgz", + "integrity": "sha512-InwqeHHN2XpumIkMvpl/DCJVrAHgCsG5+cn1XlnLWGwtZBm8QJfSusItfrwx81CTp5agNZqpKU2J/ccC5nGT4A==", "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/immutable": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.3.tgz", - "integrity": "sha512-+chQdDfvscSF1SJqv2gn4SRO2ZyS3xL3r7IW/wWEEzrzLisnOlKiQu5ytC/BVNcS15C39WT2Hg/bjKjDMcu+zg==", - "devOptional": true + "version": "4.3.8", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.8.tgz", + "integrity": "sha512-d/Ld9aLbKpNwyl0KiM2CT1WYvkitQ1TSvmRtkcV8FKStiDoA7Slzgjmb/1G2yhKM1p0XeNOieaTbFZmU1d3Xuw==", + "dev": true }, "node_modules/import-fresh": { "version": "3.3.1", @@ -4020,132 +8971,75 @@ "node": ">=0.8.19" } }, - "node_modules/index-to-position": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/index-to-position/-/index-to-position-1.1.0.tgz", - "integrity": "sha512-XPdx9Dq4t9Qk1mTMbWONJqU7boCoumEH7fRET37HX5+khDUl3J2W6PdALxhILYlIYx2amlwYcRPp28p0tSiojg==", + "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": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, - "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==", + "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": { - "es-errors": "^1.3.0", - "hasown": "^2.0.2", - "side-channel": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" + "once": "^1.3.0", + "wrappy": "1" } }, - "node_modules/invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "dependencies": { - "loose-envify": "^1.0.0" - } + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true }, - "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==", + "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, - "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": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/ip-address": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", + "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/ipaddr.js": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.3.0.tgz", + "integrity": "sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg==", + "dev": true, + "engines": { + "node": ">= 10" } }, "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==", - "optional": true + "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-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==", + "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": { - "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" + "binary-extensions": "^2.0.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-boolean-object": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", - "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", - "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-bun-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-2.0.0.tgz", - "integrity": "sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==", - "dev": true, - "dependencies": { - "semver": "^7.7.1" - } - }, - "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": ">=8" } }, "node_modules/is-core-module": { @@ -4163,63 +9057,29 @@ "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==", + "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, - "dependencies": { - "call-bound": "^1.0.2", - "get-intrinsic": "^1.2.6", - "is-typed-array": "^1.1.13" + "bin": { + "is-docker": "cli.js" }, "engines": { - "node": ">= 0.4" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "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" + "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": "4.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", @@ -4232,29 +9092,10 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "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" }, @@ -4262,66 +9103,89 @@ "node": ">=0.10.0" } }, - "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==", + "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": ">= 0.4" + "node": ">=14.16" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-negative-zero": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "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": ">= 0.4" + "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-network-error": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.3.1.tgz", + "integrity": "sha512-6QCxa49rQbmUWLfk0nuGqzql9U8uaV2H6279bRErPBHe/109hCzsLUBUHfbEtvLIHBd6hyXbgedBSHevm43Edw==", + "dev": true, + "engines": { + "node": ">=16" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "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==", + "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, - "dependencies": { - "call-bound": "^1.0.3", - "has-tostringtag": "^1.0.2" - }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8" } }, "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==", + "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": ">=12" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, + "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/is-regex": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", @@ -4340,183 +9204,215 @@ "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==", + "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": ">= 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, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=10" }, "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==", + "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.1", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.1.tgz", + "integrity": "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==", "dev": true, "dependencies": { - "call-bound": "^1.0.3", - "has-tostringtag": "^1.0.2" + "is-inside-container": "^1.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=16" }, "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-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.1", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", - "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", - "dev": true, - "dependencies": { - "call-bound": "^1.0.3" - }, - "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" + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "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/iterator.prototype": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", - "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==", - "dev": true, - "dependencies": { - "define-data-property": "^1.1.4", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.6", - "get-proto": "^1.0.0", - "has-symbols": "^1.1.0", - "set-function-name": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "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==", + "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/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, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "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.2.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", + "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", + "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-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/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/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/jiti": { + "version": "1.21.7", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", + "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", + "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==" }, "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==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dev": true, "dependencies": { "argparse": "^2.0.1" @@ -4525,16 +9421,36 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, "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": "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/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==", + "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": { @@ -4544,30 +9460,326 @@ "dev": true }, "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" - }, + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "bin": { "json5": "lib/cli.js" - } - }, - "node_modules/jsx-ast-utils": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", - "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", - "dev": true, - "dependencies": { - "array-includes": "^3.1.6", - "array.prototype.flat": "^1.3.1", - "object.assign": "^4.1.4", - "object.values": "^1.1.6" }, "engines": { - "node": ">=4.0" + "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==", + "dev": true + }, + "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/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/karma": { + "version": "6.4.4", + "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.4.tgz", + "integrity": "sha512-LrtUxbdvt1gOpo3gxG+VAJlJAEMhbWlM4YrFQgql98FwF7+K8K12LYO4hnDdUkNjeztYrOXEMqgTajSWgmtI/w==", + "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": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/karma-coverage/-/karma-coverage-2.2.1.tgz", + "integrity": "sha512-yj7hbequkQP2qOSb20GuNSIyE//PgJWHwC2IydLE6XRtsnaflv+/OSGNssPjobYUlhVVagy99TQpqUt3vAUG7A==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.2.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.1", + "istanbul-reports": "^3.0.5", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/karma-coverage/node_modules/brace-expansion": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/karma-coverage/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/karma-coverage/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/karma-coverage/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/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-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.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", + "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/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/karma/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/karma/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "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/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/karma/node_modules/tmp": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", + "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==", + "dev": true, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/karma/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/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/keyv": { @@ -4579,22 +9791,122 @@ "json-buffer": "3.0.1" } }, - "node_modules/language-subtag-registry": { - "version": "0.3.23", - "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", - "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==", - "dev": true + "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/language-tags": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", - "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", + "node_modules/launch-editor": { + "version": "2.13.2", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.13.2.tgz", + "integrity": "sha512-4VVDnbOpLXy/s8rdRCSXb+zfMeFR0WlJWpET1iA9CQdlZDfwyLjUuGQzXU4VeOoey6AicSAluWan7Etga6Kcmg==", "dev": true, "dependencies": { - "language-subtag-registry": "^0.3.20" + "picocolors": "^1.1.1", + "shell-quote": "^1.8.3" + } + }, + "node_modules/less": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/less/-/less-4.2.0.tgz", + "integrity": "sha512-P3b3HJDBtSzsXUl0im2L7gTO5Ubg8mEN6G8qoTS77iXxXX4Hvu4Qj540PZDvQ8V6DmX6iXo98k7Md0Cm1PrLaA==", + "dev": true, + "dependencies": { + "copy-anything": "^2.0.1", + "parse-node-version": "^1.0.1", + "tslib": "^2.3.0" + }, + "bin": { + "lessc": "bin/lessc" }, "engines": { - "node": ">=0.10" + "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/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": { @@ -4610,61 +9922,33 @@ "node": ">= 0.8.0" } }, - "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, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antonk52" - } - }, - "node_modules/lint-staged": { - "version": "15.5.2", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.5.2.tgz", - "integrity": "sha512-YUSOLq9VeRNAo/CTaVmhGDKG+LBtA8KF1X4K5+ykMSwWST1vDxJRB2kv2COgLb1fvpCo+A/y9A0G0znNVmdx4w==", + "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": { - "chalk": "^5.4.1", - "commander": "^13.1.0", - "debug": "^4.4.0", - "execa": "^8.0.1", - "lilconfig": "^3.1.3", - "listr2": "^8.2.5", - "micromatch": "^4.0.8", - "pidtree": "^0.6.0", - "string-argv": "^0.3.2", - "yaml": "^2.7.0" + "webpack-sources": "^3.0.0" }, - "bin": { - "lint-staged": "bin/lint-staged.js" - }, - "engines": { - "node": ">=18.12.0" - }, - "funding": { - "url": "https://opencollective.com/lint-staged" + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-sources": { + "optional": true + } } }, - "node_modules/lint-staged/node_modules/chalk": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.5.0.tgz", - "integrity": "sha512-1tm8DTaJhPBG3bIkVeZt1iZM9GfSX2lzOeDVZH9R9ffRHpmHvxZ/QhgQH/aDTkswQVt+YHdXAdS/In/30OjCbg==", - "dev": true, - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } + "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/listr2": { - "version": "8.3.3", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.3.3.tgz", - "integrity": "sha512-LWzX2KsqcB1wqQ4AHgYb4RsDXauQiqhjLk+6hjbaeHG4zpjjVAB6wC/gz6X0l+Du1cN3pUB5ZlrvTbhGSNnUQQ==", + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.2.4.tgz", + "integrity": "sha512-opevsywziHd3zHCVQGAj8zu+Z3yHNkkoYhWIGnq54RrCVwLz0MozotJEDnKsIBLvkfLGN6BLOyAeRrYI0pKA4g==", "dev": true, "dependencies": { "cli-truncate": "^4.0.0", @@ -4678,6 +9962,115 @@ "node": ">=18.0.0" } }, + "node_modules/listr2/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "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.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/listr2/node_modules/eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "dev": true + }, + "node_modules/listr2/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/listr2/node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "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.0.13", + "resolved": "https://registry.npmjs.org/lmdb/-/lmdb-3.0.13.tgz", + "integrity": "sha512-UGe+BbaSUQtAMZobTb4nHvFMrmvuAQKSeaqAX2meTEQjfsbpl5sxdHD8T72OnwD4GU9uwNhYXIVe4QGs8N9Zyw==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "msgpackr": "^1.10.2", + "node-addon-api": "^6.1.0", + "node-gyp-build-optional-packages": "5.2.2", + "ordered-binary": "^1.4.1", + "weak-lru-cache": "^1.2.2" + }, + "bin": { + "download-lmdb-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@lmdb/lmdb-darwin-arm64": "3.0.13", + "@lmdb/lmdb-darwin-x64": "3.0.13", + "@lmdb/lmdb-linux-arm": "3.0.13", + "@lmdb/lmdb-linux-arm64": "3.0.13", + "@lmdb/lmdb-linux-x64": "3.0.13", + "@lmdb/lmdb-win32-x64": "3.0.13" + } + }, + "node_modules/loader-runner": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz", + "integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==", + "dev": true, + "engines": { + "node": ">=6.11.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "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/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -4693,12 +10086,45 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash": { + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", + "dev": true + }, + "node_modules/lodash-es": { + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.23.tgz", + "integrity": "sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg==" + }, + "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-update": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", @@ -4718,10 +10144,37 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/log-update/node_modules/ansi-escapes": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.3.0.tgz", + "integrity": "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==", + "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.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "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==", + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", "dev": true, "engines": { "node": ">=12" @@ -4731,12 +10184,12 @@ } }, "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==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", + "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", "dev": true, "dependencies": { - "get-east-asian-width": "^1.0.0" + "get-east-asian-width": "^1.3.1" }, "engines": { "node": ">=18" @@ -4746,9 +10199,9 @@ } }, "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==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz", + "integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==", "dev": true, "dependencies": { "ansi-styles": "^6.2.1", @@ -4761,15 +10214,107 @@ "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "node_modules/log-update/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" + "ansi-regex": "^6.2.2" }, - "bin": { - "loose-envify": "cli.js" + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "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/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==", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/magic-string": { + "version": "0.30.11", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz", + "integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.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, + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-fetch-happen": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-13.0.1.tgz", + "integrity": "sha512-cKTUFc/rbKUd/9meOvgrpJ2WrNzymt6jfRDdwg5UCnVzv9dTpEj9JS5m3wtziXVCjluIXyL8pcaukYqezIzZQA==", + "dev": true, + "dependencies": { + "@npmcli/agent": "^2.0.0", + "cacache": "^18.0.0", + "http-cache-semantics": "^4.1.1", + "is-lambda": "^1.0.1", + "minipass": "^7.0.2", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "proc-log": "^4.2.0", + "promise-retry": "^2.0.1", + "ssri": "^10.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" } }, "node_modules/math-intrinsics": { @@ -4781,59 +10326,51 @@ "node": ">= 0.4" } }, - "node_modules/mdast-util-from-markdown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", - "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark": "^4.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-decode-string": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "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/mdast-util-to-hast": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", - "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==", + "node_modules/memfs": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.57.1.tgz", + "integrity": "sha512-WvzrWPwMQT+PtbX2Et64R4qXKK0fj/8pO85MrUCzymX3twwCiJCdvntW3HdhG1teLJcHDDLIKx5+c3HckWYZtQ==", + "dev": true, "dependencies": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "@ungap/structured-clone": "^1.0.0", - "devlop": "^1.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "trim-lines": "^3.0.0", - "unist-util-position": "^5.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0" + "@jsonjoy.com/fs-core": "4.57.1", + "@jsonjoy.com/fs-fsa": "4.57.1", + "@jsonjoy.com/fs-node": "4.57.1", + "@jsonjoy.com/fs-node-builtins": "4.57.1", + "@jsonjoy.com/fs-node-to-fsa": "4.57.1", + "@jsonjoy.com/fs-node-utils": "4.57.1", + "@jsonjoy.com/fs-print": "4.57.1", + "@jsonjoy.com/fs-snapshot": "4.57.1", + "@jsonjoy.com/json-pack": "^1.11.0", + "@jsonjoy.com/util": "^1.9.0", + "glob-to-regex.js": "^1.0.1", + "thingies": "^2.5.0", + "tree-dump": "^1.0.3", + "tslib": "^2.0.0" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" } }, - "node_modules/mdast-util-to-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", - "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", - "dependencies": { - "@types/mdast": "^4.0.0" - }, + "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": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/merge-stream": { @@ -4846,437 +10383,23 @@ "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/micromark": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", - "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "@types/debug": "^4.0.0", - "debug": "^4.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" + "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/micromark-core-commonmark": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", - "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-destination": "^2.0.0", - "micromark-factory-label": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-title": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-html-tag-name": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-destination": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", - "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-label": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", - "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-space": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-title": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", - "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-whitespace": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", - "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-character": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-chunked": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", - "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-classify-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", - "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-combine-extensions": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", - "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-chunked": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-numeric-character-reference": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", - "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-string": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", - "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-encode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", - "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-html-tag-name": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", - "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-normalize-identifier": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", - "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-resolve-all": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", - "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-sanitize-uri": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", - "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-subtokenize": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", - "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", - "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, "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" @@ -5285,16 +10408,57 @@ "node": ">=8.6" } }, - "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, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", "engines": { - "node": ">=12" + "node": ">=8.6" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "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-function": { @@ -5309,16 +10473,45 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/mini-css-extract-plugin": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.0.tgz", + "integrity": "sha512-Zs1YsZVfemekSZG+44vBsYTLQORkPMwnlv+aehcxK/NLKC+EGhDB39/YePYYqx/sTk6NnYpuqikhSn7+JIevTA==", "dev": true, "dependencies": { - "brace-expansion": "^1.1.7" + "schema-utils": "^4.0.0", + "tapable": "^2.2.1" }, "engines": { - "node": "*" + "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": { @@ -5330,15 +10523,249 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "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": "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/minipass-flush": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.7.tgz", + "integrity": "sha512-TbqTz9cUwWyHS2Dy89P3ocAGUGxKjjLuR9z8w4WUTGAVgEj17/4nhgo2Du56i0Fm3Pm30g4iA8Lcqctc76jCzA==", + "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/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/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.9", + "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.9.tgz", + "integrity": "sha512-FkoAAyyA6HM8wL882EcEyFZ9s7hVADSwG9xrVx3dxxNQAtgADTrJoEWivID82Iv1zWDsv/OtbrrcZAzGzOMdNw==", + "dev": 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": "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/nanoid": { "version": "3.3.11", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, "funding": [ { "type": "github", @@ -5352,116 +10779,414 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/napi-postinstall": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.2.tgz", - "integrity": "sha512-tWVJxJHmBWLy69PvO96TZMZDrzmw5KeiZBz3RHmiM2XZ9grBJ2WgMAFVVg25nqp3ZjTFUs2Ftw1JhscL3Teliw==", - "dev": true, - "bin": { - "napi-postinstall": "lib/cli.js" - }, - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/napi-postinstall" - } - }, "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/next": { - "version": "15.4.5", - "resolved": "https://registry.npmjs.org/next/-/next-15.4.5.tgz", - "integrity": "sha512-nJ4v+IO9CPmbmcvsPebIoX3Q+S7f6Fu08/dEWu0Ttfa+wVwQRh9epcmsyCPjmL2b8MxC+CkBR97jgDhUUztI3g==", + "node_modules/needle": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/needle/-/needle-3.5.0.tgz", + "integrity": "sha512-jaQyPKKk2YokHrEg+vFDYxXIHTCBgiZwSHOoVx/8V3GIBS8/VN6NdVRmg8q1ERtPkMvmOvebsgga4sAj5hls/w==", + "dev": true, + "optional": true, "dependencies": { - "@next/env": "15.4.5", - "@swc/helpers": "0.5.15", - "caniuse-lite": "^1.0.30001579", - "postcss": "8.4.31", - "styled-jsx": "5.1.6" + "iconv-lite": "^0.6.3", + "sax": "^1.2.4" }, "bin": { - "next": "dist/bin/next" + "needle": "bin/needle" }, "engines": { - "node": "^18.18.0 || ^19.8.0 || >= 20.0.0" - }, - "optionalDependencies": { - "@next/swc-darwin-arm64": "15.4.5", - "@next/swc-darwin-x64": "15.4.5", - "@next/swc-linux-arm64-gnu": "15.4.5", - "@next/swc-linux-arm64-musl": "15.4.5", - "@next/swc-linux-x64-gnu": "15.4.5", - "@next/swc-linux-x64-musl": "15.4.5", - "@next/swc-win32-arm64-msvc": "15.4.5", - "@next/swc-win32-x64-msvc": "15.4.5", - "sharp": "^0.34.3" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.1.0", - "@playwright/test": "^1.51.1", - "babel-plugin-react-compiler": "*", - "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", - "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", - "sass": "^1.3.0" - }, - "peerDependenciesMeta": { - "@opentelemetry/api": { - "optional": true - }, - "@playwright/test": { - "optional": true - }, - "babel-plugin-react-compiler": { - "optional": true - }, - "sass": { - "optional": true - } + "node": ">= 4.4.x" } }, - "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==", + "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/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/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/ng-chartist": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/ng-chartist/-/ng-chartist-8.3.2.tgz", + "integrity": "sha512-Guy3Z3CWqe2wppKXmVZE/mCZssNjn3qLMJ3G9Gha+cc4lYU011KS6L+hCtz9xlCdZDOvd5lz61HMFPtVbJLOUw==", + "dependencies": { + "tslib": "2.6.3" + }, + "peerDependencies": { + "@angular/common": "^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", + "@angular/core": "^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", + "chartist": "^1.0.0" + } + }, + "node_modules/ng-chartist/node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + }, + "node_modules/ng2-charts": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ng2-charts/-/ng2-charts-6.0.1.tgz", + "integrity": "sha512-pO7evbvHqjiKB7zqE12tCKWQI9gmQ8DVOEaWBBLlxJabc4fLGk7o9t4jC4+Q9pJiQrTtQkugm0dIPQ4PFHUaWA==", + "dependencies": { + "lodash-es": "^4.17.15", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/cdk": ">=17.0.0", + "@angular/common": ">=17.0.0", + "@angular/core": ">=17.0.0", + "@angular/platform-browser": ">=17.0.0", + "chart.js": "^3.4.0 || ^4.0.0", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/ngx-skeleton-loader": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/ngx-skeleton-loader/-/ngx-skeleton-loader-9.0.0.tgz", + "integrity": "sha512-aO4/V6oGdZGNcTjasTg/fwzJJYl/ZmNKgCukOEQdUK3GSFOZtB/3GGULMJuZ939hk3Hzqh1OBiLfIM1SqTfhqg==", + "dependencies": { + "tslib": "^2.0.0" + }, + "peerDependencies": { + "@angular/common": ">=16.0.0", + "@angular/core": ">=16.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/nice-napi/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/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==", + "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 + }, + "node_modules/node-forge": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.4.0.tgz", + "integrity": "sha512-LarFH0+6VfriEhqMMcLX2F7SwSXeWwnEAJEsYm5QKWchiVYVvJyV9v7UDvUv+w5HO23ZpQTXDv/GxdDdMyOuoQ==", "dev": true, - "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": ">= 6.13.0" } }, - "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==", + "node_modules/node-gyp": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-10.3.1.tgz", + "integrity": "sha512-Pp3nFHBThHzVtNY7U6JfPjvT/DTE8+o/4xKsLQtBoU+j2HLsGlhcfzflAoUreaJbNmYnX+LlLi0qjV8kpyO6xQ==", "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": "^13.0.0", + "nopt": "^7.0.0", + "proc-log": "^4.1.0", + "semver": "^7.3.5", + "tar": "^6.2.1", + "which": "^4.0.0" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, "engines": { - "node": ">=12" + "node": "^16.14.0 || >=18.0.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, + "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-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, + "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/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "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/sindresorhus" + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/node-gyp/node_modules/isexe": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.5.tgz", + "integrity": "sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/node-gyp/node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/node-gyp/node_modules/which": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "dev": true, + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, + "node_modules/node-releases": { + "version": "2.0.36", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.36.tgz", + "integrity": "sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==" + }, + "node_modules/nopt": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.1.tgz", + "integrity": "sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==", + "dev": true, + "dependencies": { + "abbrev": "^2.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.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, + "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-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": "11.0.3", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-11.0.3.tgz", + "integrity": "sha512-sHGJy8sOC1YraBywpzQlIKBE4pBbGbiF95U6Auspzyem956E0+FtDtsx1ZxlOJkQCZ1AFXAY/yuvtFYrOxF+Bw==", + "dev": true, + "dependencies": { + "hosted-git-info": "^7.0.0", + "proc-log": "^4.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^5.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm-packlist": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-8.0.2.tgz", + "integrity": "sha512-shYrPFIS/JLP4oQmAwDyk5HcyysKW8/JLTEA32S0Z5TzvpaeeX2yMFfoK1fjEBnCBvVyIB/Jj/GBFdm0wsgzbA==", + "dev": true, + "dependencies": { + "ignore-walk": "^6.0.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-pick-manifest": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-9.1.0.tgz", + "integrity": "sha512-nkc+3pIIhqHVQr085X9d2JzPzLyjzQS96zbruppqC9aZRm/x8xx6xhI98gHtsfELP2bE+loHq8ZaHFHhe+NauA==", + "dev": true, + "dependencies": { + "npm-install-checks": "^6.0.0", + "npm-normalize-package-bin": "^3.0.0", + "npm-package-arg": "^11.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm-registry-fetch": { + "version": "17.1.0", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-17.1.0.tgz", + "integrity": "sha512-5+bKQRH0J1xG1uZ1zMNvxW0VEyoNWgJpY9UDuluPFLKDfJ9u2JmmjmTJV1srBGQOROfdBMiVvnH2Zvpbm+xkVA==", + "dev": true, + "dependencies": { + "@npmcli/redact": "^2.0.0", + "jsonparse": "^1.3.1", + "make-fetch-happen": "^13.0.0", + "minipass": "^7.0.2", + "minipass-fetch": "^3.0.0", + "minizlib": "^2.1.2", + "npm-package-arg": "^11.0.0", + "proc-log": "^4.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.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/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" } @@ -5478,145 +11203,73 @@ "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/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dev": true }, - "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==", + "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": { - "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" + "ee-first": "1.1.1" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">= 0.8" } }, - "node_modules/object.entries": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz", - "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==", + "node_modules/on-headers": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz", + "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==", "dev": true, - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.4", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.1.1" - }, "engines": { - "node": ">= 0.4" + "node": ">= 0.8" } }, - "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==", + "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, "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" + "wrappy": "1" } }, "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==", + "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-fn": "^4.0.0" + "mimic-function": "^5.0.0" }, "engines": { - "node": ">=12" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/openapi-typescript": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/openapi-typescript/-/openapi-typescript-7.8.0.tgz", - "integrity": "sha512-1EeVWmDzi16A+siQlo/SwSGIT7HwaFAVjvMA7/jG5HMLSnrUOzPL7uSTRZZa4v/LCRxHTApHKtNY6glApEoiUQ==", + "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": { - "@redocly/openapi-core": "^1.34.3", - "ansi-colors": "^4.1.3", - "change-case": "^5.4.4", - "parse-json": "^8.3.0", - "supports-color": "^10.0.0", - "yargs-parser": "^21.1.1" + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "is-wsl": "^3.1.0" }, - "bin": { - "openapi-typescript": "bin/cli.js" - }, - "peerDependencies": { - "typescript": "^5.x" - } - }, - "node_modules/openapi-typescript/node_modules/supports-color": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-10.1.0.tgz", - "integrity": "sha512-GBuewsPrhJPftT+fqDa9oI/zc5HNsG9nREqwzoSFDOIqf0NggOZbHQj2TE1P1CDJK8ZogFnlZY9hWoUiur7I/A==", - "dev": true, "engines": { "node": ">=18" }, "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/optionator": { @@ -5636,21 +11289,88 @@ "node": ">= 0.8.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==", + "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": { - "get-intrinsic": "^1.2.6", - "object-keys": "^1.1.1", - "safe-push-apply": "^1.0.0" + "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": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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/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/ordered-binary": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.6.1.tgz", + "integrity": "sha512-QkCdPooczexPLiXIrbVOPYkR3VO3T6v2OyKRkR1Xbhpy7/LAVXwahnRCgRp78Oe/Ehf0C/HATAxfSr6eA1oX+w==", + "dev": 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/p-limit": { @@ -5683,6 +11403,84 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "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": "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/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 + }, + "node_modules/pacote": { + "version": "18.0.6", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-18.0.6.tgz", + "integrity": "sha512-+eK3G27SMwsB8kLIuj4h1FUhHtwiEUo21Tw8wNjmvdlpOEr613edv+8FUsTj/4F/VN5ywGE19X18N7CC2EJk6A==", + "dev": true, + "dependencies": { + "@npmcli/git": "^5.0.0", + "@npmcli/installed-package-contents": "^2.0.1", + "@npmcli/package-json": "^5.1.0", + "@npmcli/promise-spawn": "^7.0.0", + "@npmcli/run-script": "^8.0.0", + "cacache": "^18.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^7.0.2", + "npm-package-arg": "^11.0.0", + "npm-packlist": "^8.0.0", + "npm-pick-manifest": "^9.0.0", + "npm-registry-fetch": "^17.0.0", + "proc-log": "^4.0.0", + "promise-retry": "^2.0.1", + "sigstore": "^2.2.0", + "ssri": "^10.0.0", + "tar": "^6.1.11" + }, + "bin": { + "pacote": "bin/index.js" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -5696,22 +11494,97 @@ } }, "node_modules/parse-json": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.3.0.tgz", - "integrity": "sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==", + "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.26.2", - "index-to-position": "^1.1.0", - "type-fest": "^4.39.1" + "@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": ">=18" + "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==", + "dev": true + }, + "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.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "devOptional": true, + "dependencies": { + "entities": "^6.0.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/parse5/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "devOptional": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?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", @@ -5721,6 +11594,15 @@ "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-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -5736,57 +11618,181 @@ "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.13", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.13.tgz", + "integrity": "sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA==", + "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/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": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "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": ">=8.6" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/pidtree": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz", - "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==", + "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, - "bin": { - "pidtree": "bin/pidtree.js" + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/piscina": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/piscina/-/piscina-4.6.1.tgz", + "integrity": "sha512-z30AwWGtQE+Apr+2WBZensP2lIvwoaMcOPkQlIEmSGMJNUvaYACylPYrQM6wSdUNJlnDVMSpLv7xTMJqlVshOA==", + "dev": true, + "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": ">=0.10" + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/pluralize": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", - "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "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": ">=4" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/possible-typed-array-names": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", - "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "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": ">= 0.4" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/pkg-dir/node_modules/yocto-queue": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.2.tgz", + "integrity": "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==", + "dev": true, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/postcss": { - "version": "8.4.31", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", - "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "version": "8.4.41", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz", + "integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==", + "dev": true, "funding": [ { "type": "opencollective", @@ -5802,14 +11808,129 @@ } ], "dependencies": { - "nanoid": "^3.3.6", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" + "nanoid": "^3.3.7", + "picocolors": "^1.0.1", + "source-map-js": "^1.2.0" }, "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.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz", + "integrity": "sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==", + "dev": true, + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^7.0.0", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz", + "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "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": "7.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", + "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", + "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/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -5819,66 +11940,103 @@ "node": ">= 0.8.0" } }, - "node_modules/prettier": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", - "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", + "node_modules/proc-log": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz", + "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==", "dev": true, - "bin": { - "prettier": "bin/prettier.cjs" + "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/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": ">=14" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" + "node": ">=10" } }, - "node_modules/prop-types": { - "version": "15.8.1", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", - "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "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": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.13.1" - } - }, - "node_modules/prop-types-extra": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.1.tgz", - "integrity": "sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew==", - "dependencies": { - "react-is": "^16.3.2", - "warning": "^4.0.0" + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" }, - "peerDependencies": { - "react": ">=0.14.0" + "engines": { + "node": ">= 0.10" } }, - "node_modules/property-information": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz", - "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "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/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "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/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": ">=6" + "node": ">=0.9" + } + }, + "node_modules/qs": { + "version": "6.14.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.2.tgz", + "integrity": "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==", + "dev": true, + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "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", @@ -5894,178 +12052,155 @@ } ] }, - "node_modules/react": { - "version": "19.1.1", - "resolved": "https://registry.npmjs.org/react/-/react-19.1.1.tgz", - "integrity": "sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ==", + "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.10.0" + "node": ">= 0.6" } }, - "node_modules/react-bootstrap": { - "version": "2.10.10", - "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.10.10.tgz", - "integrity": "sha512-gMckKUqn8aK/vCnfwoBpBVFUGT9SVQxwsYrp9yDHt0arXMamxALerliKBxr1TPbntirK/HGrUAHYbAeQTa9GHQ==", + "node_modules/raw-body": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz", + "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==", + "dev": true, "dependencies": { - "@babel/runtime": "^7.24.7", - "@restart/hooks": "^0.4.9", - "@restart/ui": "^1.9.4", - "@types/prop-types": "^15.7.12", - "@types/react-transition-group": "^4.4.6", - "classnames": "^2.3.2", - "dom-helpers": "^5.2.1", - "invariant": "^2.2.4", - "prop-types": "^15.8.1", - "prop-types-extra": "^1.1.0", - "react-transition-group": "^4.4.5", - "uncontrollable": "^7.2.1", - "warning": "^4.0.3" + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "unpipe": "~1.0.0" }, - "peerDependencies": { - "@types/react": ">=16.14.8", - "react": ">=16.14.0", - "react-dom": ">=16.14.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } + "engines": { + "node": ">= 0.8" } }, - "node_modules/react-dom": { - "version": "19.1.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.1.tgz", - "integrity": "sha512-Dlq/5LAZgF0Gaz6yiqZCf6VCcZs1ghAJyrsu84Q/GT0gV+mCxbfmKNoGRKBYMJ8IEdGPqu49YWXD02GCknEDkw==", + "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, "dependencies": { - "scheduler": "^0.26.0" + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" }, - "peerDependencies": { - "react": "^19.1.1" - } - }, - "node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - }, - "node_modules/react-lifecycles-compat": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", - "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" - }, - "node_modules/react-transition-group": { - "version": "4.4.5", - "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", - "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", - "dependencies": { - "@babel/runtime": "^7.5.5", - "dom-helpers": "^5.0.1", - "loose-envify": "^1.4.0", - "prop-types": "^15.6.2" - }, - "peerDependencies": { - "react": ">=16.6.0", - "react-dom": ">=16.6.0" + "engines": { + "node": ">= 6" } }, "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==", - "devOptional": true, - "engines": { - "node": ">= 14.18.0" + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" }, - "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" + "engines": { + "node": ">=8.10.0" } }, - "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==", + "node_modules/readdirp/node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "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==" + }, + "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.2", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.2.tgz", + "integrity": "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==", "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" + "regenerate": "^1.4.2" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=4" } }, - "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==", + "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/regex-parser": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.3.1.tgz", + "integrity": "sha512-yXLRqatcCuKtVHsWrNg0JL3l1zGfdXeEvDa0bdu4tCDQw0RpMDZsqbkyRTUnKMR0tXF627V2oEWjBEaEdqTwtQ==", + "dev": true + }, + "node_modules/regexpu-core": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.4.0.tgz", + "integrity": "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==", "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" + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.2.2", + "regjsgen": "^0.8.0", + "regjsparser": "^0.13.0", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.2.1" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=4" } }, - "node_modules/rehype-stringify": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/rehype-stringify/-/rehype-stringify-10.0.1.tgz", - "integrity": "sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==", + "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.13.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.0.tgz", + "integrity": "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==", + "dev": true, "dependencies": { - "@types/hast": "^3.0.0", - "hast-util-to-html": "^9.0.0", - "unified": "^11.0.0" + "jsesc": "~3.1.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "bin": { + "regjsparser": "bin/parser" } }, - "node_modules/remark-parse": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", - "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-from-markdown": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-rehype": { - "version": "11.1.2", - "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz", - "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "mdast-util-to-hast": "^13.0.0", - "unified": "^11.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "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": { @@ -6077,22 +12212,25 @@ "node": ">=0.10.0" } }, + "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==", + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dev": true, "dependencies": { - "is-core-module": "^2.16.0", + "is-core-module": "^2.13.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" } @@ -6106,13 +12244,43 @@ "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==", + "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, - "funding": { - "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + "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": { @@ -6131,26 +12299,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/restore-cursor/node_modules/onetime": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", - "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "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, - "dependencies": { - "mimic-function": "^5.0.0" - }, "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 4" } }, "node_modules/reusify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", - "dev": true, "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -6162,11 +12323,73 @@ "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", "dev": true }, + "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/rollup": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.22.4.tgz", + "integrity": "sha512-vD8HJ5raRcWOyymsR6Z3o6+RzfEPCnVLMFJ6vRslO1jt4LO6dUo5Qnpg7y4RkZFM2DMe3WUirkI5c16onjrc6A==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.22.4", + "@rollup/rollup-android-arm64": "4.22.4", + "@rollup/rollup-darwin-arm64": "4.22.4", + "@rollup/rollup-darwin-x64": "4.22.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.22.4", + "@rollup/rollup-linux-arm-musleabihf": "4.22.4", + "@rollup/rollup-linux-arm64-gnu": "4.22.4", + "@rollup/rollup-linux-arm64-musl": "4.22.4", + "@rollup/rollup-linux-powerpc64le-gnu": "4.22.4", + "@rollup/rollup-linux-riscv64-gnu": "4.22.4", + "@rollup/rollup-linux-s390x-gnu": "4.22.4", + "@rollup/rollup-linux-x64-gnu": "4.22.4", + "@rollup/rollup-linux-x64-musl": "4.22.4", + "@rollup/rollup-win32-arm64-msvc": "4.22.4", + "@rollup/rollup-win32-ia32-msvc": "4.22.4", + "@rollup/rollup-win32-x64-msvc": "4.22.4", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-applescript": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz", + "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "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", @@ -6185,40 +12408,33 @@ "queue-microtask": "^1.2.2" } }, - "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, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", "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" + "tslib": "^2.1.0" } }, - "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==", + "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, - "dependencies": { - "es-errors": "^1.3.0", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "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-regex-test": { "version": "1.1.0", @@ -6237,14 +12453,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "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.90.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.90.0.tgz", - "integrity": "sha512-9GUyuksjw70uNpb1MTYWsH9MQHOHY6kwfnkafC24+7aOMZn9+rVMBxRbLvw756mrBFbIsFg6Xw9IkR2Fnn3k+Q==", - "devOptional": true, + "version": "1.77.6", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.6.tgz", + "integrity": "sha512-ByXE1oLD79GVq9Ht1PeHWCPMPB8XHpBuz1r85oByKHjZY6qV6rWnQovQzXJXuQ/XyE1Oj3iPk3lo28uzaRA2/Q==", + "dev": true, "dependencies": { - "chokidar": "^4.0.0", - "immutable": "^5.0.2", + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", "source-map-js": ">=0.6.2 <2.0.0" }, "bin": { @@ -6252,21 +12474,117 @@ }, "engines": { "node": ">=14.0.0" - }, - "optionalDependencies": { - "@parcel/watcher": "^2.4.1" } }, - "node_modules/scheduler": { - "version": "0.26.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", - "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==" + "node_modules/sass-loader": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-16.0.0.tgz", + "integrity": "sha512-n13Z+3rU9A177dk4888czcVFiC8CL9dii4qpXWUg3YIIgZEvi9TCFKjOQcbK0kJM7DJu9VucrZFddvNfYCPwtw==", + "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/sax": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.0.tgz", + "integrity": "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==", + "dev": true, + "optional": true, + "engines": { + "node": ">=11.0.0" + } + }, + "node_modules/schema-utils": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", + "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", + "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": ">= 10.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/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/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.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", - "devOptional": true, + "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" }, @@ -6274,99 +12592,184 @@ "node": ">=10" } }, - "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==", + "node_modules/send": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.2.tgz", + "integrity": "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==", "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" + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "~0.5.2", + "http-errors": "~2.0.1", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "~2.4.1", + "range-parser": "~1.2.1", + "statuses": "~2.0.2" }, "engines": { - "node": ">= 0.4" + "node": ">= 0.8.0" } }, - "node_modules/set-function-name": { + "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/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/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.2", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", - "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", "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": ">= 0.8" } }, - "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==", + "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": { - "dunder-proto": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" + "randombytes": "^2.1.0" } }, - "node_modules/sharp": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.3.tgz", - "integrity": "sha512-eX2IQ6nFohW4DbvHIOLRB3MHFpYqaqvXd3Tp5e/T/dSH83fxaNJQRvDMhASmkNTsNTVF2/OOopzRCt7xokgPfg==", - "hasInstallScript": true, - "optional": true, + "node_modules/serve-index": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.2.tgz", + "integrity": "sha512-KDj11HScOaLmrPxl70KYNW1PksP4Nb/CLL2yvC+Qd2kHMPEEpfc4Re2e4FOay+bC/+XQl/7zAcWON3JVo5v3KQ==", + "dev": true, "dependencies": { - "color": "^4.2.3", - "detect-libc": "^2.0.4", - "semver": "^7.7.2" + "accepts": "~1.3.8", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.8.0", + "mime-types": "~2.1.35", + "parseurl": "~1.3.3" }, "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">= 0.8.0" }, "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-darwin-arm64": "0.34.3", - "@img/sharp-darwin-x64": "0.34.3", - "@img/sharp-libvips-darwin-arm64": "1.2.0", - "@img/sharp-libvips-darwin-x64": "1.2.0", - "@img/sharp-libvips-linux-arm": "1.2.0", - "@img/sharp-libvips-linux-arm64": "1.2.0", - "@img/sharp-libvips-linux-ppc64": "1.2.0", - "@img/sharp-libvips-linux-s390x": "1.2.0", - "@img/sharp-libvips-linux-x64": "1.2.0", - "@img/sharp-libvips-linuxmusl-arm64": "1.2.0", - "@img/sharp-libvips-linuxmusl-x64": "1.2.0", - "@img/sharp-linux-arm": "0.34.3", - "@img/sharp-linux-arm64": "0.34.3", - "@img/sharp-linux-ppc64": "0.34.3", - "@img/sharp-linux-s390x": "0.34.3", - "@img/sharp-linux-x64": "0.34.3", - "@img/sharp-linuxmusl-arm64": "0.34.3", - "@img/sharp-linuxmusl-x64": "0.34.3", - "@img/sharp-wasm32": "0.34.3", - "@img/sharp-win32-arm64": "0.34.3", - "@img/sharp-win32-ia32": "0.34.3", - "@img/sharp-win32-x64": "0.34.3" + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/sharp/node_modules/detect-libc": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", - "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", - "optional": true, + "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.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "dev": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "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-static": { + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.3.tgz", + "integrity": "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==", + "dev": true, + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "~0.19.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/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/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" } @@ -6392,6 +12795,18 @@ "node": ">=8" } }, + "node_modules/shell-quote": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", + "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", + "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", @@ -6476,13 +12891,30 @@ "url": "https://github.com/sponsors/isaacs" } }, - "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==", - "optional": true, + "node_modules/sigstore": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-2.3.1.tgz", + "integrity": "sha512-8G+/XDU8wNsJOQS5ysDVO0Etg9/2uA5gR9l4ZwijjlwxBcrU6RPfwi2+jJmbP+Ap1Hlp/nVAaEO4Fj22/SL2gQ==", + "dev": true, "dependencies": { - "is-arrayish": "^0.3.1" + "@sigstore/bundle": "^2.3.2", + "@sigstore/core": "^1.0.0", + "@sigstore/protobuf-specs": "^0.3.2", + "@sigstore/sign": "^2.3.2", + "@sigstore/tuf": "^2.3.4", + "@sigstore/verify": "^1.2.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "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": { @@ -6502,9 +12934,9 @@ } }, "node_modules/slice-ansi/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==", + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", "dev": true, "engines": { "node": ">=12" @@ -6513,49 +12945,269 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "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.8.3", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.3.tgz", + "integrity": "sha512-2Dd78bqzzjE6KPkD5fHZmDAKRNe3J15q+YHDrIsy9WEkqttc7GY+kT9OBLSMaPbQaEd0x1BjcmtMtXkfpc+T5A==", + "dev": true, + "dependencies": { + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "cors": "~2.8.5", + "debug": "~4.4.1", + "engine.io": "~6.6.0", + "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.6", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.6.tgz", + "integrity": "sha512-DkkO/dz7MGln0dHn5bmN3pPy+JmywNICWrJqVWiVOyvXjWQFIv9c2h24JrQLLFJ2aQVQf/Cvl1vblnd4r2apLQ==", + "dev": true, + "dependencies": { + "debug": "~4.4.1", + "ws": "~8.18.3" + } + }, + "node_modules/socket.io-parser": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.6.tgz", + "integrity": "sha512-asJqbVBDsBCJx0pTqw3WfesSY0iRX+2xzWEWzrpcH7L6fLzrhyF8WPI8UaeM4YCuDfpwA/cgsdugMsmtz8EJeg==", + "dev": true, + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.4.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/socks": { + "version": "2.8.7", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.7.tgz", + "integrity": "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==", + "dev": true, + "dependencies": { + "ip-address": "^10.0.1", + "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==", + "dev": true, + "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/space-separated-tokens": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", - "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/stable-hash": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.5.tgz", - "integrity": "sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==", - "dev": true - }, - "node_modules/stop-iteration-iterator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", - "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "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": { - "es-errors": "^1.3.0", - "internal-slot": "^1.1.0" + "iconv-lite": "^0.6.3", + "source-map-js": "^1.0.2" }, "engines": { - "node": ">= 0.4" + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.72.1" } }, - "node_modules/string-argv": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", - "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", + "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.6.19" + "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.23", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.23.tgz", + "integrity": "sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==", + "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/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/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/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, + "dependencies": { + "safe-buffer": "~5.2.0" } }, "node_modules/string-width": { @@ -6575,139 +13227,55 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/string-width/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==", + "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-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 }, - "node_modules/string.prototype.includes": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz", - "integrity": "sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==", + "node_modules/string-width-cjs/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, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.3" - }, "engines": { - "node": ">= 0.4" + "node": ">=8" } }, - "node_modules/string.prototype.matchall": { - "version": "4.0.12", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", - "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", + "node_modules/string-width/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "dev": true, - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.6", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.6", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "internal-slot": "^1.1.0", - "regexp.prototype.flags": "^1.5.3", - "set-function-name": "^2.0.2", - "side-channel": "^1.1.0" - }, "engines": { - "node": ">= 0.4" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/string.prototype.repeat": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", - "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", "dev": true, "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "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/stringify-entities": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", - "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", - "dependencies": { - "character-entities-html4": "^2.0.0", - "character-entities-legacy": "^3.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "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" + "ansi-regex": "^6.2.2" }, "engines": { "node": ">=12" @@ -6716,25 +13284,28 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "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, + "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": ">=4" + "node": ">=8" } }, - "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==", + "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, - "engines": { - "node": ">=12" + "dependencies": { + "ansi-regex": "^5.0.1" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=8" } }, "node_modules/strip-json-comments": { @@ -6749,28 +13320,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/styled-jsx": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz", - "integrity": "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==", - "dependencies": { - "client-only": "0.0.1" - }, - "engines": { - "node": ">= 12.0.0" - }, - "peerDependencies": { - "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" - }, - "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, - "babel-plugin-macros": { - "optional": true - } - } - }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -6795,14 +13344,185 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/tinyglobby": { - "version": "0.2.14", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", - "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", + "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/tapable": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.2.tgz", + "integrity": "sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "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==", + "deprecated": "Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "dev": true, "dependencies": { - "fdir": "^6.4.4", - "picomatch": "^4.0.2" + "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/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/terser": { + "version": "5.31.6", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.6.tgz", + "integrity": "sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg==", + "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.4.0", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.4.0.tgz", + "integrity": "sha512-Bn5vxm48flOIfkdl5CaD2+1CiUVbonWQ3KQPyP7/EuIl9Gbzq/gQFOzaMFUEgVjB1396tcK0SG8XcNJ/2kDH8g==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "jest-worker": "^27.4.5", + "schema-utils": "^4.3.0", + "terser": "^5.31.1" + }, + "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/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/thingies": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/thingies/-/thingies-2.6.0.tgz", + "integrity": "sha512-rMHRjmlFLM1R96UYPvpmnc3LYtdFrT33JIB7L9hetGue1qAPfn1N2LJeEjxUSidu1Iku+haLZXDuEXUHNGO/lg==", + "dev": true, + "engines": { + "node": ">=10.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "^2" + } + }, + "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/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "peer": true, + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" }, "engines": { "node": ">=12.0.0" @@ -6811,25 +13531,12 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, - "node_modules/tinyglobby/node_modules/fdir": { - "version": "6.4.6", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", - "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", - "dev": true, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, "node_modules/tinyglobby/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, + "peer": true, "engines": { "node": ">=12" }, @@ -6837,11 +13544,22 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "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" }, @@ -6849,46 +13567,50 @@ "node": ">=8.0" } }, - "node_modules/trim-lines": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", - "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "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/trough": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", - "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", + "node_modules/tree-dump": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.1.0.tgz", + "integrity": "sha512-rMuvhU4MCDbcbnleZTFezWsaZXRFemSqAM+7jPnzUl1fo9w3YEKOxAeui0fz3OI4EU4hf23iyA7uQRVko+UaBA==", + "dev": true, + "engines": { + "node": ">=10.0" + }, "funding": { "type": "github", - "url": "https://github.com/sponsors/wooorm" + "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/ts-api-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", - "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz", + "integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==", "dev": true, "engines": { - "node": ">=18.12" + "node": ">=16" }, "peerDependencies": { - "typescript": ">=4.8.4" - } - }, - "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" + "typescript": ">=4.2.0" } }, "node_modules/tslib": { @@ -6896,6 +13618,20 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" }, + "node_modules/tuf-js": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-2.2.1.tgz", + "integrity": "sha512-GwIJau9XaA8nLVbUXsN3IlFi7WmQ48gBUrl3FTkkL/XLu/POhBzfmX9hd33FNMX1qAsfl6ozO1iMmW9NC8YniA==", + "dev": true, + "dependencies": { + "@tufjs/models": "2.0.1", + "debug": "^4.3.4", + "make-fetch-happen": "^13.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -6909,96 +13645,40 @@ } }, "node_modules/type-fest": { - "version": "4.41.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", - "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "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": ">=16" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "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==", + "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": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "is-typed-array": "^1.1.14" + "media-typer": "0.3.0", + "mime-types": "~2.1.24" }, "engines": { - "node": ">= 0.4" + "node": ">= 0.6" } }, - "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/typescript": { - "version": "5.9.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", - "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", - "dev": true, + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -7007,157 +13687,159 @@ "node": ">=14.17" } }, - "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==", + "node_modules/ua-parser-js": { + "version": "0.7.41", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.41.tgz", + "integrity": "sha512-O3oYyCMPYgNNHuO7Jjk3uacJWZF8loBgwrfd/5LE/HyZ3lUIOdniQ7DNXJcIgZbwioZxk0fLfI4EVnetdiX5jg==", "dev": true, - "dependencies": { - "call-bound": "^1.0.3", - "has-bigints": "^1.0.2", - "has-symbols": "^1.1.0", - "which-boxed-primitive": "^1.1.1" + "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" + } + ], + "bin": { + "ua-parser-js": "script/cli.js" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/uncontrollable": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.2.1.tgz", - "integrity": "sha512-svtcfoTADIB0nT9nltgjujTi7BzVmwjZClOmskKu/E8FW9BXzg9os8OLr4f8Dlnk0rYWJIWr4wv9eKUXiQvQwQ==", - "dependencies": { - "@babel/runtime": "^7.6.3", - "@types/react": ">=16.9.11", - "invariant": "^2.2.4", - "react-lifecycles-compat": "^3.0.4" - }, - "peerDependencies": { - "react": ">=15.0.0" + "node": "*" } }, "node_modules/undici-types": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.10.0.tgz", - "integrity": "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true }, - "node_modules/unified": { - "version": "11.0.5", - "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", - "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", - "dependencies": { - "@types/unist": "^3.0.0", - "bail": "^2.0.0", - "devlop": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^4.0.0", - "trough": "^2.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-is": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-position": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", - "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "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==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", - "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit-parents": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", - "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unrs-resolver": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.1.tgz", - "integrity": "sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==", + "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, - "hasInstallScript": true, "dependencies": { - "napi-postinstall": "^0.3.0" + "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.1", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz", + "integrity": "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.2.0.tgz", + "integrity": "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "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, + "engines": { + "node": ">=18" }, "funding": { - "url": "https://opencollective.com/unrs-resolver" + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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" }, - "optionalDependencies": { - "@unrs/resolver-binding-android-arm-eabi": "1.11.1", - "@unrs/resolver-binding-android-arm64": "1.11.1", - "@unrs/resolver-binding-darwin-arm64": "1.11.1", - "@unrs/resolver-binding-darwin-x64": "1.11.1", - "@unrs/resolver-binding-freebsd-x64": "1.11.1", - "@unrs/resolver-binding-linux-arm-gnueabihf": "1.11.1", - "@unrs/resolver-binding-linux-arm-musleabihf": "1.11.1", - "@unrs/resolver-binding-linux-arm64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-arm64-musl": "1.11.1", - "@unrs/resolver-binding-linux-ppc64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-riscv64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-riscv64-musl": "1.11.1", - "@unrs/resolver-binding-linux-s390x-gnu": "1.11.1", - "@unrs/resolver-binding-linux-x64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-x64-musl": "1.11.1", - "@unrs/resolver-binding-wasm32-wasi": "1.11.1", - "@unrs/resolver-binding-win32-arm64-msvc": "1.11.1", - "@unrs/resolver-binding-win32-ia32-msvc": "1.11.1", - "@unrs/resolver-binding-win32-x64-msvc": "1.11.1" + "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": "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/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/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "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/uri-js": { @@ -7169,44 +13851,904 @@ "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==", + "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/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 }, - "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==", + "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": "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/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": { - "@types/unist": "^3.0.0", - "vfile-message": "^4.0.0" + "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/vite": { + "version": "5.4.21", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz", + "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==", + "dev": true, + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.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", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/vite/node_modules/postcss": { + "version": "8.5.8", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", + "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", + "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.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "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/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/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 + }, + "node_modules/webpack": { + "version": "5.94.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz", + "integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.5", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", + "acorn": "^8.7.1", + "acorn-import-attributes": "^1.9.5", + "browserslist": "^4.21.10", + "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/unified" + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } } }, - "node_modules/vfile-message": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", - "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", + "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": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" + "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/unified" + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + } } }, - "node_modules/warning": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", - "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "node_modules/webpack-dev-server": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.2.2.tgz", + "integrity": "sha512-QcQ72gh8a+7JO63TAx/6XZf/CWhgMzu5m0QirvPfGvptOusAxG12w2+aua1Jkjr7hzaWDnJ2n6JFeexMHI+Zjg==", + "dev": true, "dependencies": { - "loose-envify": "^1.0.0" + "@types/bonjour": "^3.5.13", + "@types/connect-history-api-fallback": "^1.5.4", + "@types/express": "^4.17.21", + "@types/express-serve-static-core": "^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.9", + "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.9", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.9.tgz", + "integrity": "sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q==", + "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.3.4", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.4.tgz", + "integrity": "sha512-7tP1PdV4vF+lYPnkMR0jMY5/la2ub5Fc/8VQrrU+lXkiM6C4TjVfGw7iKfyhnTQOsD+6Q/iKw0eFciziRgD58Q==", + "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.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", + "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/which": { @@ -7224,90 +14766,11 @@ "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-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-typed-array": { - "version": "1.1.19", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", - "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", - "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.8", - "call-bound": "^1.0.4", - "for-each": "^0.3.5", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "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", @@ -7319,61 +14782,186 @@ } }, "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==", + "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": "^6.2.1", - "string-width": "^7.0.0", - "strip-ansi": "^7.1.0" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "engines": { - "node": ">=18" + "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/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==", + "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 + }, + "node_modules/wrap-ansi-cjs/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/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, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true + }, + "node_modules/wrap-ansi/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/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==", + "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/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 + }, + "node_modules/ws": { + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "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/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==" + }, + "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" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/yaml": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz", - "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==", - "dev": true, - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14.6" - } - }, - "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 - }, "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/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==" + }, + "node_modules/yargs/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/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==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", @@ -7386,22 +14974,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/zod": { - "version": "3.25.76", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", - "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "node_modules/yoctocolors-cjs": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.3.tgz", + "integrity": "sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==", + "dev": true, + "engines": { + "node": ">=18" + }, "funding": { - "url": "https://github.com/sponsors/colinhacks" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/zwitch": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", - "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } + "node_modules/zone.js": { + "version": "0.14.10", + "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.14.10.tgz", + "integrity": "sha512-YGAhaO7J5ywOXW6InXNlLmfU194F8lVgu7bRntUF3TiG8Y3nBK0x1UJJuHUP/e8IyihkjCYqhCScpSwnlaSRkQ==" } } } diff --git a/package.json b/package.json index 1289ce1..c24ebcd 100644 --- a/package.json +++ b/package.json @@ -1,49 +1,67 @@ { - "name": "adastra-nextjs", - "version": "0.1.0", - "private": true, - "stackblitz": { - "startCommand": "npm start" - }, + "name": "adastra-app", + "version": "1.0.0", + "author": "Solide Apps ", + "contributors": [ + "Julien Gautier " + ], "scripts": { - "dev": "next dev --port 4201", - "secure": "next dev --experimental-https", - "build": "next build", - "start": "next start", - "lint": "next lint", - "prepare": "husky", - "format": "prettier . --write", - "fix": "next lint --fix", - "test": "npm run build", - "openapi-generate": "openapi-typescript ./api/openapi.yml --output ./src/generated/apiSchema.generated.d.ts" + "ng": "ng", + "start": "ng serve", + "build": "ng build", + "watch": "ng build --watch --configuration development", + "serve": "ng serve --configuration local --port 4201", + "dev": "APP_ENV=development ng serve --port 4300 --configuration development", + "local": "APP_ENV=local ng serve --port 4400 --configuration local", + "lint": "ng lint", + "test": "ng test" }, + "engines": { + "node": "^18.19.1 || ^20.11.1" + }, + "private": true, "dependencies": { - "@conform-to/react": "^1.2.2", - "@conform-to/zod": "^1.2.2", - "clsx": "^2.1.1", + "@angular/animations": "^18.2.14", + "@angular/cdk": "^18.2.14", + "@angular/common": "^18.2.14", + "@angular/compiler": "^18.2.14", + "@angular/core": "^18.2.14", + "@angular/forms": "^18.2.14", + "@angular/google-maps": "^17.3.8", + "@angular/localize": "^18.2.14", + "@angular/material": "^18.2.14", + "@angular/platform-browser": "^18.2.14", + "@angular/platform-browser-dynamic": "^18.2.14", + "@angular/router": "^18.2.14", "bootstrap": "^5.3.7", - "next": "^15.4.5", - "react": "^19.1.1", - "react-bootstrap": "^2.10.10", - "react-dom": "^19.1.1", - "rehype-stringify": "^10.0.1", - "remark-parse": "^11.0.0", - "remark-rehype": "^11.1.1", - "unified": "^11.0.5", - "zod": "^3.23.8" + "chart.js": "^4.4.2", + "chartist": "^1.3.0", + "ng-chartist": "^8.2.0", + "ng2-charts": "^6.0.1", + "ngx-skeleton-loader": "^9.0.0", + "rxjs": "~7.8.0", + "tslib": "^2.3.0", + "zone.js": "^0.14.10" }, "devDependencies": { - "@types/node": "^24.1.0", - "@types/react": "^19.1.9", - "@types/react-dom": "^19.1.7", - "eslint": "^9.32.0", - "eslint-config-next": "^15.4.5", - "eslint-config-prettier": "^9.1.0", - "husky": "^9.1.6", - "lint-staged": "^15.2.10", - "openapi-typescript": "^7.4.1", - "prettier": "^3.3.3", - "typescript": "^5.9.2", - "sass": "^1.89.2" + "@angular-devkit/build-angular": "^18.2.21", + "@angular-eslint/builder": "18.4.3", + "@angular-eslint/eslint-plugin": "18.4.3", + "@angular-eslint/eslint-plugin-template": "18.4.3", + "@angular-eslint/schematics": "18.4.3", + "@angular-eslint/template-parser": "18.4.3", + "@angular/cli": "^18.2.21", + "@angular/compiler-cli": "^18.2.14", + "@types/jasmine": "~5.1.0", + "@typescript-eslint/eslint-plugin": "7.2.0", + "@typescript-eslint/parser": "7.2.0", + "eslint": "^8.57.0", + "jasmine-core": "~5.1.0", + "karma": "~6.4.0", + "karma-chrome-launcher": "~3.2.0", + "karma-coverage": "~2.2.0", + "karma-jasmine": "~5.1.0", + "karma-jasmine-html-reporter": "~2.1.0", + "typescript": "~5.5.4" } } diff --git a/src/_redirects b/src/_redirects new file mode 100644 index 0000000..b21f6cb --- /dev/null +++ b/src/_redirects @@ -0,0 +1 @@ +/* /index.html 200 \ No newline at end of file diff --git a/src/app/app.component.html b/src/app/app.component.html new file mode 100644 index 0000000..e310aa3 --- /dev/null +++ b/src/app/app.component.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/app/app.component.scss b/src/app/app.component.scss new file mode 100644 index 0000000..9cae760 --- /dev/null +++ b/src/app/app.component.scss @@ -0,0 +1,8 @@ +.grayscale { + filter: grayscale(1); + transition: all 2s ease; +} +.colored { + filter: grayscale(0); + transition: all 5s ease; +} \ No newline at end of file diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts new file mode 100644 index 0000000..a095620 --- /dev/null +++ b/src/app/app.component.spec.ts @@ -0,0 +1,29 @@ +import { TestBed } from '@angular/core/testing'; +import { AppComponent } from './app.component'; + +describe('AppComponent', () => { + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [AppComponent], + }).compileComponents(); + }); + + it('should create the app', () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.componentInstance; + expect(app).toBeTruthy(); + }); + + it(`should have the 'adastra_angular' title`, () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.componentInstance; + expect(app.title).toEqual('adastra_angular'); + }); + + it('should render title', () => { + const fixture = TestBed.createComponent(AppComponent); + fixture.detectChanges(); + const compiled = fixture.nativeElement as HTMLElement; + expect(compiled.querySelector('h1')?.textContent).toContain('Hello, adastra_angular'); + }); +}); diff --git a/src/app/app.component.ts b/src/app/app.component.ts new file mode 100644 index 0000000..c38a264 --- /dev/null +++ b/src/app/app.component.ts @@ -0,0 +1,48 @@ +import { Component, OnInit, AfterContentInit } from '@angular/core'; +import { MAT_DATE_LOCALE, MAT_DATE_FORMATS, provideNativeDateAdapter } from '@angular/material/core'; +import { Title } from '@angular/platform-browser'; + +import { FullComponent } from '@components/shared/layout'; +import { UserService } from "@services"; + +export const MY_FORMATS = { + parse: { + dateInput: 'DD/MM/YYYY', + }, + display: { + dateInput: 'DD/MM/YYYY', + monthYearLabel: 'MMM YYYY', + dateA11yLabel: 'LL', + monthYearA11yLabel: 'MMMM-YYYY', + }, +}; + +@Component({ + selector: 'app-root', + standalone: true, + imports: [ + FullComponent + ], + providers: [ + { provide: MAT_DATE_LOCALE, useValue: 'fr-FR' }, + { provide: MAT_DATE_FORMATS, useValue: MY_FORMATS }, + provideNativeDateAdapter(MY_FORMATS) + ], + templateUrl: './app.component.html', + styleUrl: './app.component.scss' +}) +export class AppComponent implements OnInit, AfterContentInit { + public title = 'Ad Astra'; + public appClass = 'grayscale'; + + constructor(private userService: UserService, private titleService: Title) { } + + ngOnInit() { + this.userService.populate(); + this.titleService.setTitle(this.title); + } + + ngAfterContentInit() { + this.appClass = 'colored'; + } +} \ No newline at end of file diff --git a/src/app/app.config.ts b/src/app/app.config.ts new file mode 100644 index 0000000..be3e1c4 --- /dev/null +++ b/src/app/app.config.ts @@ -0,0 +1,40 @@ +import { APP_INITIALIZER, ApplicationConfig, LOCALE_ID } from '@angular/core'; +import { Title } from '@angular/platform-browser'; +//import { provideRouter, withComponentInputBinding, withDebugTracing } from '@angular/router'; +import { provideRouter, withViewTransitions } from '@angular/router'; +import { provideAnimations } from '@angular/platform-browser/animations'; +import { provideHttpClient, withInterceptors } from '@angular/common/http'; +import { registerLocaleData } from '@angular/common'; +import localeFr from '@angular/common/locales/fr'; +import { provideCharts, withDefaultRegisterables } from 'ng2-charts'; +import { EMPTY } from "rxjs"; + +registerLocaleData(localeFr); + +import { routes } from './app.routes'; +import { apiInterceptor, tokenInterceptor, errorInterceptor } from "@interceptors"; +import { JwtService, UserService } from "@services"; + +export function initAuth(jwtService: JwtService, userService: UserService) { + return () => (jwtService.getToken() ? userService.getCurrentUser() : EMPTY); +} + +export const appConfig: ApplicationConfig = { + providers: [ + //provideRouter(routes, withComponentInputBinding(), withDebugTracing()), + provideRouter(routes, withViewTransitions()), + provideHttpClient( + withInterceptors([apiInterceptor, tokenInterceptor, errorInterceptor]) + ), + provideAnimations(), + provideCharts(withDefaultRegisterables()), + Title, + { provide: LOCALE_ID, useValue: 'fr-FR' }, + { + provide: APP_INITIALIZER, + useFactory: initAuth, + deps: [JwtService, UserService], + multi: true, + } + ] +}; diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts new file mode 100644 index 0000000..7306644 --- /dev/null +++ b/src/app/app.routes.ts @@ -0,0 +1,5 @@ +import { Routes } from '@angular/router'; + +import { AUTH_ROUTES, NOAUTH_ROUTES } from 'src/app/routes'; + +export const routes: Routes = [ ...AUTH_ROUTES, ...NOAUTH_ROUTES]; diff --git a/src/app/components/aeronefs/aeronefs.component.html b/src/app/components/aeronefs/aeronefs.component.html new file mode 100644 index 0000000..9ab18b9 --- /dev/null +++ b/src/app/components/aeronefs/aeronefs.component.html @@ -0,0 +1,49 @@ +
+
+
+

{{title}}

+ + Dernier saut enregistré : {{ lastJump.numero }}ème à {{ lastJump.lieu }} le {{ lastJump.date | date: 'dd/MM/yyyy' }} + +
+ +
+ + + @for (menuitem of menuItems.getMenuPanel(); track menuitem) { + + } + +
+
+ + + + {{ subtitle }} + + + @if (displayCharts) { +
+
+ +
+
+ + +
+
+ } +
+
+ + +
+
+
+
+
\ No newline at end of file diff --git a/src/app/components/aeronefs/aeronefs.component.scss b/src/app/components/aeronefs/aeronefs.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/components/aeronefs/aeronefs.component.spec.ts b/src/app/components/aeronefs/aeronefs.component.spec.ts new file mode 100644 index 0000000..219a518 --- /dev/null +++ b/src/app/components/aeronefs/aeronefs.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AeronefsComponent } from './aeronefs.component'; + +describe('AeronefsComponent', () => { + let component: AeronefsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [AeronefsComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(AeronefsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/aeronefs/aeronefs.component.ts b/src/app/components/aeronefs/aeronefs.component.ts new file mode 100644 index 0000000..1367d73 --- /dev/null +++ b/src/app/components/aeronefs/aeronefs.component.ts @@ -0,0 +1,113 @@ +import { DatePipe } from '@angular/common'; +import { trigger, state, style, animate, transition } from '@angular/animations'; +import { Component, DestroyRef, inject, OnInit, OnDestroy } from '@angular/core'; +import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; +import { ActivatedRoute } from '@angular/router'; +import { MatBadgeModule } from '@angular/material/badge'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatExpansionModule } from '@angular/material/expansion'; +import { MatGridListModule } from '@angular/material/grid-list'; +import { MatIconModule } from '@angular/material/icon'; +import { MatMenuModule } from '@angular/material/menu'; +import { Observable, Subscription } from 'rxjs'; + +import { MenuItems } from '@components/shared'; +import { HistoryTableComponent } from '@components/shared/helpers-jump'; +import { BarsChartComponent, PieChartComponent } from '@components/shared/helpers-chart'; +import { Jump, AeronefsPageData } from '@models'; +import { UtilitiesService } from '@services'; +import { AeronefByImat, AeronefByYear } from '@models'; + +@Component({ + selector: 'app-aeronefs', + standalone: true, + imports: [ + DatePipe, + MatBadgeModule, MatButtonModule, MatCardModule, MatDividerModule, + MatExpansionModule, MatGridListModule, MatIconModule, MatMenuModule, + BarsChartComponent, HistoryTableComponent, PieChartComponent + ], + templateUrl: './aeronefs.component.html', + styleUrl: './aeronefs.component.scss', + animations: [ + trigger('flyInOut', [ + state('in', style({ transform: 'translateX(0)' })), + transition('void => *', [ + style({ transform: 'translateX(-100%)' }), + animate(200) + ]), + transition('* => void', [ + style({ transform: 'translateX(100%)' }), + animate(200) + ]) + ]) + ] +}) +export class AeronefsComponent implements OnInit, OnDestroy { + private _data: Subscription = new Subscription(); + private _aeronefsByImat!: Array; + private _aeronefsByYear!: Array; + public lastJump: Jump = {} as Jump; + public title = 'Aéronefs'; + public subtitle: string = 'Nombre total de sauts par aéronef'; + public displayCharts = false; + public destroyRef = inject(DestroyRef); + public seriesHeader: string[] = []; + public seriesName: string[] = []; + public seriesValue: number[] = []; + public seriesRow: Array> = []; + public seriesColor: { + backgroundColor: string[], + borderColor: string[] + } = { + backgroundColor: this._utilitiesService.getSeriesColors(0.8, 'all'), + borderColor: this._utilitiesService.getSeriesColors(1, 'all') + }; + public seriesColorClass: string[] = this._utilitiesService.getChartColors(); + + constructor( + private route: ActivatedRoute, + private _utilitiesService: UtilitiesService, + public menuItems: MenuItems + ) { } + + ngOnInit() { + const data$: Observable<{ aeronefsPageData: AeronefsPageData }> = this.route.data as Observable<{ aeronefsPageData: AeronefsPageData }>; + this._data = data$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data: { aeronefsPageData: AeronefsPageData }) => { + const pageData: AeronefsPageData = data.aeronefsPageData; + this.lastJump = pageData.lastjump; + this._loadAeronefByImat(pageData); + }); + } + + ngOnDestroy() { + this._data.unsubscribe(); + } + + private _loadAeronefByImat(pageData: AeronefsPageData): void { + this._aeronefsByImat = pageData.aeronefsByImat.map((row: AeronefByImat) => { + this.seriesName.push(`${row.aeronef} ${row.imat}`); + this.seriesValue.push(row.count); + return row; + }); + this._loadAeronefByYear(pageData); + } + + private _loadAeronefByYear(pageData: AeronefsPageData): void { + this.seriesHeader = ['2018', '2019', '2020', '2021', '2022', '2023', '2024']; + const values: Array = this.seriesHeader.map(() => 0); + this.seriesName.forEach(() => { + this.seriesRow.push([...values]); + }); + this._aeronefsByYear = pageData.aeronefsByImatByYear.map((row: AeronefByYear) => { + const aeronef: string = row.aeronef; + const imat: string = row.imat; + const year: string = row.year.toString(); + this.seriesRow[this.seriesName.indexOf(`${aeronef} ${imat}`)][this.seriesHeader.indexOf(year)] = row.count; + return row; + }); + this.displayCharts = true; + } +} diff --git a/src/app/components/auth/auth.component.html b/src/app/components/auth/auth.component.html new file mode 100644 index 0000000..6f86fa7 --- /dev/null +++ b/src/app/components/auth/auth.component.html @@ -0,0 +1,113 @@ +
+
+
+

{{ title }}

+

+ @if (authType === 'register') { + Vous avez déjà un compte ? + } + @if (authType === 'login') { + Vous n'avez pas encore de compte ? + } +

+ +
+
+ Informations personnelles +
+ + + @if (this.authForm.controls['email'].status === 'INVALID') { + {{getErrorMessage('email')}} + } + +
+ @if (authType === 'register') { +
+ + + @if (this.authForm.controls['lastname'].status === 'INVALID') { + {{getErrorMessage('lastname')}} + } + +
+ } + @if (authType === 'register') { +
+ + + @if (this.authForm.controls['firstname'].status === 'INVALID') { + {{getErrorMessage('firstname')}} + } + +
+ } + @if (authType === 'register') { +
+ + + @if (this.authForm.controls['phone'].status === 'INVALID') { + {{getErrorMessage('phone')}} + } + +
+ } + @if (authType === 'register') { +
+ + + @if (this.authForm.controls['username'].status === 'INVALID') { + {{getErrorMessage('username')}} + } + +
+ } + @if (authType === 'register') { +
+ + + @if (this.authForm.controls['licence'].status === 'INVALID') { + {{getErrorMessage('licence')}} + } + +
+ } + @if (authType === 'register') { +
+ + + @if (this.authForm.controls['poids'].status === 'INVALID') { + {{getErrorMessage('poids')}} + } + +
+ } +
+
+ Informations de connexion +
+ + + @if (this.authForm.controls['password'].status === 'INVALID') { + {{getErrorMessage('password')}} + } + +
+ @if (authType === 'register') { +
+ + + @if (this.authForm.controls['confirmPassword'].status === 'INVALID') { + {{getErrorMessage('confirmPassword')}} + } + +
+ } +
+ +
+
+
+
+
+
diff --git a/src/app/components/auth/auth.component.scss b/src/app/components/auth/auth.component.scss new file mode 100644 index 0000000..ef4856d --- /dev/null +++ b/src/app/components/auth/auth.component.scss @@ -0,0 +1,6 @@ +fieldset { + border-style: none; + border-width: 0; + margin: 0; + padding: 0; +} \ No newline at end of file diff --git a/src/app/components/auth/auth.component.spec.ts b/src/app/components/auth/auth.component.spec.ts new file mode 100644 index 0000000..da6d393 --- /dev/null +++ b/src/app/components/auth/auth.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AuthComponent } from './auth.component'; + +describe('AuthComponent', () => { + let component: AuthComponent; + let fixture: ComponentFixture; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [AuthComponent] +}); + fixture = TestBed.createComponent(AuthComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/auth/auth.component.ts b/src/app/components/auth/auth.component.ts new file mode 100644 index 0000000..586e7a4 --- /dev/null +++ b/src/app/components/auth/auth.component.ts @@ -0,0 +1,168 @@ +import { Component, DestroyRef, inject, OnInit, OnDestroy } from '@angular/core'; +import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; +import { UntypedFormBuilder, UntypedFormGroup, AbstractControl, Validators, ValidatorFn, ValidationErrors, FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { Title } from '@angular/platform-browser'; +import { ActivatedRoute, Router, RouterLink } from '@angular/router'; +import { MatButtonModule } from '@angular/material/button'; +import { MatInputModule } from '@angular/material/input'; +import { MatFormFieldModule } from '@angular/material/form-field'; + +import { Subscription } from 'rxjs'; +import { take } from 'rxjs/operators'; + +import { Errors } from '@models'; +import { UserService } from '@services'; +import { ListErrorsComponent, ShowAuthedDirective } from '@components/shared'; + +@Component({ + standalone: true, + imports: [ + RouterLink, + FormsModule, + ReactiveFormsModule, + MatFormFieldModule, + MatInputModule, + MatButtonModule, + ListErrorsComponent, + ShowAuthedDirective + ], + selector: 'app-auth', + templateUrl: './auth.component.html', + styleUrl: './auth.component.scss' +}) +export class AuthComponent implements OnInit, OnDestroy { + private _url: Subscription = new Subscription(); + private _user: Subscription = new Subscription(); + authType = ''; + title = ''; + btnTitle = ''; + errors: Errors = { errors: {} }; + isSubmitting = false; + authForm!: UntypedFormGroup; + destroyRef = inject(DestroyRef); + + constructor( + private route: ActivatedRoute, + private router: Router, + private titleService: Title, + private userService: UserService, + private fb: UntypedFormBuilder + ) { + this._resetErrors(); + // use FormBuilder to create a form group + const controlsConfig = { + email: ['', [Validators.required, Validators.email]], + username: '', + firstname: '', + lastname: '', + phone: '', + licence: '', + poids: '', + password: ['', Validators.required], + confirmPassword: '' + }; + this.authForm = this.fb.group(controlsConfig, { validators: this.checkPasswords }); + } + + ngOnInit() { + // you would normally unsubscribe from this observable subscription + // the active route observables are exemptions from unsubribe always rule + // see notes on: https://angular.io/guide/router#observable-parammap-and-component-reuse + this.route.url.pipe(take(1)) + .subscribe(data => { + // Get the last piece of the URL (it's either 'login' or 'register') + this.authType = data[data.length - 1].path; + // Set a title for the page accordingly + if (this.authType === 'register') { + this.title = 'Création de compte'; + this.btnTitle = 'Créer le compte'; + this.titleService.setTitle(`Ad Astra - Créer un compte`); + } else { + this.title = 'Se connecter'; + this.btnTitle = 'Se connecter'; + this.titleService.setTitle(`Ad Astra - Connexion`); + } + // add form control for username if this is the register page + if (this.authType === 'register') { + this.authForm.controls['firstname'].setValidators([Validators.required]); + this.authForm.controls['lastname'].setValidators([Validators.required]); + this.authForm.controls['phone'].setValidators([Validators.required]); + this.authForm.controls['confirmPassword'].setValidators([Validators.minLength(8), Validators.required]); + } + }); + } + + ngOnDestroy() { + this._user.unsubscribe(); + //this._url.unsubscribe(); + } + + submitForm() { + this.isSubmitting = true; + this.errors = { errors: {} }; + + if (this.authForm.valid) { + this._resetErrors(); + const credentials = this.authForm.value; + const user$ = this.userService.attemptAuth(this.authType, credentials).pipe(takeUntilDestroyed(this.destroyRef)); + this._user = user$.subscribe({ + next: () => void this.router.navigateByUrl('/'), + error: (err) => { + console.log(err); + this.errors = err; + this.isSubmitting = false; + } + }); + } + } + + getErrorMessage(name: string) { + switch (name) { + case 'email': + if (this.authForm.controls['email'].errors !== null) { + return 'Indiquez votre adresse email'; + } + break; + case 'firstname': + if (this.authForm.controls['firstname'].errors !== null) { + return 'Vous devez indiquer votre prénnom'; + } + break; + case 'lastname': + if (this.authForm.controls['lastname'].errors !== null) { + return 'Vous devez indiquer votre nom'; + } + break; + case 'phone': + if (this.authForm.controls['phone'].errors !== null) { + return 'Vous devez indiquer votre numéro de téléphone'; + } + break; + case 'password': + if (this.authForm.controls['password'].errors !== null) { + return 'Un mot de passe est obligatoire'; + } + break; + case 'confirmPassword': + if (this.authForm.controls['confirmPassword'].errors !== null) { + return 'Une confirmation du mot de passe est obligatoire'; + } + break; + } + return ''; + } + + checkPasswords: ValidatorFn = (group: AbstractControl): ValidationErrors | null => { + if (this.authType !== 'register') { + return null; + } + const pass = group.get('password')!.value; + const confirmPass = group.get('confirmPassword')!.value + return (pass === confirmPass && pass !== '') ? null : { notSame: true } + } + + private _resetErrors(): void { + this.errors = { errors: {} }; + } + +} diff --git a/src/app/components/calculator/calculator.component.html b/src/app/components/calculator/calculator.component.html new file mode 100644 index 0000000..3214fdb --- /dev/null +++ b/src/app/components/calculator/calculator.component.html @@ -0,0 +1,257 @@ +
+
+
+

{{title}}

+ DT48 - 08 février 2024 +
+ +
+ + + @for (menuitem of menuItems.getMenuCalculator(); track menuitem) { + @if (menuitem.type === 'link') { + + } + } + +
+
+ + + +
+ + Nombre de sauts + + + + Poids nu + + + + Poids équipement + + + + Taille actuelle + + +
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Taille actuelleTaille minTaille min -11%
Taille de voile en ft2 ● + {{ info.sizesFeet.current }} ● {{ info.sizesFeet.min }} ● {{ info.sizesFeet.min11 }}
Charge alaire{{ info.charges.current | number : '1.2-3' }}{{ info.charges.min | number : '1.2-3' }}{{ info.charges.min11 | number : '1.2-3' }}
Taille de voile en m2{{ info.sizesMeter.current | number : '1.2-3' }}{{ info.sizesMeter.min | number : '1.2-3' }}{{ info.sizesMeter.min11 | number : '1.2-3' }}
Coefficient kilo/livres{{ coeffKgLbs }}
Coefficient pied/mètre{{ coeffFtM }}
Formule charge alaire + ( ( {{ inputs.weight }} + {{ inputs.gear }} ) * {{ coeffKgLbs }} ) / + {{ inputs.current }} = {{ info.charges.current | number : '1.5' }}
+ ( ( poids nu en kg + poids equipement en kg ) * coefficient kg/lbs ) / taille de + voile en ft2 +
+
+
+ @if (displayCharts) { +
+ + +
+ } +
+
+ +

Tailles de voile pour {{ inputs.weight }} kg

+
+ Prochain changement de valeurs dans {{ ((this.currentRange.end + 1) - inputs.jumps) }} + {{ ((this.currentRange.end + 1) - inputs.jumps) > 1 ? 'sauts' : 'saut'}}
+
+
+ {{ ((((inputs.jumps - this.currentRange.start) + 1) / ((this.currentRange.end - this.currentRange.start) + 1)) * 100) | number : '1.2-2' }}% + de la tranche actuelle ({{this.currentRange.start}} à {{this.currentRange.end}}) +
+ + + + + + @for (header of sizesHeader; track header; let index = $index) { + + } + + + + + + @for (value of sizesValuesFeet; track value; let index = $index) { + + } + + + + @for (value of sizesMinValuesFeet; track value; let index = $index) { + + } + + + + @for (charge of sizesCharges; track charge; let index = $index) { + + } + + + + @for (value of sizesValuesMeter; track value; let index = $index) { + + } + + +
{{ header.name }}
Taille de voile en ft2{{ value }}
Abbattement 11%{{ value }}
Charge alaire + {{ charge | number : '1.2-3' }}
Taille de voile en m2 + {{ value | number : '1.2-2' }}
+ +

Tableau des tailles de voile par poids

+
+ {{ ((inputs.jumps / 1600) * 100) | number : '1.2-2' }}% de la plage complète (0 à 1600) +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ {{tableHeader[0].name}} + {{element.weight}} + + {{tableHeader[1].name}} {{element.ranges[0].value}} + {{tableHeader[2].name}} {{element.ranges[1].value}} + {{tableHeader[3].name}} {{element.ranges[2].value}} + {{tableHeader[4].name}} {{element.ranges[3].value}} + {{tableHeader[5].name}} {{element.ranges[4].value}} + {{tableHeader[6].name}} {{element.ranges[5].value}} + {{tableHeader[7].name}} {{element.ranges[6].value}} + {{tableHeader[8].name}} {{element.ranges[7].value}} + {{tableHeader[9].name}} {{element.ranges[8].value}}
+
+ +
+
+
+
\ No newline at end of file diff --git a/src/app/components/calculator/calculator.component.scss b/src/app/components/calculator/calculator.component.scss new file mode 100644 index 0000000..6a1843b --- /dev/null +++ b/src/app/components/calculator/calculator.component.scss @@ -0,0 +1,33 @@ +.calculator-page { + section { + display: table; + } + .demo-label { + display: table-cell; + font-size: 14px; + margin-left: 8px; + min-width: 120px; + } + .demo-button-row { + display: table-cell; + max-width: 900px; + } + .demo-button-row .mat-mdc-button-base { + margin: 8px 8px 8px 0; + } + .demo-flex-container { + display: flex; + justify-content: space-between; + flex-wrap: wrap; + } + .demo-button-container { + display: flex; + justify-content: center; + width: 120px; + } + th { + &.first { + width: 180px; + } + } +} \ No newline at end of file diff --git a/src/app/components/calculator/calculator.component.spec.ts b/src/app/components/calculator/calculator.component.spec.ts new file mode 100644 index 0000000..2400cb7 --- /dev/null +++ b/src/app/components/calculator/calculator.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CalculatorComponent } from './calculator.component'; + +describe('CalculatorComponent', () => { + let component: CalculatorComponent; + let fixture: ComponentFixture; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [CalculatorComponent] +}); + fixture = TestBed.createComponent(CalculatorComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/calculator/calculator.component.ts b/src/app/components/calculator/calculator.component.ts new file mode 100644 index 0000000..95efc2f --- /dev/null +++ b/src/app/components/calculator/calculator.component.ts @@ -0,0 +1,222 @@ +import { Component, Input, OnInit, OnDestroy, ViewChild } from '@angular/core'; +import { trigger, state, style, animate, transition } from '@angular/animations'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatIconModule } from '@angular/material/icon'; +import { MatInputModule } from '@angular/material/input'; +import { MatMenuModule } from '@angular/material/menu'; +import { MatPaginator, MatPaginatorModule } from '@angular/material/paginator'; +import { MatProgressBarModule } from '@angular/material/progress-bar'; +import { MatSort, MatSortModule } from '@angular/material/sort'; +import { MatTableDataSource, MatTableModule } from '@angular/material/table'; +import { BaseChartDirective } from 'ng2-charts'; +import { Observable, Subscription } from 'rxjs'; + +import { MenuItems } from '@components/shared'; +import { CalculatorInfo, CalculatorResult, CalculatorState, InputParams, Jump, LineConfig, WeightSizeRange, TableHeader, User, WeightSize, weightSizes } from '@models'; +import { CalculatorService, JumpsService, UserService, UtilitiesService } from '@services'; + +@Component({ + selector: 'app-calculator', + standalone: true, + imports: [ + CommonModule, FormsModule, RouterModule, + MatButtonModule, MatCardModule, MatDividerModule, + MatFormFieldModule, MatInputModule, MatIconModule, MatMenuModule, + MatPaginatorModule, MatProgressBarModule, MatSortModule, MatTableModule, + BaseChartDirective + ], + templateUrl: './calculator.component.html', + styleUrl: './calculator.component.scss', + animations: [ + trigger('flyInOut', [ + state('in', style({ transform: 'translateY(0)' })), + transition('void => *', [ + style({ transform: 'translateY(-100%)' }), + animate(200) + ]), + transition('* => void', [ + style({ transform: 'translateY(100%)' }), + animate(200) + ]) + ]) + ] +}) +export class CalculatorComponent implements OnInit, OnDestroy { + //private _lastjump!: Subscription; // = new Subscription(); + //private _currentUser!: Subscription; // = new Subscription(); + private _subscriptions: Array = []; + public title = 'Calcul de taille de voile'; + public subtitle = 'DT48 - 08 février 2024'; + public lastjump: Jump = {} as Jump; + public currentRange: WeightSizeRange = {} as WeightSizeRange; + public currentUser: User = {} as User; + public displayedColumns: Array = ['weight']; + public tableHeader: Array = [{name: 'Poids nu en kg', active: ''}]; + public sizesHeader: Array = []; + public sizesValuesFeet: Array = []; + public sizesMinValuesFeet: Array = []; + public sizesCharges: Array = []; + public sizesValuesMeter: Array = []; + public displayCharts = false; + public chartConfig: LineConfig = this._utilitiesService.getLineChartConfig(); + public coeffKgLbs: number = this._utilitiesService.getCoeffKgLbs(); + public coeffFtM: number = this._utilitiesService.getCoeffFtM(); + public info: CalculatorInfo = { + charges: { current: 0, min: 0, min11: 0 }, + sizesFeet: { current: 0, min: 0, min11: 0 }, + sizesMeter: { current: 0, min: 0, min11: 0 }, + state: { color: 'danger' } + } + + @Input() canopy_size_table!: MatTableDataSource; + @Input() inputs: InputParams = { + jumps: 0, + weight: 60, + gear: 10, + current: 190 + } as InputParams; + + @ViewChild(MatSort) sort!: MatSort; + @ViewChild(MatPaginator) paginator!: MatPaginator; + + constructor( + private _calculatorService: CalculatorService, + private _jumpsService: JumpsService, + private _userService: UserService, + private _utilitiesService: UtilitiesService, + public menuItems: MenuItems + ) { } + + ngOnInit() { + const currentUser$: Observable = this._userService.currentUser; + const lastjump$: Observable = this._jumpsService.getLastJump(); + + weightSizes[0].ranges.forEach((range: WeightSizeRange) => { + const header: TableHeader = {name: range.label, active: range.active}; + this.tableHeader.push(header) + this.sizesHeader.push(header); + this.displayedColumns.push(range.name); + }); + this.chartConfig.lineChartData.labels = [...this.sizesHeader.map( + (data: TableHeader): string => data.name + )]; + this.chartConfig.lineChartData.datasets = [ + { + label: 'Tailles min -11%', + data: this.sizesMinValuesFeet, + fill: true, + stepped: true, + pointStyle: false, + borderColor: 'rgba(241, 80, 80, 1)', + backgroundColor: 'rgba(241, 80, 80, 0.3)' + }, + { + label: 'Tailles min', + data: this.sizesValuesFeet, + fill: true, + stepped: true, + pointStyle: false, + borderColor: 'rgba(32, 182, 252, 1)', + backgroundColor: 'rgba(32, 182, 252, 0.3)' + } + ]; + this._subscriptions.push( + currentUser$.subscribe((userData: User) => { + this.currentUser = userData; + this._subscriptions.push( + lastjump$.subscribe((jump) => { + this.lastjump = jump; + this.inputs.jumps = jump.numero; + this.inputs.weight = this.currentUser.poids!; + this.inputs.current = jump.taille!; + this.canopy_size_table = new MatTableDataSource(weightSizes); + this.refresh(); + }) + ); + }) + ); + } + + ngOnDestroy() { + this._subscriptions.forEach((sub: Subscription) => { + sub.unsubscribe(); + }); + } + + public refresh():void { + this._refreshActive(); + this._refreshSizes(); + } + + private _refreshActive(): void { + let weight: number = this.inputs.weight; + if (this.inputs.weight < 60) { + weight = 60; + } + weightSizes.forEach(element => { + element.active = ''; + element.ranges.forEach(range => { + range.active = ''; + }); + }); + this.tableHeader.forEach(element => { + element.active = ''; + }); + if (weight >= 60 && weight <= 110) { + weightSizes[(weight - 60)].active = 'active'; + } + if (this.inputs.jumps >= 0) { + const num = this._calculatorService.getRangeNum(this.inputs.jumps); + this.tableHeader[num].active = 'active'; + weightSizes.forEach(element => { + element.ranges[(num-1)].active = 'active'; + }); + this.currentRange = weightSizes[0].ranges[(num-1)]; + } + } + + private _refreshSizes(): void { + let weight: number = this.inputs.weight; + if (this.inputs.weight < 60) { + weight = 60; + } + if (this.inputs.jumps > 2000) { + this.info.state.error = '2K+ Jumps'; + } + this.sizesValuesFeet = this._calculatorService.getCanopySizes(weight); + this.sizesMinValuesFeet = this._calculatorService.getCanopySizes(weight, true); + this.sizesValuesMeter = this.sizesValuesFeet.map((value: number, index: number) => { + this.sizesCharges[index] = this._calculatorService.getCharge(value, this.inputs.weight, this.inputs.gear); + return this._calculatorService.convertFeet2Meters(value); + }); + this.info.sizesFeet = this._calculatorService.canopySizeCalc(weight, this.inputs.jumps); + this.info.sizesFeet.current = this.inputs.current; + this.info.sizesMeter = { + current: this._calculatorService.convertFeet2Meters(this.inputs.current), + min: this._calculatorService.convertFeet2Meters(this.info.sizesFeet.min), + min11: this._calculatorService.convertFeet2Meters(this.info.sizesFeet.min11) + } + this.info.charges = { + current: this._calculatorService.getCharge(this.inputs.current, this.inputs.weight, this.inputs.gear), + min: this._calculatorService.getCharge(this.info.sizesFeet.min, this.inputs.weight, this.inputs.gear), + min11: this._calculatorService.getCharge(this.info.sizesFeet.min11, this.inputs.weight, this.inputs.gear) + } + this.info.state.color = this._calculatorService.getStateColor(this.info.sizesFeet); + + this.chartConfig.lineChartData.datasets[0].data = this.sizesMinValuesFeet; + this.chartConfig.lineChartData.datasets[1].data = this.sizesValuesFeet; + this.displayCharts = true; + } + + public setCurrentWeight(weight: number) { + this.inputs.weight = weight; + this.refresh(); + } + +} diff --git a/src/app/components/canopies/canopies.component.html b/src/app/components/canopies/canopies.component.html new file mode 100644 index 0000000..7bdd887 --- /dev/null +++ b/src/app/components/canopies/canopies.component.html @@ -0,0 +1,56 @@ +
+
+
+

{{title}}

+ + Dernier saut enregistré : {{ lastJump.numero }}ème à {{ lastJump.lieu }} le {{ lastJump.date | date: 'dd/MM/yyyy' }} + +
+ +
+ + + @for (menuitem of menuItems.getMenuPanel(); track menuitem) { + + } + +
+
+ + + + {{ subtitle }} + + + @if (displayCharts) { +
+
+ +
+
+ +
+
+ + +
+
+ } +
+
+ + +
+
+ + +
+
+
+
+
\ No newline at end of file diff --git a/src/app/components/canopies/canopies.component.scss b/src/app/components/canopies/canopies.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/components/canopies/canopies.component.spec.ts b/src/app/components/canopies/canopies.component.spec.ts new file mode 100644 index 0000000..e415ea2 --- /dev/null +++ b/src/app/components/canopies/canopies.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CanopiesComponent } from './canopies.component'; + +describe('CanopiesComponent', () => { + let component: CanopiesComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [CanopiesComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CanopiesComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/canopies/canopies.component.ts b/src/app/components/canopies/canopies.component.ts new file mode 100644 index 0000000..bfbeebc --- /dev/null +++ b/src/app/components/canopies/canopies.component.ts @@ -0,0 +1,142 @@ +import { DatePipe } from '@angular/common'; +import { trigger, state, style, animate, transition } from '@angular/animations'; +import { Component, DestroyRef, inject, OnInit, OnDestroy } from '@angular/core'; +import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; +import { ActivatedRoute } from '@angular/router'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatExpansionModule } from '@angular/material/expansion'; +import { MatGridListModule } from '@angular/material/grid-list'; +import { MatIconModule } from '@angular/material/icon'; +import { MatMenuModule } from '@angular/material/menu'; +import { Observable, Subscription } from 'rxjs'; + +import { MenuItems } from '@components/shared'; +import { HistoryTableComponent } from '@components/shared/helpers-jump'; +import { BarsChartComponent, PieChartComponent } from '@components/shared/helpers-chart'; +import { Jump, CanopiesPageData } from '@models'; +import { UtilitiesService } from '@services'; +import { CanopyBySize, CanopyByYear, CanopyModelBySize, CanopyModelByYear } from '@models'; + +@Component({ + selector: 'app-canopies', + standalone: true, + imports: [ + DatePipe, + MatButtonModule, MatCardModule, MatDividerModule, MatExpansionModule, + MatGridListModule, MatIconModule, MatMenuModule, + HistoryTableComponent, BarsChartComponent, PieChartComponent + ], + templateUrl: './canopies.component.html', + styleUrl: './canopies.component.scss', + animations: [ + trigger('flyInOut', [ + state('in', style({ transform: 'translateX(0)' })), + transition('void => *', [ + style({ transform: 'translateX(-100%)' }), + animate(200) + ]), + transition('* => void', [ + style({ transform: 'translateX(100%)' }), + animate(200) + ]) + ]) + ] +}) +export class CanopiesComponent implements OnInit, OnDestroy { + private _data: Subscription = new Subscription(); + private _canopiesModelBySize!: Array; + private _canopiesModelByYear!: Array; + private _canopiesSizeBySize!: Array; + private _canopiesSizeByYear!: Array; + public lastJump: Jump = {} as Jump; + public title = 'Voiles'; + public subtitle: string = 'Nombre total de sauts par modèle et taille'; + public displayCharts = false; + public destroyRef = inject(DestroyRef); + public seriesModelHeader: string[] = []; + public seriesModelName: string[] = []; + public seriesModelValue: number[] = []; + public seriesModelRow: Array> = []; + public seriesSizeHeader: string[] = []; + public seriesSizeName: string[] = []; + public seriesSizeValue: number[] = []; + public seriesSizeRow: Array> = []; + public seriesColor: { + backgroundColor: string[], + borderColor: string[] + } = { + backgroundColor: this._utilitiesService.getSeriesColors(0.8, 'all'), + borderColor: this._utilitiesService.getSeriesColors(1, 'all') + }; + public seriesColorClass: string[] = this._utilitiesService.getChartColors(); + + constructor( + private route: ActivatedRoute, + private _utilitiesService: UtilitiesService, + public menuItems: MenuItems + ) { } + + ngOnInit() { + const data$: Observable<{ canopiesPageData: CanopiesPageData }> = this.route.data as Observable<{ canopiesPageData: CanopiesPageData }>; + this._data = data$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data: { canopiesPageData: CanopiesPageData }) => { + const pageData: CanopiesPageData = data.canopiesPageData; + this.lastJump = pageData.lastjump; + this._loadCanopyBySize(pageData); + this._loadCanopyModelBySize(pageData); + }); + } + + ngOnDestroy() { + this._data.unsubscribe(); + } + + private _loadCanopyBySize(pageData: CanopiesPageData): void { + this._canopiesSizeBySize = pageData.canopiesBySize.map((row: CanopyBySize) => { + this.seriesSizeName.push(row.taille.toString()); + this.seriesSizeValue.push(row.count); + return row; + }); + this._loadCanopyByYear(pageData); + } + + private _loadCanopyByYear(pageData: CanopiesPageData): void { + this.seriesSizeHeader = ['2018', '2019', '2020', '2021', '2022', '2023', '2024']; + const values: Array = this.seriesSizeHeader.map(() => 0); + this.seriesSizeName.forEach(() => { + this.seriesSizeRow.push([...values]); + }); + this._canopiesSizeByYear = pageData.canopiesBySizeByYear.map((row: CanopyByYear) => { + const taille: string = row.taille.toString(); + const year: string = row.year.toString(); + this.seriesSizeRow[this.seriesSizeName.indexOf(taille)][this.seriesSizeHeader.indexOf(year)] = row.count; + return row; + }); + } + + private _loadCanopyModelBySize(pageData: CanopiesPageData): void { + this._canopiesModelBySize = pageData.canopiesBySizeByModel.map((row: CanopyModelBySize) => { + this.seriesModelName.push(`${row.taille.toString()} - ${row.voile}`); + this.seriesModelValue.push(row.count); + return row; + }); + this._loadCanopyModelByYear(pageData); + } + + private _loadCanopyModelByYear(pageData: CanopiesPageData): void { + this.seriesModelHeader = ['2018', '2019', '2020', '2021', '2022', '2023', '2024']; + const values: Array = this.seriesModelHeader.map(() => 0); + this.seriesModelName.forEach(() => { + this.seriesModelRow.push([...values]); + }); + this._canopiesModelByYear = pageData.canopiesBySizeByModelByYear.map((row: CanopyModelByYear) => { + const voile: string = row.voile; + const taille: string = row.taille.toString(); + const year: string = row.year.toString(); + this.seriesModelRow[this.seriesModelName.indexOf(`${taille} - ${voile}`)][this.seriesModelHeader.indexOf(year)] = row.count; + return row; + }); + this.displayCharts = true; + } +} diff --git a/src/app/components/dashboard/dashboard.component.html b/src/app/components/dashboard/dashboard.component.html new file mode 100644 index 0000000..cf3925d --- /dev/null +++ b/src/app/components/dashboard/dashboard.component.html @@ -0,0 +1,36 @@ +

{{title}}

+ + Dernier saut enregistré : {{ lastJump.numero }}ème à {{ lastJump.lieu }} le {{ lastJump.date | date: 'dd/MM/yyyy' }} + + + +
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
\ No newline at end of file diff --git a/src/app/components/dashboard/dashboard.component.scss b/src/app/components/dashboard/dashboard.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/components/dashboard/dashboard.component.spec.ts b/src/app/components/dashboard/dashboard.component.spec.ts new file mode 100644 index 0000000..f5caa3d --- /dev/null +++ b/src/app/components/dashboard/dashboard.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { DashboardComponent } from './dashboard.component'; + +describe('DashboardComponent', () => { + let component: DashboardComponent; + let fixture: ComponentFixture; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [DashboardComponent] +}); + fixture = TestBed.createComponent(DashboardComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/dashboard/dashboard.component.ts b/src/app/components/dashboard/dashboard.component.ts new file mode 100644 index 0000000..328f56d --- /dev/null +++ b/src/app/components/dashboard/dashboard.component.ts @@ -0,0 +1,147 @@ +import { Component, OnInit, OnDestroy } from '@angular/core'; +import { DatePipe } from '@angular/common'; +import { Title } from '@angular/platform-browser'; +import { MatDividerModule } from '@angular/material/divider'; +import { ActivatedRoute, Data, Router } from '@angular/router'; + +import { Observable, Subscription } from 'rxjs'; +import { take } from 'rxjs/operators'; + +import { Aeronef, AeronefByImat, Canopy, CanopyModelBySize, DropZone, DropZoneByYear, Errors, Jump, User } from '@models'; +//import { AeronefsService, CanopiesService, DropZonesService, UserService } from '@services'; +import { JumpsService, UserService } from '@services'; +import { ShowAuthedDirective } from '@components/shared/show-authed.directive'; +import { + AeronefsPieComponent, AeronefsBarComponent, + CanopiesModelsComponent, CanopiesSizesComponent, + DropzonesPieComponent, DropzonesBarComponent, + JumpsByMonthComponent +} from '@components/shared/dashboard-components'; + +@Component({ + standalone: true, + imports: [ + DatePipe, ShowAuthedDirective, MatDividerModule, + AeronefsPieComponent, AeronefsBarComponent, + CanopiesModelsComponent, CanopiesSizesComponent, + DropzonesPieComponent, DropzonesBarComponent, + JumpsByMonthComponent + ], + selector: 'app-dashboard', + templateUrl: './dashboard.component.html', + styleUrl: './dashboard.component.scss' +}) +export class DashboardComponent implements OnInit, OnDestroy { + private _currentUser: Subscription = new Subscription(); + private _data: Subscription = new Subscription(); + private _lastjump: Subscription = new Subscription(); + private _lastjump$: Observable = new Observable(); + /* + private _aeronefs: Subscription = new Subscription(); + private _canopies: Subscription = new Subscription(); + private _dropzones: Subscription = new Subscription(); + */ + public title = 'Dashboard'; + public errors!: Errors; + public isAuthenticated = false; + public canModify = false; + public aeronefAggregate!: Array; + public aeronefs!: Array; + public aeronefsCount = 0; + public canopyAggregate!: Array; + public canopies!: Array; + public canopiesCount = 0; + public dropzoneAggregate!: Array; + public dropzones!: Array; + public dropzonesCount = 0; + public lastJump: Jump = {} as Jump; + + constructor( + private route: ActivatedRoute, + private router: Router, + private titleService: Title, + private _userService: UserService, + private _jumpsService: JumpsService + /* + private aeronefsService: AeronefsService, + private canopiesService: CanopiesService, + private dropzonesService: DropZonesService + */ + ) { + this._resetErrors(); + } + + ngOnInit() { + this.titleService.setTitle(this.title); + const data$: Observable = this.route.data.pipe(take(1)); + this._data = data$.subscribe((data: Data) => { + this.isAuthenticated = data['isAuthenticated']; + if (!this.isAuthenticated) { + this.router.navigateByUrl('/login'); + return; + } + const currentUser$: Observable = this._userService.currentUser; + this._currentUser = currentUser$.subscribe((userData: User) => { + this.canModify = userData.role === 'Admin'; + }); + + this._lastjump$ = this._jumpsService.getLastJump(); + this._lastjump = this._lastjump$.subscribe((jump) => { + this.lastJump = jump; + }); + }); + /* + this._loadAeronefs(); + this._loadCanopies(); + this._loadDropzones(); + */ + + } + + ngOnDestroy() { + this._currentUser.unsubscribe(); + this._data.unsubscribe(); + this._lastjump.unsubscribe(); + /* + this._aeronefs.unsubscribe(); + this._canopies.unsubscribe(); + this._dropzones.unsubscribe(); + */ + } + + private _resetErrors(): void { + this.errors = { errors: {} }; + } + + /* + private _loadAeronefs(): void { + const aeronefs$: Observable> = this.aeronefsService.getAllByImat(); + this._aeronefs = aeronefs$.subscribe((aggregate: Array) => { + this.aeronefAggregate = aggregate; + this.aeronefsCount = aggregate.length; + console.log(this.aeronefAggregate); + console.log(this.aeronefsCount); + }); + } + + private _loadCanopies(): void { + const canopies$: Observable> = this.canopiesService.getAllModelBySize(); + this._canopies = canopies$.subscribe((aggregate: Array) => { + this.canopyAggregate = aggregate; + this.canopiesCount = aggregate.length; + console.log(this.canopyAggregate); + console.log(this.canopiesCount); + }); + } + + private _loadDropzones(): void { + const dropzones$: Observable> = this.dropzonesService.getAllByDate(); + this._dropzones = dropzones$.subscribe((aggregate: Array) => { + this.dropzoneAggregate = aggregate; + this.dropzonesCount = aggregate.length; + console.log(this.dropzoneAggregate); + console.log(this.dropzonesCount); + }); + } + */ +} diff --git a/src/app/components/demo/demo.component.html b/src/app/components/demo/demo.component.html new file mode 100644 index 0000000..f983cc7 --- /dev/null +++ b/src/app/components/demo/demo.component.html @@ -0,0 +1,295 @@ + +
+
+
+

{{title}}

+
+ +
+
+ + +
+
+ + +
+ + Buttons variants + + + {{ getColors().length }} colors + +
+ +
+ +
+
+ +
+
Links
+
+ @for (color of getColors(); track color) { + + } +
+
+ @for (color of getColors(); track color) { +
+ {{ color }} +
+ } +
+
+ +
+
Normal
+
+ @for (color of getColors(); track color) { +
+ +
+ } +
+ +
+
+ +
+
+ <a Link +
+
+
+ +
+
Stroked
+
+ @for (color of getColors(); track color) { +
+ +
+ } +
+ +
+
+ +
+
+ <a Link +
+
+
+ +
+
Flat
+
+ @for (color of getColors(); track color) { +
+ +
+ } +
+ +
+
+ +
+
+ <a Link +
+
+
+ +
+
Raised
+
+ @for (color of getColors(); track color) { +
+ +
+ } +
+ +
+
+ +
+
+ <a Link +
+
+
+ +
+
FAB
+
+ @for (color of getColors(); track color; let index = $index) { +
+ +
+ } +
+ +
+
+ +
+
+
+ +
+
FAB extended
+
+ @for (color of getColors(); track color; let index = $index) { +
+ +
+ } +
+ +
+
+ +
+
+
+ +
+
Mini FAB
+
+ @for (color of getColors(); track color; let index = $index) { +
+ +
+ } +
+ +
+
+ +
+
+
+ +
+
Icon
+
+ @for (color of getColors(); track color; let index = $index) { +
+ +
+ } +
+ +
+
+ +
+
+
+
+
+
+ +
+ @for (color of getColors(); track color) { +
+
+ + +
+ + {{ color }} + + + Card subtitle + +
+ +
+ +
+
+ +
+
+ + + + +
+
+ + + + +
+ + + + + +
+
+
+
+ } +
\ No newline at end of file diff --git a/src/app/components/demo/demo.component.scss b/src/app/components/demo/demo.component.scss new file mode 100644 index 0000000..ea4d575 --- /dev/null +++ b/src/app/components/demo/demo.component.scss @@ -0,0 +1,58 @@ +/* Demo */ +@use 'variable' as var; + +.mat-mdc-card + .mat-mdc-card { + margin-top: 10px; +} + +.card-list { + width: 500px; + max-width: 100%; + border: solid 1px #ccc; + min-height: 60px; + display: block; + background: var.$white; + border-radius: 4px; + overflow: hidden; +} + +.card-box { + padding: 20px 10px; + border-bottom: solid 1px #ccc; + color: rgba(0, 0, 0, 0.87); + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; + box-sizing: border-box; + cursor: move; + background: var.$white; + font-size: 14px; +} + +.cdk-drag-preview { + border: none; + box-sizing: border-box; + border-radius: 4px; + box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2), + 0 8px 10px 1px rgba(0, 0, 0, 0.14), + 0 3px 14px 2px rgba(0, 0, 0, 0.12); +} + +.cdk-drag-animating { + transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); +} + +.card-box:last-child { + border: none; +} + +.card-list.cdk-drop-list-dragging .card-box:not(.cdk-drag-placeholder) { + transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); +} +.card-custom-placeholder { + background: #ccc; + border: dotted 3px #999; + min-height: 60px; + transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); +} \ No newline at end of file diff --git a/src/app/components/demo/demo.component.spec.ts b/src/app/components/demo/demo.component.spec.ts new file mode 100644 index 0000000..895b441 --- /dev/null +++ b/src/app/components/demo/demo.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { DemoComponent } from './demo.component'; + +describe('DemoComponent', () => { + let component: DemoComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [DemoComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(DemoComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/demo/demo.component.ts b/src/app/components/demo/demo.component.ts new file mode 100644 index 0000000..3412223 --- /dev/null +++ b/src/app/components/demo/demo.component.ts @@ -0,0 +1,83 @@ +import { Component, OnInit, OnDestroy } from '@angular/core'; +import {CdkDragDrop, CdkDropList, CdkDrag, CdkDragPlaceholder, moveItemInArray} from '@angular/cdk/drag-drop'; +import { Title } from '@angular/platform-browser'; +import { RouterLink } from '@angular/router'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatIconModule } from '@angular/material/icon'; +import { MatProgressBarModule } from '@angular/material/progress-bar'; +import { MatSliderModule } from '@angular/material/slider'; + +import { Subscription } from 'rxjs'; + +import { Errors, User } from '@models'; +import { UserService } from '@services'; +import { ListErrorsComponent } from '@components/shared'; + +@Component({ + selector: 'app-demo', + standalone: true, + imports: [ + CdkDropList, CdkDrag, CdkDragPlaceholder, RouterLink, + MatButtonModule, MatCardModule, MatDividerModule, + MatIconModule, MatProgressBarModule, MatSliderModule, + ListErrorsComponent + ], + templateUrl: './demo.component.html', + styleUrl: './demo.component.scss' +}) +export class DemoComponent implements OnInit, OnDestroy { + private _user: Subscription = new Subscription(); + private _colors: string[] = [ + "primary", "accent", "warn", "secondary", "megna", "raspberry", "success", "info", + "warning", "danger", "red", "orange", "yellow", "green", "teal", "turquoise", "cyan", + "blue", "navy", "navy-light", "pink", "magenta", "purple", "purple-light", "grey", "muted" + ]; + private _icons: string[] = [ + 'mode_edit', 'delete', 'bookmark', 'settings', 'home', 'person', + 'share', 'account_circle', 'public', 'search', 'favorite', 'done', + 'numbers', 'attach_file', 'insert_comment', 'format_list_bulleted', + 'filter', 'crop', 'edit_attributes', 'upload', 'download', 'expand_less', + 'expand_more', 'chevron_left', 'chevron_right', 'sync', 'power', + 'power_off', 'notifications', 'emoji_emotions', 'person_add', 'block' + ]; + + title = 'Demo'; + bannerTitle = ''; + user: Partial = {} as Partial; + errors: Errors = { errors: {} }; + btnSettingsTitle = 'Paramètres'; + + constructor( + private titleService: Title, + private userService: UserService + ) { } + + ngOnInit() { + this.titleService.setTitle(`Ad Astra - ${this.title}`); + Object.assign(this.user, this.userService.getCurrentUser()); + if (this.user.username) { + this.bannerTitle = `@${this.user.username}`; + } else { + this.bannerTitle = `${this.user.firstname} ${this.user.lastname}`; + } + } + + ngOnDestroy() { + this._user.unsubscribe(); + } + + getColors(): string[] { + return this._colors; + } + + getIcon(index: number): string { + return this._icons[index]; + } + + drop(event: CdkDragDrop) { + moveItemInArray(this._colors, event.previousIndex, event.currentIndex); + } + +} diff --git a/src/app/components/dropzones/dropzones.component.html b/src/app/components/dropzones/dropzones.component.html new file mode 100644 index 0000000..f6e83f6 --- /dev/null +++ b/src/app/components/dropzones/dropzones.component.html @@ -0,0 +1,68 @@ +
+
+
+

{{title}}

+ + Dernier saut enregistré : {{ lastJump.numero }}ème à {{ lastJump.lieu }} le {{ lastJump.date | date: 'dd/MM/yyyy' }} + +
+ +
+ + + @for (menuitem of menuItems.getMenuPanel(); track menuitem) { + + } + +
+
+ + + + {{ subtitle }} + + + @if (displayCharts) { +
+
+ +
+
+ + +
+
+ } +
+
+ + +
+
+
+
+ + + + Carte des DZ + + +
+ + + +
+
+
+
\ No newline at end of file diff --git a/src/app/components/dropzones/dropzones.component.scss b/src/app/components/dropzones/dropzones.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/components/dropzones/dropzones.component.spec.ts b/src/app/components/dropzones/dropzones.component.spec.ts new file mode 100644 index 0000000..cf69b3a --- /dev/null +++ b/src/app/components/dropzones/dropzones.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { DropzonesComponent } from './dropzones.component'; + +describe('DropzonesComponent', () => { + let component: DropzonesComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [DropzonesComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(DropzonesComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/dropzones/dropzones.component.ts b/src/app/components/dropzones/dropzones.component.ts new file mode 100644 index 0000000..560c921 --- /dev/null +++ b/src/app/components/dropzones/dropzones.component.ts @@ -0,0 +1,188 @@ +import { DatePipe } from '@angular/common'; +import { trigger, state, style, animate, transition } from '@angular/animations'; +import { Component, DestroyRef, inject, OnInit, OnDestroy } from '@angular/core'; +import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; +import { GoogleMap, MapKmlLayer} from '@angular/google-maps'; +import { ActivatedRoute } from '@angular/router'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatExpansionModule } from '@angular/material/expansion'; +import { MatGridListModule } from '@angular/material/grid-list'; +import { MatIconModule } from '@angular/material/icon'; +import { MatMenuModule } from '@angular/material/menu'; +//import { ChartistModule, Configuration } from 'ng-chartist'; +//import { AxisOptions, Label } from 'chartist'; +import { Observable, Subscription } from 'rxjs'; + +import { MenuItems } from '@components/shared'; +import { BarsChartComponent, PieChartComponent } from '@components/shared/helpers-chart'; +import { HistoryTableComponent } from '@components/shared/helpers-jump'; +import { DropZoneByOaci, DropZoneByYear, DropZonesPageData, Jump } from '@models'; +import { UtilitiesService } from '@services'; + +@Component({ + selector: 'app-dropzones', + standalone: true, + imports: [ + DatePipe, GoogleMap, MapKmlLayer, + MatButtonModule, MatCardModule, MatDividerModule, MatExpansionModule, + MatGridListModule, MatIconModule, MatMenuModule, + //ChartistModule, + HistoryTableComponent, BarsChartComponent, PieChartComponent + ], + templateUrl: './dropzones.component.html', + styleUrl: './dropzones.component.scss', + animations: [ + trigger('flyInOut', [ + state('in', style({ transform: 'translateX(0)' })), + transition('void => *', [ + style({ transform: 'translateX(-100%)' }), + animate(200) + ]), + transition('* => void', [ + style({ transform: 'translateX(100%)' }), + animate(200) + ]) + ]) + ] +}) +export class DropzonesComponent implements OnInit, OnDestroy { + private _data: Subscription = new Subscription(); + private _lastjump: Subscription = new Subscription(); + private _dropzonesByOaci!: Array; + private _dropzonesByYear!: Array; + public lastJump: Jump = {} as Jump; + public title = 'Drop zones'; + public subtitle: string = 'Nombre total de sauts par drop zone'; + public displayCharts = false; + public destroyRef = inject(DestroyRef); + public seriesHeader: string[] = []; + public seriesName: string[] = []; + public seriesValue: number[] = []; + public seriesRow: Array> = []; + public seriesColor: { + backgroundColor: string[], + borderColor: string[] + } = { + backgroundColor: this._utilitiesService.getSeriesColors(0.8, 'all'), + borderColor: this._utilitiesService.getSeriesColors(1, 'all') + }; + public seriesColorClass: string[] = this._utilitiesService.getChartColors(); + //public chartBarConfig: Configuration = this._utilitiesService.getBarConfig(); + + public center: google.maps.LatLngLiteral = {lat: 44.596408, lng: -1.115958}; + public zoom = 16; + public kmlUrl = 'https://rampeur.com/assets/kmls/dropzones.kml?v=6'; + //public mapTypeId: google.maps.MapTypeId = google.maps.MapTypeId.SATELLITE; + public options: google.maps.MapOptions = { + //zoomControl: false, + //scrollwheel: false, + //mapTypeId: google.maps.MapTypeId.SATELLITE, + mapTypeId: 'satellite', + disableDoubleClickZoom: true, + maxZoom: 20, + minZoom: 3 + }; + // Arcachon : 44.596408,-1.115958 + // La Réole : 44.566309,-0.054606 + // Soulac : 45.495395,-1.081039 + // Royan : 45.632660,-0.977096 + // Rochefort : 45.888477,-0.984551 + // Sables : 46.475393,-1.722160 + // Pamiers : 43.091951,1.698546 + // Pau : 43.426255,-0.288453 + // Cahors : 44.348635,1.478898 + // Béni : 32.394218,-6.327999 + + constructor( + private route: ActivatedRoute, + private _utilitiesService: UtilitiesService, + public menuItems: MenuItems + ) { } + + ngOnInit() { + const data$: Observable<{ dropZonesPageData: DropZonesPageData }> = this.route.data as Observable<{ dropZonesPageData: DropZonesPageData }>; + this._data = data$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data: { dropZonesPageData: DropZonesPageData }) => { + const pageData: DropZonesPageData = data.dropZonesPageData; + this.lastJump = pageData.lastjump; + this._loadDropZoneByOaci(pageData); + }); + } + + ngOnDestroy() { + this._data.unsubscribe(); + } + + private _loadDropZoneByOaci(pageData: DropZonesPageData): void { + this._dropzonesByOaci = pageData.dropZonesByOaci.map((row: DropZoneByOaci) => { + this.seriesName.push(`${row.oaci} - ${row.lieu}`); + this.seriesValue.push(row.count); + return row; + }); + this._loadDropZoneByYear(pageData); + } + + private _loadDropZoneByYear(pageData: DropZonesPageData): void { + this.seriesHeader = ['2018', '2019', '2020', '2021', '2022', '2023', '2024']; + const values: Array = this.seriesHeader.map(() => 0); + this.seriesName.forEach(() => { + this.seriesRow.push([...values]); + }); + this._dropzonesByYear = pageData.dropZonesByOaciByYear.map((row: DropZoneByYear) => { + const lieu: string = row.lieu; + const oaci: string = row.oaci; + const year: string = row.year.toString(); + this.seriesRow[this.seriesName.indexOf(`${oaci} - ${lieu}`)][this.seriesHeader.indexOf(year)] = row.count; + return row; + }); + /* + const axisX: AxisOptions = { + labelInterpolationFnc: function(value: Label, index: number): string { + return index % 1 === 0 ? `${value.toString()}` : ''; + } + } + this.chartBarConfig = { + type: 'Bar', + data: { + 'labels': this.seriesHeader, + 'series': this.seriesRow + }, + options: { + seriesBarDistance: 15, + horizontalBars: false, + high: 180, + axisX: { + showGrid: false, + offset: 20 + }, + axisY: { + showGrid: true, + offset: 40 + }, + height: 300 + }, + responsiveOptions: [ + ['screen and (min-width: 1024px)', { + axisX: axisX + }], + ['screen and (min-width: 641px) and (max-width: 1024px)', { + seriesBarDistance: 7, + axisY: { + offset: 30 + }, + axisX: axisX + }], + ['screen and (max-width: 640px)', { + seriesBarDistance: 5, + axisY: { + offset: 20 + }, + axisX: axisX + }] + ] + }; + */ + this.displayCharts = true; + } +} diff --git a/src/app/components/herowars-guildraid/herowars-guildraid.component.html b/src/app/components/herowars-guildraid/herowars-guildraid.component.html new file mode 100644 index 0000000..8bf741f --- /dev/null +++ b/src/app/components/herowars-guildraid/herowars-guildraid.component.html @@ -0,0 +1,114 @@ +
+
+
+

{{title}}

+
+ +
+ {{ now | date: 'dd/MM/yyyy' }} +
+
+ + +
+

{{description}}

+
+ + + +
+ + {{ title }} + +
+ +
+ {{ subtitle }} +
+
+ + + + Stage 1 +
+
+

Stage 1

+
+ +
+

Power limit: 320k

+
+
+ +
+ + +
+
+ + Stage 2 +
+
+

Stage 2

+
+ +
+

Power limit: 500k

+
+
+ +
+ + +
+
+ + Stage 3 +
+
+

Stage 3

+
+ +
+

No power limit

+
+
+ +
+ + +
+
+ + Statistics +
+
+

Statistics

+
+ +
+

variation ≥ {{ minVarPct }}%

+ + Variation + + percent + excess power in % + +
+
+ +
+ + +
+
+ + timeline + + + manage_search + +
+
+
+
diff --git a/src/app/components/herowars-guildraid/herowars-guildraid.component.scss b/src/app/components/herowars-guildraid/herowars-guildraid.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/components/herowars-guildraid/herowars-guildraid.component.spec.ts b/src/app/components/herowars-guildraid/herowars-guildraid.component.spec.ts new file mode 100644 index 0000000..9bdf140 --- /dev/null +++ b/src/app/components/herowars-guildraid/herowars-guildraid.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { HerowarsGuildraidComponent } from './herowars-guildraid.component'; + +describe('HerowarsGuildraidComponent', () => { + let component: HerowarsGuildraidComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [HerowarsGuildraidComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(HerowarsGuildraidComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/herowars-guildraid/herowars-guildraid.component.ts b/src/app/components/herowars-guildraid/herowars-guildraid.component.ts new file mode 100644 index 0000000..d1b2dfe --- /dev/null +++ b/src/app/components/herowars-guildraid/herowars-guildraid.component.ts @@ -0,0 +1,94 @@ +import { DatePipe } from '@angular/common'; +import { Title } from '@angular/platform-browser'; +import { trigger, state, style, animate, transition } from '@angular/animations'; +import { Component, DestroyRef, Injectable, inject, OnInit } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { STEPPER_GLOBAL_OPTIONS } from '@angular/cdk/stepper'; +import { MatCardModule } from '@angular/material/card'; +import { MatButtonModule } from '@angular/material/button'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatIconModule } from '@angular/material/icon'; +import { MatInputModule } from '@angular/material/input'; +import { MatStepperIntl, MatStepperModule } from '@angular/material/stepper'; + +import { ListErrorsComponent } from '@components/shared'; +import { Errors } from '@models'; +import { HWGuildRaid, HWGuildRaidAttacker, HWGuildRaidAttackers, HWGuildRaidStage, HWMember } from '@models/herowars'; + +import guildRaids from 'src/files-data/hw-guild-raids.json'; // page Asgard -> Guild Raid -> Log + +@Injectable() +export class GuildRaidStepperIntl extends MatStepperIntl { + // the default optional label text, if unspecified is "Optional" + override optionalLabel = 'Optional Label'; +} +@Component({ + selector: 'app-herowars-guildraid', + standalone: true, + providers: [ + { + provide: STEPPER_GLOBAL_OPTIONS, + useValue: { displayDefaultIndicatorType: false }, + }, + ], + imports: [ + DatePipe, FormsModule, ListErrorsComponent, + MatButtonModule, MatCardModule, MatDividerModule, MatFormFieldModule, + MatIconModule, MatInputModule, MatStepperModule + ], + templateUrl: './herowars-guildraid.component.html', + styleUrl: './herowars-guildraid.component.scss', + animations: [ + trigger('flyInOut', [ + state('in', style({ transform: 'translateY(0)' })), + transition('void => *', [ + style({ transform: 'translateY(-100%)' }), + animate(200) + ]), + transition('* => void', [ + style({ transform: 'translateY(100%)' }), + animate(200) + ]) + ]) + ] +}) +export class HerowarsGuildraidComponent implements OnInit { + public title = 'Guild Raids'; + public subtitle = 'Log'; + public description = 'Tools in working progress.'; + public errors: Errors = { errors: {} }; + public destroyRef = inject(DestroyRef); + public minVarPct = 3; + public minValue = 0; + public now = new Date(); + private _guildMembers: HWMember[] = []; + private _matStepperIntl = inject(MatStepperIntl); + private _guildRaids: HWGuildRaid[] = []; + private _raidStages: HWGuildRaidStage[] = [ + { num: 1, name: 'Stage 1', maxPower: 320000, duration: 8, startTime: 0, endTime: 0 }, + { num: 2, name: 'Stage 2', maxPower: 500000, duration: 8, startTime: 0, endTime: 0 }, + { num: 3, name: 'Stage 3', maxPower: 0, duration: 0, startTime: 0, endTime: 0 } + ]; + + constructor( + private _titleService: Title + ) { } + + ngOnInit() { + this._titleService.setTitle(this.title); + this._guildMembers.map((data) => { + data.raids = []; + data.raidsInfo = { + variationAvg: 0, + variationSum: 0 + }; + return data; + }); + } + + getMembers(): HWMember[] { + return this._guildMembers; + } + +} diff --git a/src/app/components/herowars-guildwar/herowars-guildwar.component.html b/src/app/components/herowars-guildwar/herowars-guildwar.component.html new file mode 100644 index 0000000..7716eb6 --- /dev/null +++ b/src/app/components/herowars-guildwar/herowars-guildwar.component.html @@ -0,0 +1,215 @@ +
+
+
+

{{title}}

+
+ +
+ {{ now | date: 'dd/MM/yyyy' }} +
+
+ + +
+

{{description}}

+
+ + + + +
+
+ + @if (clanLoaded) { + + +
+
+

+ {{ getClanViewModel().getTitle() }} – Server {{ getClanViewModel().getServer() }} +

+
+ +
+ Members: {{ getClanViewModel().getMembersCount() }}/{{ maxClanMembers }} +
+
+
+
+
+ + +
+
+
+
+
country
+
{{ getClanViewModel().getCountry() }}
+
serverId
+
{{ getClanViewModel().getServer() }}
+
description
+
{{ getClanViewModel().getDescription() }}
+
level
+
{{ getClanViewModel().getLevel() }}
+
minLevel
+
{{ getClanViewModel().getMinLevel() }}
+
+
+
+
+
topActivity
+
{{ getClanViewModel().getTopActivity() | number : '1.0' }}
+
topDungeon
+
{{ getClanViewModel().getTopDungeon() | number : '1.0' }}
+
disbanding
+
{{ getClanViewModel().getDisbanding() }}
+
frameId
+
{{ getClanViewModel().getFrameId() }}
+
ownerId
+
{{ getClanViewModel().getOwnerId() | number : '1.0' }}
+
+
+
+
+ } + @else { +
+ +
+ } + @if (membersLoaded) { + +
+ + + + + + + + + + + + + + + + @for (memberVM of getMembersViewModel().getMembers(); track memberVM.getId(); let index = $index) { + + + + + + + + + + + + } + +
+
+ # +
+
+
+ Name + +
+
+
+ ID +
+
+
+ Last Login +
+
+
+ Dismissal Delay +
+
+
+ Clan +
+
+
+ Server +
+
+
+ Heroes +
+
+
+ Titans +
+
+ {{ (index+1) }} + +
+ + {{ memberVM.getName() }} +
+
+ {{ memberVM.getId() }} [{{ memberVM.getLevel() }}] + + {{ memberVM.getLastLoginTime() + '000' | date: 'dd/MM HH:mm' }} + + {{ memberVM.getInactivity().dropDelay }} + + {{ memberVM.getClanTitle() }} + + {{ memberVM.getServerId() }} + + {{ memberVM.getMemberHeroes().power | number : '1.0' }} + + {{ memberVM.getMemberTitans().power | number : '1.0' }} +
+
+
+ } +
+
+
+ +
+
+ + + +
+
+ + + +
+
+
+ +
+
+ + + +
+
+ + + +
+
+
+ +
+
+ + + +
+
+
+
+
diff --git a/src/app/components/herowars-guildwar/herowars-guildwar.component.scss b/src/app/components/herowars-guildwar/herowars-guildwar.component.scss new file mode 100644 index 0000000..6323951 --- /dev/null +++ b/src/app/components/herowars-guildwar/herowars-guildwar.component.scss @@ -0,0 +1,8 @@ +.btn-group-vertical { + flex-direction: column; + align-items: flex-end; + justify-content: center; + button { + margin: 2px 0; + } +} \ No newline at end of file diff --git a/src/app/components/herowars-guildwar/herowars-guildwar.component.spec.ts b/src/app/components/herowars-guildwar/herowars-guildwar.component.spec.ts new file mode 100644 index 0000000..d1a3d24 --- /dev/null +++ b/src/app/components/herowars-guildwar/herowars-guildwar.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { HerowarsGuildwarComponent } from './herowars-guildwar.component'; + +describe('HerowarsGuildwarComponent', () => { + let component: HerowarsGuildwarComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [HerowarsGuildwarComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(HerowarsGuildwarComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/herowars-guildwar/herowars-guildwar.component.ts b/src/app/components/herowars-guildwar/herowars-guildwar.component.ts new file mode 100644 index 0000000..313be5b --- /dev/null +++ b/src/app/components/herowars-guildwar/herowars-guildwar.component.ts @@ -0,0 +1,136 @@ +import { DatePipe, DecimalPipe } from '@angular/common'; +import { Title } from '@angular/platform-browser'; +import { trigger, state, style, animate, transition } from '@angular/animations'; +import { Component, DestroyRef, inject, OnInit } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { MatCardModule } from '@angular/material/card'; +import { MatButtonModule } from '@angular/material/button'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatIconModule } from '@angular/material/icon'; +import { MatInputModule } from '@angular/material/input'; +import { MatTabsModule } from '@angular/material/tabs'; + +import { CardContainerComponent, ListErrorsComponent, GuildwarAttackComponent, GuildwarDefenceComponent } from '@components/shared'; +import { CardColors, Errors, HWActivityStat, HWGuildClan, HWMember } from '@models'; +import { ClanViewModel, MembersViewModel } from '@viewmodels/herowars'; +import { HWClanService, HWMemberService, UtilitiesService } from '@services'; +import { MAX_CLAN_MEMBERS } from '@constants'; + +import guildData from '@data/hw-guild-data.json'; // page Membres +import guildStatistics from '@data/hw-guild-statistics.json'; // page Overview -> Statistics + +@Component({ + selector: 'app-herowars-guildwar', + standalone: true, + imports: [ + DatePipe, DecimalPipe, FormsModule, CardContainerComponent, ListErrorsComponent, + MatButtonModule, MatCardModule, MatDividerModule, MatFormFieldModule, + MatIconModule, MatInputModule, MatTabsModule, + GuildwarAttackComponent, GuildwarDefenceComponent + ], + templateUrl: './herowars-guildwar.component.html', + styleUrl: './herowars-guildwar.component.scss', + animations: [ + trigger('flyInOut', [ + state('in', style({ transform: 'translateY(0)' })), + transition('void => *', [ + style({ transform: 'translateY(-100%)' }), + animate(200) + ]), + transition('* => void', [ + style({ transform: 'translateY(100%)' }), + animate(200) + ]) + ]) + ] +}) +export class HerowarsGuildwarComponent implements OnInit { + public destroyRef = inject(DestroyRef); + public title = 'Guild War'; + public subtitle = 'Log'; + public description = 'Tools in working progress.'; + public colors: CardColors = { background: 'bg-raspberry', text: 'text-bg-primary' }; + public errors: Errors = { errors: {} }; + public now = new Date(); + public daysToWarn = 1; + public maxClanMembers = MAX_CLAN_MEMBERS; + public clanLoaded = false; + public membersLoaded = false; + public clanViewModel: ClanViewModel = {} as ClanViewModel; + public membersViewModel: MembersViewModel = {} as MembersViewModel; + private _guildClan: HWGuildClan = {} as HWGuildClan; + private _guildMembers: HWMember[] = []; + private _guildInfo: HWActivityStat = {} as HWActivityStat; + + constructor( + private _titleService: Title, + private _utilitiesService: UtilitiesService, + private _clanService: HWClanService, + private _memberService: HWMemberService + ) { } + + ngOnInit() { + this._titleService.setTitle(this.title); + } + + getClanViewModel(): ClanViewModel { + return this.clanViewModel; + } + + getMembersViewModel(): MembersViewModel { + return this.membersViewModel; + } + + getColors(color = 'megna'): CardColors { + if (color === 'accent') { + this.colors = { background: 'bg-accent', text: 'text-navy' }; + } else if (color === 'raspberry') { + this.colors = { background: 'bg-raspberry', text: 'text-bg-primary' }; + } else { + this.colors = { background: 'bg-megna', text: 'text-bg-primary' }; + } + return this.colors; + } + + loadClan(): void { + this._guildClan = this._clanService.loadClan(); + this.clanViewModel = new ClanViewModel(this._guildClan); + this.clanLoaded = true; + } + + loadData(): void { + this._guildClan = this._clanService.loadClan(); + this._guildMembers = this._memberService.loadMembers(this._guildClan); + this._guildClan = this._clanService.loadClanStats(this._guildClan, this._guildMembers); + this.daysToWarn = (parseInt(this._guildClan.daysToKick) / 2); + this.clanViewModel = new ClanViewModel(this._guildClan); + this.clanLoaded = true; + this.membersViewModel = new MembersViewModel(this._guildMembers); + this.membersLoaded = true; + console.log(this._guildClan); + console.log(this._guildMembers); + } + + loadMembers(): void { + this._guildMembers = this._memberService.loadMembers(this._guildClan); + this.membersViewModel = new MembersViewModel(this._guildMembers); + this._guildClan = this._clanService.loadClanStats(this._guildClan, this._guildMembers); + this.membersLoaded = true; + } + + getMembers(): HWMember[] { + return this._guildMembers; + } + + syncClan(): void { + console.log(this._guildClan); + console.log(guildData); + } + + syncMembers(): void { + console.log(this._guildMembers); + console.log(guildStatistics); + } + +} diff --git a/src/app/components/herowars/herowars.component.html b/src/app/components/herowars/herowars.component.html new file mode 100644 index 0000000..da187bf --- /dev/null +++ b/src/app/components/herowars/herowars.component.html @@ -0,0 +1,66 @@ +
+
+
+

{{title}}

+
+ +
+ {{ now | date: 'dd/MM/yyyy' }} +
+
+ + +
+

{{description}}

+
+ + + +
+
+ +
+
+ +
+
+
+
+ +
+
+
+ +
+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+ +
+
+ +
+
+
+ +
+
+ +
+
+
+
+
\ No newline at end of file diff --git a/src/app/components/herowars/herowars.component.scss b/src/app/components/herowars/herowars.component.scss new file mode 100644 index 0000000..a4626cd --- /dev/null +++ b/src/app/components/herowars/herowars.component.scss @@ -0,0 +1,37 @@ +/* herowars */ +//@use 'variable' as var; +.icon-xxsmall { + transform: scale(0.25); +} +.icon-xsmall { + font-size: 16px; + height: 16px; + width: 16px; +} +.icon-small { + font-size: 18px; + height: 18px; + width: 18px; +} +.icon-medium { + font-size: 20px; + height: 20px; + width: 20px; +} +.hstack .value { + min-width: 56px; +} + +/* +#FF41F8 +#F0060B +#F0070C +#CC26D5 +#7702FF + +#35A2EB +#B7DDD0 +#B0D9CB +#D9CAAE +#9788C7 +*/ diff --git a/src/app/components/herowars/herowars.component.spec.ts b/src/app/components/herowars/herowars.component.spec.ts new file mode 100644 index 0000000..0636ce2 --- /dev/null +++ b/src/app/components/herowars/herowars.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { HerowarsComponent } from './herowars.component'; + +describe('HerowarsComponent', () => { + let component: HerowarsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [HerowarsComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(HerowarsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/herowars/herowars.component.ts b/src/app/components/herowars/herowars.component.ts new file mode 100644 index 0000000..193d159 --- /dev/null +++ b/src/app/components/herowars/herowars.component.ts @@ -0,0 +1,84 @@ +import { DatePipe } from '@angular/common'; +import { Title } from '@angular/platform-browser'; +import { trigger, state, style, animate, transition } from '@angular/animations'; +//import { Component, DestroyRef, inject, OnInit, computed, signal, Signal } from '@angular/core'; +import { Component, DestroyRef, inject, OnInit } from '@angular/core'; +import { MatCardModule } from '@angular/material/card'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatIconModule } from '@angular/material/icon'; +import { MatTabsModule } from '@angular/material/tabs'; + +import { + ListErrorsComponent, + GuildCardComponent, GuildraidsLogComponent, GuildwarChampionsComponent, + GuildwarAttackComponent, GuildwarDefenceComponent, GuildwarTeamsComponent, MembersStatisticsComponent +} from '@components/shared'; +import { Errors, HWMember } from '@models'; +import guildData from 'src/files-data/hw-guild-data.json'; // page Membres +//import guildWarData from 'src/files-data/hw-guild-war.json'; // page Overview -> Statistics | page Guild War -> Guild War +//import guildStatistics from 'src/files-data/hw-guild-statistics.json'; // page Overview -> Statistics +//import guildWarSlots from 'src/files-data/hw-guild-war-slots.json'; // no pages + +@Component({ + selector: 'app-herowars', + standalone: true, + imports: [ + DatePipe, + MatCardModule, MatDividerModule, MatIconModule, MatTabsModule, + ListErrorsComponent, + GuildCardComponent, GuildraidsLogComponent, GuildwarChampionsComponent, + GuildwarAttackComponent, GuildwarDefenceComponent, GuildwarTeamsComponent, MembersStatisticsComponent + ], + templateUrl: './herowars.component.html', + styleUrl: './herowars.component.scss', + animations: [ + trigger('flyInOut', [ + state('in', style({ transform: 'translateY(0)' })), + transition('void => *', [ + style({ transform: 'translateY(-100%)' }), + animate(200) + ]), + transition('* => void', [ + style({ transform: 'translateY(100%)' }), + animate(200) + ]) + ]) + ] +}) +export class HerowarsComponent implements OnInit { + public title = 'HeroWars GM Tools'; + public description = 'Tools in working progress.'; + public errors: Errors = { errors: {} }; + public destroyRef = inject(DestroyRef); + public now = new Date(); + private _guildMembers: HWMember[] = []; + + constructor( + private _titleService: Title + ) { } + + ngOnInit() { + try { + this._titleService.setTitle(this.title); + for (const data of Object.entries(guildData.clan.members)) { + const member: HWMember = {} as HWMember; + Object.assign(member, data[1]); + if (guildData.clan.warriors.indexOf(parseInt(member.id)) !== -1) { + member.champion = true; + } else { + member.champion = false; + } + member.heroes = { power: 0, teams: []}; + member.titans = { power: 0, teams: []}; + this._guildMembers.push(member); + } + } catch (error) { + console.error(error); + } + } + + getMembers(): HWMember[] { + return this._guildMembers; + } + +} diff --git a/src/app/components/home/home.component.html b/src/app/components/home/home.component.html new file mode 100644 index 0000000..0ddbd78 --- /dev/null +++ b/src/app/components/home/home.component.html @@ -0,0 +1,93 @@ +
+
+
+

{{title}}

+
+ +
+ {{ now | date: 'dd/MM/yyyy' }} +
+
+ + +
+

{{description}}

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
\ No newline at end of file diff --git a/src/app/components/home/home.component.scss b/src/app/components/home/home.component.scss new file mode 100644 index 0000000..0034d03 --- /dev/null +++ b/src/app/components/home/home.component.scss @@ -0,0 +1,37 @@ +/* Home */ +//@use 'variable' as var; +.icon-xxsmall { + transform: scale(0.25); +} +.icon-xsmall { + font-size: 16px; + height: 16px; + width: 16px; +} +.icon-small { + font-size: 18px; + height: 18px; + width: 18px; +} +.icon-medium { + font-size: 20px; + height: 20px; + width: 20px; +} +.hstack .value { + min-width: 56px; +} + +/* +#FF41F8 +#F0060B +#F0070C +#CC26D5 +#7702FF + +#35A2EB +#B7DDD0 +#B0D9CB +#D9CAAE +#9788C7 +*/ diff --git a/src/app/components/home/home.component.spec.ts b/src/app/components/home/home.component.spec.ts new file mode 100644 index 0000000..60c47c4 --- /dev/null +++ b/src/app/components/home/home.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { HomeComponent } from './home.component'; + +describe('HomeComponent', () => { + let component: HomeComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [HomeComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(HomeComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/home/home.component.ts b/src/app/components/home/home.component.ts new file mode 100644 index 0000000..01adc29 --- /dev/null +++ b/src/app/components/home/home.component.ts @@ -0,0 +1,74 @@ +import { DatePipe } from '@angular/common'; +import { Title } from '@angular/platform-browser'; +import { trigger, state, style, animate, transition } from '@angular/animations'; +import { Component, DestroyRef, inject, OnInit } from '@angular/core'; +import { MatCardModule } from '@angular/material/card'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatIconModule } from '@angular/material/icon'; + +import { ListErrorsComponent } from '@components/shared'; +import { Errors } from '@models'; +//import { UtilitiesService } from '@services'; +//import { UserService } from '@services'; +@Component({ + selector: 'app-home', + standalone: true, + imports: [ + DatePipe, + MatCardModule, MatDividerModule, MatIconModule, + ListErrorsComponent + ], + templateUrl: './home.component.html', + styleUrl: './home.component.scss', + animations: [ + trigger('flyInOut', [ + state('in', style({ transform: 'translateY(0)' })), + transition('void => *', [ + style({ transform: 'translateY(-100%)' }), + animate(200) + ]), + transition('* => void', [ + style({ transform: 'translateY(100%)' }), + animate(200) + ]) + ]) + ] +}) +export class HomeComponent implements OnInit { + public title = 'Shop bientôt disponible!'; + public description = 'Encore un peu de patience, notre shop sera mis en ligne d\'ici peu.'; + public errors: Errors = { errors: {} }; + public destroyRef = inject(DestroyRef); + public now = new Date(); + + constructor( + private _titleService: Title, + //private _utilitiesService: UtilitiesService + //private _userService: UserService + ) { } + + ngOnInit() { + + this._titleService.setTitle(this.title); + /* + type CreateArrayWithLengthX< + LENGTH extends number, + ACC extends unknown[] = [], + > = ACC['length'] extends LENGTH + ? ACC + : CreateArrayWithLengthX; + + type NumericRange< + START_ARR extends number[], + END extends number, + ACC extends number = never> + = START_ARR['length'] extends END + ? ACC | END + : NumericRange<[...START_ARR, 1], END, ACC | START_ARR['length']>; + + //type TWENTY_TO_FORTY = NumericRange, 13, 7>; + //type TWENTY_TO_FORTY = NumericRange, 19>; + type TWENTY_TO_FORTY = NumericRange, 10>; + */ + } +} diff --git a/src/app/components/index.ts b/src/app/components/index.ts new file mode 100644 index 0000000..d539cc6 --- /dev/null +++ b/src/app/components/index.ts @@ -0,0 +1,22 @@ +export * from './auth/auth.component'; +export * from './aeronefs/aeronefs.component'; +export * from './calculator/calculator.component'; +export * from './canopies/canopies.component'; +export * from './dashboard/dashboard.component'; +export * from './demo/demo.component'; +export * from './dropzones/dropzones.component'; +export * from './herowars/herowars.component'; +export * from './herowars-guildwar/herowars-guildwar.component'; +export * from './herowars-guildraid/herowars-guildraid.component'; +export * from './home/home.component'; +export * from './jump/jump.component'; +export * from './jumps/jumps.component'; +export * from './logbook/logbook.component'; +export * from './page/page.component'; +export * from './pages/pages.component'; +export * from './product/product.component'; +export * from './products/products.component'; +export * from './profile/profile.component'; +export * from './qcm/qcm.component'; +export * from './settings'; +export * from './shared'; \ No newline at end of file diff --git a/src/app/components/jump/jump.component.html b/src/app/components/jump/jump.component.html new file mode 100644 index 0000000..a015869 --- /dev/null +++ b/src/app/components/jump/jump.component.html @@ -0,0 +1,283 @@ +
+
+

+ {{title}} + {{ jump.categorie }} + @if (jump.module) { + / + {{ jump.module }} + } +

+ + Le {{ jump.date | date: 'dd/MM/yyyy' }} + à {{ jump.lieu }} {{ jump.oaci }} + +
+ +
+ +
+ {{ jump.numero }} +
+ +
+
+ + + @if (jump.x2data) { + + + } + @for (menuitem of menuItems.getMenuJump(); track menuitem) { + + } + +
+
+ + + +
+
+
+
Aeronef:
+
{{ jump.aeronef }} {{ jump.imat }}
+
Voile:
+
{{ jump.voile }} {{ jump.taille }} ft2
+ @if (jump.programme) { +
Programme:
+
{{ jump.programme }}
+ } +
+
+
+
+ @if (!jump.x2data) { +
Hauteur:
+
{{ jump.hauteur }} m
+
Déploiement:
+
{{ jump.deploiement }} m
+ } + @for (file of jump.files; track file) { +
Fichier {{ file.type }}
+
{{ file.name }}
+ } +
+
+
+
+
+@if (jump.x2data) { + + +
+
+
Hauteur
+ @if (jump.x2data.altitude.exit > 4200) { + + } + {{ jump.x2data.altitude.exit }} m +
+
+
Durée de la chute
+ {{ formatDuration(jump.x2data.duration.freeFall) }} +
+
+
Déploiement
+ @if (jump.x2data.altitude.deployment < 650) { + + {{ jump.x2data.altitude.deployment }} m + } + @else if (jump.x2data.altitude.deployment < 750) { + + {{ jump.x2data.altitude.deployment }} m + } + @else if (jump.x2data.altitude.deployment > 1000) { + + {{ jump.x2data.altitude.deployment }} m + } +
+
+
+
+
Participants ({{ jump.sautants.length + 1 }})
+ @for (sautant of jump.sautants; track sautant) { + + + {{ sautant }} + + } + + + {{ jump.author.username }} + +
+ @if (jump.accessoires) { +
+
Accessoires
+ + + {{ jump.accessoires }} + +
+ } +
+
+
+ + +
+
+
Vitesse en chute
+
+ + +
+
Vitesse maximale
+ {{ (jump.x2data.speed.freeFall.vertical.max / 1000 * 60 * 60) | number : '1.0-0' }} km/h +
+
+
Vitesse moyenne
+ {{ (jump.x2data.speed.freeFall.vertical.avg / 1000 * 60 * 60) | number : '1.0-0' }} km/h +
+
+
Vitesse maximale
+ {{ (jump.x2data.speed.freeFall.horizontal.max / 1000 * 60 * 60) | number : '1.0-0' }} km/h +
+
+
Vitesse moyenne
+ {{ (jump.x2data.speed.freeFall.horizontal.avg / 1000 * 60 * 60) | number : '1.0-0' }} km/h +
+
+
+
+ + +
+
+
Vitesse sous voile
+
+ + +
+
Vitesse maximale
+ {{ (jump.x2data.speed.underCanopy.vertical.max / 1000 * 60 * 60) | number : '1.0-0' }} km/h +
+
+
Vitesse moyenne
+ {{ (jump.x2data.speed.underCanopy.vertical.avg / 1000 * 60 * 60) | number : '1.0-0' }} km/h +
+
+
Vitesse maximale
+ {{ (jump.x2data.speed.underCanopy.horizontal.max / 1000 * 60 * 60) | number : '1.0-0' }} km/h +
+
+
Vitesse moyenne
+ {{ (jump.x2data.speed.underCanopy.horizontal.avg / 1000 * 60 * 60) | number : '1.0-0' }} km/h +
+
+
+
+ + +
+
+
Finesse
+
+ + +
+
Finesse Max
+ {{ jump.x2data.glideRatio.freeFall.max | number : '1.2-2' }} +
+
+
Finesse Moyenne
+ {{ jump.x2data.glideRatio.freeFall.avg | number : '1.2-2' }} +
+
+
Finesse Max
+ {{ jump.x2data.glideRatio.underCanopy.max | number : '1.2-2' }} +
+
+
Finesse Moyenne
+ {{ jump.x2data.glideRatio.underCanopy.avg | number : '1.2-2' }} +
+
+
+
+ + +
+
+
Distance
+
+
+
Distance au largage
+ {{ jump.x2data.distance.exitFromLandingZone| number : '1.0-0' }} m +
+
+
Durée sous voile
+ {{ formatDuration(jump.x2data.duration.underCanopy) }} +
+
+
Distance totale
+ {{ jump.x2data.distance.totalFlying | number : '1.0-0' }} m +
+
+
Distance horizontale
+ {{ jump.x2data.distance.totalHorizontal | number : '1.0-0' }} m +
+
+
+
+} +@else { + + +
+
+
Participants ({{ jump.sautants.length + 1 }})
+ @for (sautant of jump.sautants; track sautant) { + + + {{ sautant }} + + } + + + {{ jump.author.username }} + +
+
+
+
+ + +
Aucune donnée GPS
+
+
+} \ No newline at end of file diff --git a/src/app/components/jump/jump.component.scss b/src/app/components/jump/jump.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/components/jump/jump.component.spec.ts b/src/app/components/jump/jump.component.spec.ts new file mode 100644 index 0000000..474dc8c --- /dev/null +++ b/src/app/components/jump/jump.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { JumpComponent } from './jump.component'; + +describe('JumpComponent', () => { + let component: JumpComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [JumpComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(JumpComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/jump/jump.component.ts b/src/app/components/jump/jump.component.ts new file mode 100644 index 0000000..ea3f811 --- /dev/null +++ b/src/app/components/jump/jump.component.ts @@ -0,0 +1,71 @@ +import { Component, DestroyRef, inject, OnInit, OnDestroy } from '@angular/core'; +import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; +import { DatePipe, DecimalPipe } from '@angular/common'; +import { ActivatedRoute, RouterLink } from '@angular/router'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatIconModule } from '@angular/material/icon'; +import { MatMenuModule } from '@angular/material/menu'; +import { Observable, Subscription } from 'rxjs'; + +import { ListErrorsComponent, MenuItems } from '@components/shared'; +import { Errors, Jump, JumpPageData } from '@models'; + +@Component({ + selector: 'app-jump', + standalone: true, + imports: [ + DatePipe, DecimalPipe, RouterLink, + MatButtonModule, MatCardModule, + MatDividerModule, MatIconModule, MatMenuModule, + ListErrorsComponent + ], + templateUrl: './jump.component.html', + styleUrl: './jump.component.scss' +}) +export class JumpComponent implements OnInit, OnDestroy { + private _data: Subscription = new Subscription(); + public title: string = ''; + public errors: Errors = { errors: {} }; + public destroyRef = inject(DestroyRef); + public jump: Jump = {} as Jump; + public prevSlug: string = ''; + public nextSlug: string = ''; + + constructor( + private route: ActivatedRoute, + public menuItems: MenuItems + ) { } + + ngOnInit() { + const data$: Observable<{ pageData: JumpPageData }> = this.route.data as Observable<{ pageData: JumpPageData }>; + this._data = data$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data: { pageData: JumpPageData }) => { + this.jump = data.pageData.jump; + this.prevSlug = data.pageData.prevJump?.slug; + this.nextSlug = data.pageData.nextJump?.slug; + this.title = `Saut n° ${this.jump.numero} `; + }); + /* + const data$: Observable = this.route.data as Observable; + this._data = data$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data: Jump) => { + this.jump = data; + console.log('jump : ', this.jump); + }); + */ + } + + ngOnDestroy() { + this._data.unsubscribe(); + } + + formatDuration(duration: number): string { + const start = new Date(0); + start.setSeconds(duration); + return start.toISOString().substring(14, 19); + } + + private _resetErrors(): void { + this.errors = { errors: {} }; + } +} diff --git a/src/app/components/jumps/jumps.component.html b/src/app/components/jumps/jumps.component.html new file mode 100644 index 0000000..217365f --- /dev/null +++ b/src/app/components/jumps/jumps.component.html @@ -0,0 +1,130 @@ +
+
+
+

{{title}}

+ + Dernier saut enregistré : {{ lastJump.numero }}ème à {{ lastJump.lieu }} le {{ lastJump.date | date: 'dd/MM/yyyy' }} + +
+ +
+ + + @for (menuitem of menuItems.getMenuPanel(); track menuitem) { + + } + +
+
+ + + + {{ subtitle }} + + + @if(displayCharts) { +
+
+ +
+
+ +
+
+ } +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{{ name }} Total
● {{ seriesName[i] }} + {{ value }} + {{ value }} + {{ seriesRowTotal[i] }}
Total + {{ value }} + {{ value }} + {{ grandTotal }}
Moyenne + {{ value | number : '1.0-1' }} + {{ value | number : '1.0-1' }} + {{ grandAvg | number : '1.0-1' }}
Moyenne 3 dernières années + {{ value | number : '1.0-1' }} + {{ value | number : '1.0-1' }} + {{ grandAvgLastYears | number : '1.0-1' }}
+
+
+
+
+ + + Types de sauts + + + @if(displayCharts) { +
+
+ +
+
+ +
+ @for (item of getCategories(); track $index) { +
+ +
+ } + @for (item of getModules(); track $index) { +
+ +
+ } +
+ + + } +
+
+
\ No newline at end of file diff --git a/src/app/components/jumps/jumps.component.scss b/src/app/components/jumps/jumps.component.scss new file mode 100644 index 0000000..06eb3f2 --- /dev/null +++ b/src/app/components/jumps/jumps.component.scss @@ -0,0 +1,12 @@ +element.style { + margin: 1.5rem -1.5rem -1.5rem -1.5rem; + padding: 0.9rem 1.1rem; + border-radius: 0; +} +.bannercard { + background-color: #202020; + color: #ffffff; + margin: 1.5rem -1.5rem -1.5rem -1.5rem; + padding: 0.9rem 1.1rem; + border-radius: 0; +} \ No newline at end of file diff --git a/src/app/components/jumps/jumps.component.spec.ts b/src/app/components/jumps/jumps.component.spec.ts new file mode 100644 index 0000000..48c78e8 --- /dev/null +++ b/src/app/components/jumps/jumps.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { JumpsComponent } from './jumps.component'; + +describe('JumpsComponent', () => { + let component: JumpsComponent; + let fixture: ComponentFixture; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [JumpsComponent] +}); + fixture = TestBed.createComponent(JumpsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/jumps/jumps.component.ts b/src/app/components/jumps/jumps.component.ts new file mode 100644 index 0000000..9259472 --- /dev/null +++ b/src/app/components/jumps/jumps.component.ts @@ -0,0 +1,249 @@ +import { trigger, state, style, animate, transition } from '@angular/animations'; +import { Component, DestroyRef, inject, OnInit, OnDestroy } from '@angular/core'; +import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; +import { ActivatedRoute } from '@angular/router'; +import { CommonModule } from '@angular/common'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatExpansionModule } from '@angular/material/expansion'; +import { MatIconModule } from '@angular/material/icon'; +import { MatMenuModule } from '@angular/material/menu'; + +import { Observable, Subscription } from 'rxjs'; + +import { MenuItems } from '@components/shared'; +import { BarsChartComponent, CircleChartComponent, LineChartComponent, LineAreaChartComponent } from '@components/shared/helpers-chart'; +import { UtilitiesService } from '@services'; +import { Jump, JumpByCategorie, JumpByDate, JumpByDateByModule, JumpByModule, JumpsPageData, JumpYears } from '@models'; + +@Component({ + selector: 'app-jumps', + standalone: true, + imports: [ + CommonModule, + MatButtonModule, MatCardModule, MatDividerModule, + MatExpansionModule, MatIconModule, MatMenuModule, + BarsChartComponent, CircleChartComponent, LineChartComponent, LineAreaChartComponent + ], + templateUrl: './jumps.component.html', + styleUrl: './jumps.component.scss', + animations: [ + trigger('flyInOut', [ + state('in', style({ transform: 'translateX(0)' })), + transition('void => *', [ + style({ transform: 'translateX(-100%)' }), + animate(200) + ]), + transition('* => void', [ + style({ transform: 'translateX(100%)' }), + animate(200) + ]) + ]) + ] +}) +export class JumpsComponent implements OnInit, OnDestroy { + private _data: Subscription = new Subscription(); + private _jumpsByCategorie: Array = []; + private _jumpsByModule: Array = []; + private _jumpsByDate: Array = []; + public lastJump: Jump = {} as Jump; + public title: string = 'Sauts'; + public subtitle: string = 'Nombre total de sauts par mois'; + public displayCharts = false; + public destroyRef = inject(DestroyRef); + public min = 0; + public max = 0; + public grandAvg = 0; + public grandAvgLastYears = 0; + public grandTotal = 0; + public seriesHeader: string[] = []; + public seriesName: string[] = []; + public seriesRow: Array> = []; + public seriesColor: { + backgroundColor: string[], + borderColor: string[] + } = { + backgroundColor: this._utilitiesService.getSeriesColors(0.8, 'all'), + borderColor: this._utilitiesService.getSeriesColors(1, 'all') + }; + public seriesTypesHeader: string[] = []; + public seriesTypesName: string[] = []; + public seriesTypesRow: Array> = []; + public seriesTypesRowCumulated: Array> = []; + public seriesTypesColor: { + backgroundColor: string[], + borderColor: string[] + } = { + backgroundColor: this._utilitiesService.getSeriesColors(0.8, 'pastels'), + borderColor: this._utilitiesService.getSeriesColors(1, 'pastels') + }; + public seriesColorClass: string[] = this._utilitiesService.getChartColors(); + public seriesRowTotal: number[] = []; + public seriesRowAvg: number[] = []; + public seriesRowAvgLastYears: number[] = []; + public seriesColTotal: number[] = []; + public seriesColTotalClosed: number[] = []; + public seriesColTotalLastYears: number[] = []; + + constructor( + private route: ActivatedRoute, + private _utilitiesService: UtilitiesService, + public menuItems: MenuItems + ) { } + + ngOnInit() { + const data$: Observable<{ pageData: JumpsPageData }> = this.route.data as Observable<{ pageData: JumpsPageData }>; + this._data = data$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data: { pageData: JumpsPageData }) => { + const pageData: JumpsPageData = data.pageData; + this.lastJump = pageData.lastjump; + const currentYear: number = new Date().getFullYear(); + const types: Array = ['FF', 'Solo', 'VR', 'Wingsuit']; + const verticals: Array = ['Chutas', 'Head Up', 'Head Down']; + const others: Array = ['Track', 'Trace']; + const modules: Array = [...verticals, ...others]; + const minoration = 2; // -2 pour ne pas compter la première année + this.min = pageData.jumpsByYears[0].year; + this.max = pageData.jumpsByYears[(pageData.jumpsByYears.length-1)].year; + + this.seriesHeader = this._utilitiesService.getMonthsList(); + const values: Array = this.seriesHeader.map(() => 0); + this.seriesColTotal = [...values]; + this.seriesColTotalClosed = [...values]; + this.seriesColTotalLastYears = [...values]; + this.seriesName = pageData.jumpsByYears.map((row: JumpYears) => { + this.seriesRow.push([...values]); + return row.year.toString(); + }); + + this._jumpsByDate = pageData.jumpsByDate.map((row: JumpByDate) => { + this.seriesRow[(row.year-this.min)][(row.month-1)] = row.count; + this.seriesColTotal[(row.month-1)] += row.count; + if (row.year < currentYear) { + this.seriesColTotalClosed[(row.month-1)] += row.count; + } + if (row.year >= (currentYear-3) && row.year < currentYear) { + this.seriesColTotalLastYears[(row.month-1)] += row.count; + } + return row; + }); + this.seriesRow.forEach((row: number[]) => { + const total = row.reduce((partialSum, a) => partialSum + a, 0); + this.seriesRowTotal.push(total); + }); + this.seriesColTotalClosed.forEach((row: number) => { + const value: number = (row/(this.seriesName.length-minoration)); + this.seriesRowAvg.push(parseInt(value.toFixed(0))); + }); + this.seriesColTotalLastYears.forEach((row: number) => { + const value: number = (row/3); // Les 3 dernières années + this.seriesRowAvgLastYears.push(parseInt(value.toFixed(0))); + }); + this.grandAvg = this.seriesRowAvg.reduce((partialSum, accumulated) => partialSum + accumulated, 0); + this.grandAvgLastYears = this.seriesRowAvgLastYears.reduce((partialSum, accumulated) => partialSum + accumulated, 0); + this.grandTotal = this.seriesColTotal.reduce((partialSum, accumulated) => partialSum + accumulated, 0); + + pageData.jumpsByCategory.forEach((row: JumpByCategorie) => { + if (types.indexOf(row.categorie) !== -1) { + this._jumpsByCategorie.push(row); + } + }); + + //const focus: Array = ['FF', 'Solo']; // ['FF'] + let verticalCount:number = 0; + let otherCount:number = 0; + pageData.jumpsByModule.forEach((row: JumpByModule) => { + //if (focus.indexOf(row.categorie) !== -1 && modules.indexOf(row.module) !== -1) { + if (modules.indexOf(row.module) !== -1) { + if (verticals.indexOf(row.module) !== -1) { + verticalCount += row.count; + } else { + otherCount += row.count; + } + } + }); + if (verticalCount > 0) { + const row:JumpByModule = { + categorie: 'FF', + module: 'Vertical', + count: verticalCount + } + this._jumpsByModule.push(row); + } + if (otherCount > 0) { + const row:JumpByModule = { + categorie: 'FF', + module: 'Track/Trace', + count: otherCount + } + this._jumpsByModule.push(row); + } + + for (let year = 0; year < pageData.jumpsByYears.length; year++) { + for (let index = 0; index < 12; index++) { + const month: string = ((index+1) < 10) ? `0${(index+1)}` : `${(index+1)}`; + this.seriesTypesHeader.push(`${month}-${pageData.jumpsByYears[year].year}`); + } + } + const emptyValues: Array = this.seriesTypesHeader.map(() => 0); + this.seriesTypesName = types; + this.seriesTypesName.forEach(() => { + this.seriesTypesRow.push([...emptyValues]); + }); + pageData.jumpsByDateByModule.forEach((row: JumpByDateByModule) => { + const indexOf: number = this.seriesTypesName.indexOf(row.categorie); + if (indexOf !== -1) { + this.seriesTypesRow[indexOf][(((row.year-this.min)*12)+row.month-1)] += row.count; + } + }); + this.seriesTypesRowCumulated = this.seriesTypesRow.map((row: Array) => { + let accumulated: number = 0; + return row.map((value: number) => { + accumulated += value; + return accumulated; + }); + }); + this.seriesTypesHeader = this.seriesTypesHeader.slice((pageData.jumpsByDateByModule[0].month+1), -(pageData.jumpsByDateByModule[(pageData.jumpsByDateByModule.length-1)].month)); + this.seriesTypesRow = this.seriesTypesRow.map((row: Array) => { + return row.slice((pageData.jumpsByDateByModule[0].month+1), -(pageData.jumpsByDateByModule[(pageData.jumpsByDateByModule.length-1)].month)); + }); + this.seriesTypesRowCumulated = this.seriesTypesRowCumulated.map((row: Array) => { + return row.slice((pageData.jumpsByDateByModule[0].month+1), -(pageData.jumpsByDateByModule[(pageData.jumpsByDateByModule.length-1)].month)); + }); + /* + console.log('this.min', this.min); + console.log('this.max', this.max); + console.log('this.lastJump', this.lastJump); + console.log('this.seriesHeader', this.seriesHeader); + console.log('this.seriesName', this.seriesName); + console.log('this.seriesRow', this.seriesRow); + console.log('this.seriesRowTotal', this.seriesRowTotal); + console.log('this.seriesRowAvg', this.seriesRowAvg); + console.log('this.seriesRowAvgLastYears', this.seriesRowAvgLastYears); + console.log('this._jumpsByCategorie', this._jumpsByCategorie); + console.log('this._jumpsByModule', this._jumpsByModule); + console.log('this.seriesTypesHeader', this.seriesTypesHeader); + console.log('this.seriesTypesName', this.seriesTypesName); + console.log('this.seriesTypesRow', this.seriesTypesRow); + console.log('this.seriesTypesRowCumulated', this.seriesTypesRowCumulated); + */ + this.displayCharts = true; + }); + } + + ngOnDestroy() { + this._data.unsubscribe(); + } + + public getCategories(): Array { + return this._jumpsByCategorie; + } + + public getModules(): Array { + return this._jumpsByModule; + } + + public getModuleColor(index: number): number { + return (this._jumpsByCategorie.length + index); + } +} diff --git a/src/app/components/logbook/dialogs/index.ts b/src/app/components/logbook/dialogs/index.ts new file mode 100644 index 0000000..5cb40ea --- /dev/null +++ b/src/app/components/logbook/dialogs/index.ts @@ -0,0 +1,4 @@ +export * from './jump-add.dialog'; +export * from './jump-delete.dialog'; +export * from './jump-edit.dialog'; +export * from './jump-view.dialog'; diff --git a/src/app/components/logbook/dialogs/jump-add.dialog.html b/src/app/components/logbook/dialogs/jump-add.dialog.html new file mode 100644 index 0000000..ec88aa3 --- /dev/null +++ b/src/app/components/logbook/dialogs/jump-add.dialog.html @@ -0,0 +1,301 @@ +

+ Ajouter un saut + +

+ +
+ +
+
+ + Numéro ou plage de saut à ajouter + + 645 / +5 / 650-660 + + + Choisissez une date + + MM/DD/YYYY + + + + + + + + + + Utiliser les valeurs du dernier saut + +
+
+

+ Dropzone + + + +

+ + Lieu + + + @for (option of filteredOptions.dropzones | async; track option) { + {{option.lieu}} - {{option.oaci}} + } + + @if (this.jumpForm.controls['lieu'].status === 'INVALID') { + {{getErrorMessage('lieu')}} + } + + + Oaci + + + @for (option of filteredOptions.oaci | async; track option) { + {{option.lieu}} - {{option.oaci}} + } + + @if (this.jumpForm.controls['oaci'].status === 'INVALID') { + {{getErrorMessage('oaci')}} + } + +

+ Aéronef + + + +

+ + Aéronef + + + @for (option of filteredOptions.aeronefs | async; track option) { + {{option.aeronef}} - {{option.imat}} + } + + @if (this.jumpForm.controls['aeronef'].status === 'INVALID') { + {{getErrorMessage('aeronef')}} + } + + + Imatriculation + + + @for (option of filteredOptions.imats | async; track option) { + {{option.aeronef}} - {{option.imat}} + } + + @if (this.jumpForm.controls['imat'].status === 'INVALID') { + {{getErrorMessage('imat')}} + } + +

+ Voile + + + +

+ + Modèle + + + @for (option of filteredOptions.canopies | async; track option) { + {{option.voile}} - {{option.taille}} + } + + @if (this.jumpForm.controls['voile'].status === 'INVALID') { + {{getErrorMessage('voile')}} + } + + + Taille en ft2 + + + @for (option of filteredOptions.tailles | async; track option) { + {{option.voile}} - {{option.taille}} + } + + ft2 + @if (this.jumpForm.controls['taille'].status === 'INVALID') { + {{getErrorMessage('taille')}} + } + +
+
+

+ Altitude + + + +

+ + Hauteur de largage + + @if (this.jumpForm.controls['hauteur'].status === 'INVALID') { + {{getErrorMessage('hauteur')}} + } + + + Hauteur de déploiement + + @if (this.jumpForm.controls['deploiement'].status === 'INVALID') { + {{getErrorMessage('deploiement')}} + } + +

+ Discipline + + + +

+ + Categorie + + + @for (option of filteredOptions.categories | async; track option) { + {{option.categorie}}{{option.categorie && option.module ? ' - ' : ''}}{{option.module}} + } + + @if (this.jumpForm.controls['categorie'].status === 'INVALID') { + {{getErrorMessage('categorie')}} + } + + + Module + + + @for (option of filteredOptions.modules | async; track option) { + {{option.categorie}}{{option.categorie && option.module ? ' - ' : ''}}{{option.module}} + } + + @if (this.jumpForm.controls['module'].status === 'INVALID') { + {{getErrorMessage('module')}} + } + +

+ Divers + + + +

+ + Accessoires + + @if (this.jumpForm.controls['accessoires'].status === 'INVALID') { + {{getErrorMessage('accessoires')}} + } + + + Zone + + @if (this.jumpForm.controls['zone'].status === 'INVALID') { + {{getErrorMessage('zone')}} + } + +
+
+

+ Groupe + + + +

+ + Sautants + + + + Nombre de participants + + @if (this.jumpForm.controls['participants'].status === 'INVALID') { + {{getErrorMessage('participants')}} + } + +
+ @for (sautant of jump.sautants; track sautant) { + + + {{ sautant }} + + } + + + {{ lastJump.author.username }} + +
+
+
+

+ Programme + + + +

+ + Programme + + @if (this.jumpForm.controls['programme'].status === 'INVALID') { + {{getErrorMessage('programme')}} + } + +
+
+

Vidéo

+ + Dossier + + @if (this.jumpForm.controls['dossier'].status === 'INVALID') { + {{getErrorMessage('dossier')}} + } + + + Video + + @if (this.jumpForm.controls['video'].status === 'INVALID') { + {{getErrorMessage('video')}} + } + + {{ filepath }}{{ filename }} +
+
+

Données GPS

+
+ + Rechercher le fichier kml + +
+
+
+
+
+ + + + + + diff --git a/src/app/components/logbook/dialogs/jump-add.dialog.ts b/src/app/components/logbook/dialogs/jump-add.dialog.ts new file mode 100644 index 0000000..62c5afe --- /dev/null +++ b/src/app/components/logbook/dialogs/jump-add.dialog.ts @@ -0,0 +1,873 @@ +import { Component, Inject, OnDestroy } from '@angular/core'; +import { AsyncPipe, DatePipe } from '@angular/common'; +import { FormBuilder, FormControl, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; +import { MatAutocompleteModule } from '@angular/material/autocomplete'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatDatepickerModule } from '@angular/material/datepicker'; +import { MatDialogRef, MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog'; +import { MatIconModule } from '@angular/material/icon'; +import { MatInputModule } from '@angular/material/input'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatOptionModule } from '@angular/material/core'; +import { MatSelectModule } from '@angular/material/select'; +import { Observable, Subscription } from 'rxjs'; +import { map, startWith, take } from 'rxjs/operators'; + +import { AeronefByImat, CanopyModelBySize, DropZoneByOaci, Errors, Jump, JumpAddParams, JumpByModule, JumpFile, JumpFileType } from '@models'; +import { AeronefsService, CanopiesService, DropZonesService, JumpsService } from '@services'; + +@Component({ + selector: 'app-jump-add-dialog', + templateUrl: 'jump-add.dialog.html', + standalone: true, + imports: [ + AsyncPipe, + DatePipe, + FormsModule, + ReactiveFormsModule, + MatAutocompleteModule, + MatButtonModule, + MatCheckboxModule, + MatDatepickerModule, + MatDialogModule, + MatFormFieldModule, + MatIconModule, + MatInputModule, + MatSelectModule, + MatOptionModule +] +}) +export class JumpAddDialogComponent implements OnDestroy { + private _formChanges: Array = []; + private _subscriptions: Array = []; + private _aeronefByImat: Subscription = new Subscription(); + private _canopyModelBySize: Subscription = new Subscription(); + private _dropZoneByOaci: Subscription = new Subscription(); + private _jumpByModule: Subscription = new Subscription(); + public errors!: Errors; + public tagField = new FormControl('', { nonNullable: true}); + public jumpForm: FormGroup; + public jump: Jump; + public lastJump: Jump; + public nextJump: number; + public params: JumpAddParams; + public filename: string; + public filepath: string; + public useLast: { + all: boolean; + aeronef: boolean; + altitude: boolean; + discipline: boolean; + divers: boolean; + dropzone: boolean; + groupe: boolean; + programme: boolean; + voile: boolean; + } = { + all: false, + aeronef: false, + altitude: false, + discipline: false, + divers: false, + dropzone: false, + groupe: false, + programme: false, + voile: false + }; + public inputOptions: { + aeronefs: Array; + canopies: Array; + dropzones: Array; + categories: Array; + }; + public filteredOptions: { + aeronefs: Observable>; + imats: Observable>; + canopies: Observable>; + tailles: Observable>; + dropzones: Observable>; + oaci: Observable>; + categories: Observable>; + modules: Observable>; + }; + + constructor( + public dialogRef: MatDialogRef, + private fb: FormBuilder, + private _aeronefsService: AeronefsService, + private _canopiesService: CanopiesService, + private _dropZonesService: DropZonesService, + private _jumpsService: JumpsService, + @Inject(MAT_DIALOG_DATA) public data: {jump: Jump, lastJump: Jump} + ) { + this.inputOptions = { aeronefs: [], canopies: [], dropzones: [], categories: [] }; + //this.filteredOptions.aeronefs = this._aeronefsService.getAllByImat(); + this.jump = data.jump; + this.lastJump = data.lastJump; + this.nextJump = (this.lastJump.numero + 1); + this.params = { + numeros: this.nextJump.toString(), + date: '', + video: true + }; + this.jump.numero = this.nextJump; + const controlsConfig = { + date: ['', Validators.required], + numero: [this.nextJump, Validators.required], + lieu: ['', Validators.required], + oaci: '', + aeronef: ['', Validators.required], + imat: '', + hauteur: ['', Validators.required], + deploiement: '', + voile: '', + taille: ['', Validators.required], + categorie: '', + module: '', + participants: [1, Validators.required], + sautants: [[]], + programme: '', + accessoires: '', + zone: '', + dossier: '', + video: '' + }; + this.jumpForm = this.fb.group(controlsConfig); + this.filename = this._computeFilename(); + this.filepath = this._computeFilepath(); + this._subscriptions.push( + this.jumpForm.controls['module'].valueChanges.subscribe(() => { + this.filepath = this._computeFilepath(); + }), + this.jumpForm.controls['numero'].valueChanges.subscribe(() => { + this.filename = this._computeFilename(); + }) + ); + /* + this.filteredAeronefOptions = this.jumpForm.controls['aeronef'].valueChanges.pipe( + startWith(''), + map(value => { + const aeronef = typeof value === 'string' ? value : ''; + return aeronef ? this._filterString(aeronef as string, this.aeronefOptions) : this.aeronefOptions.slice(); + }), + ); + this.filteredImatOptions = this.jumpForm.controls['imat'].valueChanges.pipe( + startWith(''), + map(value => { + const imat = typeof value === 'string' ? value : value?.imat; + return imat ? this._filterImat(imat as string) : this.imatOptions.slice(); + }), + ); + //this.filteredAeronefOptions = this._aeronefsService.getAllByImat(); + */ + this.filteredOptions = { + aeronefs: this.jumpForm.controls['aeronef'].valueChanges.pipe( + startWith(''), + map(value => { + const aeronef = typeof value === 'string' ? value : value?.aeronef; + return aeronef ? this._filterImat(aeronef as string) : this.inputOptions.aeronefs.slice(); + }), + ), + imats: this.jumpForm.controls['imat'].valueChanges.pipe( + startWith(''), + map(value => { + const imat = typeof value === 'string' ? value : value?.imat; + return imat ? this._filterImat(imat as string) : this.inputOptions.aeronefs.slice(); + }), + ), + canopies: this.jumpForm.controls['voile'].valueChanges.pipe( + startWith(''), + map(value => { + const voile = typeof value === 'string' ? value : value?.voile; + return voile ? this._filterTaille(voile as string) : this.inputOptions.canopies.slice(); + }), + ), + tailles: this.jumpForm.controls['taille'].valueChanges.pipe( + startWith(''), + map(value => { + const taille = typeof value === 'string' ? value : value?.taille.toString(); + return taille ? this._filterTaille(taille as string) : this.inputOptions.canopies.slice(); + }), + ), + dropzones: this.jumpForm.controls['lieu'].valueChanges.pipe( + startWith(''), + map(value => { + const lieu = typeof value === 'string' ? value : value?.lieu; + return lieu ? this._filterOaci(lieu as string) : this.inputOptions.dropzones.slice(); + }), + ), + oaci: this.jumpForm.controls['oaci'].valueChanges.pipe( + startWith(''), + map(value => { + const oaci = typeof value === 'string' ? value : value?.oaci; + return oaci ? this._filterOaci(oaci as string) : this.inputOptions.dropzones.slice(); + }), + ), + categories: this.jumpForm.controls['categorie'].valueChanges.pipe( + startWith(''), + map(value => { + const category = typeof value === 'string' ? value : value?.categorie; + return category ? this._filterModule(category as string) : this.inputOptions.categories.slice(); + }), + ), + modules: this.jumpForm.controls['module'].valueChanges.pipe( + startWith(''), + map(value => { + const module = typeof value === 'string' ? value : value?.module; + return module ? this._filterModule(module as string) : this.inputOptions.categories.slice(); + }), + ) + }; + this._loadAeronefByImat(); + this._loadCanopyModelBySize(); + this._loadDropZoneByOaci(); + this._loadJumpByModule(); + } + + ngOnDestroy() { + this._subscriptions.forEach((sub: Subscription) => { + sub.unsubscribe(); + }); + this._aeronefByImat.unsubscribe(); + this._canopyModelBySize.unsubscribe(); + this._dropZoneByOaci.unsubscribe(); + this._jumpByModule.unsubscribe(); + } + + public onDateChange(): void { + this.filename = this._computeFilename(); + } + + private _computeFilename(numero?: string): string { + let file: string = ''; + const timestamp: number = Date.parse(this.jumpForm.controls['date'].value); + if (isNaN(timestamp) == false) { + const date: Date = new Date(timestamp); + file += `${(date.getFullYear() + '').padStart(2, '0')}-${((date.getMonth() + 1) + '').padStart(2, '0')}-${(date.getDate() + '').padStart(2, '0')}_`; + } + if (numero !== undefined) { + numero = (numero + '').padStart(5, '0'); + } else { + numero = (this.jumpForm.controls['numero'].value + '').padStart(5, '0'); + } + file += `S${numero}.mp4`; + this.jumpForm.controls['video'].setValue(file); + + return file; + } + + private _computeFilepath(): string { + let path: string = '/Volumes/Storage/Skydive/Videos/'; + if (this.jumpForm.controls['module'].value != '') { + //path += `${this.jumpForm.controls['module'].value}/`; + path += typeof this.jumpForm.controls['module'].value === 'string' ? `${this.jumpForm.controls['module'].value}/` : `${this.jumpForm.controls['module'].value?.module}/`; + } + this.jumpForm.controls['dossier'].setValue(path); + + return path; + } + + private _isLastForAllSections() { + return ( + this.useLast.aeronef + && this.useLast.altitude + && this.useLast.discipline + && this.useLast.divers + && this.useLast.dropzone + && this.useLast.groupe + && this.useLast.programme + && this.useLast.voile + ); + } + + private _filterImat(imat: string): Array { + const filterValue = imat.toLowerCase(); + return this.inputOptions.aeronefs.filter(option => (option.aeronef.toLowerCase().includes(filterValue) || option.imat.toLowerCase().includes(filterValue))); + } + + private _filterModule(module: string): Array { + const filterValue = module.toLowerCase(); + return this.inputOptions.categories.filter(option => (option.categorie.toLowerCase().includes(filterValue) || option.module.toLowerCase().includes(filterValue))); + } + + private _filterOaci(oaci: string): Array { + const filterValue = oaci.toLowerCase(); + return this.inputOptions.dropzones.filter(option => (option.lieu.toLowerCase().includes(filterValue) || option.oaci.toLowerCase().includes(filterValue))); + } + + private _filterTaille(taille: string): Array { + const filterValue = taille.toLowerCase(); + return this.inputOptions.canopies.filter(option => (option.voile.toLowerCase().includes(filterValue) || option.taille.toString().includes(filterValue))); + } + + private _loadAeronefByImat(): void { + const aeronefs$ = this._aeronefsService.getAllByImat(); + const subscription: Subscription = aeronefs$.subscribe((aggregate: Array) => { + /* + this.inputOptions.imats = aggregate.map((row: AeronefByImat) => { + if (this.inputOptions.aeronefs.indexOf(row.aeronef) === -1) { + this.inputOptions.aeronefs.push(row.aeronef); + } + return row; + }); + */ + this.inputOptions.aeronefs = aggregate; + }); + this._subscriptions.push(subscription); + } + + private _loadCanopyModelBySize(): void { + const canopies$ = this._canopiesService.getAllBySizeByModel(); + const subscription: Subscription = canopies$.subscribe((aggregate: Array) => { + /* + this.inputOptions.tailles = aggregate.map((row: CanopyModelBySize) => { + if (this.inputOptions.canopies.indexOf(row.voile) === -1) { + this.inputOptions.canopies.push(row.voile); + } + return row; + }); + */ + this.inputOptions.canopies = aggregate; + }); + this._subscriptions.push(subscription); + } + + private _loadDropZoneByOaci(): void { + const dropzones$ = this._dropZonesService.getAllByOaci(); + const subscription: Subscription = dropzones$.subscribe((aggregate: Array) => { + /* + this.inputOptions.oaci = aggregate.map((row: DropZoneByOaci) => { + if (this.inputOptions.dropzones.indexOf(row.lieu) === -1) { + this.inputOptions.dropzones.push(row.lieu); + } + return row; + }); + */ + this.inputOptions.dropzones = aggregate; + }); + this._subscriptions.push(subscription); + } + + private _loadJumpByModule(): void { + const jumps$ = this._jumpsService.getAllByModule(); + const subscription: Subscription = jumps$.subscribe((aggregate: Array) => { + this.inputOptions.categories = aggregate; + }); + this._subscriptions.push(subscription); + } + + private _setAllLast(checked: boolean) { + this.useLast.all = checked; + this.useLast.aeronef = checked; + this.useLast.altitude = checked; + this.useLast.discipline = checked; + this.useLast.divers = checked; + this.useLast.dropzone = checked; + this.useLast.groupe = checked; + this.useLast.programme = checked; + this.useLast.voile = checked; + } + + addSautant(): void { + this.useLast.groupe = false; + this.useLast.all = this._isLastForAllSections(); + const tag = this.tagField.value; + if (tag != null && tag.trim() !== '') { + if (tag.includes(',') === true) { + const tags = tag.split(','); + tags.forEach(sautant => { + if (this.jump.sautants.indexOf(sautant.trim()) < 0) { + this.jump.sautants.push(sautant.trim()); + } + }); + } else if (this.jump.sautants.indexOf(tag) < 0) { + this.jump.sautants.push(tag); + } + } + this.tagField.reset(''); + const participants = (this.jump.sautants.length + 1); + this.jumpForm.controls['participants'].setValue(participants); + } + + closeDialog(): void { + this._setAllLast(false); + //this.jump = {}; + //this.jump.numero = this.nextJump; + this.dialogRef.close(); + } + + displayAeronefFn(aeronef: AeronefByImat): string { + let res = ''; + if (aeronef) { + if (typeof aeronef === 'string') { + res = aeronef; + } else { + res = aeronef.aeronef ? aeronef.aeronef : ''; + } + } + return res; + } + + displayImatFn(aeronef: AeronefByImat): string { + let res = ''; + if (aeronef) { + if (typeof aeronef === 'string') { + res = aeronef; + } else { + res = aeronef.imat ? aeronef.imat : ''; + } + } + return res; + } + + displayLieuFn(dropzone: DropZoneByOaci): string { + //return dropzone && dropzone.oaci ? `${dropzone.lieu} - ${dropzone.oaci}` : ''; + let res = ''; + if (dropzone) { + if (typeof dropzone === 'string') { + res = dropzone; + } else { + res = dropzone.lieu ? dropzone.lieu : ''; + } + } + //return dropzone && dropzone.lieu ? dropzone.lieu : ''; + return res; + } + + displayOaciFn(dropzone: DropZoneByOaci): string { + //return dropzone && dropzone.oaci ? `${dropzone.lieu} - ${dropzone.oaci}` : ''; + let res = ''; + if (dropzone) { + if (typeof dropzone === 'string') { + res = dropzone; + } else { + res = dropzone.oaci ? dropzone.oaci : ''; + } + } + //return dropzone && dropzone.oaci ? dropzone.oaci : ''; + return res; + } + + displayTailleFn(canopy: CanopyModelBySize): string { + let res = ''; + if (canopy) { + if (typeof canopy === 'string') { + res = canopy; + } else { + res = canopy.taille ? canopy.taille.toString() : ''; + } + } + return res; + } + + displayVoileFn(canopy: CanopyModelBySize): string { + let res = ''; + if (canopy) { + if (typeof canopy === 'string') { + res = canopy; + } else { + res = canopy.voile ? canopy.voile : ''; + } + } + return res; + } + + displayCategorieFn(jump: JumpByModule): string { + let res = ''; + if (jump) { + if (typeof jump === 'string') { + res = jump; + } else { + res = jump.categorie ? jump.categorie : ''; + } + } + return res; + } + + displayModuleFn(jump: JumpByModule): string { + let res = ''; + if (jump) { + if (typeof jump === 'string') { + res = jump; + } else { + res = jump.module ? jump.module : ''; + } + } + return res; + } + + getErrorMessage(name: string): string { + if (this.jumpForm.controls[name].errors !== null) { + return 'Ce champ est requis.'; + } + return ''; + } + + onSelAeronef(aeronef: AeronefByImat) { + if (aeronef && aeronef.aeronef) { + //this.jumpForm.controls['imat'].setValue(aeronef.imat); + this.jumpForm.controls['imat'].setValue(aeronef); + } + } + + onSelImat(aeronef: AeronefByImat) { + if (aeronef && aeronef.imat) { + //this.jumpForm.controls['aeronef'].setValue(aeronef.aeronef); + this.jumpForm.controls['aeronef'].setValue(aeronef); + } + } + + onSelLieu(dropzone: DropZoneByOaci) { + if (dropzone && dropzone.oaci) { + //this.jumpForm.controls['oaci'].setValue(dropzone.oaci); + this.jumpForm.controls['oaci'].setValue(dropzone); + } + } + + onSelOaci(dropzone: DropZoneByOaci) { + if (dropzone && dropzone.lieu) { + //this.jumpForm.controls['lieu'].setValue(dropzone.lieu); + this.jumpForm.controls['lieu'].setValue(dropzone); + } + } + + onSelTaille(canopy: CanopyModelBySize) { + if (canopy && canopy.voile) { + //this.jumpForm.controls['voile'].setValue(canopy.voile); + this.jumpForm.controls['voile'].setValue(canopy); + } + } + + onSelVoile(canopy: CanopyModelBySize) { + if (canopy && canopy.taille) { + //this.jumpForm.controls['taille'].setValue(canopy.taille.toString()); + this.jumpForm.controls['taille'].setValue(canopy); + } + } + + onSelCategorie(jump: JumpByModule) { + if (jump && jump.categorie) { + this.jumpForm.controls['module'].setValue(jump); + } + } + + onSelModule(jump: JumpByModule) { + if (jump && jump.module) { + this.jumpForm.controls['categorie'].setValue(jump); + } + } + + removeSautant(index: string): void { + this.useLast.groupe = false; + this.useLast.all = this._isLastForAllSections(); + this.jump.sautants = this.jump.sautants.filter((sautant) => sautant !== index); + const participants = (this.jump.sautants.length + 1); + this.jumpForm.controls['participants'].setValue(participants); + } + + setLastJump(checked: boolean) { + if (checked) { + this._setAllLast(true); + this.jumpForm.controls['lieu'].setValue(this.lastJump.lieu); + this.jumpForm.controls['oaci'].setValue(this.lastJump.oaci); + this.jumpForm.controls['aeronef'].setValue(this.lastJump.aeronef); + this.jumpForm.controls['imat'].setValue(this.lastJump.imat); + this.jumpForm.controls['hauteur'].setValue(this.lastJump.hauteur); + this.jumpForm.controls['deploiement'].setValue(this.lastJump.deploiement); + this.jumpForm.controls['voile'].setValue(this.lastJump.voile); + this.jumpForm.controls['taille'].setValue(this.lastJump.taille?.toString()); + this.jumpForm.controls['categorie'].setValue(this.lastJump.categorie); + this.jumpForm.controls['module'].setValue(this.lastJump.module); + this.jumpForm.controls['participants'].setValue(this.lastJump.participants); + //this.jumpForm.controls['sautants'].setValue(this.lastJump.sautants); + this.jumpForm.controls['programme'].setValue(this.lastJump.programme); + this.jumpForm.controls['accessoires'].setValue(this.lastJump.accessoires); + this.jumpForm.controls['zone'].setValue(this.lastJump.zone); + this.jump.sautants = this.lastJump.sautants; + /* + Object.assign( + this.jump, + { + date: this.lastJump.date, + numero: this.lastJump.numero, + lieu: this.lastJump.lieu, + oaci: this.lastJump.oaci, + aeronef: this.lastJump.aeronef, + imat: this.lastJump.imat, + hauteur: this.lastJump.hauteur, + deploiement: this.lastJump.deploiement, + voile: this.lastJump.voile, + taille: this.lastJump.taille, + categorie: this.lastJump.categorie, + module: this.lastJump.module, + participants: this.lastJump.participants, + sautants: this.lastJump.sautants, + programme: this.lastJump.programme, + accessoires: this.lastJump.accessoires, + zone: this.lastJump.zone, + } + ); + */ + this.jump.date = ''; + } else { + this._setAllLast(false); + this.jumpForm.controls['lieu'].setValue(''); + this.jumpForm.controls['oaci'].setValue(''); + this.jumpForm.controls['aeronef'].setValue(''); + this.jumpForm.controls['imat'].setValue(''); + this.jumpForm.controls['hauteur'].setValue(''); + this.jumpForm.controls['deploiement'].setValue(''); + this.jumpForm.controls['voile'].setValue(''); + this.jumpForm.controls['taille'].setValue(''); + this.jumpForm.controls['categorie'].setValue(''); + this.jumpForm.controls['module'].setValue(''); + this.jumpForm.controls['participants'].setValue(1); + //this.jumpForm.controls['sautants'].setValue(''); + this.jumpForm.controls['programme'].setValue(''); + this.jumpForm.controls['accessoires'].setValue(''); + this.jumpForm.controls['zone'].setValue(''); + this.jump.sautants = []; + } + this.jump.numero = this.nextJump; + } + + setLastAeronef(checked: boolean = false) { + if (checked) { + this.useLast.aeronef = true; + this.jumpForm.controls['aeronef'].setValue(this.lastJump.aeronef); + this.jumpForm.controls['imat'].setValue(this.lastJump.imat); + } else { + this.useLast.aeronef = false; + this.jumpForm.controls['aeronef'].setValue(''); + this.jumpForm.controls['imat'].setValue(''); + } + this.useLast.all = this._isLastForAllSections(); + } + + setLastAltitude(checked: boolean = false) { + if (checked) { + this.useLast.altitude = true; + this.jumpForm.controls['hauteur'].setValue(this.lastJump.hauteur); + this.jumpForm.controls['deploiement'].setValue(this.lastJump.deploiement); + } else { + this.useLast.altitude = false; + this.jumpForm.controls['hauteur'].setValue(''); + this.jumpForm.controls['deploiement'].setValue(''); + } + this.useLast.all = this._isLastForAllSections(); + } + + setLastDiscipline(checked: boolean = false) { + if (checked) { + this.useLast.discipline = true; + this.jumpForm.controls['categorie'].setValue(this.lastJump.categorie); + this.jumpForm.controls['module'].setValue(this.lastJump.module); + } else { + this.useLast.discipline = false; + this.jumpForm.controls['categorie'].setValue(''); + this.jumpForm.controls['module'].setValue(''); + } + this.useLast.all = this._isLastForAllSections(); + } + + setLastDivers(checked: boolean = false) { + if (checked) { + this.useLast.divers = true; + this.jumpForm.controls['accessoires'].setValue(this.lastJump.accessoires); + this.jumpForm.controls['zone'].setValue(this.lastJump.zone); + } else { + this.useLast.divers = false; + this.jumpForm.controls['accessoires'].setValue(''); + this.jumpForm.controls['zone'].setValue(''); + } + this.useLast.all = this._isLastForAllSections(); + } + + setLastDropzone(checked: boolean = false) { + if (checked) { + this.useLast.dropzone = true; + this.jumpForm.controls['lieu'].setValue(this.lastJump.lieu); + this.jumpForm.controls['oaci'].setValue(this.lastJump.oaci); + } else { + this.useLast.dropzone = false; + this.jumpForm.controls['lieu'].setValue(''); + this.jumpForm.controls['oaci'].setValue(''); + } + this.useLast.all = this._isLastForAllSections(); + } + + setLastGroupe(checked: boolean = false) { + if (checked) { + this.useLast.groupe = true; + this.jumpForm.controls['participants'].setValue(this.lastJump.participants); + //this.jumpForm.controls['sautants'].setValue(this.lastJump.sautants); + this.jump.sautants = this.lastJump.sautants; + } else { + this.useLast.groupe = false; + this.jumpForm.controls['participants'].setValue(1); + //this.jumpForm.controls['sautants'].setValue(''); + this.jump.sautants = []; + } + this.useLast.all = this._isLastForAllSections(); + } + + setLastProgramme(checked: boolean = false) { + if (checked) { + this.useLast.programme = true; + this.jumpForm.controls['programme'].setValue(this.lastJump.participants); + } else { + this.useLast.programme = false; + this.jumpForm.controls['programme'].setValue(''); + } + this.useLast.all = this._isLastForAllSections(); + } + + setLastVoile(checked: boolean = false) { + if (checked) { + this.useLast.voile = true; + this.jumpForm.controls['voile'].setValue(this.lastJump.voile); + this.jumpForm.controls['taille'].setValue(this.lastJump.taille?.toString()); + } else { + this.useLast.voile = false; + this.jumpForm.controls['voile'].setValue(''); + this.jumpForm.controls['taille'].setValue(''); + } + this.useLast.all = this._isLastForAllSections(); + } + + submitForm(): void { + /* + * Création d'un tableau de saut contenant de 1 à n saut en fonction + * de la valeur du champ numero du formulaire jumpForm + */ + const jumps: Array = []; + const jump: Jump = {} as Jump; + const numeros: Array = []; + let date: Date; + /* Controle de la validité du champ date et conversion au format ISO */ + const timestamp: number = Date.parse(this.jumpForm.controls['date'].value); + if (isNaN(timestamp) == false) { + date = new Date(timestamp); + } else { + date = new Date(); + } + let value = this.jumpForm.controls['numero'].value; + if (typeof value !== 'string') { + value = value.toString(); + } + + if (isNaN(+value) || value.split('+').length == 2) { + /* + * 'numero' n'est pas un entier , il s'agit donc d'une plage, d'une quantité ou de plusieurs valeur + * decomposer la valeur 'numero' et ajouter chaque sauts au tableau retourné par la fenêtre dialog + */ + let jumpNum: number = this.lastJump.numero; + const elements: string[] = this.jumpForm.controls['numero'].value.split(';'); + elements.forEach((element: string) => { + if (element == '') { + jumpNum ++; + element = jumpNum.toString(); + } + const values: string[] = element.split('-'); + if (values.length == 2) { + const start: number = parseInt(values[0]); + const stop: number = parseInt(values[1]); + const diff: number = (stop - start); + /* Ajout de saut par plage */ + for (let index = 0; index <= diff; index++) { + jumpNum = (start + index); + numeros.push(jumpNum); + } + } else { + const quantity: string[] = values[0].split('+'); + if (quantity.length == 2) { + /* Ajout de sauts par quantité */ + //const start: number = jumpNum; + for (let index = 1; index <= parseInt(quantity[1]); index++) { + jumpNum ++; + numeros.push(jumpNum); + } + } else { + /* Ajout de sauts par numero */ + jumpNum = parseInt(quantity[0]); + numeros.push(jumpNum); + } + } + }); + } else { + /* 'numero' est un entier */ + numeros.push(this.jumpForm.controls['numero'].value); + } + + /* Valeurs communes aux 1 à n saut(s) à ajouter */ + jump.date = date.toISOString(); + jump.lieu = typeof this.jumpForm.controls['lieu'].value === 'string' ? this.jumpForm.controls['lieu'].value : this.jumpForm.controls['lieu'].value.lieu; + jump.oaci = typeof this.jumpForm.controls['oaci'].value === 'string' ? this.jumpForm.controls['oaci'].value : this.jumpForm.controls['oaci'].value.oaci; + jump.aeronef = typeof this.jumpForm.controls['aeronef'].value === 'string' ? this.jumpForm.controls['aeronef'].value : this.jumpForm.controls['aeronef'].value.aeronef; + jump.imat = typeof this.jumpForm.controls['imat'].value === 'string' ? this.jumpForm.controls['imat'].value : this.jumpForm.controls['imat'].value.imat; + jump.voile = typeof this.jumpForm.controls['voile'].value === 'string' ? this.jumpForm.controls['voile'].value : this.jumpForm.controls['voile'].value.voile; + jump.taille = typeof this.jumpForm.controls['taille'].value === 'string' ? this.jumpForm.controls['taille'].value : this.jumpForm.controls['taille'].value.taille; + jump.categorie = typeof this.jumpForm.controls['categorie'].value === 'string' ? this.jumpForm.controls['categorie'].value : this.jumpForm.controls['categorie'].value.categorie; + jump.module = typeof this.jumpForm.controls['module'].value === 'string' ? this.jumpForm.controls['module'].value : this.jumpForm.controls['module'].value.module; + jump.hauteur = this.jumpForm.controls['hauteur'].value; + jump.deploiement = this.jumpForm.controls['deploiement'].value; + jump.participants = this.jumpForm.controls['participants'].value; + jump.sautants = this.jump.sautants; + //jump.sautants = this.jumpForm.controls['sautants'].value; + jump.programme = this.jumpForm.controls['programme'].value; + jump.accessoires = this.jumpForm.controls['accessoires'].value; + jump.zone = this.jumpForm.controls['zone'].value; + //jump.dossier = this.jumpForm.controls['dossier'].value; + //jump.video = this.jumpForm.controls['video'].value; + + /* Ajout du saut au tableau à retourner */ + numeros.forEach((numero: number) => { + const item: Jump = {} as Jump; + Object.assign(item, jump); + item.numero = numero; + if (this.jumpForm.controls['dossier'].value !== '' && this.jumpForm.controls['video'].value !== '') { + item.dossier = this._computeFilepath(); + item.video = this._computeFilename(numero.toString()); + const file: JumpFile = { + name: item.video, + path: item.dossier, + type: JumpFileType.VIDEO + } as JumpFile; + this._subscriptions.push( + this._jumpsService.saveFile(item.slug, file) + .pipe(take(1)) + .subscribe({ + next: (file) => { + item.files.push(file); + console.log(`Le fichier ${file.name} a été ajouté au saut n°${item.numero} !`, 'OK'); + }, + error: (err) => { + this.errors = err; + } + }) + ); + } + jumps.push(item); + //console.log(item); + }); + //console.log(jumps); + /* Reset all 'last jump values' booleans */ + this._setAllLast(false); + /* close the dialog with result */ + this.dialogRef.close(jumps); + + /* + // Reset all 'last jump values' booleans + this._setAllLast(false); + // update the model + this.updateJump(this.jumpForm.value); + // close the dialog with result + this.dialogRef.close(this.jump); + */ + } + + updateJump(values: NonNullable): void { + Object.assign(this.jump, values); + } +} diff --git a/src/app/components/logbook/dialogs/jump-delete.dialog.html b/src/app/components/logbook/dialogs/jump-delete.dialog.html new file mode 100644 index 0000000..0ee31ad --- /dev/null +++ b/src/app/components/logbook/dialogs/jump-delete.dialog.html @@ -0,0 +1,64 @@ +

+ Supprimer le saut n°{{jump.numero}} + +

+ +
+
+

+ Veuillez confirmer la suppression de ce saut.
+ Attention, cette action est irréversible. +

+
+

Données du saut :

+
+
+
+
numero:
+
{{jump.numero}}
+
lieu:
+
{{jump.lieu}}
+
aeronef:
+
{{jump.aeronef}}
+
voile:
+
{{jump.voile}}
+
hauteur:
+
{{jump.hauteur}} m
+
categorie:
+
{{jump.categorie}}
+
accessoires:
+
{{jump.accessoires}}
+
dossier:
+
{{jump.dossier}}
+
programme:
+
{{jump.programme}}
+
+
+
+
+
date:
+
{{jump.date | date: 'mediumDate'}}
+
oaci:
+
{{jump.oaci}}
+
imat:
+
{{jump.imat}}
+
taille:
+
{{jump.taille}} ft2
+
participants:
+
{{jump.participants}}
+
module:
+
{{jump.module}}
+
zone:
+
{{jump.zone}}
+
video:
+
{{jump.video}}
+
+
+
+
+
+ + + + + diff --git a/src/app/components/logbook/dialogs/jump-delete.dialog.ts b/src/app/components/logbook/dialogs/jump-delete.dialog.ts new file mode 100644 index 0000000..fcc0b30 --- /dev/null +++ b/src/app/components/logbook/dialogs/jump-delete.dialog.ts @@ -0,0 +1,27 @@ +import { Component, Inject } from '@angular/core'; +import { DatePipe } from '@angular/common'; +import { MatButtonModule } from '@angular/material/button'; +import { MatDialogRef, MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog'; +import { MatIconModule } from '@angular/material/icon'; + +import { Jump } from '@models'; + +@Component({ + selector: 'app-jump-delete-dialog', + templateUrl: 'jump-delete.dialog.html', + standalone: true, + imports: [ + DatePipe, + MatDialogModule, MatButtonModule, MatIconModule + ] +}) +export class JumpDeleteDialogComponent { + constructor( + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public jump: Jump + ) { } + + closeDialog(): void { + this.dialogRef.close(); + } +} diff --git a/src/app/components/logbook/dialogs/jump-edit.dialog.html b/src/app/components/logbook/dialogs/jump-edit.dialog.html new file mode 100644 index 0000000..8a72925 --- /dev/null +++ b/src/app/components/logbook/dialogs/jump-edit.dialog.html @@ -0,0 +1,219 @@ +

+ Modifier un saut + +

+ +
+
+
+ + Numéro du saut + + + + Choisissez une date + + MM/DD/YYYY + + + + + + + + +
+
+

Dropzone

+ + Lieu + + + @for (option of filteredOptions.dropzones | async; track option) { + {{option.lieu}} - {{option.oaci}} + } + + @if (this.jumpForm.controls['lieu'].status === 'INVALID') { + {{getErrorMessage('lieu')}} + } + + + Oaci + + + @for (option of filteredOptions.oaci | async; track option) { + {{option.lieu}} - {{option.oaci}} + } + + @if (this.jumpForm.controls['oaci'].status === 'INVALID') { + {{getErrorMessage('oaci')}} + } + +

Aéronef

+ + Aéronef + + + @for (option of filteredOptions.aeronefs | async; track option) { + {{option.aeronef}} - {{option.imat}} + } + + @if (this.jumpForm.controls['aeronef'].status === 'INVALID') { + {{getErrorMessage('aeronef')}} + } + + + Imatriculation + + + @for (option of filteredOptions.imats | async; track option) { + {{option.aeronef}} - {{option.imat}} + } + + @if (this.jumpForm.controls['imat'].status === 'INVALID') { + {{getErrorMessage('imat')}} + } + +

Voile

+ + Modèle + + + @for (option of filteredOptions.canopies | async; track option) { + {{option.voile}} - {{option.taille}} + } + + @if (this.jumpForm.controls['voile'].status === 'INVALID') { + {{getErrorMessage('voile')}} + } + + + Taille en ft2 + + + @for (option of filteredOptions.tailles | async; track option) { + {{option.voile}} - {{option.taille}} + } + + ft2 + @if (this.jumpForm.controls['taille'].status === 'INVALID') { + {{getErrorMessage('taille')}} + } + +
+
+

Altitude

+ + Hauteur de largage + + @if (this.jumpForm.controls['hauteur'].status === 'INVALID') { + {{getErrorMessage('hauteur')}} + } + + + Hauteur de déploiement + + @if (this.jumpForm.controls['deploiement'].status === 'INVALID') { + {{getErrorMessage('deploiement')}} + } + +

Discipline

+ + Categorie + + + @for (option of filteredOptions.categories | async; track option) { + {{option.categorie}}{{option.categorie && option.module ? ' - ' : ''}}{{option.module}} + } + + @if (this.jumpForm.controls['categorie'].status === 'INVALID') { + {{getErrorMessage('categorie')}} + } + + + Module + + + @for (option of filteredOptions.modules | async; track option) { + {{option.categorie}}{{option.categorie && option.module ? ' - ' : ''}}{{option.module}} + } + + @if (this.jumpForm.controls['module'].status === 'INVALID') { + {{getErrorMessage('module')}} + } + +

Divers

+ + Accessoires + + @if (this.jumpForm.controls['accessoires'].status === 'INVALID') { + {{getErrorMessage('accessoires')}} + } + + + Zone + + @if (this.jumpForm.controls['zone'].status === 'INVALID') { + {{getErrorMessage('zone')}} + } + +
+
+

Groupe

+ + Sautants + + + + Nombre de participants + + @if (this.jumpForm.controls['participants'].status === 'INVALID') { + {{getErrorMessage('participants')}} + } + +
+ @for (sautant of jump.sautants; track sautant) { + + + {{ sautant }} + + } + + + {{ jump.author.username }} + +
+
+
+

Programme

+ + Programme + + @if (this.jumpForm.controls['programme'].status === 'INVALID') { + {{getErrorMessage('programme')}} + } + +

Vidéo

+ + Dossier + + @if (this.jumpForm.controls['dossier'].status === 'INVALID') { + {{getErrorMessage('dossier')}} + } + + + Video + + @if (this.jumpForm.controls['video'].status === 'INVALID') { + {{getErrorMessage('video')}} + } + +
+
+
+
+ + + + + diff --git a/src/app/components/logbook/dialogs/jump-edit.dialog.ts b/src/app/components/logbook/dialogs/jump-edit.dialog.ts new file mode 100644 index 0000000..fefb7ea --- /dev/null +++ b/src/app/components/logbook/dialogs/jump-edit.dialog.ts @@ -0,0 +1,407 @@ +import { Component, Inject, OnDestroy } from '@angular/core'; +import { AsyncPipe, DatePipe } from '@angular/common'; +import { FormBuilder, FormControl, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; +import { MatAutocompleteModule } from '@angular/material/autocomplete'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatDatepickerModule } from '@angular/material/datepicker'; +import { MatDialogRef, MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog'; +import { MatIconModule } from '@angular/material/icon'; +import { MatInputModule } from '@angular/material/input'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatOptionModule } from '@angular/material/core'; +import { MatSelectModule } from '@angular/material/select'; +import { Observable, Subscription } from 'rxjs'; +import { map, startWith } from 'rxjs/operators'; + +import { AeronefByImat, CanopyModelBySize, DropZoneByOaci, Jump, JumpByModule } from '@models'; +import { AeronefsService, CanopiesService, DropZonesService, JumpsService } from '@services'; + +@Component({ + selector: 'app-jump-edit-dialog', + templateUrl: 'jump-edit.dialog.html', + standalone: true, + imports: [ + AsyncPipe, + DatePipe, + FormsModule, + ReactiveFormsModule, + MatAutocompleteModule, + MatButtonModule, + MatCheckboxModule, + MatDatepickerModule, + MatDialogModule, + MatFormFieldModule, + MatIconModule, + MatInputModule, + MatSelectModule, + MatOptionModule +] +}) +export class JumpEditDialogComponent implements OnDestroy { + private _aeronefByImat: Subscription = new Subscription(); + private _canopyModelBySize: Subscription = new Subscription(); + private _dropZoneByOaci: Subscription = new Subscription(); + private _jumpByModule: Subscription = new Subscription(); + public tagField = new FormControl('', { nonNullable: true}); + public jumpForm: FormGroup; + public inputOptions: { + aeronefs: Array; + canopies: Array; + dropzones: Array; + categories: Array; + }; + public filteredOptions: { + aeronefs: Observable>; + imats: Observable>; + canopies: Observable>; + tailles: Observable>; + dropzones: Observable>; + oaci: Observable>; + categories: Observable>; + modules: Observable>; + }; + + constructor( + public dialogRef: MatDialogRef, + private fb: FormBuilder, + private _aeronefsService: AeronefsService, + private _canopiesService: CanopiesService, + private _dropZonesService: DropZonesService, + private _jumpsService: JumpsService, + @Inject(MAT_DIALOG_DATA) public jump: Jump + ) { + this.inputOptions = { aeronefs: [], canopies: [], dropzones: [], categories: [] }; + const controlsConfig = { + slug: [this.jump.slug, Validators.required], + date: [this.jump.date, Validators.required], + numero: [this.jump.numero, Validators.required], + lieu: [this.jump.lieu, Validators.required], + oaci: this.jump.oaci, + aeronef: [this.jump.aeronef, Validators.required], + imat: this.jump.imat, + hauteur: [this.jump.hauteur, Validators.required], + deploiement: this.jump.deploiement, + voile: this.jump.voile, + taille: [this.jump.taille?.toString(), Validators.required], + categorie: this.jump.categorie, + module: this.jump.module, + participants: [this.jump.participants, Validators.required], + programme: this.jump.programme, + accessoires: this.jump.accessoires, + zone: this.jump.zone, + dossier: this.jump.dossier, + video: this.jump.video + }; + this.jumpForm = this.fb.group(controlsConfig); + + this.filteredOptions = { + aeronefs: this.jumpForm.controls['aeronef'].valueChanges.pipe( + startWith(''), + map(value => { + const aeronef = typeof value === 'string' ? value : value?.aeronef; + return aeronef ? this._filterImat(aeronef as string) : this.inputOptions.aeronefs.slice(); + }), + ), + imats: this.jumpForm.controls['imat'].valueChanges.pipe( + startWith(''), + map(value => { + const imat = typeof value === 'string' ? value : value?.imat; + return imat ? this._filterImat(imat as string) : this.inputOptions.aeronefs.slice(); + }), + ), + canopies: this.jumpForm.controls['voile'].valueChanges.pipe( + startWith(''), + map(value => { + const voile = typeof value === 'string' ? value : value?.voile; + return voile ? this._filterTaille(voile as string) : this.inputOptions.canopies.slice(); + }), + ), + tailles: this.jumpForm.controls['taille'].valueChanges.pipe( + startWith(''), + map(value => { + const taille = typeof value === 'string' ? value : value?.taille.toString(); + return taille ? this._filterTaille(taille as string) : this.inputOptions.canopies.slice(); + }), + ), + dropzones: this.jumpForm.controls['lieu'].valueChanges.pipe( + startWith(''), + map(value => { + const lieu = typeof value === 'string' ? value : value?.lieu; + return lieu ? this._filterOaci(lieu as string) : this.inputOptions.dropzones.slice(); + }), + ), + oaci: this.jumpForm.controls['oaci'].valueChanges.pipe( + startWith(''), + map(value => { + const oaci = typeof value === 'string' ? value : value?.oaci; + return oaci ? this._filterOaci(oaci as string) : this.inputOptions.dropzones.slice(); + }), + ), + categories: this.jumpForm.controls['categorie'].valueChanges.pipe( + startWith(''), + map(value => { + const category = typeof value === 'string' ? value : value?.categorie; + return category ? this._filterModule(category as string) : this.inputOptions.categories.slice(); + }), + ), + modules: this.jumpForm.controls['module'].valueChanges.pipe( + startWith(''), + map(value => { + const module = typeof value === 'string' ? value : value?.module; + return module ? this._filterModule(module as string) : this.inputOptions.categories.slice(); + }), + ) + }; + this._loadAeronefByImat(); + this._loadCanopyModelBySize(); + this._loadDropZoneByOaci(); + this._loadJumpByModule(); + } + + ngOnDestroy() { + this._aeronefByImat.unsubscribe(); + this._canopyModelBySize.unsubscribe(); + this._dropZoneByOaci.unsubscribe(); + this._jumpByModule.unsubscribe(); + } + + private _filterImat(imat: string): Array { + const filterValue = imat.toLowerCase(); + return this.inputOptions.aeronefs.filter(option => (option.aeronef.toLowerCase().includes(filterValue) || option.imat.toLowerCase().includes(filterValue))); + } + + private _filterModule(module: string): Array { + const filterValue = module.toLowerCase(); + return this.inputOptions.categories.filter(option => (option.categorie.toLowerCase().includes(filterValue) || option.module.toLowerCase().includes(filterValue))); + } + + private _filterOaci(oaci: string): Array { + const filterValue = oaci.toLowerCase(); + return this.inputOptions.dropzones.filter(option => (option.lieu.toLowerCase().includes(filterValue) || option.oaci.toLowerCase().includes(filterValue))); + } + + private _filterTaille(taille: string): Array { + const filterValue = taille.toLowerCase(); + return this.inputOptions.canopies.filter(option => (option.voile.toLowerCase().includes(filterValue) || option.taille.toString().includes(filterValue))); + } + + private _loadAeronefByImat(): void { + const aeronefs$ = this._aeronefsService.getAllByImat(); + this._aeronefByImat = aeronefs$.subscribe((aggregate: Array) => { + this.inputOptions.aeronefs = aggregate; + }); + } + + private _loadCanopyModelBySize(): void { + const canopies$ = this._canopiesService.getAllBySizeByModel(); + this._canopyModelBySize = canopies$.subscribe((aggregate: Array) => { + this.inputOptions.canopies = aggregate; + }); + } + + private _loadDropZoneByOaci(): void { + const dropzones$ = this._dropZonesService.getAllByOaci(); + this._dropZoneByOaci = dropzones$.subscribe((aggregate: Array) => { + this.inputOptions.dropzones = aggregate; + }); + } + + private _loadJumpByModule(): void { + const jumps$ = this._jumpsService.getAllByModule(); + this._jumpByModule = jumps$.subscribe((aggregate: Array) => { + this.inputOptions.categories = aggregate; + }); + } + + addSautant(): void { + const tag = this.tagField.value; + if (tag != null && tag.trim() !== '' && this.jump.sautants.indexOf(tag) < 0) { + this.jump.sautants.push(tag); + } + const participants = (this.jump.sautants.length + 1); + this.jumpForm.controls['participants'].setValue(participants); + this.tagField.reset(''); + } + + closeDialog(): void { + // close the dialog without result + this.dialogRef.close(); + } + + displayAeronefFn(aeronef: AeronefByImat): string { + let res = ''; + if (aeronef) { + if (typeof aeronef === 'string') { + res = aeronef; + } else { + res = aeronef.aeronef ? aeronef.aeronef : ''; + } + } + return res; + } + + displayImatFn(aeronef: AeronefByImat): string { + let res = ''; + if (aeronef) { + if (typeof aeronef === 'string') { + res = aeronef; + } else { + res = aeronef.imat ? aeronef.imat : ''; + } + } + return res; + } + + displayLieuFn(dropzone: DropZoneByOaci): string { + let res = ''; + if (dropzone) { + if (typeof dropzone === 'string') { + res = dropzone; + } else { + res = dropzone.lieu ? dropzone.lieu : ''; + } + } + return res; + } + + displayOaciFn(dropzone: DropZoneByOaci): string { + let res = ''; + if (dropzone) { + if (typeof dropzone === 'string') { + res = dropzone; + } else { + res = dropzone.oaci ? dropzone.oaci : ''; + } + } + return res; + } + + displayTailleFn(canopy: CanopyModelBySize): string { + let res = ''; + if (canopy) { + if (typeof canopy === 'string') { + res = canopy; + } else { + res = canopy.taille ? canopy.taille.toString() : ''; + } + } + return res; + } + + displayVoileFn(canopy: CanopyModelBySize): string { + let res = ''; + if (canopy) { + if (typeof canopy === 'string') { + res = canopy; + } else { + res = canopy.voile ? canopy.voile : ''; + } + } + return res; + } + + displayCategorieFn(jump: JumpByModule): string { + let res = ''; + if (jump) { + if (typeof jump === 'string') { + res = jump; + } else { + res = jump.categorie ? jump.categorie : ''; + } + } + return res; + } + + displayModuleFn(jump: JumpByModule): string { + let res = ''; + if (jump) { + if (typeof jump === 'string') { + res = jump; + } else { + res = jump.module ? jump.module : ''; + } + } + return res; + } + + getErrorMessage(name: string): string { + if (this.jumpForm.controls[name].errors !== null) { + return `Ce champ est requis.`; + } + return ''; + } + + onSelAeronef(aeronef: AeronefByImat) { + if (aeronef && aeronef.aeronef) { + this.jumpForm.controls['imat'].setValue(aeronef); + } + } + + onSelImat(aeronef: AeronefByImat) { + if (aeronef && aeronef.imat) { + this.jumpForm.controls['aeronef'].setValue(aeronef); + } + } + + onSelLieu(dropzone: DropZoneByOaci) { + if (dropzone && dropzone.oaci) { + this.jumpForm.controls['oaci'].setValue(dropzone); + } + } + + onSelOaci(dropzone: DropZoneByOaci) { + if (dropzone && dropzone.lieu) { + this.jumpForm.controls['lieu'].setValue(dropzone); + } + } + + onSelTaille(canopy: CanopyModelBySize) { + if (canopy && canopy.voile) { + this.jumpForm.controls['voile'].setValue(canopy); + } + } + + onSelVoile(canopy: CanopyModelBySize) { + if (canopy && canopy.taille) { + this.jumpForm.controls['taille'].setValue(canopy); + } + } + + onSelCategorie(jump: JumpByModule) { + if (jump && jump.categorie) { + this.jumpForm.controls['module'].setValue(jump); + } + } + + onSelModule(jump: JumpByModule) { + if (jump && jump.module) { + this.jumpForm.controls['categorie'].setValue(jump); + } + } + + removeSautant(index: string): void { + this.jump.sautants = this.jump.sautants.filter((sautant) => sautant !== index); + const participants = (this.jump.sautants.length + 1); + this.jumpForm.controls['participants'].setValue(participants); + } + + submitForm(): void { + // update the model + this.updateJump(this.jumpForm.value); + this.jump.lieu = typeof this.jumpForm.controls['lieu'].value === 'string' ? this.jumpForm.controls['lieu'].value : this.jumpForm.controls['lieu'].value.lieu; + this.jump.oaci = typeof this.jumpForm.controls['oaci'].value === 'string' ? this.jumpForm.controls['oaci'].value : this.jumpForm.controls['oaci'].value.oaci; + this.jump.aeronef = typeof this.jumpForm.controls['aeronef'].value === 'string' ? this.jumpForm.controls['aeronef'].value : this.jumpForm.controls['aeronef'].value.aeronef; + this.jump.imat = typeof this.jumpForm.controls['imat'].value === 'string' ? this.jumpForm.controls['imat'].value : this.jumpForm.controls['imat'].value.imat; + this.jump.voile = typeof this.jumpForm.controls['voile'].value === 'string' ? this.jumpForm.controls['voile'].value : this.jumpForm.controls['voile'].value.voile; + this.jump.taille = typeof this.jumpForm.controls['taille'].value === 'string' ? this.jumpForm.controls['taille'].value : this.jumpForm.controls['taille'].value.taille; + this.jump.categorie = typeof this.jumpForm.controls['categorie'].value === 'string' ? this.jumpForm.controls['categorie'].value : this.jumpForm.controls['categorie'].value.categorie; + this.jump.module = typeof this.jumpForm.controls['module'].value === 'string' ? this.jumpForm.controls['module'].value : this.jumpForm.controls['module'].value.module; + // close the dialog with result + this.dialogRef.close(this.jump); + } + + updateJump(values: NonNullable): void { + Object.assign(this.jump, values); + } +} diff --git a/src/app/components/logbook/dialogs/jump-view.dialog.html b/src/app/components/logbook/dialogs/jump-view.dialog.html new file mode 100644 index 0000000..ac1ebe6 --- /dev/null +++ b/src/app/components/logbook/dialogs/jump-view.dialog.html @@ -0,0 +1,214 @@ +

+ Saut n° {{jump.numero}} + +

+ +
+
+
+
Le {{ jump.date | date: 'dd/MM/yyyy' }} à {{ jump.lieu }} {{ jump.zone ? jump.zone : jump.oaci }} :
+
+ +
+ {{ jump.categorie }} + @if (jump.module) { + / + {{ jump.module }} + } +
+
+
+
+
+
Aeronef:
+
{{ jump.aeronef }} {{ jump.imat }}
+
Voile:
+
{{ jump.voile }} {{ jump.taille }} ft2
+ @if (jump.programme) { +
Programme:
+
{{ jump.programme }}
+ } +
+
+
+
+ @if (!jump.x2data) { +
Hauteur:
+
{{ jump.hauteur }} m
+
Déploiement:
+
{{ jump.deploiement }} m
+ } + @for (file of jump.files; track file) { +
Fichier {{ file.type }}
+
{{ file.name }}
+ } +
+
+
+ + @if (jump.x2data) { +
+
+
Hauteur
+ {{ jump.x2data.altitude.exit }} m +
+
+
Durée de la chute
+ {{formatDuration(jump.x2data.duration.freeFall)}} +
+
+
Déploiement
+ {{ jump.x2data.altitude.deployment }} m +
+
+
+
+
Participants ({{ jump.sautants.length + 1 }})
+ @for (sautant of jump.sautants; track sautant) { + + + {{ sautant }} + + } + + + {{ jump.author.username }} + +
+ @if (jump.accessoires) { +
+
Accessoires
+ + + {{ jump.accessoires }} + +
+ } +
+ +
+
+
Vitesse en chute
+
+
+
Max Verticale
+ {{ (jump.x2data.speed.freeFall.vertical.max / 1000 * 60 * 60) | number : '1.0-0' }} km/h +
+
+
Max Horizontale
+ {{ (jump.x2data.speed.freeFall.horizontal.max / 1000 * 60 * 60) | number : '1.0-0' }} km/h +
+
+
Moyenne Verticale
+ {{ (jump.x2data.speed.freeFall.vertical.avg / 1000 * 60 * 60) | number : '1.0-0' }} km/h +
+
+
Moyenne Horizontale
+ {{ (jump.x2data.speed.freeFall.horizontal.avg / 1000 * 60 * 60) | number : '1.0-0' }} km/h +
+
+ + +
+
+
Vitesse sous voile
+
+
+
Max Verticale
+ {{ (jump.x2data.speed.underCanopy.vertical.max / 1000 * 60 * 60) | number : '1.0-0' }} km/h +
+
+
Max Horizontale
+ {{ (jump.x2data.speed.underCanopy.horizontal.max / 1000 * 60 * 60) | number : '1.0-0' }} km/h +
+
+
Moyenne Verticale
+ {{ (jump.x2data.speed.underCanopy.vertical.avg / 1000 * 60 * 60) | number : '1.0-0' }} km/h +
+
+
Moyenne Horizontale
+ {{ (jump.x2data.speed.underCanopy.horizontal.avg / 1000 * 60 * 60) | number : '1.0-0' }} km/h +
+
+ + +
+
+
Finesse
+
+
+
Finesse en chute
+
+
+
Finesse sous voile
+
+
+
+
+
Finesse Max
+ {{ jump.x2data.glideRatio.freeFall.max | number : '1.2-2' }} +
+
+
Finesse Moyenne
+ {{ jump.x2data.glideRatio.freeFall.avg | number : '1.2-2' }} +
+
+
Finesse Max
+ {{ jump.x2data.glideRatio.underCanopy.max | number : '1.2-2' }} +
+
+
Finesse Moyenne
+ {{ jump.x2data.glideRatio.underCanopy.avg | number : '1.2-2' }} +
+
+ + +
+
+
Distance
+
+
+
Distance au largage
+ {{ jump.x2data.distance.exitFromLandingZone| number : '1.0-0' }} m +
+
+
Durée sous voile
+ {{formatDuration(jump.x2data.duration.underCanopy)}} +
+
+
Distance totale
+ {{ jump.x2data.distance.totalFlying | number : '1.0-0' }} m +
+
+
Distance horizontale
+ {{ jump.x2data.distance.totalHorizontal | number : '1.0-0' }} m +
+
+ + } + @else { +
+
+
Participants ({{ jump.sautants.length + 1 }})
+ @for (sautant of jump.sautants; track sautant) { + + + {{ sautant }} + + } + + + {{ jump.author.username }} + +
+
+ +
Aucune donnée GPS
+ + } +
+
+ + + + diff --git a/src/app/components/logbook/dialogs/jump-view.dialog.ts b/src/app/components/logbook/dialogs/jump-view.dialog.ts new file mode 100644 index 0000000..8d9d1f6 --- /dev/null +++ b/src/app/components/logbook/dialogs/jump-view.dialog.ts @@ -0,0 +1,37 @@ +import { Component, Inject } from '@angular/core'; +import { DatePipe, DecimalPipe } from '@angular/common'; +import { MatButtonModule } from '@angular/material/button'; +import { MatDialogRef, MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatIconModule } from '@angular/material/icon'; + +import { Jump } from '@models'; + +@Component({ + selector: 'app-jump-view-dialog', + templateUrl: 'jump-view.dialog.html', + standalone: true, + imports: [ + DatePipe, DecimalPipe, + MatButtonModule, MatDialogModule, + MatDividerModule, MatIconModule +] +}) +export class JumpViewDialogComponent { + + constructor( + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public jump: Jump + ) { } + + closeDialog(): void { + // close the dialog without result + this.dialogRef.close(); + } + + formatDuration(duration: number): string { + const start = new Date(0); + start.setSeconds(duration); + return start.toISOString().substring(14, 19); + } +} diff --git a/src/app/components/logbook/logbook.component.html b/src/app/components/logbook/logbook.component.html new file mode 100644 index 0000000..7e74c37 --- /dev/null +++ b/src/app/components/logbook/logbook.component.html @@ -0,0 +1,105 @@ +
+
+
+

{{title}}

+ + Dernier saut enregistré : {{ lastJump.numero }}ème à {{ lastJump.lieu }} le {{ lastJump.date | date: 'dd/MM/yyyy' }} + +
+ +
+ + + + + @for (menuitem of menuItems.getMenuLogbook(); track menuitem) { + @if (menuitem.type === 'link') { + + } + } + +
+
+ + @if (jumpsToHundred() <= 20) { +
+ + +
+ {{ lastJump.numero + jumpsToHundred() }}ème à venir dans {{ jumpsToHundred() }} + {{ jumpsToHundred() > 1 ? 'sauts' : 'saut' }} +
+
+ } + + + + + Filtrer les sauts + @if (jumpsCount < lastJump.numero) { + + {{ jumpsCount }} {{ jumpsCount > 1 ? 'sauts' : 'saut' }} sur {{ lastJump.numero }} correspondent à la recherche + + } + +
+
+
+ + +
+ + + + +
+
+
+ + +
+ + + + +
+
+
+ + +
+ + + + +
+
+
+ + +
+ + + + +
+ +
+
+
+ + + + +
+
\ No newline at end of file diff --git a/src/app/components/logbook/logbook.component.scss b/src/app/components/logbook/logbook.component.scss new file mode 100644 index 0000000..a9c65b0 --- /dev/null +++ b/src/app/components/logbook/logbook.component.scss @@ -0,0 +1,11 @@ +.mat-expansion-panel { + border-bottom-right-radius: initial; + border-bottom-left-radius: initial; +} +.mat-mdc-slider { + max-width: 300px; + width: 100%; +} +.label-container { + max-width: 284px; +} \ No newline at end of file diff --git a/src/app/components/logbook/logbook.component.spec.ts b/src/app/components/logbook/logbook.component.spec.ts new file mode 100644 index 0000000..a7ac751 --- /dev/null +++ b/src/app/components/logbook/logbook.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { LogbookComponent } from './logbook.component'; + +describe('LogbookComponent', () => { + let component: LogbookComponent; + let fixture: ComponentFixture; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [LogbookComponent] +}); + fixture = TestBed.createComponent(LogbookComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/logbook/logbook.component.ts b/src/app/components/logbook/logbook.component.ts new file mode 100644 index 0000000..a989bc0 --- /dev/null +++ b/src/app/components/logbook/logbook.component.ts @@ -0,0 +1,399 @@ +import { CommonModule } from '@angular/common'; +import { trigger, state, style, animate, transition } from '@angular/animations'; +import { Component, AfterContentChecked, OnInit, OnDestroy, computed, signal, Signal } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { ActivatedRoute, Router, RouterModule } from '@angular/router'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatDialog, MatDialogModule } from '@angular/material/dialog'; +import { MatExpansionModule } from '@angular/material/expansion'; +import { MatIconModule } from '@angular/material/icon'; +import { MatInputModule } from '@angular/material/input'; +import { MatMenuModule } from '@angular/material/menu'; +import { MatSliderModule } from '@angular/material/slider'; +import { MatSnackBar, MatSnackBarConfig, MatSnackBarHorizontalPosition, MatSnackBarModule, MatSnackBarVerticalPosition } from '@angular/material/snack-bar'; +import { Observable, Subscription } from 'rxjs'; +import { take } from 'rxjs/operators'; + +import { JumpAddDialogComponent } from '@components/logbook/dialogs'; +import { MenuItems, JumpTableComponent } from '@components/shared'; +import { Errors, Jump, JumpFile, JumpFileType, JumpListConfig, Range, User, X2Data } from '@models'; +import { JumpsService, JumpTableService, UserService } from '@services'; +import data from 'src/jumps.json'; +//import data from 'src/jumps_02.json'; + +@Component({ + standalone: true, + imports: [ + CommonModule, RouterModule, FormsModule, + MatButtonModule, MatCardModule, MatDividerModule, MatExpansionModule, + MatIconModule, MatInputModule, MatMenuModule, MatDialogModule, + MatSliderModule, MatSnackBarModule, + JumpTableComponent + ], + selector: 'app-logbook', + templateUrl: './logbook.component.html', + styleUrl: './logbook.component.scss', + animations: [ + trigger('flyInOut', [ + state('in', style({ transform: 'translateY(0)' })), + transition('void => *', [ + style({ transform: 'translateY(-100%)' }), + animate(200) + ]), + transition('* => void', [ + style({ transform: 'translateY(100%)' }), + animate(200) + ]) + ]) + ] +}) +export class LogbookComponent implements OnInit, OnDestroy, AfterContentChecked { + private _currentUser: Subscription = new Subscription(); + private _subscriptions: Array = []; + private _data: Subscription = new Subscription(); + private _lastjump: Subscription = new Subscription(); + private _lastjump$: Observable = new Observable(); + public jumpsCount = 0; + public errors!: Errors; + public title = 'Carnet de sauts'; + public jump: Jump = {} as Jump; + public lastJump: Jump = {} as Jump; + public currentUser: User = {} as User; + public listConfig: JumpListConfig = { type: 'all', filters: {} }; + public isAuthenticated = false; + public isUser = true; + public canModify = false; + public isSubmitting = false; + public tableRefresh = false; + public jumpRefresh = false; + public jumpsSinceHundred: Signal = signal(0); + public jumpsToHundred: Signal = signal(100); + public rangesMinMax: { + numero: Range; + taille: Range; + participants: Range; + hauteur: Range; + year: Range; + } = { + numero: {start: 1, end: 100000}, + taille: {start: 1, end: 400}, + participants: {start: 1, end: 200}, + hauteur: {start: 0, end: 10000}, + year: {start: 1970, end: 2020} + }; + + constructor( + private route: ActivatedRoute, + private router: Router, + private dialog: MatDialog, + private snackBar: MatSnackBar, + private _jumpsService: JumpsService, + private _jumpTableService: JumpTableService, + private _userService: UserService, + public menuItems: MenuItems + ) { } + + ngOnInit() { + //this.importJumps(); + const data$: Observable<{isAuthenticated: boolean, lastjump: Jump}> = this.route.data as Observable<{isAuthenticated: boolean, lastjump: Jump}>; + this._data = data$.subscribe((data: {isAuthenticated: boolean, lastjump: Jump}) => { + this.isAuthenticated = data.isAuthenticated; + if (!this.isAuthenticated) { + this.router.navigateByUrl('/login'); + return; + } + + const currentUser$: Observable = this._userService.currentUser; + this._currentUser = currentUser$.subscribe((userData: User) => { + this.currentUser = userData; + this.canModify = this.currentUser.role === 'Admin'; + }); + + const currentYear: number = new Date().getFullYear(); + this.lastJump = data['lastjump']; + this.rangesMinMax = { + numero: {start: 1, end: data.lastjump.numero}, + taille: {start: data.lastjump.taille!, end: 230}, + participants: {start: 1, end: 20}, + hauteur: {start: 1000, end: 8000}, + year: {start: 2018, end: currentYear} + } + this.listConfig.filters.numeroRangeStart = this.rangesMinMax.numero.start; + this.listConfig.filters.numeroRangeEnd = this.rangesMinMax.numero.end; + this.listConfig.filters.tailleRangeStart = this.rangesMinMax.taille.start; + this.listConfig.filters.tailleRangeEnd = this.rangesMinMax.taille.end; + this.listConfig.filters.participantsRangeStart = this.rangesMinMax.participants.start; + this.listConfig.filters.participantsRangeEnd = (this.rangesMinMax.participants.end / 2); + this.listConfig.filters.hauteurRangeStart = this.rangesMinMax.hauteur.start; + this.listConfig.filters.hauteurRangeEnd = this.rangesMinMax.hauteur.end; + this.listConfig.filters.yearRangeStart = this.rangesMinMax.year.start; + this.listConfig.filters.yearRangeEnd = this.rangesMinMax.year.end; + this.jumpsSinceHundred = computed(() => (this.lastJump.numero % 100)); + this.jumpsToHundred = computed(() => (100 - this.jumpsSinceHundred())); + /* + this._lastjump$ = this._jumpsService.getLastJump(); + this._lastjump = this._lastjump$.subscribe((jump) => { + const currentYear: number = new Date().getFullYear(); + this.lastJump = jump; + this.rangesMinMax = { + numero: {start: 1, end: jump.numero}, + taille: {start: jump.taille!, end: 230}, + participants: {start: 1, end: 20}, + hauteur: {start: 1000, end: 8000}, + year: {start: 2018, end: currentYear} + } + this.listConfig.filters.numeroRangeStart = this.rangesMinMax.numero.start; + this.listConfig.filters.numeroRangeEnd = this.rangesMinMax.numero.end; + this.listConfig.filters.tailleRangeStart = this.rangesMinMax.taille.start; + this.listConfig.filters.tailleRangeEnd = this.rangesMinMax.taille.end; + this.listConfig.filters.participantsRangeStart = this.rangesMinMax.participants.start; + this.listConfig.filters.participantsRangeEnd = (this.rangesMinMax.participants.end / 2); + this.listConfig.filters.hauteurRangeStart = this.rangesMinMax.hauteur.start; + this.listConfig.filters.hauteurRangeEnd = this.rangesMinMax.hauteur.end; + this.listConfig.filters.yearRangeStart = this.rangesMinMax.year.start; + this.listConfig.filters.yearRangeEnd = this.rangesMinMax.year.end; + this.jumpsSinceHundred = computed(() => (this.lastJump.numero % 100)); + this.jumpsToHundred = computed(() => (100 - this.jumpsSinceHundred())); + }); + */ + }); + } + + ngOnDestroy() { + this._data.unsubscribe(); + this._currentUser.unsubscribe(); + this._lastjump.unsubscribe(); + this._subscriptions.forEach(subscription => { + subscription.unsubscribe(); + }); + } + + ngAfterContentChecked() { + if (this.tableRefresh != this._jumpTableService.tableRefresh) { + this.tableRefresh = this._jumpTableService.tableRefresh; + this._lastjump$ = this._jumpsService.getLastJump(); + this._lastjump = this._lastjump$.subscribe((jump) => { + this.lastJump = jump; + }); + console.log('lastjump has been updated in logbook component'); + } + } + + importJumps() { + try { + data.forEach((entry) => { + Object.assign(this.jump, entry); + this._jumpsService.save(this.jump) + .pipe(take(1)) + .subscribe({ + next: (jump) => { + console.log(`Le saut n°${jump.numero} a été ajouté !`, 'OK'); + }, + error: (err) => { + console.log(`Le saut n'a pas été ajouté !`, 'Error', err); + this.errors = err; + } + }); + }); + } catch (error) { + console.error(error); + } + } + + openAddDialog(): void { + this.jump = {}; + this.jump.numero = (this.lastJump.numero + 1); + this.jump.sautants = []; + this.jump.participants = 1; + const dialogRef = this.dialog.open(JumpAddDialogComponent, { + width: '70vw', + data: {jump: this.jump, lastJump: this.lastJump} + }); + dialogRef.afterClosed().pipe(take(1)) + .subscribe(result => { + if (result != undefined) { + this._onEntry(result); + } + }); + } + + setTotalResults(value: number): void { + this.jumpsCount = value; + } + + private _loadSkydiverIdJumps(jumps: Array) { + const config: JumpListConfig = { type: 'all', filters: {} } as JumpListConfig; + config.filters.limit = 200; + config.filters.offset = 0; + config.filters.dateRangeStart = `${jumps[0].date!.substring(0, 10)} 00:00:00`; + config.filters.dateRangeEnd = `${jumps[0].date!.substring(0, 10)} 23:59:59`; + const subscription: Subscription = this._jumpsService.getAllFromSkydiverIdApi(config) + .pipe(take(1)) + .subscribe({ + next: (data) => { + if (data.items.length) { + const diff = jumps.length - data.items.length; + if (diff < 0) { + console.error(`${diff} ${diff > 1 ? 'données' : 'donnée'} altimètre de trop le ${jumps[0].date!.substring(0, 10)}`); + } + if (diff > 0) { + console.error(`${diff}/${jumps.length} ${diff > 1 ? 'données altimètre manquantes' : 'donnée altimètre manquante'} le ${jumps[0].date!.substring(0, 10)}`, jumps, data.items); + } + console.log(`${jumps.length} ${jumps.length > 1 ? 'sauts' : 'saut'} le ${data.items[0].date!.substring(0, 10)}`, jumps.sort((a, b) => b.numero! - a.numero!), data.items); + this._addX2Data(data.items, jumps); + } else { + console.info('Aucune données altimètre pour le ', jumps[0].date!.substring(0, 10)); + } + }, + error: (err) => { + console.error('getAllFromSkydiverIdApi error'); + this.errors = err; + } + }); + this._subscriptions.push(subscription); + } + + private _addJump(jumps: Array, index: number = 0) { + this._jumpsService.save(jumps[index]) + .pipe(take(1)) + .subscribe({ + next: (jump) => { + jumps[index] = jump; + console.log('Ajout du saut', jump.numero); + Object.assign(this.jump, jump); + this._openSnackBar(`Le saut n°${jump.numero} a été ajouté !`, 'Annuler'); + this._resetErrors(); + if (jumps.length == (index + 1)) { + this._loadSkydiverIdJumps(jumps); + } else { + this._addJump(jumps, (index + 1)); + } + }, + error: (err) => { + this.errors = err; + this.isSubmitting = false; + } + }); + } + + private _addX2Data(x2data: Array, jumps: Array, index: number = 0) { + const file: JumpFile = { + name: x2data[index].name, + path: `/Volumes/Storage/Skydive/X2_Logs/${x2data[index].date!.substring(0, 4)}/`, + type: JumpFileType.CSV + } as JumpFile; + this._subscriptions.push( + this._jumpsService.saveX2Data(jumps[index].slug!, file, x2data[index]) + .pipe(take(1)) + .subscribe({ + next: (jump) => { + jumps[index] = jump; + console.log(`Le fichier ${file.name} a été ajouté au saut n°${jump.numero} !`, 'OK'); + if (jumps.length == (index + 1) || x2data.length == (index + 1)) { + this._addKmlFile(jumps); + } else { + this._addX2Data(x2data, jumps, (index + 1)); + } + + }, + error: (err) => { + this.errors = err; + } + }) + ); + } + + private _addKmlFile(jumps: Array, index: number = 0) { + if (jumps[index].x2data !== null) { + //console.log(`Le fichier ${jump.x2data.name} existe pour le saut n°${jump.numero} !`, `https://skydiver.id/api/jump/${jump.x2data.id}/kml`); + const file: JumpFile = { + name: jumps[index].x2data.name.substring(0, -4) + '.kml', + path: `/Volumes/Storage/Skydive/X2_Kmls/${jumps[index].date.substring(0, 4)}/`, + type: JumpFileType.KML + } as JumpFile; + this._subscriptions.push( + this._jumpsService.saveKml(jumps[index].slug, file) + .pipe(take(1)) + .subscribe({ + next: (file) => { + console.log(`Le fichier ${file.path}${file.name} a été ajouté au saut n°${jumps[index].numero} !`, 'OK'); + if (jumps.length == (index + 1)) { + this._resetErrors(); + this.jumpRefresh = !this.jumpRefresh; + this._jumpTableService.updateJumpRefresh(this.jumpRefresh); + this._lastjump$ = this._jumpsService.getLastJump(); + this._lastjump = this._lastjump$.subscribe((jump) => { + this.lastJump = jump; + }); + } else { + this._addKmlFile(jumps, (index + 1)); + } + }, + error: (err) => { + this.errors = err; + } + }) + ); + } + } + + private _onEntry(jumps: Array): void { + if (jumps.length) { + this._addJump(jumps); + } + } + + /* + private _onEntry(jumps: Array): void { + const max: number = jumps.length; + let refresh: boolean = false; + jumps.forEach((jump: Jump, index: number) => { + console.log('Ajout du saut', jump.numero); + Object.assign(this.jump, jump); + if (max == index+1) { + refresh = true; + } + this._saveJump(jump, refresh); + }); + } + + private _saveJump(jump: Jump, refresh: boolean) { + this._jumpsService.save(jump) + .pipe(take(1)) + .subscribe({ + next: (jump) => { + this._openSnackBar(`Le saut n°${jump.numero} a été ajouté !`, 'Annuler'); + this._resetErrors(); + if (refresh) { + this.jumpRefresh = !this.jumpRefresh; + this._jumpTableService.updateJumpRefresh(this.jumpRefresh); + this._lastjump$ = this._jumpsService.getLastJump(); + this._lastjump = this._lastjump$.subscribe((jump) => { + this.lastJump = jump; + }); + } + }, + error: (err) => { + this.errors = err; + this.isSubmitting = false; + } + }); + } + */ + + private _openSnackBar(content: string, title: string) { + const config: MatSnackBarConfig = { + horizontalPosition: 'end', + verticalPosition: 'bottom', + duration: 4000 + }; + this.snackBar.open(content, title, config); + } + + private _resetErrors(): void { + this.errors = { errors: {} }; + } + +} diff --git a/src/app/components/page/page.component.html b/src/app/components/page/page.component.html new file mode 100644 index 0000000..098d6db --- /dev/null +++ b/src/app/components/page/page.component.html @@ -0,0 +1,30 @@ +
+
+
+

{{ article.title }}

+
+ +
+ {{ article.createdAt | date: 'dd/MM/yyyy' }} +
+
+ + +
+ {{ article.description }} +
+
+ {{ article.body }} +
+ @if (article.tagList) { + +
+ @for (tag of getArticleTags(); track tag) { + + + {{ tag.name }} + + } +
+ } +
\ No newline at end of file diff --git a/src/app/components/page/page.component.scss b/src/app/components/page/page.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/components/page/page.component.spec.ts b/src/app/components/page/page.component.spec.ts new file mode 100644 index 0000000..c389595 --- /dev/null +++ b/src/app/components/page/page.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PageComponent } from './page.component'; + +describe('PageComponent', () => { + let component: PageComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [PageComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(PageComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/page/page.component.ts b/src/app/components/page/page.component.ts new file mode 100644 index 0000000..7351729 --- /dev/null +++ b/src/app/components/page/page.component.ts @@ -0,0 +1,69 @@ +import { Title } from '@angular/platform-browser'; +import { trigger, state, style, animate, transition } from '@angular/animations'; +import { Component, DestroyRef, inject, OnInit, OnDestroy } from '@angular/core'; +import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; +import { DatePipe } from '@angular/common'; +import { ActivatedRoute, RouterLink } from '@angular/router'; +import { MatCardModule } from '@angular/material/card'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatIconModule } from '@angular/material/icon'; +import { Observable, Subscription } from 'rxjs'; + +import { ListErrorsComponent, } from '@components/shared'; +import { Errors, Article, ArticlePageData } from '@models'; + +@Component({ + selector: 'app-page', + standalone: true, + imports: [ + DatePipe, RouterLink, + MatCardModule, MatDividerModule, MatIconModule, + ListErrorsComponent + ], + templateUrl: './page.component.html', + styleUrl: './page.component.scss', + animations: [ + trigger('flyInOut', [ + state('in', style({ transform: 'translateY(0)' })), + transition('void => *', [ + style({ transform: 'translateY(-100%)' }), + animate(200) + ]), + transition('* => void', [ + style({ transform: 'translateY(100%)' }), + animate(200) + ]) + ]) + ] +}) +export class PageComponent implements OnInit, OnDestroy { + private _data: Subscription = new Subscription(); + public title = 'Shop bientôt disponible!'; + public description = 'Encore un peu de patience, notre shop sera mis en ligne d\'ici peu.'; + public errors: Errors = { errors: {} }; + public destroyRef = inject(DestroyRef); + public article: Article = {} as Article; + + constructor( + private route: ActivatedRoute, + private titleService: Title + ) { } + + ngOnInit() { + const data$: Observable<{ pageData: ArticlePageData }> = this.route.data as Observable<{ pageData: ArticlePageData }>; + this._data = data$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data: { pageData: ArticlePageData }) => { + this.article = data.pageData.article; + this.title = this.article.title; + this.titleService.setTitle(this.article.title); + console.log(this.article); + }); + } + + ngOnDestroy() { + this._data.unsubscribe(); + } + + getArticleTags() { + return this.article.tagList; + } +} diff --git a/src/app/components/pages/pages.component.html b/src/app/components/pages/pages.component.html new file mode 100644 index 0000000..c56369e --- /dev/null +++ b/src/app/components/pages/pages.component.html @@ -0,0 +1 @@ +

pages works!

diff --git a/src/app/components/pages/pages.component.scss b/src/app/components/pages/pages.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/components/pages/pages.component.spec.ts b/src/app/components/pages/pages.component.spec.ts new file mode 100644 index 0000000..f69a6b2 --- /dev/null +++ b/src/app/components/pages/pages.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PagesComponent } from './pages.component'; + +describe('PagesComponent', () => { + let component: PagesComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [PagesComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(PagesComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/pages/pages.component.ts b/src/app/components/pages/pages.component.ts new file mode 100644 index 0000000..874899b --- /dev/null +++ b/src/app/components/pages/pages.component.ts @@ -0,0 +1,12 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-pages', + standalone: true, + imports: [], + templateUrl: './pages.component.html', + styleUrl: './pages.component.scss' +}) +export class PagesComponent { + +} diff --git a/src/app/components/product/product.component.html b/src/app/components/product/product.component.html new file mode 100644 index 0000000..c95517f --- /dev/null +++ b/src/app/components/product/product.component.html @@ -0,0 +1,28 @@ +
+
+
+

{{ product.name }}- Sachet {{ product.weightNet | number : '1.0' }} g

+

{{ (product.priceRetail! * (1 + (product.priceTaxe! / 100))) | number : '1.2-2' }} € TTC

+
+ +
+ {{ product.createdAt | date: 'dd/MM/yyyy' }} +
+
+ + +
+ {{ product.description }} +
+ @if (product.tags) { + +
+ @for (tag of getProductTags(); track tag) { + + + {{ tag.name }} + + } +
+ } +
\ No newline at end of file diff --git a/src/app/components/product/product.component.scss b/src/app/components/product/product.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/components/product/product.component.spec.ts b/src/app/components/product/product.component.spec.ts new file mode 100644 index 0000000..fe69534 --- /dev/null +++ b/src/app/components/product/product.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ProductComponent } from './product.component'; + +describe('ProductComponent', () => { + let component: ProductComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [ProductComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(ProductComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/product/product.component.ts b/src/app/components/product/product.component.ts new file mode 100644 index 0000000..062bf65 --- /dev/null +++ b/src/app/components/product/product.component.ts @@ -0,0 +1,70 @@ +import { Title } from '@angular/platform-browser'; +import { trigger, state, style, animate, transition } from '@angular/animations'; +import { Component, DestroyRef, inject, OnInit, OnDestroy } from '@angular/core'; +import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; +import { DatePipe, DecimalPipe } from '@angular/common'; +import { ActivatedRoute, RouterLink } from '@angular/router'; +import { MatCardModule } from '@angular/material/card'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatIconModule } from '@angular/material/icon'; +import { Observable, Subscription } from 'rxjs'; + +import { ListErrorsComponent, } from '@components/shared'; +import { Errors, Product, ProductPageData } from '@models'; + +@Component({ + selector: 'app-product', + standalone: true, + imports: [ + DatePipe, DecimalPipe, RouterLink, + MatCardModule, MatDividerModule, MatIconModule, + ListErrorsComponent + ], + templateUrl: './product.component.html', + styleUrl: './product.component.scss', + animations: [ + trigger('flyInOut', [ + state('in', style({ transform: 'translateY(0)' })), + transition('void => *', [ + style({ transform: 'translateY(-100%)' }), + animate(200) + ]), + transition('* => void', [ + style({ transform: 'translateY(100%)' }), + animate(200) + ]) + ]) + ] +}) +export class ProductComponent implements OnInit, OnDestroy { + private _data: Subscription = new Subscription(); + public title = 'Ad Astra - Produit'; + public description = 'Encore un peu de patience, notre shop sera mis en ligne d\'ici peu.'; + public errors: Errors = { errors: {} }; + public destroyRef = inject(DestroyRef); + public product: Product = {} as Product; + + constructor( + private route: ActivatedRoute, + private titleService: Title + ) { } + + ngOnInit() { + const data$: Observable<{ pageData: ProductPageData }> = this.route.data as Observable<{ pageData: ProductPageData }>; + this._data = data$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data: { pageData: ProductPageData }) => { + this.product = data.pageData.product; + this.title = this.product.name; + this.description = this.product.description; + this.titleService.setTitle(this.product.name); + console.log(this.product); + }); + } + + ngOnDestroy() { + this._data.unsubscribe(); + } + + getProductTags() { + return this.product.tags; + } +} diff --git a/src/app/components/products/products.component.html b/src/app/components/products/products.component.html new file mode 100644 index 0000000..28ab7b2 --- /dev/null +++ b/src/app/components/products/products.component.html @@ -0,0 +1,50 @@ +
+
+
+

{{ title }} ({{ productsCount }})

+
+ +
+ +
+
+ + +
+
+
+ +
+ @for (product of products; track product) { +
+ + +
+ + {{ product.name }} + +
+ +
+ Sachet {{ product.weightNet | number : '1.0' }} g +
+
+ +

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sodales ultrices dolor, ullamcorper cursus mauris.
+ Nam risus metus, porttitor eget lacinia nec, mollis ac augue. In hac habitasse platea dictumst.
+ Aliquam vel volutpat diam. Integer sed nulla posuere, commodo augue ac, tincidunt. +

+ + {{ product.productCategories[0].name }} {{ product.brand.name }} + +
+ {{ (product.priceRetail! * (1 + (product.priceTaxe! / 100))) | number : '1.2-2' }} € TTC + +
+
+
+
+ } +
+
diff --git a/src/app/components/products/products.component.scss b/src/app/components/products/products.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/components/products/products.component.spec.ts b/src/app/components/products/products.component.spec.ts new file mode 100644 index 0000000..ca186a4 --- /dev/null +++ b/src/app/components/products/products.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ProductsComponent } from './products.component'; + +describe('ProductsComponent', () => { + let component: ProductsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [ProductsComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(ProductsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/products/products.component.ts b/src/app/components/products/products.component.ts new file mode 100644 index 0000000..c897305 --- /dev/null +++ b/src/app/components/products/products.component.ts @@ -0,0 +1,72 @@ +import { Title } from '@angular/platform-browser'; +import { trigger, state, style, animate, transition } from '@angular/animations'; +import { Component, DestroyRef, inject, OnInit, OnDestroy } from '@angular/core'; +import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; +import { DatePipe, DecimalPipe } from '@angular/common'; +import { ActivatedRoute, RouterLink } from '@angular/router'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatIconModule } from '@angular/material/icon'; +import { Observable, Subscription } from 'rxjs'; + +import { ListErrorsComponent, } from '@components/shared'; +import { Errors, Product, ProductsPageData } from '@models'; + +@Component({ + selector: 'app-products', + standalone: true, + imports: [ + DatePipe, DecimalPipe, RouterLink, + MatButtonModule, MatCardModule, MatDividerModule, MatIconModule, + ListErrorsComponent + ], + templateUrl: './products.component.html', + styleUrl: './products.component.scss', + animations: [ + trigger('flyInOut', [ + state('in', style({ transform: 'translateY(0)' })), + transition('void => *', [ + style({ transform: 'translateY(-100%)' }), + animate(200) + ]), + transition('* => void', [ + style({ transform: 'translateY(100%)' }), + animate(200) + ]) + ]) + ] +}) +export class ProductsComponent implements OnInit, OnDestroy { + private _data: Subscription = new Subscription(); + public title = 'Ad Astra - Produit'; + public description = 'Encore un peu de patience, notre shop sera mis en ligne d\'ici peu.'; + public errors: Errors = { errors: {} }; + public destroyRef = inject(DestroyRef); + public products: Array = []; + public productsCount = 0; + + constructor( + private route: ActivatedRoute, + private titleService: Title + ) { } + + ngOnInit() { + const data$: Observable<{ pageData: ProductsPageData }> = this.route.data as Observable<{ pageData: ProductsPageData }>; + this._data = data$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data: { pageData: ProductsPageData }) => { + this.products = data.pageData.products; + this.productsCount = data.pageData.count; + //this.title = 'Fleurs CBD'; + this.title = data.pageData.products[0].productCategories[0]!.name; + this.description = data.pageData.products[0].productCategories[0]!.description; + this.titleService.setTitle(this.title); + console.log(data.pageData); + console.log(this.products); + }); + } + + ngOnDestroy() { + this._data.unsubscribe(); + } + +} diff --git a/src/app/components/profile/profile.component.html b/src/app/components/profile/profile.component.html new file mode 100644 index 0000000..1742c8c --- /dev/null +++ b/src/app/components/profile/profile.component.html @@ -0,0 +1,158 @@ + +
+
+
+

{{title}}

+
+ +
+
+ + + + +
+
+
+
Nom:
+
{{ user.lastname }}
+
Prénom:
+
{{ user.firstname }}
+
+
+
+
+
Email:
+
{{ user.email }}
+
Téléphone:
+
{{ user.phone }}
+
+
+
+
+
+ + +
+ + Mes commandes + +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ Date +
+
+
+ Numéro +
+
+
+ Statut +
+
+
+ Total +
+
+ 20/04/2025 13:37 + + #aa2025042013371 + + Terminé + + 56.00 € +
+ 20/04/2025 13:42 + + #aa2025042013421 + + Expédié + + 224.70 € +
+ 20/04/2025 13:54 + + #aa2025042013541 + + Annulé + + 128.80 € +
+ 14/06/2025 13:37 + + #aa2025061413371 + + En cours de préparation + + 195.30 € +
+ 07/07/2025 14:39 + + #aa2025070714391 + + En attente de paiement + + 64.00 € +
+
+
+
diff --git a/src/app/components/profile/profile.component.scss b/src/app/components/profile/profile.component.scss new file mode 100644 index 0000000..e462dc7 --- /dev/null +++ b/src/app/components/profile/profile.component.scss @@ -0,0 +1,32 @@ +/* Profile */ +//@use 'variable' as var; +// --> background-color: var.$sidebar-footer; + +.mat-mdc-card + .mat-mdc-card { + margin-top: 10px; +} +/* + + /-----------------------------\ + | Skydive Paracord Keychain | + |-----------------------------| + | 01-Rouge - #FF2F19 | + | 02-Orange - #FF9124 | + | 03-Jaune - #FFF135 | + | 04-Vert-fluo - #AEFC3C | + | 05-Turquoise - #4AD2C2 | + | 06-Bleu-ciel - #E2F5FF | + | 07-Bleu-clair - #1BACFF | + | 08-Bleu-foncé - #1E45CE | + | 09-Violet - #4F2AA4 | + | 10-Rose - #FC5EC0 | + |-----------------------------| + | 11-Blanc - #FFFFFF | + | 12-Beige - #D8CBA2 | + | 13-Ruby - #B21B27 | + | 14-Vert-olive - #335034 | + | 15-Bleu-navy - #35496F | + | 16-Noir - #000000 | + \-----------------------------/ + +*/ \ No newline at end of file diff --git a/src/app/components/profile/profile.component.spec.ts b/src/app/components/profile/profile.component.spec.ts new file mode 100644 index 0000000..57df256 --- /dev/null +++ b/src/app/components/profile/profile.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ProfileComponent } from './profile.component'; + +describe('ProfileComponent', () => { + let component: ProfileComponent; + let fixture: ComponentFixture; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [ProfileComponent] +}); + fixture = TestBed.createComponent(ProfileComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/profile/profile.component.ts b/src/app/components/profile/profile.component.ts new file mode 100644 index 0000000..7f87ff0 --- /dev/null +++ b/src/app/components/profile/profile.component.ts @@ -0,0 +1,53 @@ +import { Component, OnInit, OnDestroy } from '@angular/core'; +import { Title } from '@angular/platform-browser'; +import { RouterLink } from '@angular/router'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatIconModule } from '@angular/material/icon'; + +import { Subscription } from 'rxjs'; + +import { Errors, User } from '@models'; +import { UserService } from '@services'; +import { ListErrorsComponent } from '@components/shared'; + +@Component({ + standalone: true, + imports: [ + RouterLink, + MatButtonModule, MatCardModule, MatDividerModule, MatIconModule, + ListErrorsComponent + ], + selector: 'app-profile', + templateUrl: './profile.component.html', + styleUrl: './profile.component.scss' +}) +export class ProfileComponent implements OnInit, OnDestroy { + private _user: Subscription = new Subscription(); + title = 'Mon compte'; + bannerTitle = ''; + user: Partial = {} as Partial; + errors: Errors = { errors: {} }; + btnSettingsTitle = 'Paramètres'; + + constructor( + private titleService: Title, + private userService: UserService + ) { } + + ngOnInit() { + this.titleService.setTitle(`Ad Astra - ${this.title}`); + Object.assign(this.user, this.userService.getCurrentUser()); + if (this.user.username) { + this.bannerTitle = `@${this.user.username}`; + } else { + this.bannerTitle = `${this.user.firstname} ${this.user.lastname}`; + } + } + + ngOnDestroy() { + this._user.unsubscribe(); + } + +} diff --git a/src/app/components/qcm/dev_acproapidb.users.json b/src/app/components/qcm/dev_acproapidb.users.json new file mode 100644 index 0000000..ff1c455 --- /dev/null +++ b/src/app/components/qcm/dev_acproapidb.users.json @@ -0,0 +1,506 @@ +[{ + "_id": { + "$oid": "646676e011a65b214af84215" + }, + "favorites": [ + { + "$oid": "6468e67d3a6bccf2fe57fb18" + }, + { + "$oid": "6468e67d3a6bccf2fe57fb1a" + }, + { + "$oid": "6468e67d3a6bccf2fe57fb15" + }, + { + "$oid": "6468e67d3a6bccf2fe57fb24" + } + ], + "following": [], + "username": "jgautier", + "email": "jgautier@aucoffre.com", + "firstname": "Julien", + "lastname": "Gautier", + "phone": "0661655763", + "society": "AuCoffre", + "salt": "ddaa921b00889b72c53a443f379022f9", + "hash": "0b767756b834d313c9f2d2addbc16a1c42ee15385d65c73ddbaa474da66239bbe77cbfbaf40f53a127bfedfd81403cbc252902ff6ac8f16b7d70fdfa1d20c98aab3b367dbeebbb76d9e74fdabbbbb06fda9b14b60add027042d5b582b2d259f58024069da79b018449bcf752c7ac8faa0580f0b85c14a0e49883bd4e5eebcf1803731997d7c5d2216ea80fb4463021483d5e8d196ccddcdc3b51bb8cbb85f563a2f51b616385a50fbbb5b7fb1bd4c25cae4b81eb7ccde0d89e302782590a26e2f769a5903d4649076f3df15f2a9c60a0180d143702b0259c090b52432fcfca4693a3b79d09d00f820c9ecc53984c41ea215ae032d89e4c089e7dddbfdf2352e6d429f3c896fe2b2c6a671f6fcd73134e8ebb082d3060aaa36cc40e6d5f24236b13d3643aeb4d03fad11cce434c95cf4f812186a9093117e3f3a57a978702f3a86beedea0aafbb1d0b04db6de42151f80a3c86dd55705e5ab8b70ca6fc2321e9960076674b93c097451bc0834a4be2e7f69881296c75432fd13127bbf6efc2fbcd4a6752164f03ba8079d30715b2d5a1d6f0d4ffa8670c593a2c96791e621617f139ad985f0843763691f6e6348ea6d4e07cadac5680b7037b30511372230cb65aa3c36cb4ea8154e852ea76da853c9b090a5e0e6f0e3b9fe568f35dc0b6902d75ae7d95a34f040f69add055fb375be86de1498f362e1265e38cfa20e402b7e80", + "role": "Admin", + "createdAt": { + "$date": "2023-05-18T19:05:04.978Z" + }, + "updatedAt": { + "$date": "2023-08-23T14:12:49.144Z" + }, + "__v": 83, + "image": "/assets/images/user_avatar.jpg", + "pseudoAC": "LEPARA" +}, +{ + "_id": { + "$oid": "64681bf16ff7b20feae78554" + }, + "favorites": [ + { + "$oid": "6469770267a3086eb994c62c" + }, + { + "$oid": "6468e67d3a6bccf2fe57fb1a" + }, + { + "$oid": "6468e67d3a6bccf2fe57fb32" + }, + { + "$oid": "6468e67d3a6bccf2fe57fb48" + }, + { + "$oid": "646b78739cc692a8a4eb9970" + }, + { + "$oid": "6468e67d3a6bccf2fe57fb36" + }, + { + "$oid": "6468e67d3a6bccf2fe57fb38" + }, + { + "$oid": "6468e67d3a6bccf2fe57fb16" + } + ], + "following": [], + "username": "julien_gautier", + "email": "rampeur@gmail.com", + "firstname": "Julien", + "lastname": "Gautier", + "phone": "0661655763", + "society": "AuCoffre", + "salt": "4c87e9e9f899d03593faa1eb9e903bda", + "hash": "e27251923c34a0bb886d8d21b2de3fc784002071865b4e69b4c8b1c3adca1bc1ed68e7387453612abdffaa9f24476d81e621d450346a77f6303c8fc2e69ad74a6a795de7f12b0520772a37cc70af166920beac1e57e7f837b4c995016e00e44e1638da5916b209ceab543c8f58bdc2ada8d3dbb6d91630f3923a0901719432410c040fd379ded1f2ed7cbc2015b36ae1b31357b99e6aec9e1179a74dbd2620684f66d6ed3d117144349277d488effd7ea897c6040b3a0c8068ba982a155c3b1d2c8f063e6e8c8590b2b0e8c489b28b48503ffd35c99f54b59f58522319abc81a1e5197ba0f6d2cbbb2affda309e87db48aa76228418ec6875a8f678c35e805ebbfe54a2bc23c429153a4c4e18aedd6b74cf61a237899a9c94c104a69f04323cce32c95890c5cbae84415dc44068072fb7bec14379d61b77c084f967f42de331421d31e36ab423925cce28ddcbd770223936c026af7d8a5ecbf6777f52845e9e85ed67e358fbe591f68231e8f658b140bcda358faa4dd028b1048679900314ec75fdfb5f64c96dd6abc39e3c60d22c67500da9883e2dedb508175a8cb4f66091ea142b3c3a4fa5e9784875a9e0a1aff659ddf8bdccaf1dc3524a5a83c094333afd29e6280bc7af93d0aa6f593b40f49c29739940a412aa0364bb21d6463318826267e4cd4825ca4baa7e1a526d62ceeadcf8d73969e0c490c3588f476058eb4e0", + "role": "User", + "createdAt": { + "$date": "2023-05-20T01:01:37.633Z" + }, + "updatedAt": { + "$date": "2023-08-01T08:40:21.130Z" + }, + "__v": 70, + "image": "/assets/images/logo_user_002.jpg" +}, +{ + "_id": { + "$oid": "64ba8c824ecc6ac7bb7629a3" + }, + "favorites": [ + { + "$oid": "646921ceae37e3f3574d9ab4" + }, + { + "$oid": "6468e67d3a6bccf2fe57fb15" + }, + { + "$oid": "647739a22ee14fec66329870" + } + ], + "following": [], + "username": "abusco", + "email": "abusco@aucoffre.com", + "firstname": "Anthony", + "lastname": "Busco", + "phone": "0631902525", + "society": "AuCoffre", + "salt": "b8e33b5ae7ca938ab466ba80fdae6e5f", + "hash": "37ee30a899b7fa6596555d2b538ca89ee5af42e7fbc9de0bea82657b0561c8dc747ffcd383776b97e56fc40513098a2860b13646b9112b1c0f0b086d718ae881e313153b0947b807485169931ed4ff99e8d70df7e0481b6a13f83cc2750dc3e1b3fde0e8a5de5cb939647250b677e1f5958c6a0cc8c64ebceffa009c13ee89b1c4acdba9e4b4dde8fd08201a813e320317806716adcd984959c29ef21e67b4acbc0f2a54f606a469a7e4708bd60b75229af03972a14eb1dd5c62533428ee1acb2d1e4e66d045689f5a4d31ddaeccebe2e9254dd87417490378ae568c0ff16708063de56754e3550ba1c6be498773b0e8fd5c260a8e9e97b284db8ec2694ccdd9290dba83111d1c894af57bc70ac11337b2df0cdcd3c44e2adbea2939b70ee3402c0bcdcbe13ca220406422e3ef43f1ba8e57018d461822adc234b44430db8079ddf9b32d926ac82db9a23169b79ada4482c7bf14e6b1a4f7a38840e578d0307f9acaae9d6c373f65415e6b5dbcdda94bf40331f7c39c9eb07da1a1f18ee7d2eae8773e8aa76c9cd822bf25daefbefcdc4d8d1576197cf5dbb2c5677f2a624b5aac549cccb53a6d9b4c37243dd865f150e042c798ab1904dc704bc62853253a7ca8a58f79c5b607b043a9a5efed2e86c8380c1fbdc3227b5c0288f49ad7cb005c015bf1785caaee41fdf37fdfcb6a5e35789339a36ed6d31fe5bcccecec04b9b3", + "role": "Admin", + "createdAt": { + "$date": "2023-05-18T19:05:04.978Z" + }, + "updatedAt": { + "$date": "2023-07-21T13:49:08.539Z" + }, + "__v": 1, + "image": "/assets/images/logo_user_001.jpg" +}, +{ + "_id": { + "$oid": "64d35f07f42bebe5d1625fef" + }, + "favorites": [], + "following": [], + "username": "christophe_marchesseau", + "email": "info@oretcie.fr", + "firstname": "Christophe", + "lastname": "Marchesseau", + "phone": "0671563041", + "society": "Or Et Compagnie Eysines/Villenave/Fargue", + "pseudoAC": "WYLERA", + "salt": "10b786c0f3500268f59b72eeac903d00", + "hash": "57d9a1600146152d274749f2a9237d3ca33eb6c2265ee2f89f557ce375a91f1699a14c0a57145d12cab55b96d5cea995a1a87ba768ee01c7717c6a622580c64719d2cffba1b6027ca27cfcdd1cdc2ddeeaa91fc5b6b533b89c453723d68a5611f2c01b23bc32860834b28e158984a96bcecd05c990a3f6ed0e3111f9619375f6a16e52c02999d3b58f815be115e9e49f30c54bf6b2416287b7cb46dbb90e1634ba545637b565eda680b543d041d41dcd0c79b8c32f2bc40446d634ba065ff44a5a2dd1e21cb1144066ff34a08d03b00e94b75c5c94f81cab9f352fc9b7456e5ce2741fccee92a7835dc4d117cabecf1307978c9e1507541245d4e629a251e730ad388a1bb42e06a3a0478f50914289a96bc226375cab8a61b6f840979d75b57a0821174914ae931805dea02af37c7d2f5a2cc75578ad4f4ea4684fb0047dbc2463f0164a543da271f8b3b743ed1d981af05d230398b9f4246d7030c983db81628639373d612bc9b49de703b7de84de812914f1214d958e3b737600a4f5a8ee0ec6cb4c03c4b96fba6d0f1ba58ec23880d16a9df072b8cf96df2430e183caf0f16955c409913adda2fad8942178a77fb31d6273b9bf49f24a219a2b7c6897cccad8d5d6e24a2b2e342bcfc510a74f9f43539cb69380e3a9bdb3da03169814aca1d37a942e2951ef9e1a13ee865ba1aabb6a2083f6c609a659fa242c17b1d82afb", + "role": "User", + "createdAt": { + "$date": "2023-08-09T09:40:23.133Z" + }, + "updatedAt": { + "$date": "2023-08-09T09:40:23.133Z" + }, + "__v": 0 +}, +{ + "_id": { + "$oid": "64d35f98f42bebe5d1626001" + }, + "favorites": [], + "following": [], + "username": "joel_hourcourigaray", + "email": "oap33170@outlook.fr", + "firstname": "Joel", + "lastname": "Hourcourigaray", + "phone": "0619446471", + "society": "Au Napoléon d'Or Gradignan", + "pseudoAC": "JECUPU", + "salt": "1078ee75bad68b2845bfae3c8ab2df4f", + "hash": "4135d652f196e75d4e1a8e975ae559b05a65d05feaabf373a6844656437c03a6e7756dd0be696859bf8c877037aae1b41ac9919f84dd3ff55549a6de4ae5a9972662c668e163e1c97d182ca941f4821f99d0cb4c3e95b887793cf20b282ce491d55aad31e6f381a14f0919274b26122d7e548808276fbb003d03bcafbdc3315022d2047b2ce76f93cc324c1e5f3e30fb278d1f68b507469a35f43d0f416894f090a0b9ef1dbe7583be438b17c336f8728178437a24fa39d4e4bcd19b27c2c9ce24647575c3e1dca9d4488717901e555f920cfaf1cbe1761f9609747369f376ce135e9dfeb7439e66cd02ef66e62f59e96ab5c93292361bc8f2629ed35627f6c851b2f4c75154ec3246e1b2ed1f8a8b7746ca77014ce1cf1973a6059612dc108dde2bc1d46801e877a7690b24674f69f5e6df5361028966d7d2cc814afc44e1b661d9996c0b8c26cfe5a8d0f63a9be397cf37ecbcf541ab3ab296b4dc14ac8516aa929590d0d1110670182d3b998e0b6ec6b26cffbafd255dea6a738b65b3145df55aafbf983044ded11b2606517888af56665a2eeffbf767d1fb75cde2fe1d714ec15badab4e9bc57e963991c047cf997959255cd6d2e8ac4755afd28a1a393ebafbe3397a0493ed23f1c4c73e5ecd4cff07b664cf880d430409503801888d77b7afd1bf3e5e5ef83f92d9169c4bf9e751aed7f3adb2305d6dce60f7a8ab8bb2", + "role": "User", + "createdAt": { + "$date": "2023-08-09T09:42:48.377Z" + }, + "updatedAt": { + "$date": "2023-08-09T09:42:48.377Z" + }, + "__v": 0 +}, +{ + "_id": { + "$oid": "64d36004f42bebe5d1626013" + }, + "favorites": [], + "following": [], + "username": "valentin_darteyre", + "email": "aunapoleondor@outlook.fr", + "firstname": "Valentin", + "lastname": "Darteyre", + "phone": "0637848630", + "society": "Au Napoléon d'Or Langon", + "pseudoAC": "UMIFER", + "salt": "047815ff4983d8848ab14aa9af6ca054", + "hash": "d0640f88e03e20e9b7fe84970226dde3346f6ce139a714b7b63e5d2c0dff3c60e6a36c2856f94c85578a8bf2f4410eb418ca28e9bad23e7cd45c583a79128d188a9d92b020f0c43175f94bf7c5fa72a65ac94d9b59bc558807177a3013167b4e3379305bab32808a2d64264c78950d242ff8ac6524cf08bc7d8ff28c97e79cea62cb414a04e1c7aa838a1d29121a92f4d574c45058352aa5c632384dff05f0f00b57295795bc2d2ae62612fe0b3ede0d0ed7860da86ad8eba5fa09a00bb0f7bba911a9659f8f8980946a5068f2e1077c864ba21b36d01f299269f4faf24ccedf2fc005f9e62ce7d1fbf2b322415fb9f0f3cf6c3f9edff1a2d45aefee8ae631a8dda425b8d5285637c96ae57911fdbf7179e6a5eed40dea89e1836545c1e1247734556a4d78ce69f65ab8a74ddc4a7ed3d5688afa1192b6383ceac427e1f79e99ec3db2dc700f847a9393e17f5aa9a267ce4a649f32d623f010e7d218b7c99624aacd2239760735c83e6f9f01ce38474aa7e07feb69aea69304725d8e9bfb9c8c7d0000a84a03cb4efa82629052437c352f27bdd356486eb9c498e9759abb15dfd6405b0b301913991dec68ae5ae4e649e30f738f535bbd95f9f4511e171eb978eae47b542c05156a9b7fcfa7987497a31a99538044bbba933d58cae7880da132dd083e2ca24c060be090608138e49893cbdf1b61b672046dc5a2acb30d8b49ac", + "role": "User", + "createdAt": { + "$date": "2023-08-09T09:44:36.505Z" + }, + "updatedAt": { + "$date": "2023-08-09T09:44:36.505Z" + }, + "__v": 0 +}, +{ + "_id": { + "$oid": "64d36063f42bebe5d162602b" + }, + "favorites": [], + "following": [], + "username": "johann_abecassis", + "email": "or-vintage@tutanota.com", + "firstname": "Johann", + "lastname": "Abecassis", + "phone": "0623196292", + "society": "Or Vintage", + "pseudoAC": "ZUDYXE", + "salt": "2f8976c3e7653ecfb64102303e8717bb", + "hash": "3fa4e42ecff2d0a827e42667e59d6c75db79c7e4c8e4fb69028f46c6160d63255314a3878e60a7ba11b603d0be74ef786f241ab324a5d31852beaecead19843e753cdf45ff74ff25a0839ab5405807656633ab2a244c8d8e643e4eb8dc81e2b09ded66fdbc93867a12c110dc0a96de01702f88ce4d99521ed6974dfe483467c352110ec1b4f675cf4aba2094e9b755f897e8cf5cc6b45558663df91593bf5da889d37a81c4129e522576e2facd28513decd1a4c01fa879f75d33fbc315f70c8b8f2dc8fd2125dadd95653c6d266189a2e1624fcd3a333ed798b7f24b676f1493a8feba627334979a7ecadda07a3d13d0baa98499a795181c1b1b6233d6ac22bb7cc3ce19f069a72019ed7d27ad3ce01be0c308885bcd7685aa8eabcc2393e1a6b85ae883972eb662ba660f469d16663b728c3a3b3f6e0ae0eef92e08f205f63ed8bf86054766d3095cfeed1f462d66f826a71dd453db52c4212a70b319edc19c4b329b901b9fa5ffbf4a20e691ec3981d781ed94bafbc646443850d76629b346aa60f5b480a82ff79d487fb7462f33b9b9534baf1970027a8b6f5994b7655c00b5ee5bf0c2311b8bb1688167c5fef786b0e1cdf93f0742f3a6093272cea551312fb5ef431fb70a61f69a647205195094faddccbe55cb27f9be4b32c3fee326271fcf8fa586a1ebc65b43f00a23dabdb324ff3277f679ba9bd6d0dee920a51126", + "role": "User", + "createdAt": { + "$date": "2023-08-09T09:46:11.647Z" + }, + "updatedAt": { + "$date": "2023-08-09T09:46:11.647Z" + }, + "__v": 0 +}, +{ + "_id": { + "$oid": "64d360b0f42bebe5d1626063" + }, + "favorites": [], + "following": [], + "username": "murat_aydin", + "email": "eliyor4430@gmail.com", + "firstname": "Murat", + "lastname": "Aydin", + "phone": "+32499344802", + "society": "Eliyor (Belgique)", + "pseudoAC": "FEZABA", + "salt": "0137a9f77588bba98b10bb759b471045", + "hash": "0a4ebdf614963e9a1deb53499faa716a1895ff228f763b799828f7fe1917bf1625f5c95b88ee103f9516d129ca8bfbcf821c18977ce583e293e02e210aa97f4239d10a30a36ef0af69377b0e5c8d565ecd64597774d0064b6855713703b12536ae631f333db68a108aab426c8888561a88dca6ddafcf7b0c61c6d76c0c623b18ba7c72fd380cefa83aacf37a9c16dbb866f8a86b933966b86145623b2cfda034a7e257f4847d7ae982cd439cb6ccbfd5b61856247819aa2de75a55cf308a0e0832d7fa94bdfee85bc883bb47020f16ff12d13882216bb4adb27bcf44c704454bddd0a200961b0acd8eb5e41a7afc127c678399dbe2b3a0677d6e81330669babfac481a3fde4db59e0e4bd36f8bc6deb01bbfa375959f666b5108acab37c40590bfcd7ea4093c2e04d7ba0c51b295d119813185abdf6b29e5c05b6b47ccc60a9661b997d753b9350c9e00e95d5a33398ba5bae3c5365f7d19699650001f19f70da874db812149d53d93d13ae8f51bb0af39fd23bd85f5d31e1c2362ff8e38c554dce4e263f70407f09d7f67eb2ac032da854232ff0329e16f375c322c3b1b9e1d8776af6cb2d0ed6cc6a81aa16c9cc602757a3447ebe684cbc2c986cf6921f289021f22732845928e006c8a96d3641fdffde9b4994bf77422667e9cb2e8f142f89e4b6376dbc4801a10d26cad368a22bab92d2ac30f5b0f19e61bba14af0c6e49", + "role": "User", + "createdAt": { + "$date": "2023-08-09T09:47:28.244Z" + }, + "updatedAt": { + "$date": "2023-08-09T09:47:28.244Z" + }, + "__v": 0 +}, +{ + "_id": { + "$oid": "64d360def42bebe5d1626075" + }, + "favorites": [], + "following": [], + "username": "eric_buichon", + "email": "eric.buichon@orange.fr", + "firstname": "Eric", + "lastname": "Buichon", + "phone": "0683460137", + "society": "ERBB / Aureus", + "pseudoAC": "", + "salt": "bd93626a314b3fb1a87c5a0ebd4bec60", + "hash": "7660f16bac71d7c26645aa2cf050423c9e63d4ea3150ac383f54ea66268e12c8d1f3ab2263fae6f1b9a82961f4ac9dd5e24e6f4c6be5ac980ea3cb670448585c5f9a20c042d89e6c3353475d5ab190f273a032e9c7afe00fc9173ba9d9c4bada0eb862081c81e3d875ec36754b19d9581333c3d228cc1cb26add38b23a468b5d0ba524c3ecbfb338c4e4d07a8461fc98750c8afbc8ebbf7a672c7d188d078cb095751818250f93a6212fe9c1bb0201c19348f2e1fd56bc7e7f3df453be3b7b4762580c8c1a63d953ca79ed40b40ebc50aed1e338025952e54ecd9973f10336d2a93a771536c588b54727b70f31d435e9409075bf59246e46d7525fbea2371b05d3e93d8018ae0be1d5e6a925cd2160ac4d1a81f857c4b5a9f893f5fac93e00e52c07d7f0fe97c92e573c50fea3f7a01468bfddc3499a23dd4d59f1bfea6c0a6c01cebdb2beb06f14d128de067c1d8b1b876747701182c4946a05b78424e4a6953448ca676e7fb7db48144bd7958d0a491b06df92d7b44fa8c5906845999711c68fd4bb799f03d9f64dd3081ff8f564214c36846f446f74dd65c7a473bdb8ba5aea738b59fd60d69cbd62dd71dac41a2c55c0a372372cb5222b8ca932233f712908de4bd0b92e2b045aaaf9f9084d4a537ab5b90b2fe752e7fc16c18392daeb90a4378d9c8bc56280e1164c045cd9d7393b36506f7fa0943c19d0a131c384a693", + "role": "User", + "createdAt": { + "$date": "2023-08-09T09:48:14.532Z" + }, + "updatedAt": { + "$date": "2023-08-09T09:48:14.532Z" + }, + "__v": 0 +}, +{ + "_id": { + "$oid": "64d3610bf42bebe5d1626086" + }, + "favorites": [], + "following": [], + "username": "sonia_yungcker", + "email": "contact@numissima.com", + "firstname": "Sonia", + "lastname": "Yungcker", + "phone": "0682751820", + "society": "Numissima", + "pseudoAC": "", + "salt": "dd5ee0f64b1e69664ceaac107c56668f", + "hash": "0efd56217b6a19fa841e7997bd34c3913df55a46d6310d44731bfc60f80ee0247503783ddc7a61adb14a9c71ccdaf6b02bce9f4b454c170a1b605bc21bcb30ad14886008193adf6b4f422e827f12f75d123aa8fec658b22de3cc0ed9331452a631af8d8a431a98bfc5310788dd4a2b58d36471f6608dc08f085eaf0f223a01e47738aad20c271fbd8575d6e22b82a6932749538b7dacd3b547634ed692df7a54d8571f8db24914f17954845de46df658a63c4cd25fca892b581c6cf5ae8f1871d9e36f3997dcb7190e284314331c018f573eb6bb72597e6406f1a88f5ec6d29d5288b8b8aa4a7d0a0184463e51b65dae5d37ced74939d4c1ea37c767e0f92a0cf8e6d990ad33abd331593d2722bfcf7276e5d55b879cfe726f759865151a3bd1f9c43e77aa09da765b05b6faebc512bb6071da5f66e4057c1d9161994769d53c3fd3c98637fc11a4d6b3a4e1263b9978b62a90761efbd4f6bc431c43f91eee6df1c9df1b259c6f232db794ed02b83d5d669965608dd6554a6f4e5613a6347520065d56d73e5184cf6a446ab13e652513fce973f8055642a547c3bfc0ca48652e8c030389203fb83d37358b0f1542900adf1c27c68fb9aaf7455ebf78d9f2419a9c6a264291ff06883025f78e1dccf4d1e7ed57893d601eec5a19b166c6496f8f4a770b3b78172f4c7fb5727d9dda7399f3c7b68af7f734a0109f0eadcceb7ae8", + "role": "User", + "createdAt": { + "$date": "2023-08-09T09:48:59.923Z" + }, + "updatedAt": { + "$date": "2023-08-09T09:48:59.923Z" + }, + "__v": 0 +}, +{ + "_id": { + "$oid": "64d36205f42bebe5d162609d" + }, + "favorites": [], + "following": [], + "username": "mohamed_hamza", + "email": "cbbo.33@wanadoo.fr", + "firstname": "Mohamed", + "lastname": "Hamza", + "phone": "0643358437", + "society": "CBBO", + "pseudoAC": "", + "salt": "e3d8602fae3ded82fa80a67b2b784630", + "hash": "d2a0de718d8d2766130482264b3236af7612dd12607cb5bd1717c12b7ee6dea3f40c62ea3e5c7b1d537b5e47a536ca3a20b7d5805854384199d1249687be06f2d123f54b55cba52de343142287820a6d80786353bb8968a01e2bd8a7d7cbd62844fe710b85b837e0e272c02ddb634fb65c390f149cc0e75515ee69297c7a09dd3454e1e841931c400be0368271d85f3718714fc434bd35adf0503f040baeabf6de747ce54da2291aca4b5b75288e7e3d9d78bb3b0cf6486dfc01eeb23c3011f2fd0002fca3b9d227987dac6ff483d4e27da0ad42224a1b0b0e31a0c34b9a0e62c8c2cca00ff52391d8ac763e02bc88260dbe28d45b1f200494ab155d294021ade4e4829b708540371cc640d3d305d237067b81b130d49a8eea377f3aa5f69ce1d51ff7529d5e12f67d2b1b00e0efe6e5afb647e8a4e36863e9517b83ddddc93bd63392d385831edba06a870621cfed6f525eec80be8532ffef4b6026a39c90c68aadebb9417d3a4f9e84a31fe419e4a3af2301e559d9bc249c43c0c1c1b9db594dc36c542e5316868bc22c2a34062aeeb2c6049d8fd1d66796a88c7e679f5cd0a811e5a3c3626b7a6ec1d52158869696a22b8293c950f2d77d2a0324715386dfa50edd83f1e170520fea11e0a7ef04651523610ad984977542729206c709fe12a75c33535015d72d4ab08e832a335d3df8833fd6f9f833f9c4b960eec980a552", + "role": "User", + "createdAt": { + "$date": "2023-08-09T09:53:09.330Z" + }, + "updatedAt": { + "$date": "2023-08-09T09:53:09.330Z" + }, + "__v": 0 +}, +{ + "_id": { + "$oid": "64d36234f42bebe5d16260af" + }, + "favorites": [], + "following": [], + "username": "bruno_abitbol", + "email": "info@artetorbordeaux.fr", + "firstname": "Bruno", + "lastname": "Abitbol", + "phone": "0608994303", + "society": "Art et Or", + "pseudoAC": "", + "salt": "7ac0adf3e8cd029bffdae7972e1285f0", + "hash": "aa4b30596df6d9ff74c9412587a469b6a90316bd7cf59f1d9a032f23e95a62cf8c73f1e3f97ad401bea1a74e3b987861fb929e99022bbff4ad18c3592412b32ebd7e0b387b4319060a624486488d9760cf98a306d49de61da87c26ad8640b3e297946663a7c04e7f2b7b6c015f601e1c7f180d7cade3e0a4e9f039d92f1cbf4f9ddea521aa638fd2d80c1cd6ed2dc8e085122446f14951a78728698ba67871746739cc330ab820f8200cb8be43f88ff2a8fbccaa60000c629af4bbf1251fac444169d92139d65e372ab946d46398e90976328bb55e4f5e741824614b50c8dbea7e67026983966d7bc5d2a10bb4b32cc2ba608557fb80efea74fb3dc5a08101087f08a1c35d3d5816d3065d79c9f46c55f761c49daeeac389f1ccb867a3416df29516524765ecdcfe39bb5fd7cc5b69c186d850c7ce25d1264445d368a02bcbfb1f822cd5335b99e1ff54fcded3c65a2ee3251fee30c02b5041c6f96a019c3107c327f9e170c090f23d0ed8412521ff1cbb2f0525612618024361394bd97c0b9488a66ac77bae86ebda0507b2994a0431284ddcd9543cb1d95b6ef0fb64fa3fead41d2d9f9bf818117dcd6f28578071460bb8e3d917ef73836c234f34d39f73d988c03647ed476ba8ce251d52a767b0790ff6596a0d0f6390d64c73d14b6100361661d3b10dfd56dc0a888dd6e1358b4256bb0802a66eb0df0ba8aeee8113c24c", + "role": "User", + "createdAt": { + "$date": "2023-08-09T09:53:56.395Z" + }, + "updatedAt": { + "$date": "2023-08-09T09:53:56.395Z" + }, + "__v": 0 +}, +{ + "_id": { + "$oid": "64d3627ef42bebe5d16260bf" + }, + "favorites": [], + "following": [], + "username": "manuel_rodrigues", + "email": "changeplus64@gmail.com", + "firstname": "Manuel", + "lastname": "Rodrigues", + "phone": "0621745693", + "society": "Change Plus", + "pseudoAC": "", + "salt": "07841463ed0da7f3e47f3a6faf414e93", + "hash": "90b40e506332109636b0285eeb50f9e76b0ac37b9a9fe13b59fb3426754363e7f4c217fff07567f4a7c4ec14a2ad4e5e144863ca52fb1ba2d865d2a62335404b3c79fc19891fe9cbd858eb1d84d178a901ab0b03362f2685775fe5b18d8f51818a337f53b5700bf79b2f639d2c60309af164028fb84e86ca2559a531e62bbfb0aa31246d715f1ab50cffbd1c3687cff8f4d07db1b0345296ba78270216da444dc501ac452842aee292466843290a7d4c5393c633f922c98d075e80dfa888af75cc6db0c15efed3a931a9ea5f27c179c4f5983ef542063df7ea059bdda25d00069652c82d41fd8458d84bac59077d39494d2cf55b87147b0278705b5b871f4509dcfaa720a99a6bc54dd7cf754e9f080c2f2f7a1152904e4164c30487af18c449d5ff7df19c8ce66fba7372bc9c4c2dbe3f45027f6d97642deb7493c43e715c3b143b850c8636b2d2a5975999c6d2d0e4b85156e0f9788a67e391bb05ab796cee2f99e25c908269cc82ea95764437b92b596d22081403363103e305b8352748b77aea2690865dcd782921a6f198908ff8342076475565d50182a9cf0b6fe0d266d829ac9fa67b6f9fa33737aaf68c07c66094fb5efd813fe8ce2e711d17fd95cf1f82096d7314a9b3b19276e22f2f4367e1f3d1d86cde26fd245032ca1cdd02a39712aba6793167853ed3847a6461d56f2d41db4ef9f4b71ac0b78b0d4bd7583e", + "role": "User", + "createdAt": { + "$date": "2023-08-09T09:55:10.737Z" + }, + "updatedAt": { + "$date": "2023-08-09T09:55:10.737Z" + }, + "__v": 0 +}, +{ + "_id": { + "$oid": "64d362a3f42bebe5d16260d1" + }, + "favorites": [], + "following": [], + "username": "frederic_cabon", + "email": "fcabon.numis@yahoo.fr", + "firstname": "Frederic", + "lastname": "Cabon", + "phone": "0556812159", + "society": "Cabon Numismatique", + "pseudoAC": "", + "salt": "ac563ffe5abef7f6d4930d90b7c535d8", + "hash": "1e665a577c9806386c66a6fcfbad5ee0340ca0ba2f3f0379f20d5ff171d3218dad85a6ed885148a2a96e45b3c5758217e49f0ae17260310bc1b21f09ff44bfe5434cd05b90aa4883ab31966a49de9231b46139bd337897610653ffdd39ffedf3bfcb5a31ce34e6ade723e847333bdd0369becf613593d88c4c48ba06aa6b35aabf1940846d5d1452f87ec603b625edd5566987564364e436c4f9cf65b0d849bb8b792216bad471c3e60382c893d37bb5f7c7f8ba0dd515e5062a4d92e85b4c2472a2cc25ee48d6b4e6d8370ad111933852732019c7a33e90fe0114b8b67709581920a5a9054806ec50b5fed7c42458bc3bb3f7c319bee23e7b8ffcd323ad16fe7beadc0a1d00d8ffd7575e4e2cc93410dd46679c7360627ddbc44c8fc0b62cd447dd3092482a43981160219d596911f4a7e99a4975904bb21d719524af2b36355fb7411f01e6e826dd6e98a37d83c1c29216aea24a15a29212f7265b379c4a1aea9afb74c43cf24ee11be2514af6305d7691e92911cd1c56d2e71af29be39bbb3e0653d7bc9d8f1d2f2ac099ead62962bb76f59308ead5ce861d61af8eadc7778954aa25b0ab321952f8cd38cff92ed725aa5cbed1b0a9f9ab35cd2d6194523ed2c6366dbe10ab47898d351fd0ea4bc487cf9f915672c093e7df5416d279af18cd94e5891e520fe092d2af19c223ede6fce3f7954547e2cbf6877a66876e2046", + "role": "User", + "createdAt": { + "$date": "2023-08-09T09:55:47.818Z" + }, + "updatedAt": { + "$date": "2023-08-09T09:55:47.818Z" + }, + "__v": 0 +}, +{ + "_id": { + "$oid": "64d362d4f42bebe5d16260e1" + }, + "favorites": [], + "following": [], + "username": "sebastien_gheneyn", + "email": "sebastien.gheneyn@gmail.com", + "firstname": "Sebastien", + "lastname": "Gheneyn", + "phone": "0630765688", + "society": "Euro GS Finance", + "pseudoAC": "EREGAP", + "salt": "82dc595495fc4f5ced00ffe5f62f0366", + "hash": "311d477ef906c62dcb5a066ac2ef1c9e6521c0a16042a53cd83f73ec79d5a88917c71650bcfbd29d04c06d0cdb87c6cf0b944111b325584b050127000e14f13efea3dc9f105c22d7bf8596c211ba45c1406191dbe1ee8dac9fc9b60bcd0e794165179df46a6482e860bc6b6df2ea8eb3d87be173ec29478576d15e5faebacef158af1c6630df0a247c021bc3a720e7f9a11a368b56b7c69a8505ac70dbd38ab319a7ef314f231768612e421ff1f1f63797fd0704018086e05ecbf4f53db78433b7972d81cf5794d656475331b765f58698f019e523345d8f49d84abb781f0d831161438b946ccda0eecf9eb0b1da20dfa4c22c099ca14384a9ea48af8f01f26239d96713fcca5d48731de9931236708f4a101cd00d257b6e8828759c56c2218fa3f84641cbc62b30e8e05be416f950ce47627734e4d175735275b5c4a14a3724b4500c335e3c6704ddcdd8f8f15f5737c7a69fb3f6854b7f7256f193b98daf7c3fd367172d61b4294ce44962e8ffd7bf3ec362c4854d83ae6b075d27c3039c8bafb2d790410603642dd4f10c9b6a858fd46107dfc37d214e9461e239c27ff9791d9bc5b5a3d0ae6e65eee7aa33413f401deac1c10ae08f087d5c57105f45f3bcd2ace7727dd3819b384606453ff4c142e108bd7de4592dfb5bb283854d9871d6632d872cbd37881001e9e7003a050967d9dbe47a6c48fc77ded9a22493f89b7c", + "role": "User", + "createdAt": { + "$date": "2023-08-09T09:56:36.883Z" + }, + "updatedAt": { + "$date": "2023-08-09T09:56:36.883Z" + }, + "__v": 0 +}, +{ + "_id": { + "$oid": "64d36325f42bebe5d16260f3" + }, + "favorites": [], + "following": [], + "username": "patrice_tassistro", + "email": "sarlctmp@gmail.com", + "firstname": "Patrice", + "lastname": "Tassistro", + "phone": "0688017403", + "society": "CTMP (Comptoir Toulousain Métaux Précieux)", + "pseudoAC": "", + "salt": "f8946d23b20184c05ff9af9fd30f8ba0", + "hash": "65b35ad6ca6240becb63826afe3942e062ab62ca7e2bea1b3a14ee67d558367bfe57d7461c88b1cf44fbeca65418500e3ab1bf4a95f2fe64549616108c2d7558c7e778ff486ec0c315a9cf22f21aefc2df706f1253b76fac39b54fc8cc2888c6ae447a20916148c6b75b6a0595b5cbe462357a64ec368864641615d3343df57440295704eaeb94fed45ad805b6124777700da5589c704105bafb7a0e7c12f5f84e30b12e467362cc94ea4f3e53c93319b5078c7fbdab1ac14f0ff2ce96aa54df444bda9505441eb2d9522913f5c7b41a287ca2ecb0db9ee5be1f92936bbd12b8d26ac2834971e1a2bcf0637fae03d39d6f59eea312291a8930e999ac337f8519589b1cc2cdf6e09c6fef736a6da58f0da4d3cb6553baaa37087a4f2f14e2cb235cb47b1dd3012ee073d3aa0cf21354c2bb8ae5fd2e152743af8ebb5bb9be7d6c7c72f8e4f5ab8bb24d6dbb97d2b77bd5a06d347dd4e1227599c483a288f390aa1ac2c70295bdfd1b70d3e03179750209987d5355aa1f04a53d1cc0d465a973859c7cd2101a85ee488d27636600c5ec225546145f22a9664f6db4a0c3ac7ab3faa84bcf428f882ee632270c1549cf8f103aafcc520af6e1d229f081453ec307535ded8f778088ed0af7bbcc370c17451443903c6705f488c79ce5ba155af5ef5ad8f021396c1e76f667045d8e264a880edb02e4324ddfd3ac1f8ee518a169a96d", + "role": "User", + "createdAt": { + "$date": "2023-08-09T09:57:57.795Z" + }, + "updatedAt": { + "$date": "2023-08-09T09:57:57.795Z" + }, + "__v": 0 +}, +{ + "_id": { + "$oid": "64d3636bf42bebe5d1626105" + }, + "favorites": [], + "following": [], + "username": "franck_gicquel", + "email": "bordeaux@fidso.com", + "firstname": "Franck", + "lastname": "Gicquel", + "phone": "0557999999", + "society": "Or Expertise Fidso", + "pseudoAC": "", + "salt": "d24d34f28257b974145cafe8d38e82c3", + "hash": "6ebf5514b234a418500a03d916bb477b6c2859240ea2918ab38e8cd51c28cc9fb09932c00dad7bca97a5f65e2088d8da42b8863f0fcbfff950c799442f2d2fc8f69a282bcf9332926a6f6a0dbbcb24789793d64730c4f67abef4371af5b849afe8cfb9ba3c9d763557beb2fa13690d961c4310a0e8bc389b8344569412d4425d3eb3d6d1169a9d5b17298b3cb9c867acf966f577661fca549d2567a724d8b9ac2028b4c93c53e41ee3968758a9fb7e40c86953614419566f8ef5e0e9c5dbdc052d6e0c36e512b5a3de7df07134d2c98d01131d061aa2a6c4d497a06daf55ef2757908b29e32a284f70418fcfea1ad6cfc189c2c7ee22cf961b27593c46f2625d1493f339f2093a3aa713904847308fa53aa751ba5134f00555cc6018491db2bf35a25e96a0407c830c3dffbf85e2eda4d3fcfd47b4dc74995baad720d088c0eeee07890dc1907b145ebefa382811d92c1b03af4f1c2f9b246cbce70bad94ead2fcaaaa8b337a3839c51b9c43849e2a2278dfdc2e62319a10b2bbbf49615e66ff953c86e3a8ddb4bfd8bf1e2160a9d7da34b18bd67e6bd9be034d770a96855a026dc5badd2f16bf3175e45e196962a196101a013eb3ab8b8eb1c42b40194a93f9b1a403e5d468d2ebec6f534e9defadf815131a410baf8fd72b9b53b660faa6c70551450515ca28fa9800f66bf9076b6313551e8c3cd085a148672a5a596bb902", + "role": "User", + "createdAt": { + "$date": "2023-08-09T09:59:07.208Z" + }, + "updatedAt": { + "$date": "2023-08-09T09:59:07.208Z" + }, + "__v": 0 +}, +{ + "_id": { + "$oid": "64d3641ff42bebe5d1626163" + }, + "favorites": [], + "following": [], + "username": "julien_dapsens_turquat", + "email": "mail@galerie-des-monnaies.fr", + "firstname": "Julien", + "lastname": "Dapsens-Turquat", + "phone": "0662012604", + "society": "Galerie des Monnaies", + "pseudoAC": "", + "salt": "fc59f59219a8bdfdf87aa951b3154db5", + "hash": "dc8a69c86415d84ec4dd16d95f04971f0deefd55ee83c32b362878cc959f25acc99d528b84f1a889c54b775f6be332010a8fa2f4ee95add677453c0654be7704e6ee0912bbf830655d95080260063f52672854f08b826ccfe6fe643458d9d7f4c79a849ce2045b1b6923ef725c0e42ca326631ae2ed8af43829331909da2a79e610d7397333954cd58c2bb76b0b1dae011af4c038442858134c0c7719c209dcb316ff1a477f52287a1821aea6c99163f4a118f36e2dd3a69f35fae8669dbf44ddc9229567b0e65de070138bc1a2191c2b4eae09ed0c89374549ef1999b8b336743921c517359f43e318a123579a30e13adc1b2669ee0c136c3590b60da555e6baf5d85913590d348c50013bd54f5d0a8d01f3b1dec975982089ed27645ac79b10dc2559efbe893226453b7e2f9d8f91e5d2bcd9f6d98bc67df021fb51454ea8c4dc240310f3655f150d30f0b421aee1723ca9d42d1e949577410111ed81fb36f5256f191e16090e0703754d01b5f22be7a78e1ef8982d04bf8c539714e1c8d084ae65cd0f11738a28da21ffed2f44000c4df19b84dd7a342fd2658ba3578085187a459800caa0761d65b2dcf24dcf4bdf13afefcbb1d2eb8c56047017d51eb2dcc9c7f02d1dbed594386ae188cf7658b3e4bb5dd65299d5ab6370285e0a21f1be43edd29f3803e8e7b8dbac04626a90fa94ac23831885ae7fa09db1b3028757e", + "role": "User", + "createdAt": { + "$date": "2023-08-09T10:02:08.050Z" + }, + "updatedAt": { + "$date": "2023-08-09T10:02:38.743Z" + }, + "__v": 0, + "image": "/assets/images/user_avatar.jpg" +}, +{ + "_id": { + "$oid": "64d397d9f42bebe5d162619e" + }, + "favorites": [], + "following": [], + "username": "antoine_vincent", + "email": "avincent@aucoffre.com", + "firstname": "Antoine", + "lastname": "Vincent", + "phone": "0788834747", + "society": "AuCoffre", + "pseudoAC": "", + "salt": "fb310aa95696dcec3351d03c9a68855b", + "hash": "2f00be603829a8c30f89b9d6a9bc0a0123aa921c31d10246e3000ca93ae329a0b12e54eec5091a5c30fec9e3c9bcfc9cdad2991786ed2f87a19618e1ac2521754d0329235709b86de82f655903f75d680fb0bc5836017f0a1d54c28212f4eb81f9255d3bc24815ba67a922498b1ef0e0c4ae125f5346d6abf0136663ff8df1c9eac8974fe9a9874bf699877652375c12fa2618ce96fed6a1eedf205a2311ada78d829d48fa7f688a6e820fe1dfa2762a430bf7132ef6826005fa186ce849fc6dbda112983d8504e53d5cf5a3bcd160e62905a72ece2c7e73d0b0c3163ecc09c217084d9009b0f301b9235961b7286a06ee235ab980d1eee37128bfd5b9b65d46377ca315eaeb283192d80e0d83fda5eac79cd9c39b9cdaf0cb11b553204a8cd27fb678550fb3d6676f94f5e8e1727d0d94914993d75c8142d6d8792da497ebb76a93d006850fd17bad826cfae6367dd315740293353b22f23553a43e4689678bcfe553500e6a49605a6f7668c6d03c05705a3365986119a57cfdcb9c4b6a58e73aa9cbbed1719673dc08b3a5da06e28cad2775fce88a5d844c9deb29bb23b50e36ae9fb813d95b6919eea975f38d47401cca8ff2e7320b5ead2b2a3481167129b97c4432fc9f4f0d658c5cc6be300a90fdcf4864291bafd09d209fbeac74ef80606f3c9a1b4249413e277067b31d9100cf7974c6c017f5597c0b442dc4e2dfed", + "role": "User", + "createdAt": { + "$date": "2023-08-09T13:42:49.353Z" + }, + "updatedAt": { + "$date": "2023-08-09T13:42:49.353Z" + }, + "__v": 0 +}] \ No newline at end of file diff --git a/src/app/components/qcm/headupdb.qcm_categories.json b/src/app/components/qcm/headupdb.qcm_categories.json new file mode 100644 index 0000000..2278252 --- /dev/null +++ b/src/app/components/qcm/headupdb.qcm_categories.json @@ -0,0 +1,112 @@ +[{ + "_id": { + "$oid": "652075758a2b41cd02ad2f4c" + }, + "num": 1, + "name": "Aéronefs", + "questions": [] +}, +{ + "_id": { + "$oid": "652075758a2b41cd02ad2f4d" + }, + "num": 2, + "name": "Altimètre", + "questions": [] +}, +{ + "_id": { + "$oid": "652075758a2b41cd02ad2f4e" + }, + "num": 3, + "name": "Déclencheurs et matériels", + "questions": [] +}, +{ + "_id": { + "$oid": "652075758a2b41cd02ad2f4f" + }, + "num": 4, + "name": "Largage", + "questions": [] +}, +{ + "_id": { + "$oid": "652075758a2b41cd02ad2f50" + }, + "num": 5, + "name": "Règlementation", + "questions": [] +}, +{ + "_id": { + "$oid": "652075758a2b41cd02ad2f51" + }, + "num": 6, + "name": "Pilotage et mécanique de vol", + "questions": [] +}, +{ + "_id": { + "$oid": "652075758a2b41cd02ad2f52" + }, + "num": 7, + "name": "Physiologie", + "questions": [] +}, +{ + "_id": { + "$oid": "652075758a2b41cd02ad2f53" + }, + "num": 8, + "name": "Connaissances générales", + "questions": [] +}, +{ + "_id": { + "$oid": "652075758a2b41cd02ad2f54" + }, + "num": 9, + "name": "Unités de mesure", + "questions": [] +}, +{ + "_id": { + "$oid": "652075758a2b41cd02ad2f55" + }, + "num": 10, + "name": "Altimétrie", + "questions": [] +}, +{ + "_id": { + "$oid": "652075758a2b41cd02ad2f56" + }, + "num": 11, + "name": "Météorologie et aérologie", + "questions": [] +}, +{ + "_id": { + "$oid": "652075758a2b41cd02ad2f57" + }, + "num": 12, + "name": "Sauts spéciaux", + "questions": [] +}, +{ + "_id": { + "$oid": "652075758a2b41cd02ad2f58" + }, + "num": 13, + "name": "Questions spécifiques au brevet C", + "questions": [] +}, +{ + "_id": { + "$oid": "652075758a2b41cd02ad2f59" + }, + "num": 14, + "name": "Questions spécifiques au brevet D", + "questions": [] +}] \ No newline at end of file diff --git a/src/app/components/qcm/headupdb.qcms.json b/src/app/components/qcm/headupdb.qcms.json new file mode 100644 index 0000000..26ed994 --- /dev/null +++ b/src/app/components/qcm/headupdb.qcms.json @@ -0,0 +1,143 @@ +[ + { + "_id": { + "$oid": "651f4b5beb17b73b9333b777" + }, + "name": "bpa", + "categories": [ + { + "$oid": "652075758a2b41cd02ad2f4c" + }, + { + "$oid": "652075758a2b41cd02ad2f4d" + }, + { + "$oid": "652075758a2b41cd02ad2f4e" + }, + { + "$oid": "652075758a2b41cd02ad2f4f" + }, + { + "$oid": "652075758a2b41cd02ad2f50" + }, + { + "$oid": "652075758a2b41cd02ad2f51" + }, + { + "$oid": "652075758a2b41cd02ad2f52" + }, + { + "$oid": "652075758a2b41cd02ad2f53" + }, + { + "$oid": "652075758a2b41cd02ad2f54" + }, + { + "$oid": "652075758a2b41cd02ad2f55" + }, + { + "$oid": "652075758a2b41cd02ad2f56" + }, + { + "$oid": "652075758a2b41cd02ad2f57" + } + ] + }, + { + "_id": { + "$oid": "651f4b91eb17b73b9333b778" + }, + "name": "c", + "categories": [ + { + "$oid": "652075758a2b41cd02ad2f4c" + }, + { + "$oid": "652075758a2b41cd02ad2f4d" + }, + { + "$oid": "652075758a2b41cd02ad2f4e" + }, + { + "$oid": "652075758a2b41cd02ad2f4f" + }, + { + "$oid": "652075758a2b41cd02ad2f50" + }, + { + "$oid": "652075758a2b41cd02ad2f51" + }, + { + "$oid": "652075758a2b41cd02ad2f52" + }, + { + "$oid": "652075758a2b41cd02ad2f53" + }, + { + "$oid": "652075758a2b41cd02ad2f54" + }, + { + "$oid": "652075758a2b41cd02ad2f55" + }, + { + "$oid": "652075758a2b41cd02ad2f56" + }, + { + "$oid": "652075758a2b41cd02ad2f57" + }, + { + "$oid": "652075758a2b41cd02ad2f58" + } + ] + }, + { + "_id": { + "$oid": "651f4bb2eb17b73b9333b779" + }, + "name": "d", + "categories": [ + { + "$oid": "652075758a2b41cd02ad2f4c" + }, + { + "$oid": "652075758a2b41cd02ad2f4d" + }, + { + "$oid": "652075758a2b41cd02ad2f4e" + }, + { + "$oid": "652075758a2b41cd02ad2f4f" + }, + { + "$oid": "652075758a2b41cd02ad2f50" + }, + { + "$oid": "652075758a2b41cd02ad2f51" + }, + { + "$oid": "652075758a2b41cd02ad2f52" + }, + { + "$oid": "652075758a2b41cd02ad2f53" + }, + { + "$oid": "652075758a2b41cd02ad2f54" + }, + { + "$oid": "652075758a2b41cd02ad2f55" + }, + { + "$oid": "652075758a2b41cd02ad2f56" + }, + { + "$oid": "652075758a2b41cd02ad2f57" + }, + { + "$oid": "652075758a2b41cd02ad2f58" + }, + { + "$oid": "652075758a2b41cd02ad2f59" + } + ] + } +] \ No newline at end of file diff --git a/src/app/components/qcm/qcm.component.html b/src/app/components/qcm/qcm.component.html new file mode 100644 index 0000000..37733a6 --- /dev/null +++ b/src/app/components/qcm/qcm.component.html @@ -0,0 +1,81 @@ +
+
+

+ {{ title }} + {{ questionsCount }} {{ questionsCount > 1 ? 'questions' : 'question' }} +

+ {{ subtitle }} +
+ +
+ + + @for (menuitem of menuItems.getMenuPanel(); track menuitem) { + + } + +
+
+ + +@if (questions.controls.length) { + +
+ + +
    + @for (answer of answers; track $index) { +
  1. {{ ($index + 1) }}
  2. + } +
+
+ +
+ @for (category of qcm.categories; track category; let index = $index) { + + + + + {{ category.num }} - {{ category.name }} + + + {{ category.questions.length }} {{ category.questions.length > 1 ? 'questions' : 'question' }} + - 0 réponse + + +
+ @for (question of category.questions; track question; let index = $index) { +
+ + + @for (choice of question.choices; track choice) { + {{ choice.libelle }} + } + +
+ } +
+
+
+ } +
+
+ +
+} diff --git a/src/app/components/qcm/qcm.component.scss b/src/app/components/qcm/qcm.component.scss new file mode 100644 index 0000000..7da2535 --- /dev/null +++ b/src/app/components/qcm/qcm.component.scss @@ -0,0 +1,37 @@ +/* QCM */ +@use 'variable' as var; + +ol.squareItems { + padding: 0; + margin: 1rem 0; + li { + color: var.$primary; + background-color: var.$sidenav-content; + background-image: none; + border: 1px solid var.$dark; + cursor: pointer; + float: left; + list-style-type: none; + margin: 0.17em; + padding: 0.34em 0; + text-align: center; + width: 33px; + height: 33px; + &.active { + border-color: var.$info; + } + &.valid { + color: var.$sidenav-content; + border-color: var.$success; + background-color: var.$primary; + } + &.defer { + border-color: var.$info-dark; + background-color: var.$navy-light; + } + &.error { + border-color: var.$purple-light; + background-color: var.$secondary; + } + } +} \ No newline at end of file diff --git a/src/app/components/qcm/qcm.component.spec.ts b/src/app/components/qcm/qcm.component.spec.ts new file mode 100644 index 0000000..5e4c639 --- /dev/null +++ b/src/app/components/qcm/qcm.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { QcmComponent } from './qcm.component'; + +describe('QcmComponent', () => { + let component: QcmComponent; + let fixture: ComponentFixture; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [QcmComponent] + }); + fixture = TestBed.createComponent(QcmComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/qcm/qcm.component.ts b/src/app/components/qcm/qcm.component.ts new file mode 100644 index 0000000..c096253 --- /dev/null +++ b/src/app/components/qcm/qcm.component.ts @@ -0,0 +1,218 @@ +import { Component, DestroyRef, inject, OnInit, OnDestroy } from '@angular/core'; +import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; +import { /*FormControl,*/ FormGroup, FormBuilder, FormArray, FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { ActivatedRoute } from '@angular/router'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatExpansionModule } from '@angular/material/expansion'; +import { MatIconModule } from '@angular/material/icon'; +import { MatMenuModule } from '@angular/material/menu'; +import { MatProgressBarModule } from '@angular/material/progress-bar'; +import { MatRadioModule } from '@angular/material/radio'; +import { MatSelectModule } from '@angular/material/select'; +import { interval, Observable, Subscription } from 'rxjs'; +import { take } from 'rxjs/operators'; + +import { MenuItems } from '@components/shared'; +import { ListErrorsComponent } from '@components/shared'; +import { Errors, Qcm, QcmCategory, QcmQuestion, QcmQuestionState, User } from '@models'; +import { QcmService, UserService } from '@services'; +import data from 'src/qcm-bpa.json'; + +@Component({ + selector: 'app-qcm', + standalone: true, + imports: [ + FormsModule, ReactiveFormsModule, + MatButtonModule, MatCardModule, MatDividerModule, MatExpansionModule, + MatIconModule, MatMenuModule, MatProgressBarModule, MatRadioModule, + MatSelectModule, + ListErrorsComponent + ], + templateUrl: './qcm.component.html', + styleUrl: './qcm.component.scss' +}) +export class QcmComponent implements OnInit, OnDestroy { + private _currentUser: Subscription = new Subscription(); + private _data: Subscription = new Subscription(); + private _timer: Subscription = new Subscription(); + private _refresh = 1000; + public qcm: Qcm = {} as Qcm; + public currentUser: User = {} as User; + public canModify = false; + public title = 'QCM Brevets'; + public subtitle = 'Préparation au questionnaires'; + public errors: Errors = { errors: {} }; + public destroyRef = inject(DestroyRef); + public expandedIndex = 0; + public questionsCount = 0; + public answers: Array = []; + public qcmForm!: FormGroup; + public loading = true; + public totalAnswer = 0; + public timeProgress = 0; + public timeProgressColor = 'primary'; + public timeMax = (60*45); + + constructor( + private route: ActivatedRoute, + private fb: FormBuilder, + private _qcmService: QcmService, + private _userService: UserService, + public menuItems: MenuItems + ) { + this.qcmForm = this.fb.group({ + questions: this.fb.array([]) + }); + } + + get questions(): FormArray { + return this.qcmForm.controls['questions'] as FormArray; + } + + ngOnInit() { + //this._importQuestions(); + //this._importChoices(); + // Retreive the prefetched QCM + const data$: Observable<{ qcm: Qcm }> = this.route.data as Observable<{ qcm: Qcm }>; + this._data = data$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data: { qcm: Qcm }) => { + this.questionsCount = 0; + this.qcm = data.qcm; + if (this.qcm.name === 'bpa') { + this.title = 'QCM du BPA'; + this.subtitle = 'Préparation au questionnaire du BPA'; + } else { + this.title = `QCM du brevet ${this.qcm.name.toUpperCase()}`; + this.subtitle = `Préparation au questionnaire du brevet ${this.qcm.name.toUpperCase()}`; + } + //console.log(this.title, this.qcm); + this.qcm.categories.forEach(category => { + this.questionsCount += category.questions.length; + category.questions.forEach(question => { + this.addQuestion(question); + }); + }); + }); + // Load the current user's data + const currentUser$: Observable = this._userService.currentUser; + this._currentUser = currentUser$.subscribe((userData: User) => { + this.currentUser = userData; + this.canModify = userData.role === 'Admin'; + }); + this.loading = false; + } + + ngOnDestroy() { + this._data.unsubscribe(); + this._currentUser.unsubscribe(); + } + + private _starTimer(): void { + this._timer = interval(1000) + .pipe(take(this.timeMax)) + .subscribe(() => { + this.timeProgress++; + if (this.timeProgress > (this.timeMax/100*70) && this.timeProgress <= (this.timeMax/100*90)) { + this.timeProgressColor = 'warning'; + } else if (this.timeProgress > (this.timeMax/100*90) && this.timeProgress <= (this.timeMax/100*98)) { + this.timeProgressColor = 'danger'; + } else if (this.timeProgress > (this.timeMax/100*98)) { + this.timeProgressColor = 'purple'; + } + if (this.timeProgress >= this.timeMax) { + this.timeProgressColor = 'accent'; + this._timer.unsubscribe(); + } + }); + } + + addQuestion(question: QcmQuestion) { + const item = this.fb.group({ + id: [question.num], + choice: [''] + }); + this.answers.push(QcmQuestionState.UNANSWERED); + this.questions.push(item); + } + + setExpandedIndex(index: number) { + this.expandedIndex = index; + } + + onChange(category: QcmCategory, question: QcmQuestion, value: unknown) { + //console.log('onChange', category.num, question.num, value); + if (this.timeProgress === 0) { + this._starTimer(); + } + this.qcm.categories[(category.num-1)].questions[(question.num-1)].choices.forEach(choice => { + if (choice.index === value) { + if (choice.correct) { + this.answers[(question.num-1)] = QcmQuestionState.VALID; + console.log(`Réponse à la question ${question.num} de la catégorie ${category.num} : correcte`); + } else { + this.answers[(question.num-1)] = QcmQuestionState.ERROR; + console.log(`Réponse à la question ${question.num} de la catégorie ${category.num} : incorrecte`); + } + } + }); + this.totalAnswer++; + this.questions.controls[(question.num-1)].disable(); + //console.log(this.questions.controls[(question.num-1)].disabled); + } + + onSubmit() { + console.log('onSubmit'); + } + + private _importChoices() { + try { + data.categories.forEach((category) => { + category.questions.forEach(question => { + this._qcmService.saveChoices(question) + .pipe(takeUntilDestroyed(this.destroyRef)) + .subscribe({ + next: (question) => { + console.log('question : ', question); + //console.log(`Le saut n°${jump.numero} a été ajouté !`, 'OK'); + }, + error: (err) => { + console.log('err : ', err); + //console.log(`Le saut n'a pas été ajouté !`, 'Error', err); + this.errors = err; + } + }); + }); + }); + } catch (error) { + console.error(error); + } + } + + private _importQuestions() { + try { + data.categories.forEach((category) => { + //Object.assign(this.jump, category); + this._qcmService.saveQuestions(category) + .pipe(takeUntilDestroyed(this.destroyRef)) + .subscribe({ + next: (category) => { + console.log('category : ', category); + //console.log(`Le saut n°${jump.numero} a été ajouté !`, 'OK'); + }, + error: (err) => { + console.log('err : ', err); + //console.log(`Le saut n'a pas été ajouté !`, 'Error', err); + this.errors = err; + } + }); + }); + } catch (error) { + console.error(error); + } + } + + private _resetErrors(): void { + this.errors = { errors: {} }; + } +} diff --git a/src/app/components/qcm/qcm_categories.json b/src/app/components/qcm/qcm_categories.json new file mode 100644 index 0000000..d5029e4 --- /dev/null +++ b/src/app/components/qcm/qcm_categories.json @@ -0,0 +1,72 @@ +[ + { + "num": 1, + "name": "Aéronefs", + "questions": [] + }, + { + "num": 2, + "name": "Altimètre", + "questions": [] + }, + { + "num": 3, + "name": "Déclencheurs et matériels", + "questions": [] + }, + { + "num": 4, + "name": "Largage", + "questions": [] + }, + { + "num": 5, + "name": "Règlementation", + "questions": [] + }, + { + "num": 6, + "name": "Pilotage et mécanique de vol", + "questions": [] + }, + { + "num": 7, + "name": "Physiologie", + "questions": [] + }, + { + "num": 8, + "name": "Connaissances générales", + "questions": [] + }, + { + "num": 9, + "name": "Unités de mesure", + "questions": [] + }, + { + "num": 10, + "name": "Altimétrie", + "questions": [] + }, + { + "num": 11, + "name": "Météorologie et aérologie", + "questions": [] + }, + { + "num": 12, + "name": "Sauts spéciaux", + "questions": [] + }, + { + "num": 13, + "name": "Questions spécifiques au brevet C", + "questions": [] + }, + { + "num": 14, + "name": "Questions spécifiques au brevet D", + "questions": [] + } +] \ No newline at end of file diff --git a/src/app/components/settings/credentials/credentials.component.html b/src/app/components/settings/credentials/credentials.component.html new file mode 100644 index 0000000..ca288e8 --- /dev/null +++ b/src/app/components/settings/credentials/credentials.component.html @@ -0,0 +1,48 @@ + +
+

{{title}}

+ + +
+
+
+
+
+ Mise à jour du mot de passe +
+ + Mot de passe + + +
+
+ + Confirmation du mot de passe + + +
+
+ +
+
+
+
+
+
+
diff --git a/src/app/components/settings/credentials/credentials.component.scss b/src/app/components/settings/credentials/credentials.component.scss new file mode 100644 index 0000000..0fd0cde --- /dev/null +++ b/src/app/components/settings/credentials/credentials.component.scss @@ -0,0 +1,16 @@ +/* Credentials */ +//@use 'variable' as var; +// --> background-color: var.$sidebar-footer; + +/* Chrome, Safari, Edge, Opera */ +input::-webkit-outer-spin-button, +input::-webkit-inner-spin-button { + appearance: none; + -webkit-appearance: none; + margin: 0; +} +/* Firefox */ +input[type=number] { + appearance: textfield; + -moz-appearance: textfield; +} \ No newline at end of file diff --git a/src/app/components/settings/credentials/credentials.component.spec.ts b/src/app/components/settings/credentials/credentials.component.spec.ts new file mode 100644 index 0000000..fab6017 --- /dev/null +++ b/src/app/components/settings/credentials/credentials.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CredentialsComponent } from './credentials.component'; + +describe('CredentialsComponent', () => { + let component: CredentialsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [CredentialsComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CredentialsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/settings/credentials/credentials.component.ts b/src/app/components/settings/credentials/credentials.component.ts new file mode 100644 index 0000000..a1a7dd9 --- /dev/null +++ b/src/app/components/settings/credentials/credentials.component.ts @@ -0,0 +1,95 @@ +import { Component, DestroyRef, inject, OnInit, OnDestroy } from '@angular/core'; +import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; +import { AbstractControl, FormsModule, ReactiveFormsModule, UntypedFormBuilder, UntypedFormGroup, Validators, ValidatorFn, ValidationErrors } from '@angular/forms'; +import { Router, RouterLink } from '@angular/router'; +import { Title } from '@angular/platform-browser'; +import { MatButtonModule } from '@angular/material/button'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatIconModule } from '@angular/material/icon'; +import { MatInputModule } from '@angular/material/input'; + +import { Observable, Subscription } from 'rxjs'; + +import { Errors, User } from '@models'; +import { UserService } from '@services'; +import { ListErrorsComponent } from '@components/shared'; + +@Component({ + selector: 'app-credentials', + standalone: true, + imports: [ + RouterLink, FormsModule, ReactiveFormsModule, + MatButtonModule, MatIconModule, MatFormFieldModule, MatInputModule, MatDividerModule, + ListErrorsComponent + ], + templateUrl: './credentials.component.html', + styleUrl: './credentials.component.scss' +}) +export class CredentialsComponent implements OnInit, OnDestroy { + private _user: Subscription = new Subscription(); + title = 'Modifier le mot de passe'; + bannerTitle = ''; + btnUpdateTitle = 'Mettre à jour'; + btnLogoutTitle = 'Se déconnecter'; + user: Partial = {} as Partial; + credentialsForm: UntypedFormGroup; + errors: Errors = { errors: {} }; + isSubmitting = false; + destroyRef = inject(DestroyRef); + + constructor( + private router: Router, + private titleService: Title, + private userService: UserService, + private fb: UntypedFormBuilder + ) { + this.credentialsForm = this.fb.group({ + password: ['', Validators.required], + confirmPassword: ['', Validators.required] + }, { validators: this.checkPasswords }); + } + + get f() { + return this.credentialsForm.controls; + } + + ngOnInit() { + this.titleService.setTitle(`Ad Astra - ${this.title}`); + Object.assign(this.user, this.userService.getCurrentUser()); + this.credentialsForm.patchValue(this.user); + if (this.user.username) { + this.bannerTitle = `@${this.user.username}`; + } else { + this.bannerTitle = `${this.user.firstname} ${this.user.lastname}`; + } + } + + ngOnDestroy() { + this._user.unsubscribe(); + } + + submitForm() { + this.isSubmitting = true; + this.updateUser(this.credentialsForm.value); + const user$: Observable<{ user: User }> = this.userService.update(this.user).pipe(takeUntilDestroyed(this.destroyRef)); + this._user = user$.subscribe({ + next: ({ user }) => void this.router.navigateByUrl('/profile/' + user.username), + error: (err) => { + this.errors = err; + this.isSubmitting = false; + } + }); + } + + updateUser(values: NonNullable) { + Object.assign(this.user, values); + } + + checkPasswords: ValidatorFn = (group: AbstractControl): ValidationErrors | null => { + const pass = group.get('password')!.value; + const confirmPass = group.get('confirmPassword')!.value + return pass === confirmPass ? null : { notSame: true } + } + +} diff --git a/src/app/components/settings/index.ts b/src/app/components/settings/index.ts new file mode 100644 index 0000000..c134636 --- /dev/null +++ b/src/app/components/settings/index.ts @@ -0,0 +1,2 @@ +export * from './credentials/credentials.component'; +export * from './settings.component'; \ No newline at end of file diff --git a/src/app/components/settings/settings.component.html b/src/app/components/settings/settings.component.html new file mode 100644 index 0000000..3cc2563 --- /dev/null +++ b/src/app/components/settings/settings.component.html @@ -0,0 +1,88 @@ + +
+

{{title}}

+ + +
+
+
+
+
+ Informations personnelles +
+ + Nom d'utilisateur + + +
+
+ + eMail + + +
+
+ + Nom + + +
+
+ + Prénom + + +
+
+ + Numéro de téléphone + + +
+
+ + Photo de profil + + @for (avatar of avatars; track avatar; let idx = $index) { + + Avatar {{ idx + 1 }} + Image {{ idx + 1 }} + + } + + +
+
+
+ Informations de connexion +
+ + + + +
+
+
+
+
+
+
diff --git a/src/app/components/settings/settings.component.scss b/src/app/components/settings/settings.component.scss new file mode 100644 index 0000000..ab303f4 --- /dev/null +++ b/src/app/components/settings/settings.component.scss @@ -0,0 +1,26 @@ +/* Settings */ +//@use 'variable' as var; +// --> background-color: var.$sidebar-footer; + +.settings-page > .container { + margin-top: 2.4rem; + margin-bottom: 2.6rem; + padding-bottom: 1rem; +} +img.avatar { + max-height: 32px; + margin-right: 8px; +} + +/* Chrome, Safari, Edge, Opera */ +input::-webkit-outer-spin-button, +input::-webkit-inner-spin-button { + appearance: none; + -webkit-appearance: none; + margin: 0; +} +/* Firefox */ +input[type=number] { + appearance: textfield; + -moz-appearance: textfield; +} diff --git a/src/app/components/settings/settings.component.spec.ts b/src/app/components/settings/settings.component.spec.ts new file mode 100644 index 0000000..f905de3 --- /dev/null +++ b/src/app/components/settings/settings.component.spec.ts @@ -0,0 +1,24 @@ +import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SettingsComponent } from './settings.component'; + +describe('SettingsComponent', () => { + let component: SettingsComponent; + let fixture: ComponentFixture; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + imports: [SettingsComponent] + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(SettingsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/settings/settings.component.ts b/src/app/components/settings/settings.component.ts new file mode 100644 index 0000000..dd472ab --- /dev/null +++ b/src/app/components/settings/settings.component.ts @@ -0,0 +1,127 @@ +import { Component, DestroyRef, inject, OnInit, OnDestroy } from '@angular/core'; +import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; +import { FormsModule, ReactiveFormsModule, UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; +import { Router, RouterLink } from '@angular/router'; +import { Title } from '@angular/platform-browser'; +import { MatButtonModule } from '@angular/material/button'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatIconModule } from '@angular/material/icon'; +import { MatInputModule } from '@angular/material/input'; +import { MatSelectModule } from '@angular/material/select'; + +import { Observable, Subscription } from 'rxjs'; + +import { Errors, User } from '@models'; +import { UserService } from '@services'; +import { ListErrorsComponent } from '@components/shared'; + +@Component({ + selector: 'app-settings-page', + standalone: true, + imports: [ + RouterLink, FormsModule, ReactiveFormsModule, + MatButtonModule, MatIconModule, MatDividerModule, MatFormFieldModule, MatInputModule, MatSelectModule, + ListErrorsComponent + ], + styleUrl: './settings.component.scss', + templateUrl: './settings.component.html' +}) +export class SettingsComponent implements OnInit, OnDestroy { + private _user: Subscription = new Subscription(); + title = 'Vos paramètres'; + bannerTitle = ''; + btnUpdateTitle = 'Mettre à jour'; + btnLogoutTitle = 'Se déconnecter'; + btnPasswordTitle = 'Changer le mot de passe'; + user: Partial = {} as Partial; + settingsForm: UntypedFormGroup; + errors: Errors = { errors: {} }; + isSubmitting = false; + destroyRef = inject(DestroyRef); + imgPath = '/assets/images/avatars/'; + imgExt = '.jpg'; + avatars = [ + `${this.imgPath}animal_001${this.imgExt}`, `${this.imgPath}animal_002${this.imgExt}`, + `${this.imgPath}animal_003${this.imgExt}`, `${this.imgPath}animal_004${this.imgExt}`, + `${this.imgPath}animal_005${this.imgExt}`, `${this.imgPath}animal_006${this.imgExt}`, + `${this.imgPath}animal_007${this.imgExt}`, `${this.imgPath}animal_008${this.imgExt}`, + `${this.imgPath}animal_009${this.imgExt}`, `${this.imgPath}animal_010${this.imgExt}`, + `${this.imgPath}animal_011${this.imgExt}`, `${this.imgPath}animal_012${this.imgExt}`, + `${this.imgPath}animal_013${this.imgExt}`, `${this.imgPath}animal_014${this.imgExt}`, + `${this.imgPath}animal_015${this.imgExt}`, `${this.imgPath}animal_016${this.imgExt}` + ]; + + constructor( + private router: Router, + private titleService: Title, + private userService: UserService, + private fb: UntypedFormBuilder + ) { + // create form group using the form builder + this.settingsForm = this.fb.group({ + username: ['', Validators.required], + email: ['', [Validators.required, Validators.email]], + firstname: ['', Validators.required], + lastname: ['', Validators.required], + phone: ['', Validators.required], + image: '' + }); + // Optional: subscribe to changes on the form : + // this.settingsForm.valueChanges.pipe(this._scavenger.collect()).subscribe(values => this.updateUser(values)); + } + + get f() { + return this.settingsForm.controls; + } + + ngOnInit() { + this.titleService.setTitle(`Ad Astra - ${this.title}`); + // Make a fresh copy of the current user's object to place in editable form fields + Object.assign(this.user, this.userService.getCurrentUser()); + // Fill the form + this.settingsForm.patchValue(this.user); + if (this.user.username) { + this.bannerTitle = `@${this.user.username}`; + } else { + this.bannerTitle = `${this.user.firstname} ${this.user.lastname}`; + } + } + + ngOnDestroy() { + this._user.unsubscribe(); + } + + logout() { + this.userService.purgeAuth(); + this.router.navigateByUrl('/login'); + } + + updatePass() { + this.router.navigateByUrl('/settings/credentials'); + } + + submitForm() { + this.isSubmitting = true; + + /* Update the model */ + if (this.avatars.indexOf(this.settingsForm.value.image) === -1) { + this.settingsForm.value.image = `${this.imgPath}animal_001${this.imgExt}`; + } + this.updateUser(this.settingsForm.value); + + const user$: Observable<{ user: User }> = this.userService.update(this.user).pipe(takeUntilDestroyed(this.destroyRef)); + this._user = user$.subscribe({ + next: ({ user }) => void this.router.navigateByUrl('/profile/' + user.username), + error: (err) => { + this.errors = err; + this.isSubmitting = false; + } + }); + } + + updateUser(values: NonNullable) { + Object.assign(this.user, values); + } + +} diff --git a/src/app/components/shared/accordion/accordion.directive.ts b/src/app/components/shared/accordion/accordion.directive.ts new file mode 100755 index 0000000..0615641 --- /dev/null +++ b/src/app/components/shared/accordion/accordion.directive.ts @@ -0,0 +1,55 @@ +import { Directive, AfterContentChecked } from '@angular/core'; +import { Router, NavigationEnd } from '@angular/router'; + +import { AccordionLinkDirective } from './accordionlink.directive'; +import { filter } from 'rxjs/operators'; + +@Directive({ + selector: '[appAccordion]', + standalone: true +}) +export class AccordionDirective implements AfterContentChecked { + protected navlinks: Array = []; + + closeOtherLinks(selectedLink: AccordionLinkDirective): void { + this.navlinks.forEach((link: AccordionLinkDirective) => { + if (link !== selectedLink) { + link.selected = false; + } + }); + } + + addLink(link: AccordionLinkDirective): void { + this.navlinks.push(link); + } + + removeGroup(link: AccordionLinkDirective): void { + const index = this.navlinks.indexOf(link); + if (index !== -1) { + this.navlinks.splice(index, 1); + } + } + + checkOpenLinks() { + this.navlinks.forEach((link: AccordionLinkDirective) => { + if (link.group) { + const routeUrl = this.router.url; + const currentUrl = routeUrl.split('/'); + if (currentUrl.indexOf(link.group) > 0) { + link.selected = true; + this.closeOtherLinks(link); + } + } + }); + } + + ngAfterContentChecked(): void { + this.router.events + .pipe(filter(event => event instanceof NavigationEnd)) + .subscribe(() => this.checkOpenLinks()); + } + + constructor(private router: Router) { + setTimeout(() => this.checkOpenLinks()); + } +} diff --git a/src/app/components/shared/accordion/accordionanchor.directive.ts b/src/app/components/shared/accordion/accordionanchor.directive.ts new file mode 100755 index 0000000..2207736 --- /dev/null +++ b/src/app/components/shared/accordion/accordionanchor.directive.ts @@ -0,0 +1,20 @@ +import { Directive, HostListener, Inject } from '@angular/core'; + +import { AccordionLinkDirective } from './accordionlink.directive'; + +@Directive({ + selector: '[appAccordionToggle]', + standalone: true +}) +export class AccordionAnchorDirective { + protected navlink: AccordionLinkDirective; + + constructor(@Inject(AccordionLinkDirective) navlink: AccordionLinkDirective) { + this.navlink = navlink; + } + + @HostListener('click', ['$event']) + onClick() { + this.navlink.toggle(); + } +} diff --git a/src/app/components/shared/accordion/accordionlink.directive.ts b/src/app/components/shared/accordion/accordionlink.directive.ts new file mode 100755 index 0000000..daf7ffe --- /dev/null +++ b/src/app/components/shared/accordion/accordionlink.directive.ts @@ -0,0 +1,51 @@ +import { + Directive, + HostBinding, + Inject, + Input, + OnInit, + OnDestroy +} from '@angular/core'; + +import { AccordionDirective } from './accordion.directive'; + +@Directive({ + selector: '[appAccordionLink]', + standalone: true +}) +export class AccordionLinkDirective implements OnInit, OnDestroy { + @Input() + public group!: string; + + @HostBinding('class.selected') + @Input() + get selected(): boolean { + return this._selected; + } + + set selected(value: boolean) { + this._selected = value; + if (value) { + this.nav.closeOtherLinks(this); + } + } + + protected _selected: boolean = false; + protected nav: AccordionDirective; + + constructor(@Inject(AccordionDirective) nav: AccordionDirective) { + this.nav = nav; + } + + ngOnInit() { + this.nav.addLink(this); + } + + ngOnDestroy(){ + this.nav.removeGroup(this); + } + + toggle() { + this.selected = !this.selected; + } +} diff --git a/src/app/components/shared/accordion/index.ts b/src/app/components/shared/accordion/index.ts new file mode 100755 index 0000000..e6673a9 --- /dev/null +++ b/src/app/components/shared/accordion/index.ts @@ -0,0 +1,3 @@ +export * from './accordionanchor.directive'; +export * from './accordionlink.directive'; +export * from './accordion.directive'; diff --git a/src/app/components/shared/card-container/card-container.component.html b/src/app/components/shared/card-container/card-container.component.html new file mode 100644 index 0000000..3091544 --- /dev/null +++ b/src/app/components/shared/card-container/card-container.component.html @@ -0,0 +1,16 @@ + + +
+ + {{ title }} + +
+ +
+ {{ subtitle }} +
+
+ + + +
\ No newline at end of file diff --git a/src/app/components/shared/card-container/card-container.component.ts b/src/app/components/shared/card-container/card-container.component.ts new file mode 100644 index 0000000..37f33d3 --- /dev/null +++ b/src/app/components/shared/card-container/card-container.component.ts @@ -0,0 +1,18 @@ +import { Component, Input } from '@angular/core'; +import { NgForOf, NgIf } from "@angular/common"; +import { MatCardModule } from '@angular/material/card'; + +import { CardColors } from 'src/app/core'; + +@Component({ + selector: 'app-card-container', + templateUrl: './card-container.component.html', + standalone: true, + imports: [NgIf, NgForOf, MatCardModule] +}) +export class CardContainerComponent { + errorList: string[] = []; + @Input() colors: CardColors = { background: 'bg-megna', text: 'text-bg-primary' }; + @Input() title: string = 'Title'; + @Input() subtitle: string = 'Subtitle'; +} \ No newline at end of file diff --git a/src/app/components/shared/confirmed.validator.ts b/src/app/components/shared/confirmed.validator.ts new file mode 100644 index 0000000..84786bb --- /dev/null +++ b/src/app/components/shared/confirmed.validator.ts @@ -0,0 +1,17 @@ +import { FormGroup } from '@angular/forms'; + +export function ConfirmedValidator(controlName: string, matchingControlName: string){ + return (formGroup: FormGroup) => { + const control = formGroup.controls[controlName]; + const matchingControl = formGroup.controls[matchingControlName]; + + if (matchingControl.errors && !matchingControl.errors['confirmedValidator']) { + return; + } + if (control.value !== matchingControl.value) { + matchingControl.setErrors({ confirmedValidator: true }); + } else { + matchingControl.setErrors(null); + } + } +} \ No newline at end of file diff --git a/src/app/components/shared/dashboard-components/aeronefs-bar/aeronefs-bar.component.html b/src/app/components/shared/dashboard-components/aeronefs-bar/aeronefs-bar.component.html new file mode 100755 index 0000000..d4e72d4 --- /dev/null +++ b/src/app/components/shared/dashboard-components/aeronefs-bar/aeronefs-bar.component.html @@ -0,0 +1,42 @@ + + + {{ title }} + {{ subtitle }} + + + + @for (menuitem of menuItems.getMenuPanel(); track menuitem) { + + } + + + + + @if (displayCharts) { + + } + + + + + + Historique annuel + + + + + + diff --git a/src/app/components/shared/dashboard-components/aeronefs-bar/aeronefs-bar.component.scss b/src/app/components/shared/dashboard-components/aeronefs-bar/aeronefs-bar.component.scss new file mode 100755 index 0000000..e69de29 diff --git a/src/app/components/shared/dashboard-components/aeronefs-bar/aeronefs-bar.component.spec.ts b/src/app/components/shared/dashboard-components/aeronefs-bar/aeronefs-bar.component.spec.ts new file mode 100755 index 0000000..2dbed21 --- /dev/null +++ b/src/app/components/shared/dashboard-components/aeronefs-bar/aeronefs-bar.component.spec.ts @@ -0,0 +1,25 @@ +import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AeronefsBarComponent } from './aeronefs-bar.component'; + +describe('AeronefsBarComponent', () => { + let component: AeronefsBarComponent; + let fixture: ComponentFixture; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + imports: [AeronefsBarComponent] +}) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(AeronefsBarComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/shared/dashboard-components/aeronefs-bar/aeronefs-bar.component.ts b/src/app/components/shared/dashboard-components/aeronefs-bar/aeronefs-bar.component.ts new file mode 100755 index 0000000..adc8d60 --- /dev/null +++ b/src/app/components/shared/dashboard-components/aeronefs-bar/aeronefs-bar.component.ts @@ -0,0 +1,95 @@ +import { Component, DestroyRef, inject, OnInit, OnDestroy } from '@angular/core'; +import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatExpansionModule } from '@angular/material/expansion'; +import { MatIconModule } from '@angular/material/icon'; +import { MatMenuModule } from '@angular/material/menu'; +import { Observable, Subscription } from 'rxjs'; + +import { MenuItems } from '@components/shared'; +import { BarHorizontalChartComponent } from '@components/shared/helpers-chart'; +import { HistoryTableComponent } from '@components/shared/helpers-jump'; +import { UtilitiesService, AeronefsService } from '@services'; +import { AeronefByImat, AeronefByYear } from '@models'; + +@Component({ + selector: 'app-aeronefs-bar', + standalone: true, + imports: [ + MatButtonModule, MatCardModule, MatDividerModule, + MatExpansionModule, MatIconModule, MatMenuModule, + BarHorizontalChartComponent, HistoryTableComponent + ], + templateUrl: './aeronefs-bar.component.html' +}) +export class AeronefsBarComponent implements OnInit, OnDestroy { + private _aeronefByImat: Subscription = new Subscription(); + private _aeronefByYear: Subscription = new Subscription(); + private _aeronefsByImat!: Array; + private _aeronefsByYear!: Array; + public title: string = 'Aéronefs'; + public subtitle: string = 'Nombre total de sauts par aéronef'; + public seriesHeader: string[] = []; + public seriesName: string[] = []; + public seriesValue: number[] = []; + public seriesRow: Array> = []; + public seriesColor: { + backgroundColor: string[], + borderColor: string[] + } = { + backgroundColor: this._utilitiesService.getSeriesColors(0.8, 'all'), + borderColor: this._utilitiesService.getSeriesColors(1, 'all') + }; + public seriesColorClass: string[] = this._utilitiesService.getChartColors(); + public displayCharts = false; + public destroyRef = inject(DestroyRef); + + constructor( + private _aeronefsService: AeronefsService, + private _utilitiesService: UtilitiesService, + public menuItems: MenuItems + ) { } + + ngOnInit() { + this._loadAeronefByImat(); + } + + ngOnDestroy() { + this._aeronefByImat.unsubscribe(); + this._aeronefByYear.unsubscribe(); + } + + private _loadAeronefByImat(): void { + const aeronefs$: Observable> = this._aeronefsService.getAllByImat().pipe(takeUntilDestroyed(this.destroyRef)); + this._aeronefByImat = aeronefs$.subscribe((aggregate: Array) => { + this._aeronefsByImat = aggregate.map((row: AeronefByImat) => { + //this.chartConfig.barChartData.labels!.push(`${row.aeronef} ${row.imat}`); + this.seriesName.push(`${row.aeronef} ${row.imat}`); + this.seriesValue.push(row.count); + return row; + }); + this._loadAeronefByYear(); + }); + } + + private _loadAeronefByYear(): void { + this.seriesHeader = ['2018', '2019', '2020', '2021', '2022', '2023', '2024']; + const values: Array = this.seriesHeader.map(() => 0); + this.seriesName.forEach(() => { + this.seriesRow.push([...values]); + }); + const dropzones$: Observable> = this._aeronefsService.getAllByImatByYear().pipe(takeUntilDestroyed(this.destroyRef)); + this._aeronefByYear = dropzones$.subscribe((aggregate: Array) => { + this._aeronefsByYear = aggregate.map((row: AeronefByYear) => { + const aeronef: string = row.aeronef; + const imat: string = row.imat; + const year: string = row.year.toString(); + this.seriesRow[this.seriesName.indexOf(`${aeronef} ${imat}`)][this.seriesHeader.indexOf(year)] = row.count; + return row; + }); + this.displayCharts = true; + }); + } +} diff --git a/src/app/components/shared/dashboard-components/aeronefs-pie/aeronefs-pie.component.html b/src/app/components/shared/dashboard-components/aeronefs-pie/aeronefs-pie.component.html new file mode 100755 index 0000000..c912ae1 --- /dev/null +++ b/src/app/components/shared/dashboard-components/aeronefs-pie/aeronefs-pie.component.html @@ -0,0 +1,42 @@ + + + {{ title }} + {{ subtitle }} + + + + @for (menuitem of menuItems.getMenuPanel(); track menuitem) { + + } + + + + + + + + + + + Historique annuel + + + + + + diff --git a/src/app/components/shared/dashboard-components/aeronefs-pie/aeronefs-pie.component.scss b/src/app/components/shared/dashboard-components/aeronefs-pie/aeronefs-pie.component.scss new file mode 100755 index 0000000..e69de29 diff --git a/src/app/components/shared/dashboard-components/aeronefs-pie/aeronefs-pie.component.spec.ts b/src/app/components/shared/dashboard-components/aeronefs-pie/aeronefs-pie.component.spec.ts new file mode 100755 index 0000000..b0af50a --- /dev/null +++ b/src/app/components/shared/dashboard-components/aeronefs-pie/aeronefs-pie.component.spec.ts @@ -0,0 +1,25 @@ +import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AeronefsPieComponent } from './aeronefs-pie.component'; + +describe('AeronefsPieComponent', () => { + let component: AeronefsPieComponent; + let fixture: ComponentFixture; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + imports: [AeronefsPieComponent] +}) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(AeronefsPieComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/shared/dashboard-components/aeronefs-pie/aeronefs-pie.component.ts b/src/app/components/shared/dashboard-components/aeronefs-pie/aeronefs-pie.component.ts new file mode 100755 index 0000000..6aae2d3 --- /dev/null +++ b/src/app/components/shared/dashboard-components/aeronefs-pie/aeronefs-pie.component.ts @@ -0,0 +1,93 @@ +import { Component, DestroyRef, inject, OnInit, OnDestroy } from '@angular/core'; +import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; +import { MatBadgeModule } from '@angular/material/badge'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatExpansionModule } from '@angular/material/expansion'; +import { MatIconModule } from '@angular/material/icon'; +import { MatMenuModule } from '@angular/material/menu'; +import { Observable, Subscription } from 'rxjs'; + +import { MenuItems } from '@components/shared'; +import { HistoryTableComponent } from '@components/shared/helpers-jump'; +import { PieChartComponent } from '@components/shared/helpers-chart'; +import { UtilitiesService, AeronefsService } from '@services'; +import { AeronefByImat, AeronefByYear } from '@models'; + +@Component({ + selector: 'app-aeronefs-pie', + standalone: true, + imports: [ + MatBadgeModule, MatButtonModule, MatCardModule, MatDividerModule, + MatExpansionModule, MatIconModule, MatMenuModule, + HistoryTableComponent, PieChartComponent + ], + templateUrl: './aeronefs-pie.component.html' +}) +export class AeronefsPieComponent implements OnInit, OnDestroy { + private _aeronefByImat: Subscription = new Subscription(); + private _aeronefByYear: Subscription = new Subscription(); + private _aeronefsByImat!: Array; + private _aeronefsByYear!: Array; + public title: string = 'Aéronefs'; + public subtitle: string = 'Nombre total de sauts par aéronef'; + public seriesHeader: string[] = []; + public seriesName: string[] = []; + public seriesValue: number[] = []; + public seriesRow: Array> = []; + public seriesColor: { + backgroundColor: string[], + borderColor: string[] + } = { + backgroundColor: this._utilitiesService.getSeriesColors(0.8, 'all'), + borderColor: this._utilitiesService.getSeriesColors(1, 'all') + }; + public seriesColorClass: string[] = this._utilitiesService.getChartColors(); + public destroyRef = inject(DestroyRef); + + constructor( + private _aeronefsService: AeronefsService, + private _utilitiesService: UtilitiesService, + public menuItems: MenuItems + ) { } + + ngOnInit() { + this._loadAeronefByImat(); + } + + ngOnDestroy() { + this._aeronefByImat.unsubscribe(); + this._aeronefByYear.unsubscribe(); + } + + private _loadAeronefByImat(): void { + const aeronefs$: Observable> = this._aeronefsService.getAllByImat().pipe(takeUntilDestroyed(this.destroyRef)); + this._aeronefByImat = aeronefs$.subscribe((aggregate: Array) => { + this._aeronefsByImat = aggregate.map((row: AeronefByImat) => { + this.seriesName.push(`${row.aeronef} ${row.imat}`); + this.seriesValue.push(row.count); + return row; + }); + this._loadAeronefByYear(); + }); + } + + private _loadAeronefByYear(): void { + this.seriesHeader = ['2018', '2019', '2020', '2021', '2022', '2023', '2024']; + const values: Array = this.seriesHeader.map(() => 0); + this.seriesName.forEach(() => { + this.seriesRow.push([...values]); + }); + const dropzones$: Observable> = this._aeronefsService.getAllByImatByYear().pipe(takeUntilDestroyed(this.destroyRef)); + this._aeronefByYear = dropzones$.subscribe((aggregate: Array) => { + this._aeronefsByYear = aggregate.map((row: AeronefByYear) => { + const aeronef: string = row.aeronef; + const imat: string = row.imat; + const year: string = row.year.toString(); + this.seriesRow[this.seriesName.indexOf(`${aeronef} ${imat}`)][this.seriesHeader.indexOf(year)] = row.count; + return row; + }); + }); + } +} diff --git a/src/app/components/shared/dashboard-components/canopies-models/canopies-models.component.html b/src/app/components/shared/dashboard-components/canopies-models/canopies-models.component.html new file mode 100755 index 0000000..dc4d4c3 --- /dev/null +++ b/src/app/components/shared/dashboard-components/canopies-models/canopies-models.component.html @@ -0,0 +1,31 @@ + + + {{ title }} + {{ subtitle }} + + + + @for (menuitem of menuItems.getMenuPanel(); track menuitem) { + + } + + + + + + + + + + + Historique annuel + + + + + diff --git a/src/app/components/shared/dashboard-components/canopies-models/canopies-models.component.scss b/src/app/components/shared/dashboard-components/canopies-models/canopies-models.component.scss new file mode 100755 index 0000000..e69de29 diff --git a/src/app/components/shared/dashboard-components/canopies-models/canopies-models.component.spec.ts b/src/app/components/shared/dashboard-components/canopies-models/canopies-models.component.spec.ts new file mode 100755 index 0000000..c80607c --- /dev/null +++ b/src/app/components/shared/dashboard-components/canopies-models/canopies-models.component.spec.ts @@ -0,0 +1,25 @@ +import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CanopiesModelsComponent } from './canopies-models.component'; + +describe('CanopiesModelsComponent', () => { + let component: CanopiesModelsComponent; + let fixture: ComponentFixture; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + imports: [CanopiesModelsComponent] +}) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(CanopiesModelsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/shared/dashboard-components/canopies-models/canopies-models.component.ts b/src/app/components/shared/dashboard-components/canopies-models/canopies-models.component.ts new file mode 100755 index 0000000..0dc7da6 --- /dev/null +++ b/src/app/components/shared/dashboard-components/canopies-models/canopies-models.component.ts @@ -0,0 +1,92 @@ +import { Component, DestroyRef, inject, OnInit, OnDestroy} from '@angular/core'; +import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatExpansionModule } from '@angular/material/expansion'; +import { MatIconModule } from '@angular/material/icon'; +import { MatMenuModule } from '@angular/material/menu'; +import { Observable, Subscription } from 'rxjs'; + +import { MenuItems } from '@components/shared'; +import { PieChartComponent } from '@components/shared/helpers-chart'; +import { HistoryTableComponent } from '@components/shared/helpers-jump'; +import { UtilitiesService, CanopiesService } from '@services'; +import { CanopyModelBySize, CanopyModelByYear } from '@models'; + +@Component({ + selector: 'app-canopies-models', + standalone: true, + imports: [ + MatButtonModule, MatCardModule, MatDividerModule, + MatExpansionModule, MatIconModule, MatMenuModule, + PieChartComponent, HistoryTableComponent + ], + templateUrl: './canopies-models.component.html' +}) +export class CanopiesModelsComponent implements OnInit, OnDestroy { + private _canopyBySize: Subscription = new Subscription(); + private _canopyByYear: Subscription = new Subscription(); + private _canopiesBySize!: Array; + private _canopiesByYear!: Array; + public title: string = 'Modèles de voile'; + public subtitle: string = 'Nombre total de sauts par modèle'; + public seriesHeader: string[] = []; + public seriesName: string[] = []; + public seriesValue: number[] = []; + public seriesRow: Array> = []; + public seriesColor: { + backgroundColor: string[], + borderColor: string[] + } = { + backgroundColor: this._utilitiesService.getSeriesColors(0.8, 'all'), + borderColor: this._utilitiesService.getSeriesColors(1, 'all') + }; + public seriesColorClass: string[] = this._utilitiesService.getChartColors(); + public destroyRef = inject(DestroyRef); + + constructor( + private _canopiesService: CanopiesService, + private _utilitiesService: UtilitiesService, + public menuItems: MenuItems + ) { } + + ngOnInit() { + this._loadCanopyModelBySize(); + } + + ngOnDestroy() { + this._canopyBySize.unsubscribe(); + this._canopyByYear.unsubscribe(); + } + + private _loadCanopyModelBySize(): void { + const canopies$: Observable> = this._canopiesService.getAllBySizeByModel().pipe(takeUntilDestroyed(this.destroyRef)); + this._canopyBySize = canopies$.subscribe((aggregate: Array) => { + this._canopiesBySize = aggregate.map((row: CanopyModelBySize) => { + this.seriesName.push(`${row.taille.toString()} - ${row.voile}`); + this.seriesValue.push(row.count); + return row; + }); + this._loadCanopyModelByYear(); + }); + } + + private _loadCanopyModelByYear(): void { + this.seriesHeader = ['2018', '2019', '2020', '2021', '2022', '2023', '2024']; + const values: Array = this.seriesHeader.map(() => 0); + this.seriesName.forEach(() => { + this.seriesRow.push([...values]); + }); + const dropzones$: Observable> = this._canopiesService.getAllBySizeByModelByYear().pipe(takeUntilDestroyed(this.destroyRef)); + this._canopyByYear = dropzones$.subscribe((aggregate: Array) => { + this._canopiesByYear = aggregate.map((row: CanopyModelByYear) => { + const voile: string = row.voile; + const taille: string = row.taille.toString(); + const year: string = row.year.toString(); + this.seriesRow[this.seriesName.indexOf(`${taille} - ${voile}`)][this.seriesHeader.indexOf(year)] = row.count; + return row; + }); + }); + } +} diff --git a/src/app/components/shared/dashboard-components/canopies-sizes/canopies-sizes.component.html b/src/app/components/shared/dashboard-components/canopies-sizes/canopies-sizes.component.html new file mode 100755 index 0000000..8b27f57 --- /dev/null +++ b/src/app/components/shared/dashboard-components/canopies-sizes/canopies-sizes.component.html @@ -0,0 +1,42 @@ + + + {{ title }} + {{ subtitle }} + + + + @for (menuitem of menuItems.getMenuPanel(); track menuitem) { + + } + + + + + + + + + + + + Historique annuel + + + + + + diff --git a/src/app/components/shared/dashboard-components/canopies-sizes/canopies-sizes.component.scss b/src/app/components/shared/dashboard-components/canopies-sizes/canopies-sizes.component.scss new file mode 100755 index 0000000..e69de29 diff --git a/src/app/components/shared/dashboard-components/canopies-sizes/canopies-sizes.component.spec.ts b/src/app/components/shared/dashboard-components/canopies-sizes/canopies-sizes.component.spec.ts new file mode 100755 index 0000000..b107adb --- /dev/null +++ b/src/app/components/shared/dashboard-components/canopies-sizes/canopies-sizes.component.spec.ts @@ -0,0 +1,25 @@ +import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CanopiesSizesComponent } from './canopies-sizes.component'; + +describe('CanopiesSizesComponent', () => { + let component: CanopiesSizesComponent; + let fixture: ComponentFixture; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + imports: [CanopiesSizesComponent] +}) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(CanopiesSizesComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/shared/dashboard-components/canopies-sizes/canopies-sizes.component.ts b/src/app/components/shared/dashboard-components/canopies-sizes/canopies-sizes.component.ts new file mode 100755 index 0000000..7aefa95 --- /dev/null +++ b/src/app/components/shared/dashboard-components/canopies-sizes/canopies-sizes.component.ts @@ -0,0 +1,92 @@ +import { Component, DestroyRef, inject, OnInit, OnDestroy } from '@angular/core'; +import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatExpansionModule } from '@angular/material/expansion'; +import { MatIconModule } from '@angular/material/icon'; +import { MatMenuModule } from '@angular/material/menu'; + +import { Observable, Subscription } from 'rxjs'; + +import { MenuItems } from '@components/shared'; +import { PieChartComponent } from '@components/shared/helpers-chart'; +import { HistoryTableComponent } from '@components/shared/helpers-jump'; +import { UtilitiesService, CanopiesService } from '@services'; +import { CanopyBySize, CanopyByYear } from '@models'; + +@Component({ + selector: 'app-canopies-sizes', + standalone: true, + imports: [ + MatButtonModule, MatCardModule, MatDividerModule, + MatExpansionModule, MatIconModule, MatMenuModule, + PieChartComponent, HistoryTableComponent + ], + templateUrl: './canopies-sizes.component.html' +}) +export class CanopiesSizesComponent implements OnInit, OnDestroy { + private _canopyBySize: Subscription = new Subscription(); + private _canopyByYear: Subscription = new Subscription(); + private _canopiesBySize!: Array; + private _canopiesByYear!: Array; + public title: string = 'Tailles de voile'; + public subtitle: string = 'Nombre total de sauts par taille'; + public seriesHeader: string[] = []; + public seriesName: string[] = []; + public seriesValue: number[] = []; + public seriesRow: Array> = []; + public seriesColor: { + backgroundColor: string[], + borderColor: string[] + } = { + backgroundColor: this._utilitiesService.getSeriesColors(0.8, 'all'), + borderColor: this._utilitiesService.getSeriesColors(1, 'all') + }; + public seriesColorClass: string[] = this._utilitiesService.getChartColors(); + public destroyRef = inject(DestroyRef); + + constructor( + private _canopiesService: CanopiesService, + private _utilitiesService: UtilitiesService, + public menuItems: MenuItems + ) { } + + ngOnInit() { + this._loadCanopyBySize(); + } + + ngOnDestroy() { + this._canopyBySize.unsubscribe(); + this._canopyByYear.unsubscribe(); + } + + private _loadCanopyBySize(): void { + const canopies$: Observable> = this._canopiesService.getAllBySize().pipe(takeUntilDestroyed(this.destroyRef)); + this._canopyBySize = canopies$.subscribe((aggregate: Array) => { + this._canopiesBySize = aggregate.map((row: CanopyBySize) => { + this.seriesName.push(row.taille.toString()); + this.seriesValue.push(row.count); + return row; + }); + this._loadCanopyByYear(); + }); + } + + private _loadCanopyByYear(): void { + this.seriesHeader = ['2018', '2019', '2020', '2021', '2022', '2023', '2024']; + const values: Array = this.seriesHeader.map(() => 0); + this.seriesName.forEach(() => { + this.seriesRow.push([...values]); + }); + const dropzones$: Observable> = this._canopiesService.getAllBySizeByYear().pipe(takeUntilDestroyed(this.destroyRef)); + this._canopyByYear = dropzones$.subscribe((aggregate: Array) => { + this._canopiesByYear = aggregate.map((row: CanopyByYear) => { + const taille: string = row.taille.toString(); + const year: string = row.year.toString(); + this.seriesRow[this.seriesName.indexOf(taille)][this.seriesHeader.indexOf(year)] = row.count; + return row; + }); + }); + } +} diff --git a/src/app/components/shared/dashboard-components/dropzones-bar/data.json b/src/app/components/shared/dashboard-components/dropzones-bar/data.json new file mode 100755 index 0000000..1f7cf32 --- /dev/null +++ b/src/app/components/shared/dashboard-components/dropzones-bar/data.json @@ -0,0 +1,18 @@ +{ + "Bar": { + "labels": ["Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"], + "series": [ + [0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0], + [0, 0, 0, 0, 7, 1, 17, 22, 12, 18, 0, 0], + [0, 35, 8, 0, 0, 10, 31, 67, 26, 24, 0, 0], + [0, 0, 0, 0, 0, 9, 8, 0, 11, 24, 17, 4], + [0, 0, 0, 29, 37, 11, 22, 20, 17, 13, 13, 0], + [0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + ] + }, + "Pie": { + "labels": ["261", "45", "178", "16", "13", "11", "4", "2"], + "series": [261, 45, 178, 16, 13, 11, 4, 2], + "names": ["Arcachon", "Béni-Mellal", "La Réole", "Royan", "Pamiers", "Soulac", "Sables d'Olonne", "Rochefort"] + } +} diff --git a/src/app/components/shared/dashboard-components/dropzones-bar/dropzones-bar.component.html b/src/app/components/shared/dashboard-components/dropzones-bar/dropzones-bar.component.html new file mode 100755 index 0000000..0954b59 --- /dev/null +++ b/src/app/components/shared/dashboard-components/dropzones-bar/dropzones-bar.component.html @@ -0,0 +1,35 @@ + + + {{ title }} + {{ subtitle }} + + + + @for (menuitem of menuItems.getMenuPanel(); track menuitem) { + + } + + + + + @if (displayCharts) { +
+ +
+ } +
+ + + + + Historique annuel + + + + +
diff --git a/src/app/components/shared/dashboard-components/dropzones-bar/dropzones-bar.component.scss b/src/app/components/shared/dashboard-components/dropzones-bar/dropzones-bar.component.scss new file mode 100755 index 0000000..e69de29 diff --git a/src/app/components/shared/dashboard-components/dropzones-bar/dropzones-bar.component.spec.ts b/src/app/components/shared/dashboard-components/dropzones-bar/dropzones-bar.component.spec.ts new file mode 100755 index 0000000..f9287c3 --- /dev/null +++ b/src/app/components/shared/dashboard-components/dropzones-bar/dropzones-bar.component.spec.ts @@ -0,0 +1,25 @@ +import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { DropzonesBarComponent } from './dropzones-bar.component'; + +describe('DropzonesBarComponent', () => { + let component: DropzonesBarComponent; + let fixture: ComponentFixture; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + imports: [DropzonesBarComponent] +}) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(DropzonesBarComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/shared/dashboard-components/dropzones-bar/dropzones-bar.component.ts b/src/app/components/shared/dashboard-components/dropzones-bar/dropzones-bar.component.ts new file mode 100755 index 0000000..09466c8 --- /dev/null +++ b/src/app/components/shared/dashboard-components/dropzones-bar/dropzones-bar.component.ts @@ -0,0 +1,143 @@ +import { Component, DestroyRef, inject, OnInit, OnDestroy } from '@angular/core'; +import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatExpansionModule } from '@angular/material/expansion'; +import { MatIconModule } from '@angular/material/icon'; +import { MatMenuModule } from '@angular/material/menu'; +import { BaseChartDirective } from 'ng2-charts'; +import { ChartistModule, Configuration } from 'ng-chartist'; +import { AxisOptions, Label } from 'chartist'; +import { Observable, Subscription } from 'rxjs'; + +import { MenuItems } from '@components/shared'; +import { HistoryTableComponent } from '@components/shared/helpers-jump'; +import { UtilitiesService, DropZonesService } from '@services'; +import { DropZoneByOaci, DropZoneByYear } from '@models'; + +@Component({ + selector: 'app-dropzones-bar', + standalone: true, + imports: [ + MatButtonModule, MatCardModule, MatDividerModule, + MatExpansionModule, MatIconModule, MatMenuModule, + BaseChartDirective, ChartistModule, + HistoryTableComponent + ], + templateUrl: './dropzones-bar.component.html' +}) +export class DropzonesBarComponent implements OnInit, OnDestroy { + private _dropzoneByOaci: Subscription = new Subscription(); + private _dropzoneByYear: Subscription = new Subscription(); + private _dropzonesByOaci!: Array; + private _dropzonesByYear!: Array; + public title: string = 'Les dropzones'; + public subtitle: string = 'Nombre total de sauts par dropzone'; + public seriesHeader: string[] = []; + public seriesName: string[] = []; + public seriesValue: number[] = []; + public seriesRow: Array> = []; + public seriesColor: { + backgroundColor: string[], + borderColor: string[] + } = { + backgroundColor: this._utilitiesService.getSeriesColors(0.8, 'all'), + borderColor: this._utilitiesService.getSeriesColors(1, 'all') + }; + public seriesColorClass: string[] = this._utilitiesService.getChartColors(); + public displayCharts = false; + public barChartDropZones: Configuration = this._utilitiesService.getBarConfig(); + public destroyRef = inject(DestroyRef); + + constructor( + private _dropzonesService: DropZonesService, + private _utilitiesService: UtilitiesService, + public menuItems: MenuItems + ) { } + + ngOnInit() { + this._loadDropZoneByOaci(); + } + + ngOnDestroy() { + this._dropzoneByOaci.unsubscribe(); + this._dropzoneByYear.unsubscribe(); + } + + private _loadDropZoneByOaci(): void { + const dropzones$: Observable> = this._dropzonesService.getAllByOaci().pipe(takeUntilDestroyed(this.destroyRef)); + this._dropzoneByOaci = dropzones$.subscribe((aggregate: Array) => { + this._dropzonesByOaci = aggregate.map((row: DropZoneByOaci) => { + this.seriesName.push(`${row.oaci} - ${row.lieu}`); + this.seriesValue.push(row.count); + return row; + }); + this._loadDropZoneByYear(); + }); + } + + private _loadDropZoneByYear(): void { + this.seriesHeader = ['2018', '2019', '2020', '2021', '2022', '2023', '2024']; + const values: Array = this.seriesHeader.map(() => 0); + this.seriesName.forEach(() => { + this.seriesRow.push([...values]); + }); + const dropzones$: Observable> = this._dropzonesService.getAllByOaciByYear().pipe(takeUntilDestroyed(this.destroyRef)); + this._dropzoneByYear = dropzones$.subscribe((aggregate: Array) => { + this._dropzonesByYear = aggregate.map((row: DropZoneByYear) => { + const lieu: string = row.lieu; + const oaci: string = row.oaci; + const year: string = row.year.toString(); + this.seriesRow[this.seriesName.indexOf(`${oaci} - ${lieu}`)][this.seriesHeader.indexOf(year)] = row.count; + return row; + }); + const axisX: AxisOptions = { + labelInterpolationFnc: function(value: Label, index: number): string { + return index % 1 === 0 ? `${value.toString()}` : ''; + } + } + this.barChartDropZones = { + type: 'Bar', + data: { + 'labels': this.seriesHeader, + 'series': this.seriesRow + }, + options: { + seriesBarDistance: 15, + horizontalBars: false, + high: 180, + axisX: { + showGrid: false, + offset: 20 + }, + axisY: { + showGrid: true, + offset: 40 + }, + height: 300 + }, + responsiveOptions: [ + ['screen and (min-width: 1024px)', { + axisX: axisX + }], + ['screen and (min-width: 641px) and (max-width: 1024px)', { + seriesBarDistance: 7, + axisY: { + offset: 30 + }, + axisX: axisX + }], + ['screen and (max-width: 640px)', { + seriesBarDistance: 5, + axisY: { + offset: 20 + }, + axisX: axisX + }] + ] + }; + this.displayCharts = true; + }); + } +} diff --git a/src/app/components/shared/dashboard-components/dropzones-pie/data.json b/src/app/components/shared/dashboard-components/dropzones-pie/data.json new file mode 100755 index 0000000..1f7cf32 --- /dev/null +++ b/src/app/components/shared/dashboard-components/dropzones-pie/data.json @@ -0,0 +1,18 @@ +{ + "Bar": { + "labels": ["Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"], + "series": [ + [0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0], + [0, 0, 0, 0, 7, 1, 17, 22, 12, 18, 0, 0], + [0, 35, 8, 0, 0, 10, 31, 67, 26, 24, 0, 0], + [0, 0, 0, 0, 0, 9, 8, 0, 11, 24, 17, 4], + [0, 0, 0, 29, 37, 11, 22, 20, 17, 13, 13, 0], + [0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + ] + }, + "Pie": { + "labels": ["261", "45", "178", "16", "13", "11", "4", "2"], + "series": [261, 45, 178, 16, 13, 11, 4, 2], + "names": ["Arcachon", "Béni-Mellal", "La Réole", "Royan", "Pamiers", "Soulac", "Sables d'Olonne", "Rochefort"] + } +} diff --git a/src/app/components/shared/dashboard-components/dropzones-pie/dropzones-pie.component.html b/src/app/components/shared/dashboard-components/dropzones-pie/dropzones-pie.component.html new file mode 100755 index 0000000..78b28e3 --- /dev/null +++ b/src/app/components/shared/dashboard-components/dropzones-pie/dropzones-pie.component.html @@ -0,0 +1,31 @@ + + + {{ title }} + {{ subtitle }} + + + + @for (menuitem of menuItems.getMenuPanel(); track menuitem) { + + } + + + + + + + + + + + Historique annuel + + + + + diff --git a/src/app/components/shared/dashboard-components/dropzones-pie/dropzones-pie.component.scss b/src/app/components/shared/dashboard-components/dropzones-pie/dropzones-pie.component.scss new file mode 100755 index 0000000..e69de29 diff --git a/src/app/components/shared/dashboard-components/dropzones-pie/dropzones-pie.component.spec.ts b/src/app/components/shared/dashboard-components/dropzones-pie/dropzones-pie.component.spec.ts new file mode 100755 index 0000000..8fe8b45 --- /dev/null +++ b/src/app/components/shared/dashboard-components/dropzones-pie/dropzones-pie.component.spec.ts @@ -0,0 +1,25 @@ +import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { DropzonesPieComponent } from './dropzones-pie.component'; + +describe('DropzonesPieComponent', () => { + let component: DropzonesPieComponent; + let fixture: ComponentFixture; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + imports: [DropzonesPieComponent] +}) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(DropzonesPieComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/shared/dashboard-components/dropzones-pie/dropzones-pie.component.ts b/src/app/components/shared/dashboard-components/dropzones-pie/dropzones-pie.component.ts new file mode 100755 index 0000000..930d55d --- /dev/null +++ b/src/app/components/shared/dashboard-components/dropzones-pie/dropzones-pie.component.ts @@ -0,0 +1,93 @@ +import { Component, DestroyRef, inject, OnInit, OnDestroy } from '@angular/core'; +import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatExpansionModule } from '@angular/material/expansion'; +import { MatIconModule } from '@angular/material/icon'; +import { MatMenuModule } from '@angular/material/menu'; +//import { ChartConfiguration } from 'chart.js'; +import { Observable, Subscription } from 'rxjs'; + +import { MenuItems } from '@components/shared'; +import { PieChartComponent } from '@components/shared/helpers-chart'; +import { HistoryTableComponent } from '@components/shared/helpers-jump'; +import { UtilitiesService, DropZonesService } from '@services'; +import { DropZoneByOaci, DropZoneByYear } from '@models'; + +@Component({ + selector: 'app-dropzones-pie', + standalone: true, + imports: [ + MatButtonModule, MatCardModule, MatDividerModule, + MatExpansionModule, MatIconModule, MatMenuModule, + PieChartComponent, HistoryTableComponent + ], + templateUrl: './dropzones-pie.component.html' +}) +export class DropzonesPieComponent implements OnInit, OnDestroy { + private _dropzoneByOaci: Subscription = new Subscription(); + private _dropzoneByYear: Subscription = new Subscription(); + private _dropzonesByOaci!: Array; + private _dropzonesByYear!: Array; + public title: string = 'Les dropzones'; + public subtitle: string = 'Nombre total de sauts par dropzone'; + public seriesHeader: string[] = []; + public seriesName: string[] = []; + public seriesValue: number[] = []; + public seriesRow: Array> = []; + public seriesColor: { + backgroundColor: string[], + borderColor: string[] + } = { + backgroundColor: this._utilitiesService.getSeriesColors(0.8, 'all'), + borderColor: this._utilitiesService.getSeriesColors(1, 'all') + }; + public seriesColorClass: string[] = this._utilitiesService.getChartColors(); + public destroyRef = inject(DestroyRef); + + constructor( + private _dropzonesService: DropZonesService, + private _utilitiesService: UtilitiesService, + public menuItems: MenuItems + ) { } + + ngOnInit() { + this._loadDropZoneByOaci(); + } + + ngOnDestroy() { + this._dropzoneByOaci.unsubscribe(); + this._dropzoneByYear.unsubscribe(); + } + + private _loadDropZoneByOaci(): void { + const dropzones$: Observable> = this._dropzonesService.getAllByOaci().pipe(takeUntilDestroyed(this.destroyRef)); + this._dropzoneByOaci = dropzones$.subscribe((aggregate: Array) => { + this._dropzonesByOaci = aggregate.map((row: DropZoneByOaci) => { + this.seriesName.push(`${row.oaci} - ${row.lieu}`); + this.seriesValue.push(row.count); + return row; + }); + this._loadDropZoneByYear(); + }); + } + + private _loadDropZoneByYear(): void { + this.seriesHeader = ['2018', '2019', '2020', '2021', '2022', '2023', '2024']; + const values: Array = this.seriesHeader.map(() => 0); + this.seriesName.forEach(() => { + this.seriesRow.push([...values]); + }); + const dropzones$: Observable> = this._dropzonesService.getAllByOaciByYear().pipe(takeUntilDestroyed(this.destroyRef)); + this._dropzoneByYear = dropzones$.subscribe((aggregate: Array) => { + this._dropzonesByYear = aggregate.map((row: DropZoneByYear) => { + const lieu: string = row.lieu; + const oaci: string = row.oaci; + const year: string = row.year.toString(); + this.seriesRow[this.seriesName.indexOf(`${oaci} - ${lieu}`)][this.seriesHeader.indexOf(year)] = row.count; + return row; + }); + }); + } +} diff --git a/src/app/components/shared/dashboard-components/index.ts b/src/app/components/shared/dashboard-components/index.ts new file mode 100644 index 0000000..80cde65 --- /dev/null +++ b/src/app/components/shared/dashboard-components/index.ts @@ -0,0 +1,7 @@ +export * from './aeronefs-pie/aeronefs-pie.component'; +export * from './aeronefs-bar/aeronefs-bar.component'; +export * from './canopies-models/canopies-models.component'; +export * from './canopies-sizes/canopies-sizes.component'; +export * from './dropzones-pie/dropzones-pie.component'; +export * from './dropzones-bar/dropzones-bar.component'; +export * from './jumps-by-month/jumps-by-month.component'; \ No newline at end of file diff --git a/src/app/components/shared/dashboard-components/jumps-by-month/data.json b/src/app/components/shared/dashboard-components/jumps-by-month/data.json new file mode 100755 index 0000000..16834ba --- /dev/null +++ b/src/app/components/shared/dashboard-components/jumps-by-month/data.json @@ -0,0 +1,17 @@ +{ + "Bar": { + "labels": ["Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"], + "series": [ + [0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0], + [0, 0, 0, 0, 7, 1, 17, 22, 12, 18, 0, 0], + [0, 35, 8, 0, 0, 10, 31, 67, 26, 24, 0, 0], + [0, 0, 0, 0, 0, 9, 8, 0, 11, 24, 17, 4], + [0, 0, 0, 29, 37, 11, 22, 20, 17, 13, 13, 0], + [0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + ] + }, + "Pie": { + "labels": ["Arcachon", "Béni-Mellal", "La Réole", "Royan", "Pamiers", "Soulac", "Sables d'Olonne", "Rochefort"], + "series": [261, 45, 178, 16, 13, 11, 4, 2] + } +} diff --git a/src/app/components/shared/dashboard-components/jumps-by-month/jumps-by-month.component.html b/src/app/components/shared/dashboard-components/jumps-by-month/jumps-by-month.component.html new file mode 100755 index 0000000..d47f747 --- /dev/null +++ b/src/app/components/shared/dashboard-components/jumps-by-month/jumps-by-month.component.html @@ -0,0 +1,86 @@ + + + {{ title }} + {{ subtitle }} de {{min}} à {{max}} + + + + + + + + + +
+ +
+
+ + + + + Historique annuel + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{{ name }} Total
● {{ seriesName[i] }} + {{ value }} + {{ value }} + {{ seriesRowTotal[i] }}
Total + {{ value }} + {{ value }} + {{ grandTotal }}
Moyenne + {{ value | number : '1.0-1' }} + {{ value | number : '1.0-1' }} + {{ grandAvg | number : '1.0-1' }}
Moyenne 3 dernières années + {{ value | number : '1.0-1' }} + {{ value | number : '1.0-1' }} + {{ grandAvgLastYears | number : '1.0-1' }}
+
+
+
diff --git a/src/app/components/shared/dashboard-components/jumps-by-month/jumps-by-month.component.scss b/src/app/components/shared/dashboard-components/jumps-by-month/jumps-by-month.component.scss new file mode 100755 index 0000000..e69de29 diff --git a/src/app/components/shared/dashboard-components/jumps-by-month/jumps-by-month.component.spec.ts b/src/app/components/shared/dashboard-components/jumps-by-month/jumps-by-month.component.spec.ts new file mode 100755 index 0000000..a9a3dbb --- /dev/null +++ b/src/app/components/shared/dashboard-components/jumps-by-month/jumps-by-month.component.spec.ts @@ -0,0 +1,25 @@ +import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { JumpsByMonthComponent } from './jumps-by-month.component'; + +describe('JumpsByMonthComponent', () => { + let component: JumpsByMonthComponent; + let fixture: ComponentFixture; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + imports: [JumpsByMonthComponent] +}) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(JumpsByMonthComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/shared/dashboard-components/jumps-by-month/jumps-by-month.component.ts b/src/app/components/shared/dashboard-components/jumps-by-month/jumps-by-month.component.ts new file mode 100755 index 0000000..3152b74 --- /dev/null +++ b/src/app/components/shared/dashboard-components/jumps-by-month/jumps-by-month.component.ts @@ -0,0 +1,172 @@ +import { Component, DestroyRef, inject, OnInit, OnDestroy } from '@angular/core'; +import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; +import { CommonModule } from '@angular/common'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatExpansionModule } from '@angular/material/expansion'; +import { MatIconModule } from '@angular/material/icon'; +import { MatMenuModule } from '@angular/material/menu'; +import { ChartistModule, Configuration } from 'ng-chartist'; +import { AxisOptions, Label } from 'chartist'; + +import { Observable, Subscription } from 'rxjs'; + +import { MenuItems } from '@components/shared'; +import { UtilitiesService, JumpsService } from '@services'; +import { JumpByDate } from '@models'; + +@Component({ + selector: 'app-jumps-by-month', + standalone: true, + imports: [ + CommonModule, + MatButtonModule, MatCardModule, MatDividerModule, + MatExpansionModule, MatIconModule, MatMenuModule, + ChartistModule + ], + templateUrl: './jumps-by-month.component.html' +}) +export class JumpsByMonthComponent implements OnInit, OnDestroy { + private _jumpByDate: Subscription = new Subscription(); + private _jumpsByDate!: Array; + private _jumpsByDateCount = 0; + public title: string = 'Volume mensuel'; + public subtitle: string = 'Nombre total de sauts par mois'; + public min = 0; + public max = 0; + public grandAvg = 0; + public grandAvgLastYears = 0; + public grandTotal = 0; + public seriesHeader: string[] = []; + public seriesName: string[] = []; + public seriesRow: Array> = []; + public seriesColor: { + backgroundColor: string[], + borderColor: string[] + } = { + backgroundColor: this._utilitiesService.getSeriesColors(0.8, 'all'), + borderColor: this._utilitiesService.getSeriesColors(1, 'all') + }; + public seriesColorClass: string[] = this._utilitiesService.getChartColors(); + public seriesRowTotal: number[] = []; + public seriesRowAvg: number[] = []; + public seriesRowAvgLastYears: number[] = []; + public seriesColTotal: number[] = []; + public seriesColTotalClosed: number[] = []; + public seriesColTotalLastYears: number[] = []; + public displayCharts = false; + public barChartJumps: Configuration = this._utilitiesService.getBarConfig(); + public destroyRef = inject(DestroyRef); + + constructor( + private _jumpsService: JumpsService, + private _utilitiesService: UtilitiesService, + public menuItems: MenuItems + ) { } + + ngOnInit() { + this._loadJumpByDate(); + } + + ngOnDestroy() { + this._jumpByDate.unsubscribe(); + } + + private _loadJumpByDate() { + const minoration = 2; // -2 pour ne pas compter la première année + this.seriesHeader = this._utilitiesService.getMonthsList(); + const values: Array = this.seriesHeader.map(() => 0); + this.seriesColTotal = [...values]; + this.seriesColTotalClosed = [...values]; + this.seriesColTotalLastYears = [...values]; + const jumps$: Observable> = this._jumpsService.getAllByDate().pipe(takeUntilDestroyed(this.destroyRef)); + this._jumpByDate = jumps$.subscribe((aggregate: Array) => { + this._jumpsByDateCount = aggregate.length; + this._jumpsByDate = aggregate.map((row: JumpByDate) => { + const currentYear: number = new Date().getFullYear(); + const year = row.year.toString(); + const month = row.month; + if (this.seriesName.indexOf(year) < 0) { + this.seriesName.push(year); + if (row.year < this.min || this.min == 0) { + this.min = row.year; + } + if (row.year > this.max) { + this.max = row.year; + } + this.seriesRow.push([...values]); + } + this.seriesRow[(this.seriesRow.length-1)][(month-1)] = row.count; + this.seriesColTotal[(month-1)] += row.count; + if (row.year < currentYear) { + this.seriesColTotalClosed[(month-1)] += row.count; + } + if (row.year >= (currentYear-3) && row.year < currentYear) { + this.seriesColTotalLastYears[(month-1)] += row.count; + } + return row; + }); + this.seriesRow.forEach((row: number[]) => { + const total = row.reduce((partialSum, a) => partialSum + a, 0); + this.seriesRowTotal.push(total); + }); + this.seriesColTotalClosed.forEach((row: number) => { + const value: number = (row/(this.seriesName.length-minoration)); + this.seriesRowAvg.push(parseInt(value.toFixed(0))); + }); + this.seriesColTotalLastYears.forEach((row: number) => { + const value: number = (row/3); // Les 3 dernières années + this.seriesRowAvgLastYears.push(parseInt(value.toFixed(0))); + }); + this.grandAvg = this.seriesRowAvg.reduce((partialSum, accumulated) => partialSum + accumulated, 0); + this.grandAvgLastYears = this.seriesRowAvgLastYears.reduce((partialSum, accumulated) => partialSum + accumulated, 0); + this.grandTotal = this.seriesColTotal.reduce((partialSum, accumulated) => partialSum + accumulated, 0); + const axisX: AxisOptions = { + labelInterpolationFnc: function(value: Label, index: number): string { + return index % 1 === 0 ? `${value.toString()}` : ''; + } + } + this.barChartJumps = { + type: 'Bar', + data: { + 'labels': this.seriesHeader, + 'series': this.seriesRow + }, + options: { + seriesBarDistance: 15, + high: 70, + axisX: { + showGrid: false, + offset: 20 + }, + axisY: { + showGrid: true, + offset: 40 + }, + height: 300 + }, + responsiveOptions: [ + ['screen and (min-width: 1024px)', { + axisX: axisX + }], + ['screen and (min-width: 641px) and (max-width: 1024px)', { + seriesBarDistance: 10, + axisY: { + offset: 30 + }, + axisX: axisX + }], + ['screen and (max-width: 640px)', { + seriesBarDistance: 5, + axisY: { + offset: 20 + }, + axisX: axisX + }] + ] + }; + this.displayCharts = true; + }); + } +} diff --git a/src/app/components/shared/floor.pipe.ts b/src/app/components/shared/floor.pipe.ts new file mode 100644 index 0000000..6063d42 --- /dev/null +++ b/src/app/components/shared/floor.pipe.ts @@ -0,0 +1,10 @@ +import { Pipe, PipeTransform } from '@angular/core'; +@Pipe({ + name: 'floor', + standalone: true +}) +export class FloorPipe implements PipeTransform { + transform(value: number): number { + return Math.floor(value); + } +} \ No newline at end of file diff --git a/src/app/components/shared/french-paginator.component.spec.ts b/src/app/components/shared/french-paginator.component.spec.ts new file mode 100644 index 0000000..d4fdfeb --- /dev/null +++ b/src/app/components/shared/french-paginator.component.spec.ts @@ -0,0 +1,24 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { FrenchPaginator } from './french-paginator.component'; + +describe('FrenchPaginator', () => { + let component: FrenchPaginator; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [FrenchPaginator] + }) + .compileComponents(); + + fixture = TestBed.createComponent(FrenchPaginator); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); + diff --git a/src/app/components/shared/french-paginator.component.ts b/src/app/components/shared/french-paginator.component.ts new file mode 100644 index 0000000..6b77afc --- /dev/null +++ b/src/app/components/shared/french-paginator.component.ts @@ -0,0 +1,21 @@ +import { MatPaginatorIntl } from '@angular/material/paginator'; +import { Subject } from 'rxjs'; + +export class FrenchPaginator implements MatPaginatorIntl { + changes = new Subject(); + // For internationalization, the `$localize` function from + // the `@angular/localize` package can be used. + firstPageLabel = `Première page`; + itemsPerPageLabel = `Eléments par page :`; + lastPageLabel = `Dernière page`; + nextPageLabel = 'Page suivante'; + previousPageLabel = 'Page précédente'; + + getRangeLabel(page: number, pageSize: number, length: number): string { + if (length === 0) { + return `Page 1 sur 1`; + } + const amountPages = Math.ceil(length / pageSize); + return `Page ${page + 1} sur ${amountPages}`; + } +} \ No newline at end of file diff --git a/src/app/components/shared/helpers-chart/bar-chart.component.html b/src/app/components/shared/helpers-chart/bar-chart.component.html new file mode 100755 index 0000000..14e95f9 --- /dev/null +++ b/src/app/components/shared/helpers-chart/bar-chart.component.html @@ -0,0 +1,11 @@ +@if (displayCharts) { +
+ + +
+} \ No newline at end of file diff --git a/src/app/components/shared/helpers-chart/bar-chart.component.spec.ts b/src/app/components/shared/helpers-chart/bar-chart.component.spec.ts new file mode 100755 index 0000000..aedee2d --- /dev/null +++ b/src/app/components/shared/helpers-chart/bar-chart.component.spec.ts @@ -0,0 +1,25 @@ +import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { BarChartComponent } from './bar-chart.component'; + +describe('BarChartComponent', () => { + let component: BarChartComponent; + let fixture: ComponentFixture; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + imports: [BarChartComponent] +}) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(BarChartComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/shared/helpers-chart/bar-chart.component.ts b/src/app/components/shared/helpers-chart/bar-chart.component.ts new file mode 100755 index 0000000..a8ea754 --- /dev/null +++ b/src/app/components/shared/helpers-chart/bar-chart.component.ts @@ -0,0 +1,58 @@ +import { Component, Input, OnChanges } from '@angular/core'; +import { ChartDataset } from 'chart.js'; +import { BaseChartDirective } from 'ng2-charts'; + +import { UtilitiesService } from '@services'; +import { BarConfig } from '@models'; + +@Component({ + selector: 'app-bar-chart', + standalone: true, + imports: [ + BaseChartDirective + ], + templateUrl: './bar-chart.component.html' +}) +export class BarChartComponent implements OnChanges { + public displayCharts = false; + public chartConfig: BarConfig = this._utilitiesService.getBarChartConfig(); + + constructor( + private _utilitiesService: UtilitiesService + ) { } + + @Input() names: string[] = []; + @Input() values: number[] = []; + @Input() headers: string[] = []; + @Input() colors: { + backgroundColor: string[], + borderColor: string[] + } = { + backgroundColor: this._utilitiesService.getSeriesColors(0.8), + borderColor: this._utilitiesService.getSeriesColors(1) + }; + @Input() label: string = 'Nombre total de sauts'; + @Input() legend: boolean = false; + + ngOnChanges() { + this._loadBarChart(); + } + + private _loadBarChart(): void { + const dataset: ChartDataset<'bar'> = { + data: [...this.values], + label: this.label, + backgroundColor: this.colors.backgroundColor, + borderColor: this.colors.borderColor, + borderWidth: 1 + }; + this.chartConfig.barChartData.labels = [...this.names]; + this.chartConfig.barChartData.datasets!.push(dataset); + /*this.chartConfig.barChartOptions!.scales = { + x: {display: false}, + y: {display: true} + };*/ + this.chartConfig.barChartLegend = this.legend; + this.displayCharts = true; + } +} diff --git a/src/app/components/shared/helpers-chart/bar-horizontal-chart.component.html b/src/app/components/shared/helpers-chart/bar-horizontal-chart.component.html new file mode 100755 index 0000000..d85b0c2 --- /dev/null +++ b/src/app/components/shared/helpers-chart/bar-horizontal-chart.component.html @@ -0,0 +1,11 @@ +@if (displayCharts) { +
+ + +
+} \ No newline at end of file diff --git a/src/app/components/shared/helpers-chart/bar-horizontal-chart.component.spec.ts b/src/app/components/shared/helpers-chart/bar-horizontal-chart.component.spec.ts new file mode 100755 index 0000000..1cf0ac8 --- /dev/null +++ b/src/app/components/shared/helpers-chart/bar-horizontal-chart.component.spec.ts @@ -0,0 +1,25 @@ +import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { BarHorizontalChartComponent } from './bar-horizontal-chart.component'; + +describe('BarHorizontalChartComponent', () => { + let component: BarHorizontalChartComponent; + let fixture: ComponentFixture; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + imports: [BarHorizontalChartComponent] +}) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(BarHorizontalChartComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/shared/helpers-chart/bar-horizontal-chart.component.ts b/src/app/components/shared/helpers-chart/bar-horizontal-chart.component.ts new file mode 100755 index 0000000..ec70776 --- /dev/null +++ b/src/app/components/shared/helpers-chart/bar-horizontal-chart.component.ts @@ -0,0 +1,54 @@ +import { Component, Input, OnChanges } from '@angular/core'; +import { ChartDataset } from 'chart.js'; +import { BaseChartDirective } from 'ng2-charts'; + +import { UtilitiesService } from '@services'; +import { BarConfig } from '@models'; + +@Component({ + selector: 'app-bar-horizontal-chart', + standalone: true, + imports: [ + BaseChartDirective + ], + templateUrl: './bar-horizontal-chart.component.html' +}) +export class BarHorizontalChartComponent implements OnChanges { + public displayCharts = false; + public chartConfig: BarConfig = this._utilitiesService.getHorizontalBarChartConfig(); + + constructor( + private _utilitiesService: UtilitiesService + ) { } + + @Input() names: string[] = []; + @Input() values: number[] = []; + @Input() headers: string[] = []; + @Input() colors: { + backgroundColor: string[], + borderColor: string[] + } = { + backgroundColor: this._utilitiesService.getSeriesColors(0.8), + borderColor: this._utilitiesService.getSeriesColors(1) + }; + @Input() label: string = 'Nombre total de sauts'; + @Input() legend: boolean = false; + + ngOnChanges() { + this._loadBarChart(); + } + + private _loadBarChart(): void { + const dataset: ChartDataset<'bar'> = { + data: [...this.values], + label: this.label, + backgroundColor: this.colors.backgroundColor, + borderColor: this.colors.borderColor, + borderWidth: 1 + }; + this.chartConfig.barChartData.labels = [...this.names]; + this.chartConfig.barChartData.datasets!.push(dataset); + this.chartConfig.barChartLegend = this.legend; + this.displayCharts = true; + } +} diff --git a/src/app/components/shared/helpers-chart/bars-chart.component.html b/src/app/components/shared/helpers-chart/bars-chart.component.html new file mode 100755 index 0000000..aa9fc82 --- /dev/null +++ b/src/app/components/shared/helpers-chart/bars-chart.component.html @@ -0,0 +1,11 @@ +@if (displayCharts) { +
+ + +
+} \ No newline at end of file diff --git a/src/app/components/shared/helpers-chart/bars-chart.component.spec.ts b/src/app/components/shared/helpers-chart/bars-chart.component.spec.ts new file mode 100755 index 0000000..c0b45c0 --- /dev/null +++ b/src/app/components/shared/helpers-chart/bars-chart.component.spec.ts @@ -0,0 +1,25 @@ +import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { BarsChartComponent } from './bars-chart.component'; + +describe('BarsChartComponent', () => { + let component: BarsChartComponent; + let fixture: ComponentFixture; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + imports: [BarsChartComponent] +}) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(BarsChartComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/shared/helpers-chart/bars-chart.component.ts b/src/app/components/shared/helpers-chart/bars-chart.component.ts new file mode 100755 index 0000000..37a22d6 --- /dev/null +++ b/src/app/components/shared/helpers-chart/bars-chart.component.ts @@ -0,0 +1,79 @@ +import { Component, Input, OnChanges, AfterContentChecked } from '@angular/core'; +import { ChartDataset } from 'chart.js'; +import { BaseChartDirective } from 'ng2-charts'; + +import { UtilitiesService } from '@services'; +import { BarConfig } from '@models'; + +@Component({ + selector: 'app-bars-chart', + standalone: true, + imports: [ + BaseChartDirective + ], + templateUrl: './bars-chart.component.html' +}) +export class BarsChartComponent implements OnChanges, AfterContentChecked { + public displayCharts = false; + public chartConfig: BarConfig = this._utilitiesService.getBarChartConfig(); + + constructor( + private _utilitiesService: UtilitiesService + ) { } + + @Input() names: string[] = []; + @Input() values: Array> = []; + @Input() headers: string[] = []; + @Input() colors: { + backgroundColor: string[], + borderColor: string[] + } = { + backgroundColor: this._utilitiesService.getSeriesColors(0.8), + borderColor: this._utilitiesService.getSeriesColors(1) + }; + @Input() legend: boolean = false; + + ngOnChanges() { + this._loadBarChart(); + } + + ngAfterContentChecked() { + this._loadBarChart(); + } + + private _loadBarChart(): void { + this.chartConfig = this._utilitiesService.getBarChartConfig(); + this.chartConfig.barChartData.labels = [...this.headers]; + this.chartConfig.barChartOptions!.maintainAspectRatio = false; + //this.chartConfig.barChartOptions!.aspectRatio = 2.4; + this.chartConfig.barChartOptions!.scales = { + x: { + display: true, + //stacked: true, + beginAtZero: true, + ticks: { color: 'rgba(255,255,255,0.3)' }, + grid: { color: 'rgba(255,255,255,0.1)', display: true, tickBorderDash: [1,2], tickBorderDashOffset: 2 } + }, + y: { + display: true, + //stacked: true, + beginAtZero: true, + ticks: { color: 'rgba(255,255,255,0.3)' }, + grid: { color: 'rgba(255,255,255,0.2)', tickBorderDash: [1,2], tickBorderDashOffset: 2, display: true } + } + }; + this.names.forEach((label: string, index: number) => { + const dataset: ChartDataset<'bar'> = { + data: [...this.values[index]], + label: label, + backgroundColor: this.colors.backgroundColor[index], + borderColor: this.colors.borderColor[index], + borderWidth: 1, + //stack: 'Stack 0' + }; + this.chartConfig.barChartData.datasets!.push(dataset); + }); + this.chartConfig.barChartLegend = this.legend; + this.displayCharts = true; + } +} diff --git a/src/app/components/shared/helpers-chart/circle-chart.component.html b/src/app/components/shared/helpers-chart/circle-chart.component.html new file mode 100755 index 0000000..47b637a --- /dev/null +++ b/src/app/components/shared/helpers-chart/circle-chart.component.html @@ -0,0 +1,11 @@ +@if (displayCharts) { +
+ + +
+} \ No newline at end of file diff --git a/src/app/components/shared/helpers-chart/circle-chart.component.spec.ts b/src/app/components/shared/helpers-chart/circle-chart.component.spec.ts new file mode 100755 index 0000000..e3ddba9 --- /dev/null +++ b/src/app/components/shared/helpers-chart/circle-chart.component.spec.ts @@ -0,0 +1,25 @@ +import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CircleChartComponent } from './circle-chart.component'; + +describe('CircleChartComponent', () => { + let component: CircleChartComponent; + let fixture: ComponentFixture; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + imports: [CircleChartComponent] +}) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(CircleChartComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/shared/helpers-chart/circle-chart.component.ts b/src/app/components/shared/helpers-chart/circle-chart.component.ts new file mode 100755 index 0000000..a14cb2a --- /dev/null +++ b/src/app/components/shared/helpers-chart/circle-chart.component.ts @@ -0,0 +1,64 @@ +import { Component, Input, OnChanges } from '@angular/core'; +//import { ChartDataset } from 'chart.js'; +import { BaseChartDirective } from 'ng2-charts'; + +import { UtilitiesService } from '@services'; +import { CircleConfig } from '@models'; + +@Component({ + selector: 'app-circle-chart', + standalone: true, + imports: [ + BaseChartDirective + ], + templateUrl: './circle-chart.component.html' +}) +export class CircleChartComponent implements OnChanges { + public displayCharts = false; + public chartConfig: CircleConfig = this._utilitiesService.getCircleChartConfig(); + + constructor( + private _utilitiesService: UtilitiesService + ) { } + + @Input() names: string[] = []; + @Input() values: number[] = []; + @Input() headers: string[] = []; + @Input() color: number = 0; + @Input() label: string = 'Nombre total de sauts'; + @Input() legend: boolean = false; + + ngOnChanges() { + this._loadCircleChart(); + } + + private _loadCircleChart(): void { + this.chartConfig.circleChartLabels = [...this.names]; + this.chartConfig.circleChartDatasets[0].data = [...this.values]; + this.chartConfig.circleChartDatasets[0].label = this.label; + this.chartConfig.circleChartDatasets[0].backgroundColor = [ + this._utilitiesService.getSeriesColors(0.9, 'pastels')[this.color], + 'rgba(255, 255, 255, 0.05)' + ]; + this.chartConfig.circleChartDatasets[0].borderColor = [ + this._utilitiesService.getSeriesColors(1, 'pastels')[this.color], + 'rgba(255, 255, 255, 0.05)' + ]; + this.chartConfig.circleChartDatasets[0].borderWidth = 0; + this.chartConfig.circleChartLegend = this.legend; + this.displayCharts = true; + } + + /*private _loadCircleChart(): void { + const dataset: ChartDataset<'circle'> = { + data: [...this.values], + label: 'Nombre total de sauts', + backgroundColor: this._utilitiesService.getSeriesColors(0.8), + borderColor: this._utilitiesService.getSeriesColors(1), + borderWidth: 1 + }; + this.chartConfig.circleChartLabels = [...this.names]; + this.chartConfig.circleChartDatasets!.push(dataset); + this.displayCharts = true; + }*/ +} diff --git a/src/app/components/shared/helpers-chart/index.ts b/src/app/components/shared/helpers-chart/index.ts new file mode 100644 index 0000000..12c0c8b --- /dev/null +++ b/src/app/components/shared/helpers-chart/index.ts @@ -0,0 +1,7 @@ +export * from './bar-chart.component'; +export * from './bar-horizontal-chart.component'; +export * from './bars-chart.component'; +export * from './circle-chart.component'; +export * from './line-chart.component'; +export * from './linearea-chart.component'; +export * from './pie-chart.component'; \ No newline at end of file diff --git a/src/app/components/shared/helpers-chart/line-chart.component.html b/src/app/components/shared/helpers-chart/line-chart.component.html new file mode 100755 index 0000000..622c0ab --- /dev/null +++ b/src/app/components/shared/helpers-chart/line-chart.component.html @@ -0,0 +1,10 @@ +@if(displayCharts) { +
+ + +
+} \ No newline at end of file diff --git a/src/app/components/shared/helpers-chart/line-chart.component.spec.ts b/src/app/components/shared/helpers-chart/line-chart.component.spec.ts new file mode 100755 index 0000000..24d94f6 --- /dev/null +++ b/src/app/components/shared/helpers-chart/line-chart.component.spec.ts @@ -0,0 +1,25 @@ +import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { LineChartComponent } from './line-chart.component'; + +describe('LineChartComponent', () => { + let component: LineChartComponent; + let fixture: ComponentFixture; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + imports: [LineChartComponent] +}) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(LineChartComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/shared/helpers-chart/line-chart.component.ts b/src/app/components/shared/helpers-chart/line-chart.component.ts new file mode 100755 index 0000000..bb7a020 --- /dev/null +++ b/src/app/components/shared/helpers-chart/line-chart.component.ts @@ -0,0 +1,64 @@ +import { Component, Input, OnChanges } from '@angular/core'; +import { ChartDataset, Point } from 'chart.js'; +import { BaseChartDirective } from 'ng2-charts'; + +import { UtilitiesService } from '@services'; +import { LineConfig } from '@models'; + +@Component({ + selector: 'app-line-chart', + standalone: true, + imports: [ + BaseChartDirective + ], + templateUrl: './line-chart.component.html' +}) +export class LineChartComponent implements OnChanges { + public displayCharts = false; + public chartConfig: LineConfig = this._utilitiesService.getLineChartConfig(); + + constructor( + private _utilitiesService: UtilitiesService + ) { } + + @Input() headers: string[] = []; + @Input() names: string[] = []; + @Input() values: Array> = []; + @Input() colors: { + backgroundColor: string[], + borderColor: string[] + } = { + backgroundColor: this._utilitiesService.getSeriesColors(0.8), + borderColor: this._utilitiesService.getSeriesColors(1) + }; + @Input() legend: boolean = false; + @Input() hideZero: boolean = false; + + ngOnChanges() { + this._loadLineChart(); + } + + private _loadLineChart(): void { + this.chartConfig.lineChartData.labels = [...this.headers]; + this.names.forEach((label: string, index: number) => { + let data: Array<(number | Point | null)> = []; + if (this.hideZero) { + data = [...this.values[index].map(value => value === 0 ? null : value)]; + } else { + data = [...this.values[index]]; + } + const dataset: ChartDataset<'line'> = { + data: data, + label: label, + backgroundColor: this.colors.backgroundColor[index], + borderColor: this.colors.borderColor[index], + borderWidth: 2, + cubicInterpolationMode: 'monotone', + tension: 0 + }; + this.chartConfig.lineChartData.datasets!.push(dataset); + }); + this.chartConfig.lineChartLegend = this.legend; + this.displayCharts = true; + } +} diff --git a/src/app/components/shared/helpers-chart/linearea-chart.component.html b/src/app/components/shared/helpers-chart/linearea-chart.component.html new file mode 100755 index 0000000..622c0ab --- /dev/null +++ b/src/app/components/shared/helpers-chart/linearea-chart.component.html @@ -0,0 +1,10 @@ +@if(displayCharts) { +
+ + +
+} \ No newline at end of file diff --git a/src/app/components/shared/helpers-chart/linearea-chart.component.spec.ts b/src/app/components/shared/helpers-chart/linearea-chart.component.spec.ts new file mode 100755 index 0000000..3d7ffd9 --- /dev/null +++ b/src/app/components/shared/helpers-chart/linearea-chart.component.spec.ts @@ -0,0 +1,25 @@ +import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { LineAreaChartComponent } from './linearea-chart.component'; + +describe('LineAreaChartComponent', () => { + let component: LineAreaChartComponent; + let fixture: ComponentFixture; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + imports: [LineAreaChartComponent] +}) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(LineAreaChartComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/shared/helpers-chart/linearea-chart.component.ts b/src/app/components/shared/helpers-chart/linearea-chart.component.ts new file mode 100755 index 0000000..e2bdbd6 --- /dev/null +++ b/src/app/components/shared/helpers-chart/linearea-chart.component.ts @@ -0,0 +1,63 @@ +import { Component, Input, OnChanges } from '@angular/core'; +import { ChartDataset } from 'chart.js'; +import { BaseChartDirective } from 'ng2-charts'; + +import { UtilitiesService } from '@services'; +import { LineConfig } from '@models'; + +@Component({ + selector: 'app-linearea-chart', + standalone: true, + imports: [ + BaseChartDirective + ], + templateUrl: './linearea-chart.component.html' +}) +export class LineAreaChartComponent implements OnChanges { + public displayCharts = false; + public chartConfig: LineConfig = this._utilitiesService.getStackedLineAreaChartConfig(); + + constructor( + private _utilitiesService: UtilitiesService + ) { } + + @Input() headers: string[] = []; + @Input() names: string[] = []; + @Input() values: Array> = []; + @Input() colors: { + backgroundColor: string[], + borderColor: string[] + } = { + backgroundColor: this._utilitiesService.getSeriesColors(0.8), + borderColor: this._utilitiesService.getSeriesColors(1) + }; + @Input() legend: boolean = false; + + ngOnChanges() { + this._loadLineChart(); + } + + private _loadLineChart(): void { + this.chartConfig.lineChartData.labels = [...this.headers]; + this.names.forEach((label: string, index: number) => { + let fill: string | number | boolean = '-1'; + if (index === 0) { + fill = true; + } + const dataset: ChartDataset<'line'> = { + data: [...this.values[index]], + label: label, + backgroundColor: this.colors.backgroundColor[index], + borderColor: this.colors.borderColor[index], + borderWidth: 1, + fill: fill, + //stepped: true, + cubicInterpolationMode: 'monotone', + tension: 0 + }; + this.chartConfig.lineChartData.datasets!.push(dataset); + }); + this.chartConfig.lineChartLegend = this.legend; + this.displayCharts = true; + } +} diff --git a/src/app/components/shared/helpers-chart/pie-chart.component.html b/src/app/components/shared/helpers-chart/pie-chart.component.html new file mode 100755 index 0000000..686a85d --- /dev/null +++ b/src/app/components/shared/helpers-chart/pie-chart.component.html @@ -0,0 +1,11 @@ +@if (displayCharts) { +
+ + +
+} \ No newline at end of file diff --git a/src/app/components/shared/helpers-chart/pie-chart.component.spec.ts b/src/app/components/shared/helpers-chart/pie-chart.component.spec.ts new file mode 100755 index 0000000..f5e318e --- /dev/null +++ b/src/app/components/shared/helpers-chart/pie-chart.component.spec.ts @@ -0,0 +1,25 @@ +import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PieChartComponent } from './pie-chart.component'; + +describe('PieChartComponent', () => { + let component: PieChartComponent; + let fixture: ComponentFixture; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + imports: [PieChartComponent] +}) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(PieChartComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/shared/helpers-chart/pie-chart.component.ts b/src/app/components/shared/helpers-chart/pie-chart.component.ts new file mode 100755 index 0000000..e43d68b --- /dev/null +++ b/src/app/components/shared/helpers-chart/pie-chart.component.ts @@ -0,0 +1,63 @@ +import { Component, Input, OnChanges } from '@angular/core'; +//import { ChartDataset } from 'chart.js'; +import { BaseChartDirective } from 'ng2-charts'; + +import { UtilitiesService } from '@services'; +import { DoughnutConfig } from '@models'; + +@Component({ + selector: 'app-pie-chart', + standalone: true, + imports: [ + BaseChartDirective + ], + templateUrl: './pie-chart.component.html' +}) +export class PieChartComponent implements OnChanges { + public displayCharts = false; + public chartConfig: DoughnutConfig = this._utilitiesService.getDoughnutChartConfig(); + + constructor( + private _utilitiesService: UtilitiesService + ) { } + + @Input() names: string[] = []; + @Input() values: number[] = []; + @Input() headers: string[] = []; + @Input() colors: { + backgroundColor: string[], + borderColor: string[] + } = { + backgroundColor: this._utilitiesService.getSeriesColors(0.8, 'all'), + borderColor: this._utilitiesService.getSeriesColors(1, 'all') + }; + @Input() legend: boolean = false; + + ngOnChanges() { + this._loadDoughnutChart(); + } + + private _loadDoughnutChart(): void { + this.chartConfig.doughnutChartLabels = [...this.names]; + this.chartConfig.doughnutChartDatasets[0].data = [...this.values]; + this.chartConfig.doughnutChartDatasets[0].label = 'Nombre total de sauts'; + this.chartConfig.doughnutChartDatasets[0].backgroundColor = this.colors.backgroundColor; + this.chartConfig.doughnutChartDatasets[0].borderColor = this.colors.borderColor; + this.chartConfig.doughnutChartDatasets[0].borderWidth = 2; + this.chartConfig.doughnutChartLegend = this.legend; + this.displayCharts = true; + } + + /*private _loadDoughnutChart(): void { + const dataset: ChartDataset<'doughnut'> = { + data: [...this.values], + label: 'Nombre total de sauts', + backgroundColor: this._utilitiesService.getSeriesColors(0.8), + borderColor: this._utilitiesService.getSeriesColors(1), + borderWidth: 1 + }; + this.chartConfig.doughnutChartLabels = [...this.names]; + this.chartConfig.doughnutChartDatasets!.push(dataset); + this.displayCharts = true; + }*/ +} diff --git a/src/app/components/shared/helpers-jump/history-table.component.html b/src/app/components/shared/helpers-jump/history-table.component.html new file mode 100644 index 0000000..1605f39 --- /dev/null +++ b/src/app/components/shared/helpers-jump/history-table.component.html @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + +
{{name}} Total
● {{ names[i] }} + {{ value }} + + {{ values[i] }} +
Total + {{ value }} + {{ grandTotal }}
\ No newline at end of file diff --git a/src/app/components/shared/helpers-jump/history-table.component.spec.ts b/src/app/components/shared/helpers-jump/history-table.component.spec.ts new file mode 100644 index 0000000..4e4d64b --- /dev/null +++ b/src/app/components/shared/helpers-jump/history-table.component.spec.ts @@ -0,0 +1,24 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { HistoryTableComponent } from './history-table.component'; + +describe('HistoryTableComponent', () => { + let component: HistoryTableComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [HistoryTableComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(HistoryTableComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); + diff --git a/src/app/components/shared/helpers-jump/history-table.component.ts b/src/app/components/shared/helpers-jump/history-table.component.ts new file mode 100644 index 0000000..1ccc304 --- /dev/null +++ b/src/app/components/shared/helpers-jump/history-table.component.ts @@ -0,0 +1,46 @@ +import { Component, Input, AfterContentChecked } from '@angular/core'; +import { NgIf, NgFor } from '@angular/common'; + +@Component({ + standalone: true, + imports: [ + NgIf, NgFor + ], + selector: 'app-history-table', + templateUrl: './history-table.component.html', + styleUrls: [] +}) +export class HistoryTableComponent implements AfterContentChecked { + public seriesColTotal: number[] = []; + public grandTotal: number = 0; + + constructor() {} + + @Input() headers: string[] = []; + @Input() names: string[] = []; + @Input() values: number[] = []; + @Input() rows: Array> = []; + @Input() colors: string[] = []; + + /*ngOnChanges() { + //this._loadHistoryTable(); + //console.log('onChanges'); + }*/ + + ngAfterContentChecked() { + if (this.rows !== undefined && this.rows.length) { + this._loadHistoryTable(); + } + } + + private _loadHistoryTable(): void { + const values: Array = this.rows[0].map(() => 0); + this.seriesColTotal = [...values]; + this.rows.forEach((row: number[], rowIndex: number) => { + row.forEach((value: number, index: number) => { + this.seriesColTotal[index] = (this.seriesColTotal[index] + this.rows[rowIndex][index]); + }); + this.grandTotal = this.seriesColTotal.reduce((partialSum, a) => partialSum + a, 0); + }); + } +} diff --git a/src/app/components/shared/helpers-jump/index.ts b/src/app/components/shared/helpers-jump/index.ts new file mode 100644 index 0000000..f6c4677 --- /dev/null +++ b/src/app/components/shared/helpers-jump/index.ts @@ -0,0 +1,5 @@ +export * from './history-table.component'; +export * from './jump-list.component'; +export * from './jump-meta.component'; +export * from './jump-preview.component'; +export * from './jump-table.component'; diff --git a/src/app/components/shared/helpers-jump/jump-list.component.html b/src/app/components/shared/helpers-jump/jump-list.component.html new file mode 100644 index 0000000..0b5f732 --- /dev/null +++ b/src/app/components/shared/helpers-jump/jump-list.component.html @@ -0,0 +1,22 @@ +
+

{{ title }} ({{ jumpsCount }})

+ + +
+Prix actualisés toutes les {{ (refresh / 1000) }} secondes. +Aucun produit à afficher pour le moment +Chargement des produits en cours +@for (jump of jumps; track jump) { + +} + \ No newline at end of file diff --git a/src/app/components/shared/helpers-jump/jump-list.component.ts b/src/app/components/shared/helpers-jump/jump-list.component.ts new file mode 100644 index 0000000..e9cc21c --- /dev/null +++ b/src/app/components/shared/helpers-jump/jump-list.component.ts @@ -0,0 +1,96 @@ +import { Component, OnInit, OnDestroy, Input } from '@angular/core'; +import { NgClass, DatePipe } from '@angular/common'; +import { RouterLink } from '@angular/router'; +import { MatButtonModule } from '@angular/material/button'; +import { MatIconModule } from '@angular/material/icon'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { Observable, Subscription } from 'rxjs'; + +import { Errors, Jump, JumpList, JumpListConfig } from '@models'; +import { JumpsService } from '@services'; +import { JumpPreviewComponent } from './jump-preview.component'; + +@Component({ + selector: 'app-jump-list', + templateUrl: './jump-list.component.html', + standalone: true, + imports: [ + NgClass, + DatePipe, + MatProgressSpinnerModule, + MatButtonModule, + RouterLink, + MatIconModule, + JumpPreviewComponent +] +}) +export class JumpListComponent implements OnInit, OnDestroy { + private _jumps: Subscription = new Subscription(); + errors: Errors = { errors: {} }; + query!: JumpListConfig; + jumps: Array = []; + jumpsCount = 0; + loading = false; + currentPage = 1; + pages: Array = [1]; + lastUpdate: Date = new Date(); + + constructor( + private jumpsService: JumpsService + ) { } + + @Input() limit = 0; + @Input() refresh = 30000; + @Input() title = ''; + @Input() showAdd = false; + @Input() isUser = false; + @Input() showMeta = false; + @Input() + set config(config: JumpListConfig) { + if (config) { + this.query = config; + this.currentPage = 1; + this.loading = true; + } + } + + ngOnInit() { + this.runQuery(); + } + + ngOnDestroy() { + this._jumps.unsubscribe(); + } + + setPageTo(pageNumber: number) { + this.currentPage = pageNumber; + this.runQuery(); + } + + runQuery() { + if (this.limit) { + this.query.filters.limit = this.limit; + this.query.filters.offset = (this.limit * (this.currentPage - 1)); + } + + const jumps$: Observable = this.jumpsService.query(this.query); + this._jumps = jumps$.subscribe({ + next: (data: JumpList) => { + this.loading = false; + this.jumps = data.jumps; + this.jumpsCount = data.jumpsCount; + if (this.limit) { + this.pages = this.getTotalPages(this.jumpsCount, this.limit); + } + }, + error: (err) => { + this.errors = err; + } + }); + } + + getTotalPages(count: number, limit: number) { + // Used from http://www.jstips.co/en/create-range-0...n-easily-using-one-line/ + return Array.from(new Array(Math.ceil(count / limit)), (val, index) => index + 1); + } +} diff --git a/src/app/components/shared/helpers-jump/jump-meta.component.html b/src/app/components/shared/helpers-jump/jump-meta.component.html new file mode 100644 index 0000000..5545574 --- /dev/null +++ b/src/app/components/shared/helpers-jump/jump-meta.component.html @@ -0,0 +1,14 @@ +
+ + + +
+ + {{ jump.author.username }} + + + {{ jump.createdAt | date: 'longDate' }} + +
+ +
diff --git a/src/app/components/shared/helpers-jump/jump-meta.component.scss b/src/app/components/shared/helpers-jump/jump-meta.component.scss new file mode 100644 index 0000000..8ca2c94 --- /dev/null +++ b/src/app/components/shared/helpers-jump/jump-meta.component.scss @@ -0,0 +1,29 @@ +/* Jumps Meta */ +.jump-meta { + display: block; + position: relative; + font-weight: 300; + img { + display: inline-block; + vertical-align: middle; + height: 32px; + width: 32px; + border-radius: 30px; + } + .info { + margin: 0 1rem 0 .4rem; + display: inline-block; + vertical-align: middle; + line-height: 1rem; + .author { + display: block; + font-weight: 500 !important; + margin-bottom: 0.1rem; + } + .date { + color: #bbb; + font-size: .8rem; + display: block; + } + } +} diff --git a/src/app/components/shared/helpers-jump/jump-meta.component.ts b/src/app/components/shared/helpers-jump/jump-meta.component.ts new file mode 100644 index 0000000..b057c2a --- /dev/null +++ b/src/app/components/shared/helpers-jump/jump-meta.component.ts @@ -0,0 +1,16 @@ +import { Component, Input } from '@angular/core'; +import { DatePipe } from '@angular/common'; +import { RouterLink } from '@angular/router'; + +import { Jump } from '@models'; + +@Component({ + selector: 'app-jump-meta', + standalone: true, + imports: [ RouterLink, DatePipe ], + styleUrl: './jump-meta.component.scss', + templateUrl: './jump-meta.component.html' +}) +export class JumpMetaComponent { + @Input() jump!: Jump; +} diff --git a/src/app/components/shared/helpers-jump/jump-preview.component.html b/src/app/components/shared/helpers-jump/jump-preview.component.html new file mode 100644 index 0000000..0a06b3b --- /dev/null +++ b/src/app/components/shared/helpers-jump/jump-preview.component.html @@ -0,0 +1,44 @@ + + + + #{{ jump.numero }} + {{ jump.categorie }} / {{ jump.module }} + + + + + +
+
+
+
Date
+
{{ jump.date }}
+
Lieu
+
{{ jump.lieu }} {{ jump.oaci }}
+
Voile
+
{{ jump.voile }} {{ jump.taille }}
+
+
+
+
+
Hauteur
+
{{ jump.hauteur }}
+
Aeronef
+
{{ jump.aeronef }} {{ jump.imat }}
+
Type de saut
+
{{ jump.categorie }} {{ jump.module }}
+
+
+
+
Participants ({{ jump.participants }})
+
+
+ +
+ + + + + + +
diff --git a/src/app/components/shared/helpers-jump/jump-preview.component.scss b/src/app/components/shared/helpers-jump/jump-preview.component.scss new file mode 100644 index 0000000..69717d3 --- /dev/null +++ b/src/app/components/shared/helpers-jump/jump-preview.component.scss @@ -0,0 +1,44 @@ +/* Jumps preview */ +.jump-preview { + border-top: 1px solid rgba(0, 0, 0, .1); + padding: 1.4rem 0 0.5rem; + .jump-meta { + margin: 0 0 0.2rem; + } + h3 .preview-link { + font-weight: 600 !important; + font-size: 1.5rem !important; + margin-bottom: 3px; + } +} +.preview-link { + color: inherit !important; + &:hover { + text-decoration: inherit !important; + } + p { + color: #999; + margin-bottom: 15px; + font-size: 1rem; + font-weight: 300; + line-height: 1.3rem; + } + span { + max-width: 30%; + font-size: .8rem; + font-weight: 300; + color: #bbb; + vertical-align: middle; + } + ul { + float: right; + max-width: 50%; + vertical-align: top; + } + ul li { + font-weight: 300; + font-size: .8rem !important; + padding-top: .2rem; + padding-bottom: .2rem; + } +} diff --git a/src/app/components/shared/helpers-jump/jump-preview.component.ts b/src/app/components/shared/helpers-jump/jump-preview.component.ts new file mode 100644 index 0000000..cbf6433 --- /dev/null +++ b/src/app/components/shared/helpers-jump/jump-preview.component.ts @@ -0,0 +1,49 @@ +import { Component, OnDestroy, Input } from '@angular/core'; +import { DecimalPipe } from '@angular/common'; +import { Router, RouterLink } from '@angular/router'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; +import { MatDividerModule } from '@angular/material/divider'; +import { Observable, Subscription } from 'rxjs'; + +import { JumpMetaComponent } from './jump-meta.component'; +import { Jump } from '@models'; +import { JumpsService } from '@services'; + +@Component({ + selector: 'app-jump-preview', + standalone: true, + imports: [ + DecimalPipe, RouterLink, + MatDividerModule, MatButtonModule, MatCardModule, + JumpMetaComponent + ], + styleUrl: './jump-preview.component.scss', + templateUrl: './jump-preview.component.html' +}) +export class JumpPreviewComponent implements OnDestroy { + @Input() jump!: Jump; + @Input() isUser!: boolean; + @Input() showMeta!: boolean; + private _jump: Subscription = new Subscription(); + isDeleting = false; + + constructor( + private router: Router, + private jumpsService: JumpsService + ) { } + + ngOnDestroy() { + this._jump.unsubscribe(); + } + + deleteJump() { + this.isDeleting = true; + const jump$: Observable = this.jumpsService.destroy(this.jump.slug); + this._jump = jump$.subscribe({ + next: () => { + this.router.navigateByUrl('/'); + } + }); + } +} diff --git a/src/app/components/shared/helpers-jump/jump-table.component.html b/src/app/components/shared/helpers-jump/jump-table.component.html new file mode 100644 index 0000000..513eec7 --- /dev/null +++ b/src/app/components/shared/helpers-jump/jump-table.component.html @@ -0,0 +1,314 @@ +
+
+
+ + + @if (this.searchForm.controls['numero'].status === 'INVALID') { + {{getErrorMessage()}} + } + + + + Aucun saut à afficher pour le moment. + Chargement des sauts en cours +
+
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Aucun saut à afficher pour le moment.
# + @if (element.numero) { + + + } + @if (!element.numero) { + + + } + Date + @if (element.date) { + {{element.date | date: 'mediumDate'}} + } + @if (!element.numero) { + + + } + Lieu + @if (element.lieu) { + {{element.lieu}} - {{element.oaci}} + } + @if (!element.numero) { + + + } + Aeronef + @if (element.aeronef) { + {{element.aeronef}} - {{element.imat}} + } + @if (!element.numero) { + + + } + Hauteur + @if (element.hauteur) { + {{element.hauteur}} + } + @if (!element.numero) { + + + } + Voile + @if (element.voile) { + {{element.voile}} - {{element.taille}} + } + @if (!element.numero) { + + + } + Categorie + @if (element.categorie) { + {{element.categorie}}{{element.categorie && element.module ? ' - ' : ''}}{{element.module}} + } + @if (!element.numero) { + + + } + Zone + @if (element.zone) { + {{element.zone}} + } + @if (!element.numero) { + + + } + Participants + @if (element.participants) { + {{element.participants}} + } + @if (!element.numero) { + + + } + Programme + @if (element.programme) { + {{element.programme}} + } + @if (!element.numero) { + + + } + Accessoires + @if (element.accessoires) { + {{element.accessoires}} + } + @if (!element.numero) { + + + } + Fichiers + @if (element.files) { + @for (file of element.files; track $index) { + @switch (file.type) { + @case ('video') { + + } + @case ('image') { + + } + @case ('kml') { + + } + @default { + + } + } + } + } + @if (!element.numero) { + + } + {{ showAdd ? 'Actions' : 'Favoris' }} + @if (element.numero) { + + + + + + + } + @if (!element.numero) { + + + + + + + } +
\ No newline at end of file diff --git a/src/app/components/shared/helpers-jump/jump-table.component.scss b/src/app/components/shared/helpers-jump/jump-table.component.scss new file mode 100644 index 0000000..97a682e --- /dev/null +++ b/src/app/components/shared/helpers-jump/jump-table.component.scss @@ -0,0 +1,29 @@ + +/* TODO(mdc-migration): The following rule targets internal classes of card that may no longer apply for the MDC version. */ +mat-card-content { + padding-bottom: 10px; +} +.main-page { + .feed-toggle { + margin-bottom: -1px; + } + .sidebar { + padding: 5px 10px 10px; + background: #f3f3f3; + border-radius: 4px; + p { + margin-bottom: .2rem; + } + } +} +.table.table-condensed.mat-mdc-table { + tr { + height: inherit; + } + td { + vertical-align: middle; + } +} +.mat-mdc-progress-spinner { + display: inline-block; +} diff --git a/src/app/components/shared/helpers-jump/jump-table.component.ts b/src/app/components/shared/helpers-jump/jump-table.component.ts new file mode 100644 index 0000000..961e909 --- /dev/null +++ b/src/app/components/shared/helpers-jump/jump-table.component.ts @@ -0,0 +1,472 @@ +import { AfterContentChecked, Component, EventEmitter, Input, Output, OnChanges, OnDestroy, ViewChild } from '@angular/core'; +import { CommonModule, DecimalPipe, DatePipe } from '@angular/common'; +import { UntypedFormBuilder, UntypedFormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { Router, RouterLink } from '@angular/router'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; +import { MatDialog, MatDialogModule } from '@angular/material/dialog'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatIconModule } from '@angular/material/icon'; +import { MatInputModule } from '@angular/material/input'; +import { MatMenuModule } from '@angular/material/menu'; +import { MatNativeDateModule } from '@angular/material/core'; +import { MatPaginator, MatPaginatorIntl, MatPaginatorModule } from '@angular/material/paginator'; +import { MatProgressBarModule } from '@angular/material/progress-bar'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { MatSort, MatSortModule } from '@angular/material/sort'; +import { MatTableDataSource, MatTableModule } from '@angular/material/table'; +import { MatSnackBar, MatSnackBarHorizontalPosition, MatSnackBarModule, MatSnackBarVerticalPosition } from '@angular/material/snack-bar'; +import { Observable, Subscription } from 'rxjs'; +import { take } from 'rxjs/operators'; +import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; + +import { FrenchPaginator } from '@components/shared/french-paginator.component'; +import { ColumnDefinition, Errors, Jump, JumpByDay, JumpFile, JumpFileType, JumpList, JumpListConfig, jumpColumns } from '@models'; +import { JumpsService, JumpTableService } from '@services'; +import { JumpAddDialogComponent, JumpDeleteDialogComponent, JumpEditDialogComponent, JumpViewDialogComponent } from '@components/logbook/dialogs' + +@Component({ + standalone: true, + imports: [ + CommonModule, DecimalPipe, DatePipe, RouterLink, FormsModule, ReactiveFormsModule, NgxSkeletonLoaderModule, + MatButtonModule, MatCardModule, MatDialogModule, + MatFormFieldModule, MatIconModule, MatInputModule, MatNativeDateModule, MatMenuModule, + MatPaginatorModule, MatProgressBarModule, MatProgressSpinnerModule, MatSnackBarModule, MatSortModule, MatTableModule, + JumpAddDialogComponent, JumpDeleteDialogComponent, JumpEditDialogComponent, JumpViewDialogComponent + ], + selector: 'app-jump-table', + styleUrl: './jump-table.component.scss', + templateUrl: './jump-table.component.html', + providers: [{provide: MatPaginatorIntl, useClass: FrenchPaginator}] +}) +export class JumpTableComponent implements OnChanges, OnDestroy, AfterContentChecked { + private _jumps: Subscription = new Subscription(); + private _subscriptions: Array = []; + //private _jump: Subscription = new Subscription(); + private _query: JumpListConfig = { type: 'all', filters: {} }; + //private _lastjump: Jump = {} as Jump; + private _currentPage = 1; + public errors!: Errors; + public jump: Jump = {} as Jump; + public jumps!: MatTableDataSource; + public jumpsCount = 0; + /* public displayedColumns: string[] = [ + 'numero', 'date', 'lieu', 'oaci', 'aeronef', + 'imat', 'hauteur', 'voile', 'taille', 'categorie', + 'module', 'participants', 'programme', 'accessoires', + 'zone', 'files', 'actions' + ];*/ + public displayedColumns: string[] = [ + 'numero', 'date', 'lieu', 'aeronef', + 'hauteur', 'voile', 'categorie', + 'participants', 'zone', 'accessoires', + 'files', 'actions' + ]; + //public displayedColumns: string[] = jumpColumns.map((col) => col.key) + public columnsSchema: Array = jumpColumns; + public searchForm: UntypedFormGroup; + public loading = false; + public isSubmitting = false; + public isDeleting = false; + public tableRefresh = false; + public jumpRefresh = false; + //public valid: any = {}; + + @ViewChild(MatSort) sort!: MatSort; + @ViewChild(MatPaginator) paginator!: MatPaginator; + + constructor( + private router: Router, + private _jumpsService: JumpsService, + private _jumpTableService: JumpTableService, + private dialog: MatDialog, + private fb: UntypedFormBuilder, + private snackBar: MatSnackBar + ) { + this._resetErrors(); + this.searchForm = this.fb.group({ + //numero: ['', Validators.required] + numero: '' + }); + } + + @Input() title = ''; + @Input() limit = 0; + @Input() showAdd = false; + @Input() isUser = false; + @Input() + set config(config: JumpListConfig) { + if (config) { + this._query = config; + this._currentPage = 1; + } + } + + get config(): JumpListConfig { + return this._query; + } + @Output() countChange: EventEmitter = new EventEmitter(); + + ngOnChanges() { + this.loading = true; + this._query = this.config; + this.runQuery(); + //console.log('ngOnChanges event in jump-table component'); + } + + ngOnDestroy() { + this._jumps.unsubscribe(); + this._subscriptions.forEach(subscription => { + subscription.unsubscribe(); + }); + } + + ngAfterContentChecked() { + if (this.jumpRefresh != this._jumpTableService.jumpRefresh) { + this.jumpRefresh = this._jumpTableService.jumpRefresh; + this.runQuery(); + //console.log('table has been refreshed in jump-table component'); + } + } + + runQuery() { + /* + const jump$: Observable = this._jumpsService.getLastJump(); + this._jump = jump$.subscribe((jump) => { + this._lastjump = jump; + }); + */ + + if (this.limit) { + this._query.filters.limit = this.limit; + this._query.filters.offset = (this.limit * (this._currentPage - 1)); + } else { + this._query.filters.limit = 0; + this._query.filters.offset = 0; + } + /* + this._query.filters.numeroRangeStart = 1; + this._query.filters.numeroRangeEnd = 0; + this._query.filters.tailleRangeStart = 135; + this._query.filters.tailleRangeEnd = 230; + this._query.filters.participantsRangeStart = 1; + this._query.filters.participantsRangeEnd = 10; + this._query.filters.hauteurRangeStart = 0; + this._query.filters.hauteurRangeEnd = 8000; + */ + + const jumps$: Observable = this._jumpsService.query(this._query); + this._jumps = jumps$.subscribe({ + next: (data: JumpList) => { + //this.updateJumps(data.jumps); + //this.linkSkydiverIdJumps(); + //this.getKmlJumpFiles(data.jumps); + this.loading = false; + this.jumps = new MatTableDataSource(data.jumps); + this.jumpsCount = data.jumpsCount; + this.countChange.emit(this.jumpsCount); + this.paginator.length = data.jumpsCount; + this.jumps.paginator = this.paginator; + this.jumps.sort = this.sort; + this._resetErrors(); + }, + error: (err) => { + this.errors = err; + } + }); + } + + linkSkydiverIdJumps() { + const config: JumpListConfig = { type: 'all', filters: {} } as JumpListConfig; + config.filters.limit = 200; + config.filters.offset = 0; + config.filters.dateRangeStart = '2024-01-01 00:00:00'; + //const year = new Date().getFullYear(); + //config.filters.dateRangeEnd = `${year}-12-31 23:59:59`; + config.filters.dateRangeEnd = '2024-12-31 23:59:59'; + //console.log(config.filters); + const subscription: Subscription = this._jumpsService.getAllByDay(config) + .pipe(take(1)) + .subscribe({ + next: (days) => { + this._resetErrors(); + //console.log('getAllByDay : ', days); + days.forEach(day => { + this.loadSkydiverIdJumps(day, config); + }); + }, + error: (err) => { + this.errors = err; + } + }); + this._subscriptions.push(subscription); + } + + loadSkydiverIdJumps(day: JumpByDay, config: JumpListConfig) { + config.filters.dateRangeStart = `${day.jumps[0].date!.substring(0, 10)} 00:00:00`; + config.filters.dateRangeEnd = `${day.jumps[0].date!.substring(0, 10)} 23:59:59`; + const subscription: Subscription = this._jumpsService.getAllFromSkydiverIdApi(config) + .pipe(take(1)) + .subscribe({ + next: (data) => { + if (data.items.length) { + const diff = day.count - data.items.length; + if (diff < 0) { + console.error(`${diff} ${diff > 1 ? 'données' : 'donnée'} altimètre de trop le ${day.jumps[0].date!.substring(0, 10)}`); + } else { + if (diff > 0) { + console.error(`${diff}/${day.count} ${diff > 1 ? 'données altimètre manquantes' : 'donnée altimètre manquante'} le ${day.jumps[0].date!.substring(0, 10)}`, day.jumps, data.items); + } + console.log(`${day.count} ${day.count > 1 ? 'sauts' : 'saut'} le ${data.items[0].date!.substring(0, 10)}`, day.jumps.sort((a, b) => b.numero! - a.numero!), data.items); + data.items.map((jump, index) => { + const file: JumpFile = { + name: jump.name, + path: `/Volumes/Storage/Skydive/X2_Logs/${day.jumps[index].date!.substring(0, 4)}/`, + type: JumpFileType.CSV + } as JumpFile; + this._subscriptions.push( + this._jumpsService.saveX2Data(day.jumps[index].slug!, file, jump) + .pipe(take(1)) + .subscribe({ + next: (jump) => { + this._resetErrors(); + console.log(`Le fichier ${file.name} a été ajouté au saut n°${jump.numero} !`, 'OK'); + }, + error: (err) => { + this.errors = err; + } + }) + ); + return jump; + }); + } + //console.log(`${day.count} ${day.count > 1 ? 'sauts' : 'saut'} le ${day.jumps[0].date!.substring(0, 10)}`); + //console.log(`${data.items.length} ${data.items.length > 1 ? 'sauts' : 'saut'} le ${data.items[0].date!.substring(0, 10)}`, data); + } else { + console.info('Aucune données altimètre pour le ', day.jumps[0].date!.substring(0, 10)); + } + }, + error: (err) => { + console.error('getAllFromSkydiverIdApi error'); + this.errors = err; + } + }); + this._subscriptions.push(subscription); + } + + updateJumps(jumps: Array) { + jumps.map(jump => { + jump.files = []; + if (jump.dossier !== "" && jump.video !== "") { + const file: JumpFile = { + name: jump.video!, + path: jump.dossier!, + type: JumpFileType.VIDEO + } as JumpFile; + this._subscriptions.push( + this._jumpsService.saveFile(jump.slug, file) + .pipe(take(1)) + .subscribe({ + next: (file) => { + this._resetErrors(); + jump.files.push(file); + //console.log(`Le fichier ${file.name} a été ajouté au saut n°${jump.numero} !`, 'OK'); + }, + error: (err) => { + this.errors = err; + } + }) + ); + } + return jump; + }); + } + + getKmlJumpFiles(jumps: Array) { + jumps.map(jump => { + if (jump.x2data !== null) { + //console.log(`Le fichier ${jump.x2data.name} existe pour le saut n°${jump.numero} !`, `https://skydiver.id/api/jump/${jump.x2data.id}/kml`); + const file: JumpFile = { + name: jump.x2data.name.substring(0, -4) + '.kml', + path: `/X2_Kmls/${jump.date.substring(0, 4)}/`, + type: JumpFileType.KML + } as JumpFile; + this._subscriptions.push( + this._jumpsService.saveKml(jump.slug, file) + .pipe(take(1)) + .subscribe({ + next: (file) => { + this._resetErrors(); + console.log(`Le fichier ${file.path}${file.name} a été ajouté au saut n°${jump.numero} !`, 'OK'); + }, + error: (err) => { + this.errors = err; + } + }) + ); + } + return jump; + }); + } + + deleteJump(slug: string) { + this.isDeleting = true; + this._subscriptions.push( + this._jumpsService.destroy(slug) + .pipe(take(1)) + .subscribe(() => { + this.router.navigateByUrl('/'); + }) + ); + } + + openDeleteDialog(jump: Jump): void { + const dialogRef = this.dialog.open(JumpDeleteDialogComponent, { + width: '60vw', + data: jump + }); + this._subscriptions.push( + dialogRef.afterClosed() + .pipe(take(1)) + .subscribe(result => { + if (result != undefined) { + this._onDelete(result.slug); + } + }) + ); + } + + openEditDialog(jump: Jump): void { + const dialogRef = this.dialog.open(JumpEditDialogComponent, { + width: '70vw', + data: jump + }); + this._subscriptions.push( + dialogRef.afterClosed() + .pipe(take(1)) + .subscribe(result => { + if (result != undefined) { + this._onEdit(result); + } + }) + ); + } + + openViewDialog(jump: Jump): void { + const dialogRef = this.dialog.open(JumpViewDialogComponent, { + width: '60vw', + data: jump + }); + dialogRef.afterClosed(); + } + + getErrorMessage() { + if (this.searchForm.controls['numero'].errors !== null) { + return 'Vous devez indiquer une valeur'; + } + return ''; + } + + submitForm() { + if (this.searchForm.valid) { + this._query.filters.numero = this.searchForm.value.numero; + this._resetErrors(); + this.runQuery(); + } + } + + private _onDelete(slug: string): void { + try { + this.isDeleting = true; + this._subscriptions.push( + this._jumpsService.destroy(slug) + .pipe(take(1)) + .subscribe({ + next: () => { + this._resetErrors(); + this._openSnackBar(`Le saut a été supprimé !`, 'OK'); + this.runQuery(); + this.tableRefresh = !this.tableRefresh; + this._jumpTableService.updateTableRefresh(this.tableRefresh); + }, + error: (err) => { + this.errors = err; + } + }) + ); + } catch (error) { + console.error(error); + } + } + + private _onEdit(jump: Jump): void { + try { + this.isSubmitting = true; + this._subscriptions.push( + this._jumpsService.update(jump) + .pipe(take(1)) + .subscribe({ + next: (jump) => { + this._resetErrors(); + this._openSnackBar(`Le saut n°${jump.numero} a été mis à jour !`, 'OK'); + this.runQuery(); + this.tableRefresh = !this.tableRefresh; + this._jumpTableService.updateTableRefresh(this.tableRefresh); + }, + error: (err) => { + this.errors = err; + this.isSubmitting = false; + } + }) + ); + } catch (error) { + console.error(error); + } + } + + private _openSnackBar(content: string, title: string) { + this.snackBar.open(content, title, { + horizontalPosition: 'end', + verticalPosition: 'bottom', + duration: 4000, + }); + } + + private _resetErrors(): void { + this.errors = { errors: {} }; + } + + /* + disableSubmit(id: number) { + if (this.valid[id]) { + return Object.values(this.valid[id]).some((item) => item === false) + } + return false + } + + inputHandler(e: any, id: number, key: string) { + if (!this.valid[id]) { + this.valid[id] = {} + } + this.valid[id][key] = e.target.validity.valid + } + */ + + /* + isAllSelected() { + return this.jumps.data.every((item) => item.isSelected) + } + + isAnySelected() { + return this.jumps.data.some((item) => item.isSelected) + } + + selectAll(event: any) { + this.jumps.data = this.jumps.data.map((item) => ({ + ...item, + isSelected: event.checked, + })) + } + */ + +} diff --git a/src/app/components/shared/herowars-components/fortification-card-content/fortification-card-content.component.html b/src/app/components/shared/herowars-components/fortification-card-content/fortification-card-content.component.html new file mode 100644 index 0000000..1c6b4cc --- /dev/null +++ b/src/app/components/shared/herowars-components/fortification-card-content/fortification-card-content.component.html @@ -0,0 +1,37 @@ + + {{ data.name }} + [ {{ data.count | number : '1.0' }} ] + +
    + @for (champion of data.teams; track champion; let index = $index) { +
  • + slot {{data.slots[(index)]}} + @if (champion.id !== data.positions[data.slots[(index)]].toString()) { + {{ getMemberNameById(data.positions[data.slots[(index)]].toString()) }} + + } + {{ champion.name }} + + @switch (teamType) { + @case ('heroes') { + @if (champion.id !== data.positions[data.slots[(index)]].toString()) { + {{ getMemberHeroesPowerById(data.positions[data.slots[(index)]].toString()) | number : '1.0' }} + + } + {{ champion.heroes.power | number : '1.0' }} + } + @case ('titans') { + @if (champion.id !== data.positions[data.slots[(index)]].toString()) { + {{ getMemberTitansPowerById(data.positions[data.slots[(index)]].toString()) | number : '1.0' }} + + } + {{ champion.titans.power | number : '1.0' }} + } + @default { + 0 + } + } + +
  • + } +
diff --git a/src/app/components/shared/herowars-components/fortification-card-content/fortification-card-content.component.scss b/src/app/components/shared/herowars-components/fortification-card-content/fortification-card-content.component.scss new file mode 100644 index 0000000..8db5b13 --- /dev/null +++ b/src/app/components/shared/herowars-components/fortification-card-content/fortification-card-content.component.scss @@ -0,0 +1,13 @@ +.slot { + min-width: 60px; + display: inline-block; +} +.mat-mdc-standard-chip { + --mdc-chip-container-height: 28px; + --mdc-chip-container-shape-radius: 8px 8px 8px 8px; + --mdc-chip-label-text-color: inherit; + --mdc-chip-label-text-line-height: 20px; + --mdc-chip-label-text-size: 13px; + --mdc-chip-label-text-weight: 400; + --mdc-chip-with-avatar-avatar-shape-radius: 6px 6px 6px 6px; +} \ No newline at end of file diff --git a/src/app/components/shared/herowars-components/fortification-card-content/fortification-card-content.component.ts b/src/app/components/shared/herowars-components/fortification-card-content/fortification-card-content.component.ts new file mode 100644 index 0000000..6e02849 --- /dev/null +++ b/src/app/components/shared/herowars-components/fortification-card-content/fortification-card-content.component.ts @@ -0,0 +1,83 @@ +import { Component, Input } from '@angular/core'; +import { DecimalPipe } from '@angular/common'; +import { MatCardModule } from '@angular/material/card'; +import { MatChipsModule } from '@angular/material/chips'; +import { MatIconModule } from '@angular/material/icon'; + +//import { Errors } from '@models'; +//import { HWMember, HWGuildWarFortification, HWGuildWarHeroTeam, HWGuildWarTitanTeam } from '@models'; +import { HWGuildWarFortification, HWMember } from '@models'; + +@Component({ + selector: 'app-fortification-card-content', + templateUrl: './fortification-card-content.component.html', + styleUrl: './fortification-card-content.component.scss', + standalone: true, + imports: [ + DecimalPipe, + MatCardModule, MatChipsModule, MatIconModule + ] +}) +export class FortificationCardContentComponent { + public data: HWGuildWarFortification = {} as HWGuildWarFortification; + public teamType: string = ''; + public guildMembers: HWMember[] = []; + //public errorList: string[] = []; + + @Input() set fortification(data: HWGuildWarFortification) { + this.data = data; + } + + @Input() set type(value: string) { + this.teamType = value; + } + + @Input() set members(value: HWMember[]) { + this.guildMembers = value; + } + + getMemberNameById(id: string): string { + let name = ''; + this.guildMembers.some((item) => { + if (item.id === id) { + name = item.name; + return true; + } + return false; + }); + return name; + } + + getMemberHeroesPowerById(id: string): number { + let power = 0; + this.guildMembers.some((item) => { + if (item.id === id) { + power = item.heroes.power; + return true; + } + return false; + }); + return power; + } + + getMemberTitansPowerById(id: string): number { + let power = 0; + this.guildMembers.some((item) => { + if (item.id === id) { + power = item.titans.power; + return true; + } + return false; + }); + return power; + } + /* + @Input() set errors(errorList: Errors | null) { + this.errorList = errorList + ? Object.keys(errorList.errors || {}).map( + (key) => `${key} ${errorList.errors[key]}`, + ) + : []; + } + */ +} \ No newline at end of file diff --git a/src/app/components/shared/herowars-components/guild-card/guild-card.component.html b/src/app/components/shared/herowars-components/guild-card/guild-card.component.html new file mode 100644 index 0000000..4240049 --- /dev/null +++ b/src/app/components/shared/herowars-components/guild-card/guild-card.component.html @@ -0,0 +1,72 @@ + + +
+ + {{ guildData.clan.title }} |server {{ guildData.clan.serverId }} + +
+ +
+ {{ guildData.clan.membersCount }}/30 +
+
+ +
+
+ Server/Season Dates +
+
Server Reset Time
+
{{ (guildData.serverResetTime*1000) | date: 'dd/MM/yyyy HH:mm:ss' }}
+
War End Season Time
+
{{ (guildData.clanWarEndSeasonTime*1000) | date: 'dd/MM/yyyy HH:mm:ss' }}
+
Free Clan Change Start
+
{{ (guildData.freeClanChangeInterval.start * 1000) | date: 'dd/MM/yyyy HH:mm:ss' }}
+
Free Clan Change End
+
{{ (guildData.freeClanChangeInterval.end * 1000) | date: 'dd/MM/yyyy HH:mm:ss' }}
+
+
+
+ Guild Overview +
+
Members
+
{{ guildData.clan.membersCount }}/30
+
Champions
+
{{ guildData.clan.warriors.length }}/20
+
Top Activity
+
{{ guildData.clan.topActivity | number : '1.0' }}
+
Top Dungeon
+
{{ guildData.clan.topDungeon | number : '1.0' }}
+
+
+
+ +
+
+ Guild Settings +
+
Guild Min. Level
+
{{ guildData.clan.minLevel }}
+
Dismissal Delay
+
{{ guildData.clan.daysToKick }} days
+
Guild Master Gifts
+
{{ guildData.clan.giftsCount }}
+
Adventure Stat
+
{{ guildData.stat.adventureStat }}
+
+
+
+ Solide Overview +
+
Today Activity
+
{{ guildData.stat.todayActivity }}
+
Today Titanite
+
{{ guildData.stat.todayDungeonActivity }}
+
Activity Sum
+
{{ guildData.stat.activitySum }}
+
Titanite Sum
+
{{ guildData.stat.dungeonActivitySum }}
+
+
+
+
+
\ No newline at end of file diff --git a/src/app/components/shared/herowars-components/guild-card/guild-card.component.scss b/src/app/components/shared/herowars-components/guild-card/guild-card.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/components/shared/herowars-components/guild-card/guild-card.component.spec.ts b/src/app/components/shared/herowars-components/guild-card/guild-card.component.spec.ts new file mode 100644 index 0000000..f8c4e42 --- /dev/null +++ b/src/app/components/shared/herowars-components/guild-card/guild-card.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { GuildCardComponent } from './guild-card.component'; + +describe('GuildCardComponent', () => { + let component: GuildCardComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [GuildCardComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(GuildCardComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/shared/herowars-components/guild-card/guild-card.component.ts b/src/app/components/shared/herowars-components/guild-card/guild-card.component.ts new file mode 100644 index 0000000..4eba034 --- /dev/null +++ b/src/app/components/shared/herowars-components/guild-card/guild-card.component.ts @@ -0,0 +1,36 @@ +import { Component, OnInit } from '@angular/core'; +import { DatePipe, DecimalPipe } from '@angular/common'; +import { MatCardModule } from '@angular/material/card'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatIconModule } from '@angular/material/icon'; + +import { HWGuildData, HWGuildClan, HWGuildStat } from '@models'; + +import guildData from 'src/files-data/hw-guild-data.json'; // page Membres + +@Component({ + selector: 'app-guild-card', + standalone: true, + imports: [ + DatePipe, DecimalPipe, + MatCardModule, MatDividerModule, MatIconModule + ], + templateUrl: './guild-card.component.html', + styleUrl: './guild-card.component.scss' +}) +export class GuildCardComponent implements OnInit { + public guildData: HWGuildData = {} as HWGuildData; + private _guildClan: HWGuildClan = {} as HWGuildClan; + private _guildStat: HWGuildStat = {} as HWGuildStat; + + ngOnInit() { + Object.assign(this._guildClan, guildData.clan); + this.guildData.clan = this._guildClan; + Object.assign(this._guildStat, guildData.stat); + this.guildData.stat = this._guildStat; + this.guildData.serverResetTime = guildData.serverResetTime; + this.guildData.clanWarEndSeasonTime = guildData.clanWarEndSeasonTime; + this.guildData.freeClanChangeInterval = guildData.freeClanChangeInterval; + this.guildData.giftUids = guildData.giftUids; + } +} diff --git a/src/app/components/shared/herowars-components/guildraids-log/guildraids-log.component.html b/src/app/components/shared/herowars-components/guildraids-log/guildraids-log.component.html new file mode 100644 index 0000000..e96a810 --- /dev/null +++ b/src/app/components/shared/herowars-components/guildraids-log/guildraids-log.component.html @@ -0,0 +1,436 @@ + + +
+ + {{ title }} + +
+ +
+ {{ subtitle }} +
+
+ +
+ + Choisissez une date + + MM/DD/YYYY + + + + + + + + + + Duration + + Stage duration in hour + +
+ + + Stage 1 +
+
+

Stage 1

+

+ From {{ getStagesTime(0).startTime | date: 'dd/MM HH:mm' }} + to {{ getStagesTime(0).endTime | date: 'dd/MM HH:mm' }} +

+
+ +
+

Power limit: 320k

+
+
+ + + + + + + + + + + + + + + @for (raid of getRaidsLog(1); track raid; let index = $index) { + + + + + + + + + + + } + +
+
+ # +
+
+
+ Date + +
+
+
+ Member +
+
+
+ Level +
+
+
+ Damage +
+
+
+ Stage +
+
+
+ Power +
+
+
+ Variation +
+
+ {{ (index+1) }} + + {{ raid.startTime + '000' | date: 'dd/MM HH:mm:ss' }} + + {{ raid.userName }} + + {{ raid.level | number : '1.0' }} + +
+ @if (raid.damage["2"] > 0) { + + } + {{ (raid.damage["1"] + raid.damage["2"]) | number : '1.0' }} +
+
+ {{ raid.stage.name }}: {{ (raid.stage.maxPower / 1000) | number : '1.0' }}k + + {{ raid.power | number : '1.0' }} + + + {{ raid.variation.percent | number : '1.0-2' }}% + +
+
+ + +
+
+ + Stage 2 +
+
+

Stage 2

+

+ From {{ getStagesTime(1).startTime | date: 'dd/MM HH:mm' }} + to {{ getStagesTime(1).endTime | date: 'dd/MM HH:mm' }} +

+
+ +
+

Power limit: 500k

+
+
+ + + + + + + + + + + + + + + @for (raid of getRaidsLog(2); track raid; let index = $index) { + + + + + + + + + + + } + +
+
+ # +
+
+
+ Date + +
+
+
+ Member +
+
+
+ Level +
+
+
+ Damage +
+
+
+ Stage +
+
+
+ Power +
+
+
+ Variation +
+
+ {{ (index+1) }} + + {{ raid.startTime + '000' | date: 'dd/MM HH:mm:ss' }} + + {{ raid.userName }} + + {{ raid.level | number : '1.0' }} + +
+ @if (raid.damage["2"] > 0) { + + } + {{ (raid.damage["1"] + raid.damage["2"]) | number : '1.0' }} +
+
+ {{ raid.stage.name }}: {{ (raid.stage.maxPower / 1000) | number : '1.0' }}k + + {{ raid.power | number : '1.0' }} + + + {{ raid.variation.percent | number : '1.0-2' }}% + +
+
+ + +
+
+ + Stage 3 +
+
+

Stage 3

+

+ From {{ getStagesTime(2).startTime | date: 'dd/MM HH:mm' }} + to {{ getStagesTime(2).endTime | date: 'dd/MM HH:mm' }} +

+
+ +
+

No power limit

+
+
+ + + + + + + + + + + + + + + @for (raid of getRaidsLog(3); track raid; let index = $index) { + + + + + + + + + + + } + +
+
+ # +
+
+
+ Date + +
+
+
+ Member +
+
+
+ Level +
+
+
+ Damage +
+
+
+ Stage +
+
+
+ Power +
+
+
+ Variation +
+
+ {{ (index+1) }} + + {{ raid.startTime + '000' | date: 'dd/MM HH:mm:ss' }} + + {{ raid.userName }} + + {{ raid.level | number : '1.0' }} + +
+ @if (raid.damage["2"] > 0) { + + } + {{ (raid.damage["1"] + raid.damage["2"]) | number : '1.0' }} +
+
+ {{ raid.stage.name }}: {{ (raid.stage.maxPower / 1000) | number : '1.0' }}k + + {{ raid.power | number : '1.0' }} + + + {{ raid.variation.percent | number : '1.0-2' }}% + +
+
+ + +
+
+ + Statistics +
+
+

Statistics

+
+ +
+

variation ≥ {{ minVarPct }}%

+ + Variation + + percent + excess power in % + +
+
+ + + + + + + + + + + + @for (member of getMembers(); track member; let index = $index) { + + + + + + + + } + +
+
+ # +
+
+
+ Name +
+
+
+ Fights +
+
+
+ Variation moyenne + +
+
+
+ [] +
+
+ {{ (index+1) }} + + {{ member.name }} + + {{ member.raids.length }} + + {{ member.raidsInfo.variationAvg | number : '1.0-2' }}% + +
+ @for (raid of member.raids; track raid) { +
+ {{ raid.variation.percent | number : '1.2-2' }}% +
+ } +
+
+
+ + +
+
+ + timeline + + + manage_search + +
+
+
diff --git a/src/app/components/shared/herowars-components/guildraids-log/guildraids-log.component.scss b/src/app/components/shared/herowars-components/guildraids-log/guildraids-log.component.scss new file mode 100644 index 0000000..e685fc5 --- /dev/null +++ b/src/app/components/shared/herowars-components/guildraids-log/guildraids-log.component.scss @@ -0,0 +1 @@ +/* guildraids-log */ diff --git a/src/app/components/shared/herowars-components/guildraids-log/guildraids-log.component.spec.ts b/src/app/components/shared/herowars-components/guildraids-log/guildraids-log.component.spec.ts new file mode 100644 index 0000000..131e456 --- /dev/null +++ b/src/app/components/shared/herowars-components/guildraids-log/guildraids-log.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { GuildraidsLogComponent } from './guildraids-log.component'; + +describe('GuildraidsLogComponent', () => { + let component: GuildraidsLogComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [GuildraidsLogComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(GuildraidsLogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/shared/herowars-components/guildraids-log/guildraids-log.component.ts b/src/app/components/shared/herowars-components/guildraids-log/guildraids-log.component.ts new file mode 100644 index 0000000..af4efde --- /dev/null +++ b/src/app/components/shared/herowars-components/guildraids-log/guildraids-log.component.ts @@ -0,0 +1,214 @@ +import { Component, Injectable, inject, Input, OnInit } from '@angular/core'; +import { DatePipe, DecimalPipe } from '@angular/common'; +import { FormBuilder, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; +import { STEPPER_GLOBAL_OPTIONS } from '@angular/cdk/stepper'; +import { MatCardModule } from '@angular/material/card'; +import { MatButtonModule } from '@angular/material/button'; +import { MatDatepickerModule } from '@angular/material/datepicker'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatIconModule } from '@angular/material/icon'; +import { MatInputModule } from '@angular/material/input'; +import { MatStepperIntl, MatStepperModule } from '@angular/material/stepper'; +import { MatTooltipModule } from '@angular/material/tooltip'; + +import { HWGuildRaid, HWGuildRaidAttacker, HWGuildRaidAttackers, HWGuildRaidStage, HWMember } from '@models'; + +import guildRaids from 'src/files-data/hw-guild-raids.json'; // page Asgard -> Guild Raid -> Log + +@Injectable() +export class StepperIntl extends MatStepperIntl { + // the default optional label text, if unspecified is "Optional" + override optionalLabel = 'Optional Label'; +} +@Component({ + selector: 'app-guildraids-log', + standalone: true, + providers: [ + { + provide: STEPPER_GLOBAL_OPTIONS, + useValue: {displayDefaultIndicatorType: false}, + }, + ], + imports: [ + DatePipe, DecimalPipe, FormsModule, ReactiveFormsModule, + MatButtonModule, MatCardModule, MatDatepickerModule, MatDividerModule, + MatFormFieldModule, MatIconModule, MatInputModule, MatTooltipModule, + MatStepperModule + ], + templateUrl: './guildraids-log.component.html', + styleUrl: './guildraids-log.component.scss' +}) +export class GuildraidsLogComponent implements OnInit { + public now: Date; + public raidsForm: FormGroup; + public guildMembers: HWMember[] = []; + public title = 'Guild Raids'; + public subtitle = 'Log'; + public minVarPct = 3; + private _matStepperIntl = inject(MatStepperIntl); + private _guildRaids: HWGuildRaid[] = []; + private _raidStages: HWGuildRaidStage[] = [ + {num: 1, name: 'Stage 1', maxPower: 350000, duration: 8, startTime: 0, endTime: 0}, + {num: 2, name: 'Stage 2', maxPower: 550000, duration: 8, startTime: 0, endTime: 0}, + {num: 3, name: 'Stage 3', maxPower: 0, duration: 0, startTime: 0, endTime: 0} + ]; + + @Input() set members(value: HWMember[]) { + this.guildMembers = value; + } + + constructor( + private fb: FormBuilder + ) { + this.now = new Date(); + const raidsDate = new Date(); + const startHour = 4; + raidsDate.setHours(startHour, 0, 0, 0); + const controlsConfig = { + num: 1, + name: 'Stage 1', + maxPower: 350, + duration: 8, + startTime: [raidsDate.getTime(), Validators.required], + endTime: 0 + }; + this.raidsForm = this.fb.group(controlsConfig); + } + + _setStagesTime(startTime: number): void { + const raidsDate = new Date(startTime); + const startHour = 4; + raidsDate.setHours(startHour, 0, 0, 0); + this._raidStages[0].startTime = raidsDate.getTime(); + + raidsDate.setHours((startHour + this._raidStages[0].duration), 0, 0, 0); + this._raidStages[0].endTime = raidsDate.getTime(); + this._raidStages[1].startTime = raidsDate.getTime(); + + raidsDate.setHours((startHour + this._raidStages[0].duration + this._raidStages[1].duration), 0, 0, 0); + this._raidStages[1].endTime = raidsDate.getTime(); + this._raidStages[2].startTime = raidsDate.getTime(); + + raidsDate.setHours(startHour, 0, 0, 0); + raidsDate.setDate(raidsDate.getDate() + 4); + this._raidStages[2].endTime = raidsDate.getTime(); + this._matStepperIntl.optionalLabel = this._raidStages[1].duration.toString() + 'h'; + } + + ngOnInit() { + this.guildMembers.map((data) => { + data.raids = []; + data.raidsInfo = { + variationAvg: 0, + variationSum: 0 + }; + return data; + }); + + for (const member of Object.entries(guildRaids)) { + const index = this.guildMembers.findIndex(item => item.id === member[0]); + const memberRaids: HWGuildRaid[] = []; + if (index !== -1) { + for (const data of Object.entries(member[1])) { + const raid: HWGuildRaid = {} as HWGuildRaid; + Object.assign(raid, data[1]); + const startTime: number = (parseInt(raid.startTime) * 1000); + if (this._guildRaids.length === 0) { + this._setStagesTime(startTime); + } + const raidsDate = new Date(startTime); + if (raidsDate.getTime() > this._raidStages[1].endTime) { + raid.stage = this._raidStages[2]; + } else if (raidsDate.getTime() > this._raidStages[0].endTime) { + raid.stage = this._raidStages[1]; + } else { + raid.stage = this._raidStages[0]; + } + + raid.damage = data[1].result.damage; + raid.level = data[1].result.level; + raid.userName = this.guildMembers[index].name; + + const attackers: HWGuildRaidAttackers = {} as HWGuildRaidAttackers; + Object.assign(attackers, data[1].attackers); + //Object.assign(raid.attackers, data[1].attackers); + raid.attackers = []; + raid.power = 0; + for (const item of Object.entries(attackers)) { + const attacker: HWGuildRaidAttacker = { + id: item[1].id, + power: item[1].power, + type: item[1].type + } as HWGuildRaidAttacker; + raid.power += attacker.power; + raid.attackers.push(attacker); + } + let percent = 0; + if (raid.stage.maxPower > 0) { + percent = (((raid.power / raid.stage.maxPower) - 1) * 100); + } + let color = 'default'; + let value = 0; + if (raid.stage.maxPower > 0) { + if (percent > 15) { + color = 'raspberry'; + } else if (percent > 10) { + color = 'red'; + } else if (percent > 5) { + color = 'orange'; + } + value = (raid.power - raid.stage.maxPower) + } + raid.variation = { + value: value, + percent: percent, + color: color + }; + raid.tooltip = Math.floor(raid.variation.value / 1000) + 'k'; + //console.log(raid.attackers); + + memberRaids.push(raid); + this._guildRaids.push(raid); + } + this.guildMembers[index].raids = memberRaids; + const varSum = memberRaids.reduce((accumulator, currentValue) => accumulator + currentValue.variation.percent, 0); + this.guildMembers[index].raidsInfo = { + variationAvg: (varSum / memberRaids.length), + variationSum: varSum + }; + } + } + this._guildRaids.sort((a, b) => (a.startTime < b.startTime ? -1 : 1)).map((data) => { + return data; + }); + this.guildMembers.sort((a, b) => (a.raidsInfo.variationAvg > b.raidsInfo.variationAvg ? -1 : 1));/*.map((data) => { + console.log(data.name, data.raidsInfo.variationAvg, data.raids.length); + return data; + });*/ + } + + public getMembers(): HWMember[] { + //return this.guildMembers; + return this.minVarPct ? this.guildMembers.filter(member => (member.raidsInfo.variationAvg >= this.minVarPct) === true) : this.guildMembers; + } + + public getRaidsLog(stageNum: number): HWGuildRaid[] { + return this._guildRaids.filter(raid => (raid.stage.num === stageNum) === true); + } + + public getStagesTime(stageNum: number): HWGuildRaidStage { + return this._raidStages[stageNum]; + } + + public onDateChange(): void { + const timestamp: number = Date.parse(this.raidsForm.controls['startTime'].value); + if (isNaN(timestamp) == false) { + this._setStagesTime(timestamp); + } + } + + submitForm(): void { + } + +} diff --git a/src/app/components/shared/herowars-components/guildwar-attack/guildwar-attack.component.html b/src/app/components/shared/herowars-components/guildwar-attack/guildwar-attack.component.html new file mode 100644 index 0000000..22a4ab0 --- /dev/null +++ b/src/app/components/shared/herowars-components/guildwar-attack/guildwar-attack.component.html @@ -0,0 +1,149 @@ + + +
+ + Guild War Day {{ warInfo.day }} VS {{ warInfo.clanEnemyName }} + +
+ +
+ {{ warInfo.endTime | date: 'dd/MM/yyyy HH:mm:ss' }} +
+
+ + +
+
+
Server End Time
+
{{ warInfo.endTime | date: 'dd/MM/yyyy HH:mm:ss' }}
+
Next War Time
+
{{ warInfo.nextWarTime| date: 'dd/MM/yyyy HH:mm:ss' }}
+
Next Lock Time
+
{{ warInfo.nextLockTime | date: 'dd/MM/yyyy HH:mm:ss' }}
+
+
+
+
+ + + +
+ + {{ warInfo.clanEnemyName }} Members + +
+ +
+ {{ subtitle }} {{ warInfo.endTime | date: 'dd/MM/yyyy HH:mm:ss' }} +
+
+ + + + + + + + + + + + + @for (enemy of getEnemies(); track enemy; let index = $index) { + + + + + + + + } + +
+
+ # +
+
+
+ Name + +
+
+
+ Last Login +
+
+
+ Heroes +
+
+
+ Titans +
+
+ {{ (index+1) }} + +
+ + {{ enemy.name }} +
+
+ {{ enemy.lastLoginTime + '000' | date: 'dd/MM HH:mm' }} + + {{ enemy.heroes.power | number : '1.0' }} + + {{ enemy.titans.power | number : '1.0' }} +
+
+
+ +
+
+ + +
+ + {{ warInfo.clanEnemyName }} Heroes {{ title }} + +
+ +
+ {{ subtitle }} +
+
+ + + + + + + + + +
+
+
+ + +
+ + {{ warInfo.clanEnemyName }} Titans {{ title }} + +
+ +
+ {{ subtitle }} +
+
+ + + + + + + + + +
+
+
\ No newline at end of file diff --git a/src/app/components/shared/herowars-components/guildwar-attack/guildwar-attack.component.scss b/src/app/components/shared/herowars-components/guildwar-attack/guildwar-attack.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/components/shared/herowars-components/guildwar-attack/guildwar-attack.component.spec.ts b/src/app/components/shared/herowars-components/guildwar-attack/guildwar-attack.component.spec.ts new file mode 100644 index 0000000..ff431a0 --- /dev/null +++ b/src/app/components/shared/herowars-components/guildwar-attack/guildwar-attack.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { GuildwarAttackComponent } from './guildwar-attack.component'; + +describe('GuildwarAttackComponent', () => { + let component: GuildwarAttackComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [GuildwarAttackComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(GuildwarAttackComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/shared/herowars-components/guildwar-attack/guildwar-attack.component.ts b/src/app/components/shared/herowars-components/guildwar-attack/guildwar-attack.component.ts new file mode 100644 index 0000000..0ae65d2 --- /dev/null +++ b/src/app/components/shared/herowars-components/guildwar-attack/guildwar-attack.component.ts @@ -0,0 +1,285 @@ +import { Component, Input, OnInit } from '@angular/core'; +import { DatePipe, DecimalPipe } from '@angular/common'; +import { MatCardModule } from '@angular/material/card'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatIconModule } from '@angular/material/icon'; + +import { FortificationCardContentComponent } from '@components/shared'; +import { + HWGuildWarEnemySlot, HWGuildWarEnemyTeam, HWGuildWarFortification, + HWGuildWarHeroTeam, HWGuildWarTitanTeam, HWGuildWarSlots, HWMember +} from '@models'; + +/* JSON data */ +import guildWarData from 'src/files-data/hw-guild-war.json'; // page Overview -> Statistics | page Guild War -> Guild War +import guildWarInfo from 'src/files-data/hw-guild-war-info.json'; // page Guild War -> Guild War +//import guildWarLog from 'src/files-data/hw-guild-war-log.json'; // page Guild War -> Guild War +import guildWarSlots from 'src/files-data/hw-guild-war-slots.json'; // no pages + +@Component({ + selector: 'app-guildwar-attack', + standalone: true, + imports: [ + DatePipe, DecimalPipe, + MatCardModule, MatDividerModule, MatIconModule, + FortificationCardContentComponent + ], + templateUrl: './guildwar-attack.component.html', + styleUrl: './guildwar-attack.component.scss' +}) +export class GuildwarAttackComponent implements OnInit { + private _championsByPower: HWMember[] = []; + private _enemySlots: number[] = []; + public guildEnemies: HWMember[] = []; + public guildMembers: HWMember[] = []; + public title = 'Fortifications'; + public subtitle = 'Guild War Attack'; + public now = new Date(); + public warInfo: { day: number, clanEnemyName: string, endTime: number, nextWarTime: number, nextLockTime: number } = { + day: 0, + clanEnemyName: '', + endTime: 0, + nextWarTime: 0, + nextLockTime: 0 + }; + + @Input() set members(value: HWMember[]) { + this.guildMembers = value; + } + + ngOnInit() { + this.warInfo.day = parseInt(guildWarInfo.day); + this.warInfo.clanEnemyName = guildWarInfo.enemyClan.title; + this.warInfo.endTime = (guildWarInfo.endTime * 1000); + this.warInfo.nextWarTime = (guildWarInfo.nextWarTime * 1000); + this.warInfo.nextLockTime = (guildWarInfo.nextLockTime * 1000); + this._setChampionsByPower(); + this._setEnemies(); + } + + private _getFortification(indexes: number[], type: string, name: string): HWGuildWarFortification { + const teams: HWMember[] = []; + const slots: HWGuildWarSlots = guildWarSlots.slots; + let count = 0; + indexes.forEach((data) => { + switch (type) { + case 'heroes': + teams.push(this.guildEnemies[data]); + count += this.guildEnemies[data].heroes.power; + break; + case 'titans': + teams.push(this.guildEnemies[data]); + count += this.guildEnemies[data].titans.power; + break; + default: + break; + } + }); + return { + name: name, + type: type, + count: count, + teams: teams, + positions: this._enemySlots, + slots: slots[name] + }; + } + + private _getDefense(type: string, name: string): HWGuildWarFortification { + const teams: HWMember[] = []; + const slots: HWGuildWarSlots = guildWarSlots.slots; + let count = 0; + slots[name].forEach(slot => { + let enemies: HWMember[] = []; + let team: HWMember = {} as HWMember; + enemies = this.guildEnemies.filter(enemy => parseInt(enemy.id) === this._enemySlots[slot]); + if (enemies.length) { + team = enemies[0]; + teams.push(team); + switch (type) { + case 'heroes': + count += team.heroes.power; + break; + case 'titans': + count += team.titans.power; + break; + default: + break; + } + } + }); + + return { + name: name, + type: type, + count: count, + teams: teams, + positions: this._enemySlots, + slots: slots[name] + }; + } + + private _setEnemies(): void { + const warriors: number[] = []; + for (const data of Object.entries(guildWarInfo.enemyClanTries)) { + warriors.push(parseInt(data[0])); + } + for (const data of Object.entries(guildWarInfo.enemyClanMembers)) { + const enemy: HWMember = {} as HWMember; + Object.assign(enemy, data[1]); + if (warriors.indexOf(parseInt(enemy.id)) !== -1) { + enemy.champion = true; + } else { + enemy.champion = false; + } + enemy.heroes = { power: 0, teams: []}; + enemy.titans = { power: 0, teams: []}; + + //console.log(guildWarInfo.enemySlots); + + this.guildEnemies.push(enemy); + } + + for (const data of Object.entries(guildWarInfo.enemySlots)) { + const ennemySlot: HWGuildWarEnemySlot = {} as HWGuildWarEnemySlot; + Object.assign(ennemySlot, data[1]); + //console.log(ennemySlot.slotId, ennemySlot.user.name, ennemySlot.user.id); //, ennemySlot.team["1"].power); + ennemySlot.teams = []; + let totalHeroPower = 0; + let totalTitanPower = 0; + if (ennemySlot.user !== null) { + this._enemySlots[ennemySlot.slotId] = parseInt(ennemySlot.user.id); + for (const team of Object.entries(data[1].team[0])) { + /* + ennemySlot.teams.push(enemyTeam); + console.log(enemyTeam); + */ + const enemyTeam: HWGuildWarEnemyTeam = {} as HWGuildWarEnemyTeam; + Object.assign(enemyTeam, team[1]); + switch (enemyTeam.type) { + case 'hero': + case 'pet': + totalHeroPower += enemyTeam.power; + break; + case 'titan': + totalTitanPower += enemyTeam.power; + break; + default: + break; + } + ennemySlot.teams.push(team[1]); + //console.log(team[1]); + } + //console.log(totalHeroPower, totalTitanPower, ennemySlot.teams); + + this.guildEnemies.some((item) => { + if (item.id === ennemySlot.user.id) { + if (totalHeroPower) { + item.heroes.power = totalHeroPower; + item.heroes.teams = ennemySlot.teams; + } + if (totalTitanPower) { + item.titans.power = totalTitanPower; + item.titans.teams = ennemySlot.teams; + } + return true; + } + return false; + }); + } + this.guildEnemies.sort((a, b) => ((a.heroes.power + a.titans.power) > (b.heroes.power + b.titans.power) ? -1 : 1)); // Descending + } + } + + private _setChampionsByPower(): void { + for (const [teamId, teamValues] of Object.entries(guildWarData.teams)) { + const index = this.guildMembers.findIndex(member => member.id === teamId); + let totalHeroPower = 0; + let totalTitanPower = 0; + const heroes: HWGuildWarHeroTeam[] = []; + const titans: HWGuildWarTitanTeam[] = []; + + for (const unit of Object.entries(teamValues.clanDefence_heroes.units)) { + heroes.push(unit[1]); + totalHeroPower += unit[1].power; + } + for (const unit of Object.entries(teamValues.clanDefence_titans.units)) { + titans.push(unit[1]); + totalTitanPower += unit[1].power; + } + this.guildMembers[index].heroes = { power: totalHeroPower, teams: heroes }; + this.guildMembers[index].titans = { power: totalTitanPower, teams: titans }; + } + this.guildMembers.sort((a, b) => ((a.heroes.power + a.titans.power) > (b.heroes.power + b.titans.power) ? -1 : 1)); // Descending + this._championsByPower = this.guildMembers.filter(member => member.champion === true); + } + + getEnemies(): HWMember[] { + return this.guildEnemies; + } + + getMembers(): HWMember[] { + return this.guildMembers; + } + + getLighthouse(): HWGuildWarFortification { + //const indexes: number[] = [0, 4, 8]; + //return this._getFortification(indexes, 'heroes', 'Lighthouse'); + return this._getDefense('heroes', 'Lighthouse'); + } + + getBarracks(): HWGuildWarFortification { + //const indexes: number[] = [1, 5, 6]; + //return this._getFortification(indexes, 'heroes', 'Barracks'); + return this._getDefense('heroes', 'Barracks'); + } + + getMageAcademy(): HWGuildWarFortification { + //const indexes: number[] = [2, 3, 7]; + //return this._getFortification(indexes, 'heroes', 'Mage Academy'); + return this._getDefense('heroes', 'Mage Academy'); + } + + getFoundry(): HWGuildWarFortification { + //const indexes: number[] = [9, 11, 12, 13]; + //return this._getFortification(indexes, 'heroes', 'Foundry'); + return this._getDefense('heroes', 'Foundry'); + } + + getCitadel(): HWGuildWarFortification { + //const indexes: number[] = [10, 14, 15, 16, 17, 18, 19]; + //return this._getFortification(indexes, 'heroes', 'Citadel'); + return this._getDefense('heroes', 'Citadel'); + } + + getBridge(): HWGuildWarFortification { + //const indexes: number[] = [0, 1, 2, 3]; + //return this._getFortification(indexes, 'titans', 'Bridge'); + return this._getDefense('titans', 'Bridge'); + } + + getGatesOfNature(): HWGuildWarFortification { + //const indexes: number[] = [4, 9, 14, 19]; + //return this._getFortification(indexes, 'titans', 'Gates Of Nature'); + return this._getDefense('titans', 'Gates Of Nature'); + } + + getBastionOfFire(): HWGuildWarFortification { + //const indexes: number[] = [5, 10, 15, 16]; + //return this._getFortification(indexes, 'titans', 'Bastion Of Fire'); + return this._getDefense('titans', 'Bastion Of Fire'); + } + + getBastionOfIce(): HWGuildWarFortification { + //const indexes: number[] = [6, 11, 12, 17]; + //return this._getFortification(indexes, 'titans', 'Bastion Of Ice'); + return this._getDefense('titans', 'Bastion Of Ice'); + } + + getSpringOfElements(): HWGuildWarFortification { + //const indexes: number[] = [7, 8, 13, 18]; + //return this._getFortification(indexes, 'titans', 'Spring Of Elements'); + return this._getDefense('titans', 'Spring Of Elements'); + } + +} diff --git a/src/app/components/shared/herowars-components/guildwar-champions/guildwar-champions.component.html b/src/app/components/shared/herowars-components/guildwar-champions/guildwar-champions.component.html new file mode 100644 index 0000000..22d871f --- /dev/null +++ b/src/app/components/shared/herowars-components/guildwar-champions/guildwar-champions.component.html @@ -0,0 +1,57 @@ + + +
+ + {{ title }} + +
+ +
+ {{ subtitle }} +
+
+ + + + + + + + + + + @for (champion of getChampionsByPower(); track champion; let index = $index) { + + + + + + } + +
+
+ # +
+
+
+ Name +
+
+
+ Power + +
+
+ {{ (index+1) }} + + {{ champion.name }} + + @if (teamType === 'heroes') { + {{ champion.heroes.power | number : '1.0' }} + } + @else { + {{ champion.titans.power | number : '1.0' }} + } +
+
+
\ No newline at end of file diff --git a/src/app/components/shared/herowars-components/guildwar-champions/guildwar-champions.component.scss b/src/app/components/shared/herowars-components/guildwar-champions/guildwar-champions.component.scss new file mode 100644 index 0000000..9c4480f --- /dev/null +++ b/src/app/components/shared/herowars-components/guildwar-champions/guildwar-champions.component.scss @@ -0,0 +1 @@ +/* guildwar-champions */ diff --git a/src/app/components/shared/herowars-components/guildwar-champions/guildwar-champions.component.spec.ts b/src/app/components/shared/herowars-components/guildwar-champions/guildwar-champions.component.spec.ts new file mode 100644 index 0000000..eff2a52 --- /dev/null +++ b/src/app/components/shared/herowars-components/guildwar-champions/guildwar-champions.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { GuildwarChampionsComponent } from './guildwar-champions.component'; + +describe('GuildwarChampionsComponent', () => { + let component: GuildwarChampionsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [GuildwarChampionsComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(GuildwarChampionsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/shared/herowars-components/guildwar-champions/guildwar-champions.component.ts b/src/app/components/shared/herowars-components/guildwar-champions/guildwar-champions.component.ts new file mode 100644 index 0000000..dca0da4 --- /dev/null +++ b/src/app/components/shared/herowars-components/guildwar-champions/guildwar-champions.component.ts @@ -0,0 +1,58 @@ +import { Component, Input, OnInit } from '@angular/core'; +import { DecimalPipe } from '@angular/common'; +import { MatCardModule } from '@angular/material/card'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatIconModule } from '@angular/material/icon'; + +import { HWMember } from '@models'; +//import { HWGuildWarFortification, HWMember } from '@models'; + +@Component({ + selector: 'app-guildwar-champions', + standalone: true, + imports: [ + DecimalPipe, + MatCardModule, MatDividerModule, MatIconModule + ], + templateUrl: './guildwar-champions.component.html', + styleUrl: './guildwar-champions.component.scss' +}) +export class GuildwarChampionsComponent implements OnInit { + private _championsByPower: HWMember[] = []; + public guildMembers: HWMember[] = []; + public color: string = 'primary'; + public teamType: string = ''; + public title = 'Champions'; + public subtitle = 'by power'; + + @Input() set members(value: HWMember[]) { + this.guildMembers = value; + } + + @Input() set type(value: string) { + this.teamType = value; + } + + ngOnInit() { + switch (this.teamType) { + case 'heroes': + this.color = 'navy'; + this.subtitle = 'heroes power'; + this.guildMembers.sort((a, b) => (a.heroes.power > b.heroes.power ? -1 : 1)); // Descending + this._championsByPower = this.guildMembers.filter(member => member.champion === true); + break; + case 'titans': + this.color = 'purple'; + this.subtitle = 'titans power'; + this.guildMembers.sort((a, b) => (a.titans.power > b.titans.power ? -1 : 1)); // Descending + this._championsByPower = this.guildMembers.filter(member => member.champion === true); + break; + default: + break; + } + } + + getChampionsByPower(): HWMember[] { + return this._championsByPower; + } +} diff --git a/src/app/components/shared/herowars-components/guildwar-defence/guildwar-defence.component.html b/src/app/components/shared/herowars-components/guildwar-defence/guildwar-defence.component.html new file mode 100644 index 0000000..e82a52a --- /dev/null +++ b/src/app/components/shared/herowars-components/guildwar-defence/guildwar-defence.component.html @@ -0,0 +1,36 @@ + + +
+ + {{ title }} + +
+ +
+ {{ subtitle }} +
+
+ + @if (teamType === 'heroes') { + + + + + + + + } + @else { + + + + + + + + } + +
+
+ Position to check +
\ No newline at end of file diff --git a/src/app/components/shared/herowars-components/guildwar-defence/guildwar-defence.component.scss b/src/app/components/shared/herowars-components/guildwar-defence/guildwar-defence.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/components/shared/herowars-components/guildwar-defence/guildwar-defence.component.spec.ts b/src/app/components/shared/herowars-components/guildwar-defence/guildwar-defence.component.spec.ts new file mode 100644 index 0000000..f2885ed --- /dev/null +++ b/src/app/components/shared/herowars-components/guildwar-defence/guildwar-defence.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { GuildwarDefenceComponent } from './guildwar-defence.component'; + +describe('GuildwarDefenceComponent', () => { + let component: GuildwarDefenceComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [GuildwarDefenceComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(GuildwarDefenceComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/shared/herowars-components/guildwar-defence/guildwar-defence.component.ts b/src/app/components/shared/herowars-components/guildwar-defence/guildwar-defence.component.ts new file mode 100644 index 0000000..65a7021 --- /dev/null +++ b/src/app/components/shared/herowars-components/guildwar-defence/guildwar-defence.component.ts @@ -0,0 +1,191 @@ +import { Component, Input, OnInit } from '@angular/core'; +//import { DecimalPipe } from '@angular/common'; +import { MatCardModule } from '@angular/material/card'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatIconModule } from '@angular/material/icon'; + +import { FortificationCardContentComponent } from '@components/shared'; +//import { HWMember } from '@models'; +import { HWGuildWarFortification, HWGuildWarHeroTeam, HWGuildWarSlots, HWGuildWarTitanTeam, HWMember } from '@models'; + +/* JSON data */ +import guildWarData from 'src/files-data/hw-guild-war.json'; // page Overview -> Statistics | page Guild War -> Guild War +import guildWarSlots from 'src/files-data/hw-guild-war-slots.json'; // no pages + +@Component({ + selector: 'app-guildwar-defence', + standalone: true, + imports: [ + MatCardModule, MatDividerModule, MatIconModule, + FortificationCardContentComponent + ], + templateUrl: './guildwar-defence.component.html', + styleUrl: './guildwar-defence.component.scss' +}) +export class GuildwarDefenceComponent implements OnInit { + private _championsByPower: HWMember[] = []; + private _championSlots: number[] = []; + public guildMembers: HWMember[] = []; + public teamType: string = ''; + public title = 'Fortifications'; + public subtitle = 'Guild War Defence'; + + @Input() set members(value: HWMember[]) { + this.guildMembers = value; + } + + @Input() set type(value: string) { + this.teamType = value; + } + + ngOnInit() { + for (const [teamId, teamValues] of Object.entries(guildWarData.teams)) { + const index = this.guildMembers.findIndex(member => member.id === teamId); + let totalHeroPower = 0; + let totalTitanPower = 0; + const heroes: HWGuildWarHeroTeam[] = []; + const titans: HWGuildWarTitanTeam[] = []; + this.guildMembers[index].heroes = { power: totalHeroPower, teams: heroes }; + this.guildMembers[index].titans = { power: totalTitanPower, teams: titans }; + + for (const unit of Object.entries(teamValues.clanDefence_heroes.units)) { + heroes.push(unit[1]); + totalHeroPower += unit[1].power; + } + for (const unit of Object.entries(teamValues.clanDefence_titans.units)) { + titans.push(unit[1]); + totalTitanPower += unit[1].power; + } + this.guildMembers[index].heroes = { power: totalHeroPower, teams: heroes }; + this.guildMembers[index].titans = { power: totalTitanPower, teams: titans }; + } + for (const data of Object.entries(guildWarData.slots)) { + this._championSlots[parseInt(data[0])] = data[1]; + } + switch (this.teamType) { + case 'heroes': + this.title = 'Heroes Fortifications'; + this.guildMembers.sort((a, b) => (a.heroes.power > b.heroes.power ? -1 : 1)); // Descending + break; + case 'titans': + this.title = 'Titans Fortifications'; + this.guildMembers.sort((a, b) => (a.titans.power > b.titans.power ? -1 : 1)); // Descending + break; + default: + break; + } + this._championsByPower = this.guildMembers.filter(member => member.champion === true); + } + + private _getFortification(indexes: number[], type: string, name: string): HWGuildWarFortification { + const teams: HWMember[] = []; + const slots: HWGuildWarSlots = guildWarSlots.slots; + let count = 0; + indexes.forEach((data) => { + switch (type) { + case 'heroes': + //console.log(name, data, this._championsByPower[data]); + teams.push(this._championsByPower[data]); + count += this._championsByPower[data].heroes.power; + break; + case 'titans': + teams.push(this._championsByPower[data]); + count += this._championsByPower[data].titans.power; + break; + default: + break; + } + }); + return { + name: name, + type: type, + count: count, + teams: teams, + positions: this._championSlots, + slots: slots[name] + }; + } + + /* + -------------------------------- + 0 - 3 - 6 + 1 - 4 - 7 + 2 - 5 - 8 + -------------------------------- + 9 - 10 - 11 - 12 + -------------------------------- + 13 - 14 - 15 - 16 - 17 - 18 - 19 + -------------------------------- + Mage Academy 1-2-31 + Lighthouse 3-4-32 + Barracks 5-6-33 + Foundry 13-14-15-36 + Citadel 25-26-28-28-29-30-40 + */ + + getLighthouse(): HWGuildWarFortification { + const indexes: number[] = [0, 4, 8]; + return this._getFortification(indexes, 'heroes', 'Lighthouse'); + } + + getBarracks(): HWGuildWarFortification { + const indexes: number[] = [1, 5, 6]; + return this._getFortification(indexes, 'heroes', 'Barracks'); + } + + getMageAcademy(): HWGuildWarFortification { + const indexes: number[] = [2, 3, 7]; + return this._getFortification(indexes, 'heroes', 'Mage Academy'); + } + + getFoundry(): HWGuildWarFortification { + const indexes: number[] = [9, 11, 12, 13]; + return this._getFortification(indexes, 'heroes', 'Foundry'); + } + + getCitadel(): HWGuildWarFortification { + const indexes: number[] = [10, 14, 15, 16, 17, 18, 19]; + return this._getFortification(indexes, 'heroes', 'Citadel'); + } + + /* + -------------------------------- + 0 - 1 - 2 - 3 + -------------------------------- + 4 - 8 - 12 - 16 + 5 - 9 - 13 - 17 + 6 - 10 - 14 - 18 + 7 - 11 - 15 - 19 + -------------------------------- + Bridge 7-8-9-34 + Spring of Elements 10-11-12-35 + Gates of Nature 16-17-18-37 + Bastion of Fire 19-20-21-38 + Bastion of Ice 22-23-24-39 + */ + + getBridge(): HWGuildWarFortification { + const indexes: number[] = [0, 1, 2, 3]; + return this._getFortification(indexes, 'titans', 'Bridge'); + } + + getGatesOfNature(): HWGuildWarFortification { + const indexes: number[] = [5, 10, 15, 16]; + return this._getFortification(indexes, 'titans', 'Gates Of Nature'); + } + + getBastionOfFire(): HWGuildWarFortification { + const indexes: number[] = [6, 11, 12, 17]; + return this._getFortification(indexes, 'titans', 'Bastion Of Fire'); + } + + getBastionOfIce(): HWGuildWarFortification { + const indexes: number[] = [4, 9, 14, 19]; + return this._getFortification(indexes, 'titans', 'Bastion Of Ice'); + } + + getSpringOfElements(): HWGuildWarFortification { + const indexes: number[] = [7, 8, 13, 18]; + return this._getFortification(indexes, 'titans', 'Spring Of Elements'); + } +} diff --git a/src/app/components/shared/herowars-components/guildwar-teams/guildwar-teams.component.html b/src/app/components/shared/herowars-components/guildwar-teams/guildwar-teams.component.html new file mode 100644 index 0000000..fdf62ae --- /dev/null +++ b/src/app/components/shared/herowars-components/guildwar-teams/guildwar-teams.component.html @@ -0,0 +1,101 @@ + + +
+ + {{ title }} + +
+ +
+ {{ subtitle }} +
+
+ + + + + + + + + + + + + @for (member of getChampionsByPower(); track member; let index = $index) { + + + + + + + + } + + + + + + + + + + + + + +
+
+ # +
+
+
+ Name +
+
+
+ Avg + +
+
+
+ Heroes +
+
+
+ Titans +
+
+ {{ (index+1) }} + +
+ + {{ member.name }} +
+
+ {{ ((member.heroes.power + member.titans.power) / 2) | number : '1.0-0' }} + + {{ member.heroes.power | number : '1.0' }} + + {{ member.titans.power | number : '1.0' }} +
+ Totals + + {{ guildTotalHeroesPower | number : '1.0' }} + + {{ guildTotalTitansPower | number : '1.0' }} +
+ Averages + + {{ guildAverageHeroesPower | number : '1.0' }} + + {{ guildAverageTitansPower | number : '1.0' }} +
+
+
+
+ Champion signet + No Champion signet + Below average + Above average +
\ No newline at end of file diff --git a/src/app/components/shared/herowars-components/guildwar-teams/guildwar-teams.component.scss b/src/app/components/shared/herowars-components/guildwar-teams/guildwar-teams.component.scss new file mode 100644 index 0000000..f9db35e --- /dev/null +++ b/src/app/components/shared/herowars-components/guildwar-teams/guildwar-teams.component.scss @@ -0,0 +1 @@ +/* guildwar-teams */ diff --git a/src/app/components/shared/herowars-components/guildwar-teams/guildwar-teams.component.spec.ts b/src/app/components/shared/herowars-components/guildwar-teams/guildwar-teams.component.spec.ts new file mode 100644 index 0000000..89c2840 --- /dev/null +++ b/src/app/components/shared/herowars-components/guildwar-teams/guildwar-teams.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { GuildwarTeamsComponent } from './guildwar-teams.component'; + +describe('GuildwarTeamsComponent', () => { + let component: GuildwarTeamsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [GuildwarTeamsComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(GuildwarTeamsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/shared/herowars-components/guildwar-teams/guildwar-teams.component.ts b/src/app/components/shared/herowars-components/guildwar-teams/guildwar-teams.component.ts new file mode 100644 index 0000000..564d0c8 --- /dev/null +++ b/src/app/components/shared/herowars-components/guildwar-teams/guildwar-teams.component.ts @@ -0,0 +1,78 @@ +import { Component, Input, OnInit } from '@angular/core'; +import { DecimalPipe } from '@angular/common'; +import { MatCardModule } from '@angular/material/card'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatIconModule } from '@angular/material/icon'; + +import { HWGuildWarHeroTeam, HWGuildWarTitanTeam, HWMember } from '@models'; + +import guildWarData from 'src/files-data/hw-guild-war.json'; // page Overview -> Statistics | page Guild War -> Guild War + +@Component({ + selector: 'app-guildwar-teams', + standalone: true, + imports: [ + DecimalPipe, + MatCardModule, MatDividerModule, MatIconModule + ], + templateUrl: './guildwar-teams.component.html', + styleUrl: './guildwar-teams.component.scss' +}) +export class GuildwarTeamsComponent implements OnInit { + private _championsByPower: HWMember[] = []; + public guildMembers: HWMember[] = []; + public title = 'Members'; + public subtitle = 'guild war teams power'; + public guildAverageHeroesPower: number = 0; + public guildAverageTitansPower: number = 0; + public guildTotalHeroesPower: number = 0; + public guildTotalTitansPower: number = 0; + + @Input() set members(value: HWMember[]) { + this.guildMembers = value; + } + + ngOnInit() { + + this.guildMembers.sort((a, b) => (((a.heroes.power + a.titans.power) / 2) > ((b.heroes.power + b.titans.power) / 2) ? -1 : 1)) + .map((data) => { + /* + this.guildTotalHeroesPower += data.heroes.power; + this.guildTotalTitansPower += data.titans.power; + this.guildAverageHeroesPower = Math.floor((this.guildTotalHeroesPower / this.guildMembers.length)); + this.guildAverageTitansPower = Math.floor((this.guildTotalTitansPower / this.guildMembers.length)); + */ + this._championsByPower.push(data); + return data; + }); + + for (const [teamId, teamValues] of Object.entries(guildWarData.teams)) { + const index = this._championsByPower.findIndex(member => member.id === teamId); + let totalHeroPower = 0; + let totalTitanPower = 0; + const heroes: HWGuildWarHeroTeam[] = []; + const titans: HWGuildWarTitanTeam[] = []; + + for (const unit of Object.entries(teamValues.clanDefence_heroes.units)) { + heroes.push(unit[1]); + totalHeroPower += unit[1].power; + } + for (const unit of Object.entries(teamValues.clanDefence_titans.units)) { + titans.push(unit[1]); + totalTitanPower += unit[1].power; + } + this._championsByPower[index].heroes = { power: totalHeroPower, teams: heroes }; + this._championsByPower[index].titans = { power: totalTitanPower, teams: titans }; + this.guildTotalHeroesPower += totalHeroPower; + this.guildTotalTitansPower += totalTitanPower; + this._championsByPower[index].rewards = Math.floor((this._championsByPower[index].scoreGifts + this._championsByPower[index].warGifts)); + } + this.guildAverageHeroesPower = Math.floor((this.guildTotalHeroesPower / this._championsByPower.length)); + this.guildAverageTitansPower = Math.floor((this.guildTotalTitansPower / this._championsByPower.length)); + } + + getChampionsByPower(): HWMember[] { + return this._championsByPower; + } + +} diff --git a/src/app/components/shared/herowars-components/index.ts b/src/app/components/shared/herowars-components/index.ts new file mode 100644 index 0000000..0a58942 --- /dev/null +++ b/src/app/components/shared/herowars-components/index.ts @@ -0,0 +1,8 @@ +export * from './fortification-card-content/fortification-card-content.component'; +export * from './guild-card/guild-card.component'; +export * from './guildraids-log/guildraids-log.component'; +export * from './guildwar-attack/guildwar-attack.component'; +export * from './guildwar-champions/guildwar-champions.component'; +export * from './guildwar-defence/guildwar-defence.component'; +export * from './guildwar-teams/guildwar-teams.component'; +export * from './members-statistics/members-statistics.component'; diff --git a/src/app/components/shared/herowars-components/members-statistics/members-statistics.component.html b/src/app/components/shared/herowars-components/members-statistics/members-statistics.component.html new file mode 100644 index 0000000..478935f --- /dev/null +++ b/src/app/components/shared/herowars-components/members-statistics/members-statistics.component.html @@ -0,0 +1,270 @@ + + +
+ + {{ title }} + +
+ +
+ {{ subtitle }} +
+
+ + + + + + + + + + + + + + + + + + + + + @for (member of getMembersByName(); track member; let index = $index) { + + + + + + + + + + + + + + + + } + + + + + + + + + + + + + + + + + + + + + + + +
+
+ # +
+
+
+ Name + +
+
+
+ ID +
+
+
+ Last Login +
+
+
+ Dismissal Delay +
+
+
+ Dungeon +
+
+
+ Activity +
+
+
+ Prestige +
+
+
+ War Fights +
+
+
+ Adventures +
+
+
+ Score +
+
+
+ Name +
+
+
+ Rewards +
+
+ {{ (index+1) }} + +
+ + {{ member.name }} +
+
+ {{ member.id }} + + {{ member.lastLoginTime + '000' | date: 'dd/MM HH:mm' }} + + {{ member.inactivity.dropDelay }} + +
+
+ {{ member.stat.todayDungeonActivity | number : '1.0' }} +
+
+
+ {{ member.stat.dungeonActivitySum | number : '1.0' }} +
+
+
+
+
+ {{ member.stat.todayActivity | number : '1.0' }} +
+
+
+ {{ member.stat.activitySum | number : '1.0' }} +
+
+
+
+
+ {{ member.stat.todayPrestige | number : '1.0' }} +
+
+
+ {{ member.stat.prestigeSum | number : '1.0' }} +
+
+
+ {{ member.clanWarSum }} + + {{ member.adventureSum }} + + {{ member.score | number : '1.0' }} + +
+ {{ member.name }} +
+
+ {{ member.rewards | number : '1.0' }} +
+ Totals + +
+
+ {{ guildTodayTotal.titanite | number : '1.0' }} +
+
+
+ {{ guildSumTotal.titanite | number : '1.0' }} +
+
+
+
+
+ {{ guildTodayTotal.activity | number : '1.0' }} +
+
+
+ {{ guildSumTotal.activity | number : '1.0' }} +
+
+
+
+
+ {{ guildTodayTotal.prestige | number : '1.0' }} +
+
+
+ {{ guildSumTotal.prestige | number : '1.0' }} +
+
+
+ {{ guildSumTotal.war | number : '1.0' }} + + {{ guildSumTotal.adventure | number : '1.0' }} + + {{ guildSumTotal.score | number : '1.0' }} + + {{ guildSumTotal.rewards }} +
+ Averages + +
+
+ {{ guildTodayAverages.titanite | number : '1.0-1' }} +
+
+
+ {{ guildSumAverages.titanite | number : '1.0-1' }} +
+
+
+
+
+ {{ guildTodayAverages.activity | number : '1.0-1' }} +
+
+
+ {{ guildSumAverages.activity | number : '1.0-1' }} +
+
+
+
+
+ {{ guildTodayAverages.prestige | number : '1.0-1' }} +
+
+
+ {{ guildSumAverages.prestige | number : '1.0-1' }} +
+
+
+ {{ guildSumAverages.war | number : '1.0-1' }} + + {{ guildSumAverages.adventure | number : '1.0-1' }} + + {{ guildSumAverages.score | number : '1.0-1' }} + + {{ guildSumAverages.rewards | number : '1.0-1' }} +
+
+
+
+ Champion signet + No Champion signet + Inactivity > {{ daysToWarn }} days + Below average + Above average +
\ No newline at end of file diff --git a/src/app/components/shared/herowars-components/members-statistics/members-statistics.component.scss b/src/app/components/shared/herowars-components/members-statistics/members-statistics.component.scss new file mode 100644 index 0000000..bbeacbb --- /dev/null +++ b/src/app/components/shared/herowars-components/members-statistics/members-statistics.component.scss @@ -0,0 +1,5 @@ +/* members-statistics */ + +.hstack .value { + min-width: 56px; +} \ No newline at end of file diff --git a/src/app/components/shared/herowars-components/members-statistics/members-statistics.component.spec.ts b/src/app/components/shared/herowars-components/members-statistics/members-statistics.component.spec.ts new file mode 100644 index 0000000..a0f0dfd --- /dev/null +++ b/src/app/components/shared/herowars-components/members-statistics/members-statistics.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { MembersStatisticsComponent } from './members-statistics.component'; + +describe('MembersStatisticsComponent', () => { + let component: MembersStatisticsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [MembersStatisticsComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(MembersStatisticsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/shared/herowars-components/members-statistics/members-statistics.component.ts b/src/app/components/shared/herowars-components/members-statistics/members-statistics.component.ts new file mode 100644 index 0000000..2157951 --- /dev/null +++ b/src/app/components/shared/herowars-components/members-statistics/members-statistics.component.ts @@ -0,0 +1,159 @@ +import { Component, Input, OnInit } from '@angular/core'; +import { DatePipe, DecimalPipe } from '@angular/common'; +import { MatCardModule } from '@angular/material/card'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatIconModule } from '@angular/material/icon'; + +import { HWActivityStat, HWGuildClan, HWGuildData, HWMember, HWMemberStat, HWWeekStat } from '@models/herowars'; +import { UtilitiesService } from '@services'; + +import guildData from 'src/files-data/hw-guild-data.json'; // page Membres +import guildStatistics from 'src/files-data/hw-guild-statistics.json'; // page Overview -> Statistics + +@Component({ + selector: 'app-members-statistics', + standalone: true, + imports: [ + DatePipe, DecimalPipe, + MatCardModule, MatDividerModule, MatIconModule + ], + templateUrl: './members-statistics.component.html', + styleUrl: './members-statistics.component.scss' +}) +export class MembersStatisticsComponent implements OnInit { + public guildMembers: HWMember[] = []; + public title = 'Members'; + public subtitle = 'statistics'; + public daysToWarn = 1; + public guildSumAverages: HWActivityStat = { activity: 0, prestige: 0, titanite: 0, war: 0, adventure: 0, gifts: 0, score: 0, scoreGifts: 0, warGifts: 0, rewards: 0 }; + public guildTodayAverages: HWActivityStat = { activity: 0, prestige: 0, titanite: 0, war: 0, adventure: 0, gifts: 0, score: 0, scoreGifts: 0, warGifts: 0, rewards: 0 }; + public guildSumTotal: HWActivityStat = { activity: 0, prestige: 0, titanite: 0, war: 0, adventure: 0, gifts: 0, score: 0, scoreGifts: 0, warGifts: 0, rewards: 0 }; + public guildTodayTotal: HWActivityStat = { activity: 0, prestige: 0, titanite: 0, war: 0, adventure: 0, gifts: 0, score: 0, scoreGifts: 0, warGifts: 0, rewards: 0 }; + public guildData: HWGuildData = {} as HWGuildData; + private _guildClan: HWGuildClan = {} as HWGuildClan; + private _membersByName: HWMember[] = []; + private _deviations: { activity: number[], prestige: number[], titanite: number[] } = { activity: [], prestige: [], titanite: [] }; + + @Input() set members(value: HWMember[]) { + this.guildMembers = value; + } + + constructor( + private _utilitiesService: UtilitiesService + ) { } + + ngOnInit() { + + const oneDayInSec = (24 * 60 * 60); + const today = new Date(); + const daysToKick = parseInt(guildData.clan.daysToKick); + this.daysToWarn = (parseInt(guildData.clan.daysToKick) / 2); + this.guildMembers.sort((a, b) => (a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1)).map((data) => { + const last = new Date((parseInt(data.lastLoginTime) * 1000)); + const exp = new Date(last.getTime() + ((daysToKick * oneDayInSec) * 1000)); + const diff = Math.floor(((exp.getTime() - today.getTime()) / 1000)); + const daysLeft = Math.floor((diff / oneDayInSec)); + let timeLeft = diff; + if (daysLeft >= 1) { + timeLeft = (diff - (daysLeft * oneDayInSec)); + } + data.inactivity = { + daysLeft: daysLeft, + timeLeft: timeLeft, + dropDelay: `${daysLeft}d, ${this._utilitiesService.secondsToDuration(timeLeft)}`, + dropDate: Math.floor((exp.getTime() / 1000)) + }; + this._membersByName.push(data); + return data; + }); + + Object.assign(this._guildClan, guildData.clan); + this.guildData.clan = this._guildClan; + this.guildData.membersStat = guildData.membersStat; + + for (const item of Object.entries(guildStatistics.stat)) { + const index = this._membersByName.findIndex(member => member.id === item[1].id); + if (index !== -1) { + this._membersByName[index].adventureSum = item[1].adventureStat.reduce((accumulator, currentValue) => accumulator + currentValue, 0); + this._membersByName[index].clanGiftsSum = item[1].clanGifts.reduce((accumulator, currentValue) => accumulator + currentValue, 0); + this._membersByName[index].clanWarSum = item[1].clanWarStat.reduce((accumulator, currentValue) => accumulator + currentValue, 0); + this.guildSumTotal.adventure += this._membersByName[index].adventureSum; + this.guildSumTotal.gifts += this._membersByName[index].clanGiftsSum; + this.guildSumTotal.war += this._membersByName[index].clanWarSum; + const stat: HWWeekStat = {} as HWWeekStat; + Object.assign(stat, item[1]); + this._membersByName[index].weekStat = stat; + } else { + console.log(item[1].id); + } + } + + for (const data of Object.entries(guildData.membersStat)) { + const stat: HWMemberStat = {} as HWMemberStat; + Object.assign(stat, data[1]); + const index = this._membersByName.findIndex(member => member.id === data[1].userId); + if (index !== -1) { + this._membersByName[index].stat = stat; + } + this._membersByName[index].score = (this._membersByName[index].stat.dungeonActivitySum + this._membersByName[index].stat.activitySum + this._membersByName[index].stat.prestigeSum); + this._membersByName[index].warGifts = (((guildData.clan.giftsCount / 2) * ((this._membersByName[index].clanWarSum * 10) / 100)) / 20); + + this.guildTodayTotal.activity += stat.todayActivity; + this.guildTodayTotal.prestige += stat.todayPrestige; + this.guildTodayTotal.titanite += stat.todayDungeonActivity; + this.guildTodayTotal.score += (this._membersByName[index].stat.todayDungeonActivity + this._membersByName[index].stat.todayActivity + this._membersByName[index].stat.todayPrestige); + this.guildSumTotal.activity += stat.activitySum; + this.guildSumTotal.prestige += stat.prestigeSum; + this.guildSumTotal.titanite += stat.dungeonActivitySum; + this.guildSumTotal.score += this._membersByName[index].score; + this.guildSumTotal.warGifts += this._membersByName[index].warGifts; + this._deviations.activity.push(stat.activitySum); + this._deviations.prestige.push(stat.prestigeSum); + this._deviations.titanite.push(stat.dungeonActivitySum); + //this.guildSumTotal.warGifts += ((this._membersByName[index].score / this.guildSumTotal.score) * (guildData.clan.giftsCount / 2)) + } + this.guildSumTotal.scoreGifts = (guildData.clan.giftsCount - Math.floor(this.guildSumTotal.warGifts)); + this.guildTodayAverages.activity = (this.guildTodayTotal.activity / this._membersByName.length); + this.guildTodayAverages.prestige = (this.guildTodayTotal.prestige / this._membersByName.length); + this.guildTodayAverages.titanite = (this.guildTodayTotal.titanite / this._membersByName.length); + this.guildTodayAverages.score = (this.guildTodayTotal.score / this._membersByName.length); + this.guildSumAverages.activity = (this.guildSumTotal.activity / this._membersByName.length); + this.guildSumAverages.prestige = (this.guildSumTotal.prestige / this._membersByName.length); + this.guildSumAverages.titanite = (this.guildSumTotal.titanite / this._membersByName.length); + this.guildSumAverages.war = (this.guildSumTotal.war / 20); + this.guildSumAverages.adventure = (this.guildSumTotal.adventure / this._membersByName.length); + this.guildSumAverages.gifts = (this.guildSumTotal.gifts / this._membersByName.length); + this.guildSumAverages.score = (this.guildSumTotal.score / this._membersByName.length); + + this._membersByName.map((data) => { + data.scoreGifts = ((data.score / this.guildSumTotal.score) * this.guildSumTotal.scoreGifts); + data.rewards = Math.floor((data.scoreGifts + data.warGifts)); + this.guildSumTotal.rewards += data.rewards; + return data; + }); + this.guildSumAverages.rewards = (this.guildSumTotal.rewards / this._membersByName.length); + } + + getMembersByName(): HWMember[] { + return this._membersByName; + } + + private _standardDeviation(array: number[]): number { + const n = array.length; + const mean = array.reduce((a, b) => a + b) / n; + return Math.sqrt(array.map(x => Math.pow(x - mean, 2)).reduce((a, b) => a + b) / n); + } + + getStandardDeviationActivity(): number { + return this._standardDeviation(this._deviations.activity); + } + + getStandardDeviationAPrestige(): number { + return this._standardDeviation(this._deviations.prestige); + } + + getStandardDeviationTitanite(): number { + return this._standardDeviation(this._deviations.titanite); + } + +} diff --git a/src/app/components/shared/index.ts b/src/app/components/shared/index.ts new file mode 100644 index 0000000..2cce6d4 --- /dev/null +++ b/src/app/components/shared/index.ts @@ -0,0 +1,17 @@ +export * from './accordion'; +export * from './card-container/card-container.component'; +export * from './dashboard-components'; +export * from './helpers-chart'; +export * from './helpers-jump'; +export * from './herowars-components'; +//export * from './layout'; +export * from './layout/footer.component'; +export * from './layout/full.component'; +export * from './layout/header.component'; +export * from './list-errors/list-errors.component'; +export * from './spinner/spinner.component'; +export * from './confirmed.validator'; +export * from './floor.pipe'; +export * from './french-paginator.component'; +export * from './menu-items'; +export * from './show-authed.directive'; diff --git a/src/app/components/shared/layout/footer.component.html b/src/app/components/shared/layout/footer.component.html new file mode 100644 index 0000000..ede5e0b --- /dev/null +++ b/src/app/components/shared/layout/footer.component.html @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/src/app/components/shared/layout/footer.component.spec.ts b/src/app/components/shared/layout/footer.component.spec.ts new file mode 100644 index 0000000..c16e9c1 --- /dev/null +++ b/src/app/components/shared/layout/footer.component.spec.ts @@ -0,0 +1,24 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { FooterComponent } from './footer.component'; + +describe('FooterComponent', () => { + let component: FooterComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [FooterComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(FooterComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); + diff --git a/src/app/components/shared/layout/footer.component.ts b/src/app/components/shared/layout/footer.component.ts new file mode 100644 index 0000000..d0f9b4e --- /dev/null +++ b/src/app/components/shared/layout/footer.component.ts @@ -0,0 +1,14 @@ +import { Component } from '@angular/core'; +import { DatePipe } from '@angular/common'; + +@Component({ + selector: 'app-layout-footer', + templateUrl: './footer.component.html', + standalone: true, + imports: [ DatePipe ] +}) +export class FooterComponent { + today: number = Date.now(); + siteLink = 'https://www.adastra-cbd.com'; + author = 'Ad Astra'; +} diff --git a/src/app/components/shared/layout/full.component.html b/src/app/components/shared/layout/full.component.html new file mode 100755 index 0000000..336a117 --- /dev/null +++ b/src/app/components/shared/layout/full.component.html @@ -0,0 +1,199 @@ + + + + + +
+ + @{{ currentUser.username }} + + + + + + + + + + +
+
+ + + + + + +
+ + + + + + @for (menuitem of getMenuItems(); track menuitem) { + + @if (!menuitem.parent && menuitem.type === 'link') { + + @if (menuitem.icontype === 'mat') { + + } + @else { + + } + {{ menuitem.name }} + + @for (badge of menuitem.badge; track badge) { + + } + + } + @if (menuitem.type === 'menu') { + + } + + @if (menuitem.type === 'menu') { + @for (submenuitem of getMenuItems(); track submenuitem) { + @if ( isVisibleMenu(menuitem.state) === true && submenuitem.parent === menuitem.state && submenuitem.type === 'link') { + + + @if (menuitem.icontype === 'mat') { + + } + @else { + + } + {{ submenuitem.name }} + + + + } + } + } + } + + + + + + @for (menuitem of menuItems.getMenuAuth(); track menuitem) { + + @if (menuitem.type === 'link') { + + @if (menuitem.icontype === 'mat') { + + } + @else { + + } + {{ menuitem.name }} + + @for (badge of menuitem.badge; track badge) { + + } + + } + + } + + + + + + + + + + \ No newline at end of file diff --git a/src/app/components/shared/layout/full.component.spec.ts b/src/app/components/shared/layout/full.component.spec.ts new file mode 100644 index 0000000..b32f274 --- /dev/null +++ b/src/app/components/shared/layout/full.component.spec.ts @@ -0,0 +1,24 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { FullComponent } from './full.component'; + +describe('FullComponent', () => { + let component: FullComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [FullComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(FullComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); + diff --git a/src/app/components/shared/layout/full.component.ts b/src/app/components/shared/layout/full.component.ts new file mode 100755 index 0000000..7606700 --- /dev/null +++ b/src/app/components/shared/layout/full.component.ts @@ -0,0 +1,116 @@ +import { Component, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core'; +import { Router, RouterOutlet, RouterModule } from '@angular/router'; +import { MediaMatcher } from '@angular/cdk/layout'; +import { MatBadgeModule } from '@angular/material/badge'; +import { MatButtonModule } from '@angular/material/button'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatIconModule } from '@angular/material/icon'; +import { MatListModule } from '@angular/material/list'; +import { MatSidenavModule } from '@angular/material/sidenav'; +import { MatToolbarModule } from '@angular/material/toolbar'; +import { MatMenuModule } from '@angular/material/menu'; +import { Observable, Subscription } from 'rxjs'; + +import { Menu, User } from '@models'; +import { UserService } from '@services'; +import { MenuItems, ShowAuthedDirective, AccordionAnchorDirective, AccordionLinkDirective, AccordionDirective } from '@components/shared'; +//import { SpinnerComponent } from '@components/shared'; +//import { HeaderComponent, FooterComponent } from '@components/shared/layout'; +import { FooterComponent } from '@components/shared/layout'; + + +/** @title Responsive sidenav */ +@Component({ + selector: 'app-full-layout', + standalone: true, + imports: [ + RouterModule, RouterOutlet, + MatBadgeModule, MatButtonModule, MatDividerModule, + MatIconModule, MatListModule, MatMenuModule, + MatSidenavModule, MatToolbarModule, + ShowAuthedDirective, AccordionAnchorDirective, + AccordionLinkDirective, AccordionDirective, + FooterComponent + //HeaderComponent, + //SpinnerComponent + ], + providers: [ MenuItems ], + templateUrl: 'full.component.html', + styleUrls: [] +}) +export class FullComponent implements OnInit, OnDestroy { + private _currentUser: Subscription = new Subscription(); + private _mobileQueryListener: () => void; + mobileQuery: MediaQueryList; + currentUser: User = {} as User; + today: number = Date.now(); + siteLink = 'https://www.adastra-cbd.com'; + author = 'Ad Astra'; + links: Menu[] = []; + visibleMenu: string[] = []; + //visibleMenu: string[] = ['products', 'page']; + //visibleMenu: string[] = ['products']; + + constructor( + private router: Router, + private userService: UserService, + changeDetectorRef: ChangeDetectorRef, + media: MediaMatcher, + public menuItems: MenuItems + ) { + this.mobileQuery = media.matchMedia('(min-width: 768px)'); + this._mobileQueryListener = () => changeDetectorRef.detectChanges(); + this.mobileQuery.addListener(this._mobileQueryListener); + } + + ngOnInit() { + const user$: Observable = this.userService.currentUser; + this._currentUser = user$.subscribe( + (userData) => { + this.currentUser = userData; + if (this.currentUser.role === 'Admin') { + this.links = this.menuItems.getMenuItemsAdmin(); + //this.links = this.menuItems.getMenuItems(); + } else { + this.links = this.menuItems.getMenuItems(); + } + } + ); + } + + getMenuItems(): Menu[] { + return this.links; + } + + isVisibleMenu(state: string): boolean { + const indexOf: number = this.visibleMenu.indexOf(state); + if (indexOf !== -1) { + return true; + } else { + return false; + } + } + + ngOnDestroy(): void { + this._currentUser.unsubscribe(); + this.mobileQuery.removeListener(this._mobileQueryListener); + } + + goToGitHub() { + window.open('https://github.com/rampeur', '_blank'); + } + + toggleShowMenu(state: string) { + const indexOf: number = this.visibleMenu.indexOf(state); + if (indexOf !== -1) { + this.visibleMenu.splice(indexOf, 1); + } else { + this.visibleMenu.push(state); + } + } + + logout() { + this.userService.purgeAuth(); + this.router.navigateByUrl('/login'); + } +} diff --git a/src/app/components/shared/layout/header.component.html b/src/app/components/shared/layout/header.component.html new file mode 100644 index 0000000..418459f --- /dev/null +++ b/src/app/components/shared/layout/header.component.html @@ -0,0 +1,49 @@ + + + + + @if (isLogged()) { + @{{ currentUser.username }} +
+ + + + + + + + + +
+ } + @if (!isLogged()) { + + + + + } +
diff --git a/src/app/components/shared/layout/header.component.spec.ts b/src/app/components/shared/layout/header.component.spec.ts new file mode 100644 index 0000000..739c783 --- /dev/null +++ b/src/app/components/shared/layout/header.component.spec.ts @@ -0,0 +1,24 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { HeaderComponent } from './header.component'; + +describe('HeaderComponent', () => { + let component: HeaderComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [HeaderComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(HeaderComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); + diff --git a/src/app/components/shared/layout/header.component.ts b/src/app/components/shared/layout/header.component.ts new file mode 100644 index 0000000..b7510d8 --- /dev/null +++ b/src/app/components/shared/layout/header.component.ts @@ -0,0 +1,65 @@ +import { Component, DestroyRef, inject, OnInit } from '@angular/core'; + +import { Router, RouterLink, RouterLinkActive } from '@angular/router'; +import { MatButtonModule } from '@angular/material/button'; +import { MatDividerModule } from '@angular/material/divider'; +import { MatIconModule } from '@angular/material/icon'; +import { MatMenuModule } from '@angular/material/menu'; +import { MatToolbarModule } from '@angular/material/toolbar'; +import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; +import { Observable, Subscription } from 'rxjs'; + +import { User } from '@models'; +import { UserService } from '@services'; + +@Component({ + selector: 'app-layout-header', + templateUrl: './header.component.html', + standalone: true, + imports: [ + RouterLink, RouterLinkActive, + MatToolbarModule, MatButtonModule, MatDividerModule, + MatIconModule, MatMenuModule + ] +}) +export class HeaderComponent implements OnInit { + + private _currentUser: Subscription = new Subscription(); + private _isAuthenticated: Subscription = new Subscription(); + private isAuthenticated = false; + currentUser: User = {} as User; + destroyRef = inject(DestroyRef); + + constructor( + private router: Router, + private userService: UserService + ) { } + + ngOnInit() { + const user$: Observable = this.userService.currentUser.pipe(takeUntilDestroyed(this.destroyRef)); + this._currentUser = user$.subscribe( + (userData) => { + this.currentUser = userData; + } + ); + const auth$: Observable = this.userService.isAuthenticated.pipe(takeUntilDestroyed(this.destroyRef)); + this._isAuthenticated = auth$.subscribe( + (value) => { + this.isAuthenticated = value; + } + ); + } + + goToGitHub() { + window.open('https://github.com/rampeur', '_blank'); + } + + isLogged(): boolean { + return this.isAuthenticated; + } + + logout() { + this.userService.purgeAuth(); + this.router.navigateByUrl('/'); + } +} diff --git a/src/app/components/shared/layout/index.ts b/src/app/components/shared/layout/index.ts new file mode 100644 index 0000000..87c41ed --- /dev/null +++ b/src/app/components/shared/layout/index.ts @@ -0,0 +1,3 @@ +export * from './footer.component'; +export * from './full.component'; +export * from './header.component'; diff --git a/src/app/components/shared/list-errors/list-errors.component.html b/src/app/components/shared/list-errors/list-errors.component.html new file mode 100644 index 0000000..0018fe3 --- /dev/null +++ b/src/app/components/shared/list-errors/list-errors.component.html @@ -0,0 +1,11 @@ + + + @if (errorList.length) { +
    + @for (error of errorList; track error) { +
  • {{ error }}
  • + } +
+ } +
+
\ No newline at end of file diff --git a/src/app/components/shared/list-errors/list-errors.component.ts b/src/app/components/shared/list-errors/list-errors.component.ts new file mode 100644 index 0000000..c88223f --- /dev/null +++ b/src/app/components/shared/list-errors/list-errors.component.ts @@ -0,0 +1,23 @@ +import { Component, Input } from '@angular/core'; +import { NgForOf, NgIf } from "@angular/common"; +import { MatCardModule } from '@angular/material/card'; + +import { Errors } from 'src/app/core'; + +@Component({ + selector: 'app-list-errors', + templateUrl: './list-errors.component.html', + standalone: true, + imports: [NgIf, NgForOf, MatCardModule] +}) +export class ListErrorsComponent { + errorList: string[] = []; + + @Input() set errors(errorList: Errors | null) { + this.errorList = errorList + ? Object.keys(errorList.errors || {}).map( + (key) => `${key} ${errorList.errors[key]}`, + ) + : []; + } +} \ No newline at end of file diff --git a/src/app/components/shared/menu-items.ts b/src/app/components/shared/menu-items.ts new file mode 100755 index 0000000..75eec47 --- /dev/null +++ b/src/app/components/shared/menu-items.ts @@ -0,0 +1,111 @@ +import { Injectable } from '@angular/core'; + +import { Menu } from '@models/menu.model'; + +const MENUAUTH: Menu[] = [ + { state: 'home', type: 'link', name: 'Accueil', icon: 'home', icontype: 'mat', desc: '' }, + { state: 'login', type: 'link', name: 'Se connecter', icon: 'fingerprint', icontype: 'mat', desc: '' }, + { state: 'register', type: 'link', name: 'Créer un compte', icon: 'person_add_alt', icontype: 'mat', desc: '' } +]; + +const MENUITEMSADMIN: Menu[] = [ + { state: 'home', type: 'link', name: 'Accueil', icon: 'home', icontype: 'mat', desc: '' }, + { state: 'products', type: 'menu', name: 'Produits', icon: 'barcode', desc: '' }, + { parent: 'products', state: 'fleurs-cbd', type: 'link', name: 'Fleurs CBD', icon: 'marijuana', desc: '' }, + { parent: 'products', state: 'fleurs-cbg', type: 'link', name: 'Fleurs CBG', icon: 'marijuana', desc: '' }, + { parent: 'products', state: 'fleurs-cbn', type: 'link', name: 'Fleurs CBN', icon: 'marijuana', desc: '' }, + { parent: 'products', state: 'fleurs-10oh', type: 'link', name: 'Fleurs 10OH+', icon: 'molecule', desc: '' }, + { parent: 'products', state: 'resines-cbd', type: 'link', name: 'Résines CBD', icon: 'butter', desc: '' }, + { parent: 'products', state: 'resines-cbg', type: 'link', name: 'Résines CBG', icon: 'butter', desc: '' }, + { parent: 'products', state: 'resines-cbn', type: 'link', name: 'Résines CBN', icon: 'butter', desc: '' }, + { parent: 'products', state: 'resines-10oh', type: 'link', name: 'Résines 10OH+', icon: 'molecule', desc: '' }, + { parent: 'products', state: 'molecules', type: 'link', name: 'Molécules', icon: 'molecule', desc: '' }, + { state: 'page', type: 'menu', name: 'Documentation', icon: 'books', desc: '' }, + { parent: 'page', state: 'les-fleurs', type: 'link', name: 'Fleurs', icon: 'marijuana', desc: '' }, + { parent: 'page', state: 'les-resines', type: 'link', name: 'Résines', icon: 'butter', desc: '' }, + { parent: 'page', state: 'les-molecules', type: 'link', name: 'Molécules', icon: 'molecule', desc: '' }, + { state: 'skydive', type: 'menu', name: 'Skydive', icon: 'dashboard', icontype: 'mat', desc: '' }, + { parent: 'skydive', state: 'dashboard', type: 'link', name: 'Dashboard', icon: 'dashboard', icontype: 'mat', desc: '' }, + { parent: 'skydive', state: 'logbook', type: 'link', name: 'Carnet de saut', icon: 'assignment_turned_in', icontype: 'mat', desc: '' }, + { parent: 'skydive', state: 'aeronefs', type: 'link', name: 'Aéronefs', icon: 'flight', icontype: 'mat', desc: '' }, + { parent: 'skydive', state: 'dropzones', type: 'link', name: 'Drop Zones', icon: 'flight_takeoff', icontype: 'mat', desc: '' }, + { parent: 'skydive', state: 'canopies', type: 'link', name: 'Voiles', icon: 'paragliding', icontype: 'mat', desc: '' }, + { parent: 'skydive', state: 'jumps', type: 'link', name: 'Sauts', icon: 'filter_drama', icontype: 'mat', desc: '' }, + { parent: 'skydive', state: 'calculator', type: 'link', name: 'Taille de voile', icon: 'calculate', icontype: 'mat', desc: '' }, + { parent: 'skydive', state: 'qcm', type: 'menu', name: 'QCM Brevets', icon: 'rule_folder', icontype: 'mat', desc: '' }, + { parent: 'qcm', state: 'bpa', type: 'link', name: 'BPA', icon: 'rule', icontype: 'mat' }, + { parent: 'qcm', state: 'c', type: 'link', name: 'Brevet C', icon: 'rule', icontype: 'mat' }, + { parent: 'qcm', state: 'd', type: 'link', name: 'Brevet D', icon: 'rule', icontype: 'mat' }, + { state: 'herowars', type: 'menu', name: 'Hero Wars', icon: 'military_tech', icontype: 'mat', desc: '' }, + { parent: 'herowars', state: 'guildwar', type: 'link', name: 'Guild War', icon: 'military_tech', icontype: 'mat', desc: '' }, + { parent: 'herowars', state: 'guildraid', type: 'link', name: 'Guild Raid', icon: 'military_tech', icontype: 'mat', desc: '' } +]; + +const MENUITEMS: Menu[] = [ + { state: 'home', type: 'link', name: 'Accueil', icon: 'home', icontype: 'mat', desc: '' }, + { state: 'products', type: 'menu', name: 'Produits', icon: 'barcode', desc: '' }, + { parent: 'products', state: 'fleurs-cbd', type: 'link', name: 'Fleurs CBD', icon: 'marijuana', desc: '' }, + { parent: 'products', state: 'fleurs-cbg', type: 'link', name: 'Fleurs CBG', icon: 'marijuana', desc: '' }, + { parent: 'products', state: 'fleurs-cbn', type: 'link', name: 'Fleurs CBN', icon: 'marijuana', desc: '' }, + { parent: 'products', state: 'fleurs-10oh', type: 'link', name: 'Fleurs 10OH+', icon: 'molecule', desc: '' }, + { parent: 'products', state: 'resines-cbd', type: 'link', name: 'Résines CBD', icon: 'butter', desc: '' }, + { parent: 'products', state: 'resines-cbg', type: 'link', name: 'Résines CBG', icon: 'butter', desc: '' }, + { parent: 'products', state: 'resines-cbn', type: 'link', name: 'Résines CBN', icon: 'butter', desc: '' }, + { parent: 'products', state: 'resines-10oh', type: 'link', name: 'Résines 10OH+', icon: 'molecule', desc: '' }, + { parent: 'products', state: 'molecules', type: 'link', name: 'Molécules', icon: 'molecule', desc: '' }, + { state: 'page', type: 'menu', name: 'Documentation', icon: 'books', desc: '' }, + { parent: 'page', state: 'les-fleurs', type: 'link', name: 'Fleurs', icon: 'marijuana', desc: '' }, + { parent: 'page', state: 'les-resines', type: 'link', name: 'Résines', icon: 'butter', desc: '' }, + { parent: 'page', state: 'les-molecules', type: 'link', name: 'Molécules', icon: 'molecule', desc: '' }, + { state: 'herowars', type: 'menu', name: 'Hero Wars', icon: 'military_tech', icontype: 'mat', desc: '' }, + { parent: 'herowars', state: 'guildwar', type: 'link', name: 'Guild War', icon: 'military_tech', icontype: 'mat', desc: '' }, + { parent: 'herowars', state: 'guildraid', type: 'link', name: 'Guild Raid', icon: 'military_tech', icontype: 'mat', desc: '' } +]; + +const MENUPJUMP: Menu[] = [ + { state: '#', type: 'link', name: 'Modifier', icon: 'edit', icontype: 'mat', desc: '', color: 'primary' }, + { state: '#', type: 'link', name: 'Supprimer', icon: 'delete', icontype: 'mat', desc: '', color: 'raspberry' } +]; + +const MENUPANEL: Menu[] = [ + { state: '#', type: 'link', name: 'Retirer du dashboard', icon: 'add_notes', icontype: 'mat', desc: '' }, + { state: '#', type: 'link', name: 'Paramètres d\'affichage', icon: 'display_settings', icontype: 'mat', desc: '' } +]; + +const MENUCALCULATOR: Menu[] = [ + { state: '#', type: 'link', name: 'Recherche avancée', icon: 'search', icontype: 'mat', desc: '' }, + { state: '#', type: 'link', name: 'Paramètres d\'affichage', icon: 'display_settings', icontype: 'mat', desc: '' }, + { state: '#', type: 'link', name: 'Partager', icon: 'share', icontype: 'mat', desc: '' } +]; + +const MENULOGBOOK: Menu[] = [ + { state: '#', type: 'link', name: 'Recherche avancée', icon: 'search', icontype: 'mat', desc: '' }, + { state: '#', type: 'link', name: 'Recherche par participant', icon: 'person_search', icontype: 'mat', desc: '' }, + { state: '#', type: 'link', name: 'Paramètres d\'affichage', icon: 'display_settings', icontype: 'mat', desc: '' }, + { state: '#', type: 'link', name: 'Import CSV', icon: 'upload_file', icontype: 'mat', desc: '' } +]; + +@Injectable() +export class MenuItems { + getMenuAuth(): Menu[] { + return MENUAUTH; + } + getMenuCalculator(): Menu[] { + return MENUCALCULATOR; + } + getMenuItems(): Menu[] { + return MENUITEMS; + } + getMenuItemsAdmin(): Menu[] { + return MENUITEMSADMIN; + } + getMenuLogbook(): Menu[] { + return MENULOGBOOK; + } + getMenuPanel(): Menu[] { + return MENUPANEL; + } + getMenuJump(): Menu[] { + return MENUPJUMP; + } +} diff --git a/src/app/components/shared/show-authed.directive.ts b/src/app/components/shared/show-authed.directive.ts new file mode 100644 index 0000000..346f151 --- /dev/null +++ b/src/app/components/shared/show-authed.directive.ts @@ -0,0 +1,45 @@ +import { Directive, Input, OnInit, OnDestroy, TemplateRef, ViewContainerRef } from '@angular/core'; +import { Observable, Subscription } from 'rxjs'; + +import { UserService } from '@services'; + +@Directive({ + selector: '[appShowAuthed]', + standalone: true +}) +export class ShowAuthedDirective implements OnInit, OnDestroy { + private _auth: Subscription = new Subscription(); + + constructor( + //private templateRef: TemplateRef, + private templateRef: TemplateRef, + private userService: UserService, + private viewContainer: ViewContainerRef + ) { } + + @Input() set appShowAuthed(condition: boolean) { + this.condition = condition; + } + + condition: boolean = false; + //condition: boolean; + + ngOnInit() { + + const isAuthenticated$: Observable = this.userService.isAuthenticated; // .pipe(take(1)); + this._auth = isAuthenticated$.subscribe( + (isAuthenticated) => { + if (isAuthenticated && this.condition || !isAuthenticated && !this.condition) { + this.viewContainer.createEmbeddedView(this.templateRef); + } else { + this.viewContainer.clear(); + } + } + ); + } + + ngOnDestroy() { + this._auth.unsubscribe(); + } + +} diff --git a/src/app/components/shared/spinner/spinner.component.html b/src/app/components/shared/spinner/spinner.component.html new file mode 100644 index 0000000..7ab1a2a --- /dev/null +++ b/src/app/components/shared/spinner/spinner.component.html @@ -0,0 +1,8 @@ +@if (isSpinnerVisible) { +
+
+
+
+
+
+} \ No newline at end of file diff --git a/src/app/components/shared/spinner/spinner.component.ts b/src/app/components/shared/spinner/spinner.component.ts new file mode 100755 index 0000000..7c79351 --- /dev/null +++ b/src/app/components/shared/spinner/spinner.component.ts @@ -0,0 +1,44 @@ +import { Component, Input, OnDestroy, Inject, ViewEncapsulation } from '@angular/core'; + +import { Router, NavigationStart, NavigationEnd, NavigationCancel, NavigationError } from '@angular/router'; +import { DOCUMENT } from '@angular/common'; + +@Component({ + selector: 'app-spinner', + standalone: true, + imports: [], + templateUrl: './spinner.component.html', + encapsulation: ViewEncapsulation.None +}) +export class SpinnerComponent implements OnDestroy { + public isSpinnerVisible = true; + + @Input() + public backgroundColor = 'rgba(0, 115, 170, 0.69)'; + + constructor( + private router: Router, + @Inject(DOCUMENT) private document: Document + ) { + this.router.events.subscribe( + event => { + if (event instanceof NavigationStart) { + this.isSpinnerVisible = true; + } else if ( + event instanceof NavigationEnd || + event instanceof NavigationCancel || + event instanceof NavigationError + ) { + this.isSpinnerVisible = false; + } + }, + () => { + this.isSpinnerVisible = false; + } + ); + } + + ngOnDestroy(): void { + this.isSpinnerVisible = false; + } +} diff --git a/src/app/core/constants/app.constants.ts b/src/app/core/constants/app.constants.ts new file mode 100644 index 0000000..d4b0f3d --- /dev/null +++ b/src/app/core/constants/app.constants.ts @@ -0,0 +1,10 @@ +/** + * Application-wide constants + */ + +// Guild/Clan constants +export const MAX_CLAN_MEMBERS = 30; + +// Default values +export const DEFAULT_PAGE_SIZE = 10; +export const DEFAULT_TIMEOUT = 30000; // ms diff --git a/src/app/core/constants/index.ts b/src/app/core/constants/index.ts new file mode 100644 index 0000000..cd95e50 --- /dev/null +++ b/src/app/core/constants/index.ts @@ -0,0 +1 @@ +export * from './app.constants'; diff --git a/src/app/core/guards/admin.guard.spec.ts b/src/app/core/guards/admin.guard.spec.ts new file mode 100644 index 0000000..4ae275e --- /dev/null +++ b/src/app/core/guards/admin.guard.spec.ts @@ -0,0 +1,17 @@ +import { TestBed } from '@angular/core/testing'; +import { CanActivateFn } from '@angular/router'; + +import { authGuard } from './auth.guard'; + +describe('authGuard', () => { + const executeGuard: CanActivateFn = (...guardParameters) => + TestBed.runInInjectionContext(() => authGuard(...guardParameters)); + + beforeEach(() => { + TestBed.configureTestingModule({}); + }); + + it('should be created', () => { + expect(executeGuard).toBeTruthy(); + }); +}); diff --git a/src/app/core/guards/admin.guard.ts b/src/app/core/guards/admin.guard.ts new file mode 100644 index 0000000..fba2066 --- /dev/null +++ b/src/app/core/guards/admin.guard.ts @@ -0,0 +1,18 @@ +import { inject } from '@angular/core'; +import { CanActivateFn, Router } from '@angular/router'; +import { map, take } from 'rxjs/operators'; + +import { UserService } from '@services'; + +export const adminGuard: CanActivateFn = () => { + const router = inject(Router); + const userService = inject(UserService); + return userService.currentUser.pipe(take(1)).pipe(map(data => { + if (data.role !== 'Admin') { + router.navigate(['/']); + return false; + } else { + return true; + } + })); +}; diff --git a/src/app/core/guards/auth.guard.spec.ts b/src/app/core/guards/auth.guard.spec.ts new file mode 100644 index 0000000..0cb3634 --- /dev/null +++ b/src/app/core/guards/auth.guard.spec.ts @@ -0,0 +1,17 @@ +import { TestBed } from '@angular/core/testing'; +import { CanActivateFn } from '@angular/router'; + +import { adminGuard } from './admin.guard'; + +describe('adminGuard', () => { + const executeGuard: CanActivateFn = (...guardParameters) => + TestBed.runInInjectionContext(() => adminGuard(...guardParameters)); + + beforeEach(() => { + TestBed.configureTestingModule({}); + }); + + it('should be created', () => { + expect(executeGuard).toBeTruthy(); + }); +}); diff --git a/src/app/core/guards/auth.guard.ts b/src/app/core/guards/auth.guard.ts new file mode 100644 index 0000000..25fb017 --- /dev/null +++ b/src/app/core/guards/auth.guard.ts @@ -0,0 +1,18 @@ +import { inject } from '@angular/core'; +import { CanActivateFn, Router } from '@angular/router'; +import { map, take } from 'rxjs/operators'; + +import { UserService } from '@services'; + +export const authGuard: CanActivateFn = () => { + const router = inject(Router); + const userService = inject(UserService); + return userService.isAuthenticated.pipe(take(1)).pipe(map(data => { + if (!data) { + router.navigate(['/']); + return false; + } else { + return true; + } + })); +}; diff --git a/src/app/core/guards/index.ts b/src/app/core/guards/index.ts new file mode 100644 index 0000000..429fee8 --- /dev/null +++ b/src/app/core/guards/index.ts @@ -0,0 +1,3 @@ +export * from './admin.guard'; +export * from './auth.guard'; +export * from './noauth.guard'; \ No newline at end of file diff --git a/src/app/core/guards/noauth.guard.spec.ts b/src/app/core/guards/noauth.guard.spec.ts new file mode 100644 index 0000000..e5a00d0 --- /dev/null +++ b/src/app/core/guards/noauth.guard.spec.ts @@ -0,0 +1,17 @@ +import { TestBed } from '@angular/core/testing'; +import { CanActivateFn } from '@angular/router'; + +import { noauthGuard } from './noauth.guard'; + +describe('noauthGuard', () => { + const executeGuard: CanActivateFn = (...guardParameters) => + TestBed.runInInjectionContext(() => noauthGuard(...guardParameters)); + + beforeEach(() => { + TestBed.configureTestingModule({}); + }); + + it('should be created', () => { + expect(executeGuard).toBeTruthy(); + }); +}); diff --git a/src/app/core/guards/noauth.guard.ts b/src/app/core/guards/noauth.guard.ts new file mode 100644 index 0000000..5b158e7 --- /dev/null +++ b/src/app/core/guards/noauth.guard.ts @@ -0,0 +1,23 @@ +import { inject } from '@angular/core'; +import { CanActivateFn } from '@angular/router'; +import { Observable } from 'rxjs'; +import { map, take } from 'rxjs/operators'; + +import { UserService } from '@services'; + +export const noauthGuard: CanActivateFn = (): Observable => { + /* + const router = inject(Router); + const userService = inject(UserService); + return userService.isAuthenticated.pipe(take(1)).pipe(map(data => { + if (data) { + router.navigate(['/']); + return false; + } else { + return true; + } + })); + */ + const userService = inject(UserService); + return userService.isAuthenticated.pipe(take(1), map(isAuth => !isAuth)); +}; diff --git a/src/app/core/index.ts b/src/app/core/index.ts new file mode 100644 index 0000000..84be153 --- /dev/null +++ b/src/app/core/index.ts @@ -0,0 +1,7 @@ +export * from './guards'; +export * from './interceptors'; +//export * from './interfaces'; +export * from './models'; +export * from './resolvers'; +export * from './services'; +export * from './viewmodels'; diff --git a/src/app/core/interceptors/api.interceptor.ts b/src/app/core/interceptors/api.interceptor.ts new file mode 100644 index 0000000..18aa53f --- /dev/null +++ b/src/app/core/interceptors/api.interceptor.ts @@ -0,0 +1,13 @@ +import { HttpInterceptorFn } from "@angular/common/http"; + +import { environment } from '@environments/environment'; + +export const apiInterceptor: HttpInterceptorFn = (req, next) => { + const apiReq = req.clone({ + setHeaders: { + ...({ 'Content-Type': 'application/json', 'Accept': 'application/json' }), + }, + url: `${environment.apiBaseUrl}${req.url}` + }); + return next(apiReq); +}; diff --git a/src/app/core/interceptors/error.interceptor.ts b/src/app/core/interceptors/error.interceptor.ts new file mode 100644 index 0000000..eff29fc --- /dev/null +++ b/src/app/core/interceptors/error.interceptor.ts @@ -0,0 +1,10 @@ +import { HttpInterceptorFn } from "@angular/common/http"; +import { throwError } from "rxjs"; +import { catchError } from "rxjs/operators"; + +export const errorInterceptor: HttpInterceptorFn = (req, next) => { + return next(req).pipe(catchError((err) => throwError(() => { + console.log(err.error); + return err.error; + }))); +}; diff --git a/src/app/core/interceptors/index.ts b/src/app/core/interceptors/index.ts new file mode 100644 index 0000000..23c68e9 --- /dev/null +++ b/src/app/core/interceptors/index.ts @@ -0,0 +1,4 @@ +export * from './api.interceptor'; +export * from './error.interceptor'; +//export * from './http.token.interceptor'; +export * from './token.interceptor'; \ No newline at end of file diff --git a/src/app/core/interceptors/token.interceptor.ts b/src/app/core/interceptors/token.interceptor.ts new file mode 100644 index 0000000..06e25fc --- /dev/null +++ b/src/app/core/interceptors/token.interceptor.ts @@ -0,0 +1,13 @@ +import { inject } from "@angular/core"; +import { HttpInterceptorFn } from "@angular/common/http"; +import { JwtService } from "@services/jwt.service"; + +export const tokenInterceptor: HttpInterceptorFn = (req, next) => { + const token = inject(JwtService).getToken(); + const request = req.clone({ + setHeaders: { + ...(token ? { Authorization: `Token ${token}` } : {}), + }, + }); + return next(request); +}; diff --git a/src/app/core/interfaces/index.ts b/src/app/core/interfaces/index.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/app/core/models/aeronef-list.model.ts b/src/app/core/models/aeronef-list.model.ts new file mode 100644 index 0000000..b0905b2 --- /dev/null +++ b/src/app/core/models/aeronef-list.model.ts @@ -0,0 +1,6 @@ +import { Aeronef } from './aeronef.model'; + +export interface AeronefList { + aeronefs: Array, + aeronefsCount: number +} \ No newline at end of file diff --git a/src/app/core/models/aeronef.model.ts b/src/app/core/models/aeronef.model.ts new file mode 100644 index 0000000..8ac35ed --- /dev/null +++ b/src/app/core/models/aeronef.model.ts @@ -0,0 +1,29 @@ +import { Jump } from './jump.model'; +import { Profile } from './profile.model'; + +export interface Aeronef { + aeronef: string; + imat: string; + author: Profile; + createdAt: string; + updatedAt: string; +} + +export interface AeronefByImat { + aeronef: string, + imat: string, + count: number +} + +export interface AeronefByYear { + aeronef: string, + imat: string, + year: number, + count: number +} + +export interface AeronefsPageData { + aeronefsByImat: Array; + aeronefsByImatByYear: Array; + lastjump: Jump; +} \ No newline at end of file diff --git a/src/app/core/models/application-list-config.model.ts b/src/app/core/models/application-list-config.model.ts new file mode 100644 index 0000000..95e8e0b --- /dev/null +++ b/src/app/core/models/application-list-config.model.ts @@ -0,0 +1,11 @@ +export interface ApplicationListConfig { + type: string; + filters: ApplicationListFilters; +} + +export interface ApplicationListFilters { + apikey?: string | undefined; + author?: string | undefined; + limit?: number | undefined; + offset?: number | undefined; +} diff --git a/src/app/core/models/application-list.model.ts b/src/app/core/models/application-list.model.ts new file mode 100644 index 0000000..da75041 --- /dev/null +++ b/src/app/core/models/application-list.model.ts @@ -0,0 +1,6 @@ +import { Application } from './application.model'; + +export interface ApplicationList { + applications: Array; + applicationsCount: number; +} diff --git a/src/app/core/models/application.model.ts b/src/app/core/models/application.model.ts new file mode 100644 index 0000000..dffd8b4 --- /dev/null +++ b/src/app/core/models/application.model.ts @@ -0,0 +1,12 @@ +import { Profile } from './profile.model'; + +export interface Application { + apikey: string; + maskedkey: string; + slug: string; + title: string; + description: string; + author: Profile; + createdAt: string; + updatedAt: string; +} diff --git a/src/app/core/models/article-list-config.model.ts b/src/app/core/models/article-list-config.model.ts new file mode 100755 index 0000000..a1e9872 --- /dev/null +++ b/src/app/core/models/article-list-config.model.ts @@ -0,0 +1,12 @@ +export interface ArticleListConfig { + type: string; + filters: ArticleListFilters; +} + +export interface ArticleListFilters { + tag?: string, + author?: string, + favorited?: string, + limit?: number, + offset?: number +} diff --git a/src/app/core/models/article-list.model.ts b/src/app/core/models/article-list.model.ts new file mode 100644 index 0000000..e741db8 --- /dev/null +++ b/src/app/core/models/article-list.model.ts @@ -0,0 +1,6 @@ +import { Article } from './article.model'; + +export interface ArticleList { + articles: Array
; + articlesCount: number; +} diff --git a/src/app/core/models/article.model.ts b/src/app/core/models/article.model.ts new file mode 100755 index 0000000..547a11b --- /dev/null +++ b/src/app/core/models/article.model.ts @@ -0,0 +1,27 @@ +import { PageLinks, PageMeta } from './shared.model'; +import { Profile, Tag } from '.'; + +export interface Article { + slug: string; + title: string; + description: string; + body: string; + author: Profile; + createdAt: string; + updatedAt: string; + tagList: Tag[]; + favorited: boolean; + favoritesCount: number; +} + +export interface ArticlePageData { + article: Article; + _links: PageLinks; + _meta: PageMeta; +} + +export interface ArticlesPageData { + articles: Array
; + _links: PageLinks; + _meta: PageMeta; +} diff --git a/src/app/core/models/badge.model.ts b/src/app/core/models/badge.model.ts new file mode 100644 index 0000000..d41e3ed --- /dev/null +++ b/src/app/core/models/badge.model.ts @@ -0,0 +1,5 @@ +export interface Badge { + type: string; + name: string; + value: number; +} diff --git a/src/app/core/models/brand.model.ts b/src/app/core/models/brand.model.ts new file mode 100644 index 0000000..674c96d --- /dev/null +++ b/src/app/core/models/brand.model.ts @@ -0,0 +1,7 @@ +export interface Brand { + id: number; + name: string; + description: string; + createdAt: string; + updatedAt: string; +} \ No newline at end of file diff --git a/src/app/core/models/calculator.model.ts b/src/app/core/models/calculator.model.ts new file mode 100644 index 0000000..317edf1 --- /dev/null +++ b/src/app/core/models/calculator.model.ts @@ -0,0 +1,163 @@ +export interface CalculatorInfo { + charges: CalculatorResult; + sizesFeet: CalculatorResult; + sizesMeter: CalculatorResult; + state: CalculatorState +} + +export interface CalculatorResult { + current?: number; + min: number; + min11: number; +} + +export interface CalculatorState { + color: string; + error?: string; +} + +export interface InputParams { + jumps: number; + weight: number; + gear: number; + current: number; + color: string; +} + +export interface WeightSizeRange extends Range { + num: number; + active: string; + name: string; + label: string; +} + +export interface Range { + start: number; + end: number; + value?: number; +} + +export interface TableHeader { + name: string; + active: string; +} + +export interface WeightSize { + weight: number; + active: string; + ranges: WeightSizeRange[]; +} + +export interface WeightSizes { + data: WeightSize[]; +} + +/* DT48 - 08 février 2024 */ +export const weightSizes: WeightSize[] = [ + {weight: 60, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 175}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 161}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 147}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 133}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 124}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 115}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 107}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 97}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 89}] }, + {weight: 61, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 178}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 163}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 149}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 135}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 126}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 116}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 108}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 98}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 90}] }, + {weight: 62, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 180}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 166}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 151}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 137}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 127}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 118}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 109}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 99}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 91}] }, + {weight: 63, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 183}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 168}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 153}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 138}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 129}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 119}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 111}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 100}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 91}] }, + {weight: 64, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 185}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 170}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 155}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 140}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 130}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 121}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 112}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 101}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 92}] }, + {weight: 65, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 188}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 173}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 157}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 142}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 132}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 122}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 113}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 102}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 93}] }, + {weight: 66, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 190}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 175}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 159}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 144}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 134}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 123}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 114}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 103}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 94}] }, + {weight: 67, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 193}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 177}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 161}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 146}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 135}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 125}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 116}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 104}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 94}] }, + {weight: 68, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 195}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 179}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 164}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 147}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 137}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 126}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 117}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 105}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 95}] }, + {weight: 69, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 198}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 182}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 166}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 149}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 138}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 128}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 118}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 106}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 96}] }, + {weight: 70, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 200}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 184}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 168}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 151}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 140}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 129}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 119}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 107}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 96}] }, + {weight: 71, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 203}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 186}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 170}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 153}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 142}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 130}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 120}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 107}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 97}] }, + {weight: 72, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 205}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 189}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 172}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 155}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 143}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 132}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 121}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 108}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 98}] }, + {weight: 73, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 208}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 191}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 174}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 156}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 145}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 133}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 123}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 109}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 99}] }, + {weight: 74, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 210}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 193}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 176}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 158}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 146}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 134}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 124}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 110}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 99}] }, + {weight: 75, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 213}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 196}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 178}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 160}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 148}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 136}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 125}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 111}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 100}] }, + {weight: 76, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 215}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 198}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 180}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 162}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 150}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 137}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 126}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 112}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 101}] }, + {weight: 77, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 218}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 200}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 182}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 163}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 151}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 139}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 127}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 113}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 101}] }, + {weight: 78, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 220}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 202}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 184}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 165}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 153}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 140}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 128}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 114}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 102}] }, + {weight: 79, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 223}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 205}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 186}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 167}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 154}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 141}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 129}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 115}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 103}] }, + {weight: 80, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 225}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 207}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 188}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 169}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 156}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 143}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 131}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 115}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 103}] }, + {weight: 81, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 228}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 209}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 190}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 170}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 157}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 144}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 132}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 116}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 104}] }, + {weight: 82, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 230}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 212}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 192}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 172}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 159}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 145}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 133}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 117}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 104}] }, + {weight: 83, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 233}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 214}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 194}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 174}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 160}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 146}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 134}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 118}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 105}] }, + {weight: 84, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 235}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 216}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 196}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 176}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 162}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 148}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 135}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 119}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 106}] }, + {weight: 85, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 238}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 219}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 198}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 177}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 163}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 149}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 136}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 120}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 106}] }, + {weight: 86, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 240}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 221}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 201}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 179}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 165}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 150}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 137}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 120}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 107}] }, + {weight: 87, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 243}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 223}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 203}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 181}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 166}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 152}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 138}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 121}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 108}] }, + {weight: 88, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 245}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 225}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 205}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 183}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 168}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 153}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 139}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 122}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 108}] }, + {weight: 89, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 248}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 228}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 207}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 184}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 170}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 154}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 140}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 123}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 109}] }, + {weight: 90, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 250}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 230}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 209}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 186}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 171}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 156}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 141}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 124}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 109}] }, + {weight: 91, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 253}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 232}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 211}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 188}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 173}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 157}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 143}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 124}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 110}] }, + {weight: 92, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 255}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 235}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 213}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 190}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 174}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 158}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 144}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 125}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 110}] }, + {weight: 93, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 258}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 237}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 215}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 191}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 176}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 159}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 145}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 126}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 111}] }, + {weight: 94, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 260}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 239}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 217}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 193}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 177}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 161}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 146}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 127}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 112}] }, + {weight: 95, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 263}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 242}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 219}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 195}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 179}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 162}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 147}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 128}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 112}] }, + {weight: 96, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 265}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 244}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 221}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 197}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 180}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 163}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 148}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 128}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 113}] }, + {weight: 97, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 268}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 246}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 223}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 198}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 182}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 164}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 149}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 129}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 113}] }, + {weight: 98, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 270}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 248}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 225}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 200}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 183}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 166}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 150}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 130}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 114}] }, + {weight: 99, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 273}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 251}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 227}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 202}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 185}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 167}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 151}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 131}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 114}] }, + {weight: 100, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 275}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 253}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 229}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 203}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 186}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 168}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 152}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 131}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 115}] }, + {weight: 101, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 278}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 255}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 231}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 205}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 188}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 169}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 153}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 132}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 115}] }, + {weight: 102, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 280}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 258}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 233}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 207}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 189}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 171}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 154}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 133}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 116}] }, + {weight: 103, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 283}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 260}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 235}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 209}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 190}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 172}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 155}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 134}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 116}] }, + {weight: 104, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 285}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 262}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 237}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 210}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 192}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 173}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 156}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 134}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 117}] }, + {weight: 105, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 288}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 265}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 239}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 212}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 193}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 174}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 157}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 135}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 118}] }, + {weight: 106, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 290}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 267}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 241}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 214}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 195}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 175}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 158}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 136}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 118}] }, + {weight: 107, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 293}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 269}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 243}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 215}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 196}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 177}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 159}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 136}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 119}] }, + {weight: 108, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 295}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 271}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 245}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 217}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 198}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 178}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 160}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 137}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 119}] }, + {weight: 109, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 298}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 274}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 247}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 219}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 199}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 179}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 161}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 138}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 120}] }, + {weight: 110, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 300}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 276}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 249}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 220}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 201}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 180}, {num: 7, active: '', name: 'range_7', label: '1000 à 1199', start: 1000, end: 1199, value: 162}, {num: 8, active: '', name: 'range_8', label: '1200 à 1399', start: 1200, end: 1399, value: 138}, {num: 9, active: '', name: 'range_9', label: '1400 à 1600', start: 1400, end: 1600, value: 120}] } +]; + +/* DT48 - 13 mars 2020 */ +export const weightSizesPrev: WeightSize[] = [ + {weight: 60, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 175}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 161}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 147}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 133}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 124}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 115}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 107}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 97}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 89}] }, + {weight: 61, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 178}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 163}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 149}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 135}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 126}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 116}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 108}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 98}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 90}] }, + {weight: 62, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 180}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 166}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 151}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 137}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 127}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 118}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 109}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 99}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 91}] }, + {weight: 63, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 183}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 168}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 153}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 138}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 129}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 119}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 111}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 100}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 91}] }, + {weight: 64, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 185}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 170}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 155}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 140}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 130}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 121}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 112}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 101}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 92}] }, + {weight: 65, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 188}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 173}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 157}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 142}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 132}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 122}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 113}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 102}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 93}] }, + {weight: 66, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 190}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 175}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 159}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 144}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 134}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 123}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 114}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 103}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 94}] }, + {weight: 67, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 193}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 177}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 161}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 146}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 135}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 125}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 116}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 104}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 94}] }, + {weight: 68, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 195}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 179}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 164}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 147}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 137}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 126}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 117}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 105}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 95}] }, + {weight: 69, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 198}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 182}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 166}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 149}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 138}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 128}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 118}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 106}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 96}] }, + {weight: 70, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 200}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 184}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 168}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 151}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 140}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 129}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 119}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 107}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 96}] }, + {weight: 71, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 203}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 186}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 170}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 153}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 142}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 130}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 120}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 107}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 97}] }, + {weight: 72, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 205}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 189}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 172}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 155}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 143}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 132}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 121}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 108}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 98}] }, + {weight: 73, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 208}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 191}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 174}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 156}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 145}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 133}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 123}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 109}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 99}] }, + {weight: 74, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 210}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 193}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 176}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 158}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 146}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 134}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 124}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 110}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 99}] }, + {weight: 75, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 213}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 196}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 178}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 160}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 148}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 136}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 125}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 111}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 100}] }, + {weight: 76, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 215}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 198}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 180}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 162}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 150}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 137}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 126}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 112}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 101}] }, + {weight: 77, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 218}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 200}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 182}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 163}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 151}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 139}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 127}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 113}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 101}] }, + {weight: 78, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 220}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 202}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 184}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 165}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 153}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 140}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 128}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 114}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 102}] }, + {weight: 79, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 223}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 205}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 186}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 167}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 154}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 141}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 129}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 115}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 103}] }, + {weight: 80, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 225}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 207}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 188}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 169}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 156}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 143}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 131}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 115}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 103}] }, + {weight: 81, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 228}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 209}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 190}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 170}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 157}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 144}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 132}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 116}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 104}] }, + {weight: 82, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 230}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 212}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 192}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 172}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 159}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 145}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 133}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 117}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 104}] }, + {weight: 83, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 233}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 214}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 194}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 174}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 160}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 146}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 134}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 118}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 105}] }, + {weight: 84, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 235}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 216}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 196}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 176}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 162}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 148}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 135}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 119}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 106}] }, + {weight: 85, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 238}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 219}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 198}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 177}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 163}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 149}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 136}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 120}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 106}] }, + {weight: 86, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 240}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 221}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 201}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 179}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 165}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 150}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 137}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 120}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 107}] }, + {weight: 87, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 243}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 223}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 203}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 181}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 166}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 152}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 138}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 121}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 108}] }, + {weight: 88, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 245}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 225}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 205}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 183}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 168}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 153}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 139}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 122}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 108}] }, + {weight: 89, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 248}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 228}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 207}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 184}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 170}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 154}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 140}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 123}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 109}] }, + {weight: 90, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 250}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 230}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 209}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 186}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 171}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 156}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 141}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 124}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 109}] }, + {weight: 91, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 253}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 232}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 211}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 188}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 173}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 157}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 143}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 124}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 110}] }, + {weight: 92, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 255}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 235}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 213}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 190}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 174}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 158}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 144}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 125}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 110}] }, + {weight: 93, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 258}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 237}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 215}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 191}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 176}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 159}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 145}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 126}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 111}] }, + {weight: 94, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 260}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 239}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 217}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 193}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 177}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 161}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 146}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 127}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 112}] }, + {weight: 95, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 263}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 242}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 219}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 195}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 179}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 162}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 147}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 128}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 112}] }, + {weight: 96, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 265}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 244}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 221}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 197}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 180}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 163}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 148}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 128}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 113}] }, + {weight: 97, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 268}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 246}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 223}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 198}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 182}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 164}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 149}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 129}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 113}] }, + {weight: 98, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 270}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 248}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 225}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 200}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 183}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 166}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 150}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 130}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 114}] }, + {weight: 99, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 273}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 251}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 227}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 202}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 185}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 167}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 151}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 131}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 114}] }, + {weight: 100, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 275}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 253}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 229}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 203}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 186}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 168}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 152}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 131}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 115}] }, + {weight: 101, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 278}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 255}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 231}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 205}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 188}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 169}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 153}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 132}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 115}] }, + {weight: 102, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 280}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 258}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 233}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 207}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 189}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 171}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 154}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 133}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 116}] }, + {weight: 103, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 283}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 260}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 235}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 209}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 190}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 172}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 155}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 134}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 116}] }, + {weight: 104, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 285}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 262}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 237}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 210}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 192}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 173}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 156}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 134}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 117}] }, + {weight: 105, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 288}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 265}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 239}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 212}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 193}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 174}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 157}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 135}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 118}] }, + {weight: 106, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 290}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 267}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 241}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 214}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 195}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 175}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 158}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 136}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 118}] }, + {weight: 107, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 293}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 269}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 243}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 215}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 196}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 177}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 159}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 136}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 119}] }, + {weight: 108, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 295}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 271}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 245}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 217}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 198}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 178}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 160}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 137}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 119}] }, + {weight: 109, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 298}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 274}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 247}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 219}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 199}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 179}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 161}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 138}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 120}] }, + {weight: 110, active: '', ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 300}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 276}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 249}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 220}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 201}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 180}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 162}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 138}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 120}] } +]; diff --git a/src/app/core/models/canopy.model.ts b/src/app/core/models/canopy.model.ts new file mode 100644 index 0000000..7a68136 --- /dev/null +++ b/src/app/core/models/canopy.model.ts @@ -0,0 +1,42 @@ +import { Jump } from './jump.model'; +import { Profile } from './profile.model'; + +export interface Canopy { + voile: string; + taille: number; + author: Profile; + createdAt: string; + updatedAt: string; +} + +export interface CanopyModelBySize { + voile: string, + taille: number, + count: number +} + +export interface CanopyModelByYear { + voile: string, + taille: number, + year: number, + count: number +} + +export interface CanopyBySize { + taille: number, + count: number +} + +export interface CanopyByYear { + taille: number, + year: number, + count: number +} + +export interface CanopiesPageData { + canopiesBySize: Array; + canopiesBySizeByYear: Array; + canopiesBySizeByModel: Array; + canopiesBySizeByModelByYear: Array; + lastjump: Jump; +} \ No newline at end of file diff --git a/src/app/core/models/card-colors.model.ts b/src/app/core/models/card-colors.model.ts new file mode 100644 index 0000000..41dfd42 --- /dev/null +++ b/src/app/core/models/card-colors.model.ts @@ -0,0 +1,4 @@ +export interface CardColors { + background: string; + text: string; +} \ No newline at end of file diff --git a/src/app/core/models/category.model.ts b/src/app/core/models/category.model.ts new file mode 100644 index 0000000..ee7bec4 --- /dev/null +++ b/src/app/core/models/category.model.ts @@ -0,0 +1,9 @@ +export interface Category { + id: number; + slug: string; + name: string; + description: string; + parent?: Category; + createdAt: string; + updatedAt: string; +} \ No newline at end of file diff --git a/src/app/core/models/chart.model.ts b/src/app/core/models/chart.model.ts new file mode 100644 index 0000000..ffee021 --- /dev/null +++ b/src/app/core/models/chart.model.ts @@ -0,0 +1,29 @@ +import { ChartConfiguration, ChartOptions } from 'chart.js'; + +export interface BarConfig { + barChartData: ChartConfiguration<'bar'>['data'], + barChartOptions: ChartConfiguration<'bar'>['options'], + barChartPlugins: ChartConfiguration<'bar'>['plugins'], + barChartLegend: boolean +} + +export interface CircleConfig { + circleChartLabels: string[], + circleChartDatasets: ChartConfiguration<'doughnut'>['data']['datasets'], + circleChartOptions: ChartConfiguration<'doughnut'>['options'], + circleChartPlugins: ChartConfiguration<'doughnut'>['plugins'], + circleChartLegend: boolean +} + +export interface DoughnutConfig { + doughnutChartLabels: string[], + doughnutChartDatasets: ChartConfiguration<'doughnut'>['data']['datasets'], + doughnutChartOptions: ChartConfiguration<'doughnut'>['options'], + doughnutChartLegend: boolean +} + +export interface LineConfig { + lineChartData: ChartConfiguration<'line'>['data'], + lineChartOptions: ChartOptions<'line'>, + lineChartLegend: boolean +} diff --git a/src/app/core/models/dropzone.model.ts b/src/app/core/models/dropzone.model.ts new file mode 100644 index 0000000..c4acba3 --- /dev/null +++ b/src/app/core/models/dropzone.model.ts @@ -0,0 +1,29 @@ +import { Jump } from './jump.model'; +import { Profile } from './profile.model'; + +export interface DropZone { + lieu: string; + oaci: string; + author: Profile; + createdAt: string; + updatedAt: string; +} + +export interface DropZoneByOaci { + lieu: string, + oaci: string, + count: number +} + +export interface DropZoneByYear { + lieu: string, + oaci: string, + year: number, + count: number +} + +export interface DropZonesPageData { + dropZonesByOaci: Array; + dropZonesByOaciByYear: Array; + lastjump: Jump; +} \ No newline at end of file diff --git a/src/app/core/models/email.model.ts b/src/app/core/models/email.model.ts new file mode 100755 index 0000000..5aae6e9 --- /dev/null +++ b/src/app/core/models/email.model.ts @@ -0,0 +1,10 @@ +import { Article } from './article.model'; + +export interface Email { + from: string; + to: string; + subject: string; + text: string; + html: string; + article?: Article; +} diff --git a/src/app/core/models/errors.model.ts b/src/app/core/models/errors.model.ts new file mode 100644 index 0000000..930e1b3 --- /dev/null +++ b/src/app/core/models/errors.model.ts @@ -0,0 +1,3 @@ +export interface Errors { + errors: {[key: string]: string}; +} diff --git a/src/app/core/models/herowars/clan-list-config.model.ts b/src/app/core/models/herowars/clan-list-config.model.ts new file mode 100644 index 0000000..1685915 --- /dev/null +++ b/src/app/core/models/herowars/clan-list-config.model.ts @@ -0,0 +1,16 @@ +export interface HWClanListConfig { + type: string; + filters: HWClanListFilters; +} + +export interface HWClanListFilters { + id?: string; + title?: string; + country?: string; + level?: string; + minLevel?: string; + ownerId?: string; + serverId?: string; + topActivity?: string; + topDungeon?: string; +} diff --git a/src/app/core/models/herowars/clan-list.model.ts b/src/app/core/models/herowars/clan-list.model.ts new file mode 100644 index 0000000..d11f036 --- /dev/null +++ b/src/app/core/models/herowars/clan-list.model.ts @@ -0,0 +1,6 @@ +import { HWClan } from './clan.model'; + +export interface HWClanList { + clans: Array; + clansCount: number; +} diff --git a/src/app/core/models/herowars/clan-page-data.model.ts b/src/app/core/models/herowars/clan-page-data.model.ts new file mode 100644 index 0000000..a792f6f --- /dev/null +++ b/src/app/core/models/herowars/clan-page-data.model.ts @@ -0,0 +1,8 @@ +import { HWClan } from './clan.model'; +import { PageLinks, PageMeta } from '../shared.model'; + +export interface HWClanPageData { + clan: HWClan; + _links: PageLinks; + _meta: PageMeta; +} diff --git a/src/app/core/models/herowars/clan.model.ts b/src/app/core/models/herowars/clan.model.ts new file mode 100644 index 0000000..be3efb0 --- /dev/null +++ b/src/app/core/models/herowars/clan.model.ts @@ -0,0 +1,65 @@ +import { HWMember } from './member.model'; +import { HWActivityStat, HWClanIcon, HWGuildStat, HWMemberStat } from './stat.model'; + +export interface HWGuildClan { + id: string; + ownerId: string; + level: string; + title: string; + description: string; + icon: HWClanIcon; + country: string; + minLevel: string; + serverId: string; + membersCount: string; + disbanding: boolean; + topActivity: string; + topDungeon: string; + roleNames: never[]; + frameId: number; + members: {[key: string]: HWMember}; + news: string; + activityPoints: number; + dungeonPoints: number; + blackList: {[key: string]: number}; + warriors: number[]; + giftsCount: number; + daysToKick: string; + league: string; + sumAverages: HWActivityStat; + sumTotal: HWActivityStat; + todayAverages: HWActivityStat; + todayTotal: HWActivityStat; +} +export interface HWGuildData { + clan: HWGuildClan; + slots: {[key: string]: number}; + membersStat: HWMemberStat[]; + stat: HWGuildStat; + serverResetTime: number; + clanWarEndSeasonTime: number; + freeClanChangeInterval: { + start: number; + end: number; + }; + giftUids: string[]; +} + +export interface HWClan { + id: string; + country: string; + description: string; + disbanding: boolean; + frameId: number; + icon: HWClanIcon; + level: string; + members: {[key: string]: HWMember}; + membersCount: string; + minLevel: string; + ownerId: string; + /*roleNames: never[];*/ + serverId: string; + title: string; + topActivity: string; + topDungeon: string; +} diff --git a/src/app/core/models/herowars/fortification.model.ts b/src/app/core/models/herowars/fortification.model.ts new file mode 100644 index 0000000..b95a228 --- /dev/null +++ b/src/app/core/models/herowars/fortification.model.ts @@ -0,0 +1,10 @@ +import { HWMember } from './member.model'; + +export interface HWGuildWarFortification { + name: string; + type: string; + count: number; + teams: HWMember[]; + positions: number[]; + slots: number[]; +} \ No newline at end of file diff --git a/src/app/core/models/herowars/guildwar.model.ts b/src/app/core/models/herowars/guildwar.model.ts new file mode 100644 index 0000000..a2f8785 --- /dev/null +++ b/src/app/core/models/herowars/guildwar.model.ts @@ -0,0 +1,80 @@ + +export interface HWGuildWarHeroTeam { + id: number; + level: number; + color: number; + star: number; + power: number; +} +export interface HWGuildWarTitanTeam { + id: number; + level: number; + star: number; + element: string; + elementSpiritLevel: number; + elementSpiritStar: number; + elementSpiritSkills: { + skillId: number; + level: number; + tierScale: number; + }[]; + elementAffinityPower: number; + power: number; +} +export interface HWGuildWarEnemyTeam { + element: string; + elementSpiritLevel: number; + elementSpiritStar: number; + elementSpiritSkills: { + skillId: number; + level: number; + tierScale: number; + }[]; + elementAffinityPower: number; + state: { + isDead: boolean; + hp: number; + energy: number; + maxHp: number; + }; + id: number; + star: number; + color: number; + level: number; + power: number; + type: string; +} +export interface HWGuildWarSlots { + [key: string]: number[]; +} +export interface HWGuildWarEnemySlot { + attackerId: number; + status: string; + user: { + id: string; + name: string; + lastLoginTime: string; + serverId: string; + level: string; + clanId: string; + clanRole: string; + commander: boolean; + avatarId: string; + isChatModerator: boolean; + frameId: number; + leagueId: number; + allowPm: string; + clanTitle: string; + clanIcon: { + flagColor1: number; + flagColor2: number; + flagShape: number; + iconColor: number; + iconShape: number; + }; + }; + pointsFarmed: number; + slotId: number; + totalPoints: number; + teams: HWGuildWarEnemyTeam[]; +} diff --git a/src/app/core/models/herowars/hw.model.ts b/src/app/core/models/herowars/hw.model.ts new file mode 100644 index 0000000..6cfbb4d --- /dev/null +++ b/src/app/core/models/herowars/hw.model.ts @@ -0,0 +1,264 @@ +export interface HWMember { + id: string; + name: string; + lastLoginTime: string; + serverId: string; + level: string; + clanId: string; + clanRole: string; + commander: boolean; + avatarId: string; + isChatModerator: boolean; + frameId: number; + leagueId: number; + allowPm: string; + showProfile: boolean; + clanTitle: string; + clanIcon: { + flagColor1: number; + flagColor2: number; + flagShape: number; + iconColor: number; + iconShape: number; + }; + champion: boolean; + heroes: { + power: number; + teams: HWGuildWarHeroTeam[]; + }; + titans: { + power: number; + teams: HWGuildWarTitanTeam[]; + }; + stat: HWMemberStat; + inactivity: { + daysLeft: number, + timeLeft: number, + dropDate: number; + dropDelay: string; + } + adventureSum: number; + clanGiftsSum: number; + clanWarSum: number; + weekStat: HWWeekStat; + score: number; + scoreGifts: number; + warGifts: number; + rewards: number; + raids: HWGuildRaid[]; + raidsInfo: { + variationAvg: number; + variationSum: number; + } +} +export interface HWGuildWarHeroTeam { + id: number; + level: number; + color: number; + star: number; + power: number; +} +export interface HWGuildWarTitanTeam { + id: number; + level: number; + star: number; + element: string; + elementSpiritLevel: number; + elementSpiritStar: number; + elementSpiritSkills: { + skillId: number; + level: number; + tierScale: number; + }[]; + elementAffinityPower: number; + power: number; +} +export interface HWGuildWarFortification { + name: string; + type: string; + count: number; + teams: HWMember[]; + positions: number[]; + slots: number[]; +} +export interface HWGuildStat { + todayActivity: number; + activitySum: number; + dungeonActivitySum: number; + todayRaid: never[]; + todayItemsActivity: number; + todayDungeonActivity: number; + activityForRuneAvailable: boolean; + adventureStat: number; + clanWarStat: number; +} +export interface HWGuildClan { + id: string; + ownerId: string; + level: string; + title: string; + description: string; + icon: { + flagColor1: number; + flagColor2: number; + flagShape: number; + iconColor: number; + iconShape: number; + }; + country: string; + minLevel: string; + serverId: string; + membersCount: string; + disbanding: boolean; + topActivity: string; + topDungeon: string; + roleNames: never[]; + frameId: number; + members: {[key: string]: HWMember}; + news: string; + activityPoints: number; + dungeonPoints: number; + blackList: {[key: string]: number}; + warriors: number[]; + giftsCount: number; + daysToKick: string; + league: string; +} +export interface HWGuildData { + clan: HWGuildClan; + slots: {[key: string]: number}; + membersStat: HWMemberStat[]; + stat: HWGuildStat; + serverResetTime: number; + clanWarEndSeasonTime: number; + freeClanChangeInterval: { + start: number; + end: number; + }; + giftUids: string[]; +} +export interface HWActivityStat { + activity: number; + prestige: number; + titanite: number; + war: number; + adventure: number; + gifts: number; + score: number; + scoreGifts: number; + warGifts: number; + rewards: number; +} +export interface HWWeekStat { + activity: number[]; + dungeonActivity: number[]; + adventureStat: number[]; + clanWarStat: number[]; + prestigeStat: number[]; + clanGifts: number[]; +} +export interface HWMemberStat { + activitySum: number; + todayActivity: number; + dungeonActivitySum: number; + todayDungeonActivity: number; + raidSum: number; + wasChampion: boolean; + todayPrestige: number; + prestigeSum: number; +} +export interface HWGuildRaidAttacker { + id: number; + power: number; + type: string; +} +export interface HWGuildRaidStage { + num: number; + name: string; + maxPower: number; + duration: number; + startTime: number; + endTime: number; +} +export interface HWGuildRaid { + userId: string; + userName: string; + power: number; + variation: { + value: number; + percent: number; + color: string; + }; + tooltip: string; + startTime: string; + endTime: string; + damage: { + "1": number; + "2": number; + }; + level: string; + attackers: HWGuildRaidAttacker[]; + stage: HWGuildRaidStage; + +} +export interface HWGuildRaidAttackers { + [key: string]: HWGuildRaidAttacker; +} +export interface HWGuildWarEnemySlot { + attackerId: number; + status: string; + user: { + id: string; + name: string; + lastLoginTime: string; + serverId: string; + level: string; + clanId: string; + clanRole: string; + commander: boolean; + avatarId: string; + isChatModerator: boolean; + frameId: number; + leagueId: number; + allowPm: string; + clanTitle: string; + clanIcon: { + flagColor1: number; + flagColor2: number; + flagShape: number; + iconColor: number; + iconShape: number; + }; + }; + pointsFarmed: number; + slotId: number; + totalPoints: number; + teams: HWGuildWarEnemyTeam[]; +} + +export interface HWGuildWarEnemyTeam { + element: string; + elementSpiritLevel: number; + elementSpiritStar: number; + elementSpiritSkills: { + skillId: number; + level: number; + tierScale: number; + }[]; + elementAffinityPower: number; + state: { + isDead: boolean; + hp: number; + energy: number; + maxHp: number; + }; + id: number; + star: number; + color: number; + level: number; + power: number; + type: string; +} +export interface HWGuildWarSlots { + [key: string]: number[]; +} \ No newline at end of file diff --git a/src/app/core/models/herowars/index.ts b/src/app/core/models/herowars/index.ts new file mode 100644 index 0000000..14aee78 --- /dev/null +++ b/src/app/core/models/herowars/index.ts @@ -0,0 +1,13 @@ +export * from './clan.model'; +export * from './clan-list-config.model'; +export * from './clan-list.model'; +export * from './clan-page-data.model'; +export * from './fortification.model'; +export * from './guildwar.model'; +//export * from './hw.model'; +export * from './member.model'; +export * from './member-list-config.model'; +export * from './member-list.model'; +export * from './member-page-data.model'; +export * from './raid.model'; +export * from './stat.model'; diff --git a/src/app/core/models/herowars/member-list-config.model.ts b/src/app/core/models/herowars/member-list-config.model.ts new file mode 100644 index 0000000..e1992f2 --- /dev/null +++ b/src/app/core/models/herowars/member-list-config.model.ts @@ -0,0 +1,16 @@ +export interface HWMemberListConfig { + type: string; + filters: HWMemberListFilters; +} + +export interface HWMemberListFilters { + id?: string; + name?: string; + clanId?: string; + clanTitle?: string; + serverId?: string; + level?: string; + commander?: boolean; + champion?: boolean; + leagueId?: number; +} diff --git a/src/app/core/models/herowars/member-list.model.ts b/src/app/core/models/herowars/member-list.model.ts new file mode 100644 index 0000000..e67c110 --- /dev/null +++ b/src/app/core/models/herowars/member-list.model.ts @@ -0,0 +1,6 @@ +import { HWMember } from './member.model'; + +export interface HWMemberList { + members: Array; + membersCount: number; +} diff --git a/src/app/core/models/herowars/member-page-data.model.ts b/src/app/core/models/herowars/member-page-data.model.ts new file mode 100644 index 0000000..224f13f --- /dev/null +++ b/src/app/core/models/herowars/member-page-data.model.ts @@ -0,0 +1,8 @@ +import { HWMember } from './member.model'; +import { PageLinks, PageMeta } from '../shared.model'; + +export interface HWMemberPageData { + member: HWMember; + _links: PageLinks; + _meta: PageMeta; +} diff --git a/src/app/core/models/herowars/member.model.ts b/src/app/core/models/herowars/member.model.ts new file mode 100644 index 0000000..93aede3 --- /dev/null +++ b/src/app/core/models/herowars/member.model.ts @@ -0,0 +1,39 @@ +import { HWGuildRaid } from './raid.model'; +import { + HWMemberStat, HWWeekStat, HWClanIcon, HWInactivity, + HWRaidsInfo, HWMemberHeroes, HWMemberTitans +} from './stat.model'; + +export interface HWMember { + id: string; + allowPm: string; + avatarId: string; + clanIcon: HWClanIcon; + clanId: string; + clanRole: string; + clanTitle: string; + commander: boolean; + frameId: number; + isChatModerator: boolean; + lastLoginTime: string; + leagueId: number; + level: string; + name: string; + serverId: string; + showProfile: boolean; + champion: boolean; + heroes: HWMemberHeroes; + titans: HWMemberTitans; + stat: HWMemberStat; + inactivity: HWInactivity; + adventureSum: number; + clanGiftsSum: number; + clanWarSum: number; + weekStat: HWWeekStat; + score: number; + scoreGifts: number; + warGifts: number; + rewards: number; + raids: HWGuildRaid[]; + raidsInfo: HWRaidsInfo; +} \ No newline at end of file diff --git a/src/app/core/models/herowars/raid.model.ts b/src/app/core/models/herowars/raid.model.ts new file mode 100644 index 0000000..47db532 --- /dev/null +++ b/src/app/core/models/herowars/raid.model.ts @@ -0,0 +1,38 @@ + +export interface HWGuildRaidAttacker { + id: number; + power: number; + type: string; +} +export interface HWGuildRaidStage { + num: number; + name: string; + maxPower: number; + duration: number; + startTime: number; + endTime: number; +} +export interface HWGuildRaid { + userId: string; + userName: string; + power: number; + variation: { + value: number; + percent: number; + color: string; + }; + tooltip: string; + startTime: string; + endTime: string; + damage: { + "1": number; + "2": number; + }; + level: string; + attackers: HWGuildRaidAttacker[]; + stage: HWGuildRaidStage; + +} +export interface HWGuildRaidAttackers { + [key: string]: HWGuildRaidAttacker; +} diff --git a/src/app/core/models/herowars/stat.model.ts b/src/app/core/models/herowars/stat.model.ts new file mode 100644 index 0000000..644e74a --- /dev/null +++ b/src/app/core/models/herowars/stat.model.ts @@ -0,0 +1,74 @@ + +import { HWGuildWarHeroTeam, HWGuildWarTitanTeam } from './guildwar.model'; + +export interface HWGuildStat { + todayActivity: number; + activitySum: number; + dungeonActivitySum: number; + todayRaid: never[]; + todayItemsActivity: number; + todayDungeonActivity: number; + activityForRuneAvailable: boolean; + adventureStat: number; + clanWarStat: number; +} +export interface HWActivityStat { + activity: number; + prestige: number; + titanite: number; + war: number; + adventure: number; + gifts: number; + score: number; + scoreGifts: number; + warGifts: number; + rewards: number; +} +export interface HWWeekStat { + activity: number[]; + dungeonActivity: number[]; + adventureStat: number[]; + clanWarStat: number[]; + prestigeStat: number[]; + clanGifts: number[]; +} +export interface HWMemberStat { + activitySum: number; + todayActivity: number; + dungeonActivitySum: number; + todayDungeonActivity: number; + raidSum: number; + wasChampion: boolean; + todayPrestige: number; + prestigeSum: number; +} + +export interface HWClanIcon { + flagColor1: number; + flagColor2: number; + flagShape: number; + iconColor: number; + iconShape: number; +} + +export interface HWInactivity { + daysLeft: number; + timeLeft: number; + dropDate: number; + dropDelay: string; +} + +export interface HWRaidsInfo { + variationAvg: number; + variationSum: number; +} + +export interface HWMemberHeroes { + power: number; + teams: HWGuildWarHeroTeam[]; +} + +export interface HWMemberTitans { + power: number; + teams: HWGuildWarTitanTeam[]; +} \ No newline at end of file diff --git a/src/app/core/models/index.ts b/src/app/core/models/index.ts new file mode 100644 index 0000000..dafc194 --- /dev/null +++ b/src/app/core/models/index.ts @@ -0,0 +1,30 @@ +export * from './aeronef.model'; +export * from './aeronef-list.model'; +export * from './article.model'; +export * from './article-list.model'; +export * from './article-list-config.model'; +export * from './application.model'; +export * from './application-list.model'; +export * from './application-list-config.model'; +export * from './brand.model'; +export * from './calculator.model'; +export * from './canopy.model'; +export * from './card-colors.model'; +export * from './category.model'; +export * from './chart.model'; +export * from './dropzone.model'; +export * from './errors.model'; +export * from './herowars/'; +export * from './jump.model'; +export * from './jump-list.model'; +export * from './jump-list-config.model'; +export * from './menu.model'; +export * from './packaging.model'; +export * from './product.model'; +export * from './product-list.model'; +export * from './product-list-config.model'; +export * from './profile.model'; +export * from './qcm.model'; +export * from './shared.model'; +export * from './tag.model'; +export * from './user.model'; diff --git a/src/app/core/models/jump-list-config.model.ts b/src/app/core/models/jump-list-config.model.ts new file mode 100644 index 0000000..528ff70 --- /dev/null +++ b/src/app/core/models/jump-list-config.model.ts @@ -0,0 +1,38 @@ +export interface JumpListConfig { + type: string; + filters: JumpListFilters; +} + +export interface JumpListFilters { + date?: string; + numero?: number; + lieu?: string; + oaci?: string; + aeronef?: string; + imat?: string; + hauteur?: number; + deploiement?: number; + voile?: string; + taille?: number; + categorie?: string; + module?: string; + participants?: number; + sautant?: number; + accessoires?: string; + zone?: string; + author?: string; + limit?: number; + offset?: number; + numeroRangeStart?: number; + numeroRangeEnd?: number; + tailleRangeStart?: number; + tailleRangeEnd?: number; + participantsRangeStart?: number; + participantsRangeEnd?: number; + hauteurRangeStart?: number; + hauteurRangeEnd?: number; + yearRangeStart?: number; + yearRangeEnd?: number; + dateRangeStart?: string; + dateRangeEnd?: string; +} diff --git a/src/app/core/models/jump-list.model.ts b/src/app/core/models/jump-list.model.ts new file mode 100644 index 0000000..a296cc2 --- /dev/null +++ b/src/app/core/models/jump-list.model.ts @@ -0,0 +1,6 @@ +import { Jump } from './jump.model'; + +export interface JumpList { + jumps: Array; + jumpsCount: number; +} diff --git a/src/app/core/models/jump.model.ts b/src/app/core/models/jump.model.ts new file mode 100644 index 0000000..45c9aac --- /dev/null +++ b/src/app/core/models/jump.model.ts @@ -0,0 +1,313 @@ +import { FormControl } from '@angular/forms'; + +import { Profile } from './profile.model'; +import { ColumnDefinition, PageLinks, PageMeta } from './shared.model'; + +export interface Jump { + slug: string; + date: string; + numero: number; + lieu?: string; + oaci?: string; + aeronef?: string; + imat?: string; + hauteur?: number; + deploiement?: number; + voile?: string; + taille?: number; + categorie?: string; + module?: string; + participants?: number; + sautants: Array; + programme?: string; + accessoires?: string; + zone?: string; + dossier?: string; + video?: string; + files: Array; + x2data: X2Data; + author: Profile; + createdAt: string; + updatedAt: string; + //isEdit?: boolean; + isSelected?: boolean; +} + +export enum JumpFileType { + CSV = "csv", + IMAGE = "image", + KML = "kml", + VIDEO = "video" +} + +export interface JumpFile { + slug: string; + name: string; + path: string; + type: JumpFileType; +} + +export interface JumpForm { + date: FormControl; + numero: FormControl; + lieu: FormControl; + oaci: FormControl; + aeronef: FormControl; + imat: FormControl; + hauteur: FormControl; + deploiement: FormControl; + voile: FormControl; + taille: FormControl; + categorie: FormControl; + module: FormControl; + participants: FormControl; + //sautants: FormControl>; + programme: FormControl; + accessoires: FormControl; + zone: FormControl; + dossier: FormControl; + video: FormControl; +} + +export interface JumpAddParams { + numeros: string; + date: string; + video: boolean; +} + +export interface JumpByDate { + month: number; + year: number; + count: number; +} + +export interface JumpByCategorie { + categorie: string; + count: number; +} + +export interface JumpByDay { + jumps: Array>; + count: number; +} + +export interface JumpByModule { + categorie: string; + module: string; + count: number; +} + +export interface JumpByDateByModule { + categorie: string; + module: string; + year: number; + month: number; + count: number; +} + +export interface JumpYears { + year: number; + count: number; +} + +export interface SkydiverIdJumps { + items: Array; + _links: PageLinks; + _meta: PageMeta; +} + +export interface X2Data { + id: string; + name: string; + type: string; + description: string; + landingZone: string; + speed: { + freeFall: { + vertical: { + max: number; + avg: number; + }; + horizontal: { + max: number; + avg: number; + }; + }; + underCanopy: { + vertical: { + max: number; + avg: number; + }; + horizontal: { + max: number; + avg: number; + }; + }; + }; + glideRatio: { + freeFall: { + max: number; + avg: number; + }; + underCanopy: { + max: number; + avg: number; + }; + }; + duration: { + freeFall: number; + underCanopy: number; + }; + distance: { + exitFromLandingZone: number; + totalFlying: number; + totalHorizontal: number; + }; + altitude: { + exit: number; + deployment: number; + }; + cutaway: string; + malfunctions:Array< + { + name: string; + type: string; + } + >; + date: string; + createdOn: string; +} + +export interface JumpPageData { + jump: Jump; + prevJump: Jump; + nextJump: Jump; + _links: PageLinks; + _meta: PageMeta; +} + +export interface JumpsPageData { + jumpsByCategory: Array; + jumpsByDate: Array; + jumpsByDateByModule: Array; + jumpsByModule: Array; + jumpsByYears: Array; + //jumpsFromSkydiverIdApi: SkydiverIdJumps; + lastjump: Jump; + /*yearsCount: number; + jumpsByCategoryCount: number; + jumpsByDateCount: number; + jumpsByModuleCount: number;*/ +} + +export const jumpColumns: Array = [ + { + key: 'isSelected', + type: 'isSelected', + label: '' + }, + { + key: 'date', + type: 'date', + label: 'Date', + required: true + }, + { + key: 'numero', + type: 'numeric', + label: 'Numéro', + required: true, + min: 0, + step: 1 + }, + { + key: 'lieu', + type: 'text', + label: 'Lieu' + }, + { + key: 'oaci', + type: 'text', + label: 'OACI' + }, + { + key: 'aeronef', + type: 'text', + label: 'Aéronef' + }, + { + key: 'imat', + type: 'text', + label: 'Imat.' + }, + { + key: 'hauteur', + type: 'numeric', + label: 'Hauteur' + }, + { + key: 'deploiement', + type: 'numeric', + label: 'Deploiement' + }, + { + key: 'voile', + type: 'text', + label: 'Voile' + }, + { + key: 'taille', + type: 'numeric', + label: 'Taille' + }, + { + key: 'categorie', + type: 'text', + label: 'Categorie' + }, + { + key: 'module', + type: 'text', + label: 'Module' + }, + { + key: 'participants', + type: 'numeric', + label: 'Participants' + }, + { + key: 'sautants', + type: 'text', + label: 'Sautants' + }, + { + key: 'programme', + type: 'text', + label: 'Programme' + }, + { + key: 'accessoires', + type: 'text', + label: 'Accessoires' + }, + { + key: 'zone', + type: 'text', + label: 'Zone' + }, + /*{ + key: 'dossier', + type: 'text', + label: '' + },*/ + { + key: 'video', + type: 'text', + label: 'Vidéo' + }, + { + key: 'isEdit', + type: 'isEdit', + label: '' + } +]; \ No newline at end of file diff --git a/src/app/core/models/loading-state.model.ts b/src/app/core/models/loading-state.model.ts new file mode 100644 index 0000000..0110671 --- /dev/null +++ b/src/app/core/models/loading-state.model.ts @@ -0,0 +1,5 @@ +export enum LoadingState { + NOT_LOADED = "NOT_LOADED", + LOADING = "LOADING", + LOADED = "LOADED", +} \ No newline at end of file diff --git a/src/app/core/models/menu.model.ts b/src/app/core/models/menu.model.ts new file mode 100644 index 0000000..ec4e5a6 --- /dev/null +++ b/src/app/core/models/menu.model.ts @@ -0,0 +1,13 @@ +import { Badge } from './badge.model'; + +export interface Menu { + parent?: string; + state: string; + name: string; + type: string; + icon: string; + icontype?: string; + desc?: string; + badge?: Badge[]; + color?: string; +} diff --git a/src/app/core/models/packaging.model.ts b/src/app/core/models/packaging.model.ts new file mode 100644 index 0000000..85fa069 --- /dev/null +++ b/src/app/core/models/packaging.model.ts @@ -0,0 +1,7 @@ +export interface Packaging { + id: number; + name: string; + description: string; + createdAt: string; + updatedAt: string; +} \ No newline at end of file diff --git a/src/app/core/models/product-list-config.model.ts b/src/app/core/models/product-list-config.model.ts new file mode 100644 index 0000000..8e9780b --- /dev/null +++ b/src/app/core/models/product-list-config.model.ts @@ -0,0 +1,18 @@ +export interface ProductListConfig { + type: string; + filters: ProductListFilters; +} + +export interface ProductListFilters { + slug?: string; + name?: string; + numero?: number; + barcode?: number; + poid?: number; + sachets?: string; + molecules?: string; + numeroRangeStart?: number; + numeroRangeEnd?: number; + sachetsRangeStart?: number; + sachetsRangeEnd?: number; +} diff --git a/src/app/core/models/product-list.model.ts b/src/app/core/models/product-list.model.ts new file mode 100644 index 0000000..3e82683 --- /dev/null +++ b/src/app/core/models/product-list.model.ts @@ -0,0 +1,6 @@ +import { Product } from './product.model'; + +export interface ProductList { + products: Array; + productsCount: number; +} diff --git a/src/app/core/models/product.model.ts b/src/app/core/models/product.model.ts new file mode 100644 index 0000000..cbe4548 --- /dev/null +++ b/src/app/core/models/product.model.ts @@ -0,0 +1,125 @@ +import { FormControl } from '@angular/forms'; +import { ColumnDefinition, PageLinks, PageMeta } from './shared.model'; +import { Brand, Category, Packaging, Profile, Tag } from '.'; + +export interface Product { + id: number; + slug: string; + eancode: string; + name: string; + description: string; + stock: number; + weightGross?: number; + weightNet?: number; + priceBuy?: number; + priceRetail?: number; + priceTaxe?: number; + tags?: Tag[]; + brand: Brand; + packaging: Packaging; + owner: Profile; + productCategories: Category[]; + createdAt: string; + updatedAt: string; + isSelected?: boolean; +} + +export interface ProductForm { + slug: FormControl; + eancode: FormControl; + name: FormControl; + description: FormControl; + stock: FormControl; + weightGross: FormControl; + weightNet: FormControl; + priceBuy: FormControl; + priceRetail: FormControl; + priceTaxe: FormControl; + tags: FormControl>; + brandId: FormControl; + ownerId: FormControl; + packagingId: FormControl; +} + +export interface ProductPageData { + product: Product; + _links: PageLinks; + _meta: PageMeta; +} + +export interface ProductsPageData { + products: Array; + count: number; + category?: Category; + _links: PageLinks; + _meta: PageMeta; +} + + +export const productColumns: Array = [ + { + key: 'isSelected', + type: 'isSelected', + label: '' + }, + { + key: 'name', + type: 'text', + label: 'Libellé', + required: true + }, + { + key: 'eancode', + type: 'text', + label: 'Code EAN13', + required: true + }, + { + key: 'stock', + type: 'numeric', + label: 'Stock', + required: true, + min: 0, + step: 1 + }, + { + key: 'weightGross', + type: 'numeric', + label: 'Poid brut', + min: 0, + step: 1 + }, + { + key: 'weightNet', + type: 'numeric', + label: 'Poid net', + min: 0, + step: 1 + }, + { + key: 'priceBuy', + type: 'numeric', + label: 'Prix achat', + min: 0, + step: 1 + }, + { + key: 'priceRetail', + type: 'numeric', + label: 'Prix vente', + min: 0, + step: 1 + }, + { + key: 'priceTaxe', + type: 'numeric', + label: 'TVA', + min: 0, + step: 1 + }, + { + key: 'tags', + type: 'text', + label: 'Tags' + } +]; \ No newline at end of file diff --git a/src/app/core/models/profile.model.ts b/src/app/core/models/profile.model.ts new file mode 100644 index 0000000..4d8c0a2 --- /dev/null +++ b/src/app/core/models/profile.model.ts @@ -0,0 +1,8 @@ +export interface Profile { + username: string; + licence?: number; + poids?: number; + image?: string; + bg_image?: string; + following: boolean; +} diff --git a/src/app/core/models/qcm.model.ts b/src/app/core/models/qcm.model.ts new file mode 100644 index 0000000..ee47b38 --- /dev/null +++ b/src/app/core/models/qcm.model.ts @@ -0,0 +1,29 @@ +export interface Qcm { + name: string; + categories: Array; +} + +export interface QcmCategory { + num: number; + name: string; + questions: Array; +} + +export interface QcmQuestion { + num: number; + libelle: string; + choices: Array; +} + +export enum QcmQuestionState { + UNANSWERED = "unanswered", + DEFERED = "defer", + VALID = "valid", + ERROR = "error" +} + +export interface QcmChoice { + index: string; + libelle: string; + correct: boolean; +} diff --git a/src/app/core/models/reducerow.model.ts b/src/app/core/models/reducerow.model.ts new file mode 100644 index 0000000..34ae24f --- /dev/null +++ b/src/app/core/models/reducerow.model.ts @@ -0,0 +1,4 @@ +export interface ReduceRow { + key: string[]; + value: number; +} \ No newline at end of file diff --git a/src/app/core/models/shared.model.ts b/src/app/core/models/shared.model.ts new file mode 100644 index 0000000..8016d68 --- /dev/null +++ b/src/app/core/models/shared.model.ts @@ -0,0 +1,40 @@ + +export interface PageLinks { + self: { + href: string; + }; + first: { + href: string; + }; + last: { + href: string; + }; + prev: { + href: string; + }; + next: { + href: string; + }; +} + +export interface PageMeta { + totalCount: number; + pageCount: number; + currentPage: number; + perPage: number; +} + +export interface ReduceRow { + key: string[]; + value: number; +} + +export interface ColumnDefinition { + key: string; + type: string; + label: string; + required?: boolean; + pattern?: string; + min?: number; + step?: number; +} diff --git a/src/app/core/models/tag.model.ts b/src/app/core/models/tag.model.ts new file mode 100644 index 0000000..3ecfee4 --- /dev/null +++ b/src/app/core/models/tag.model.ts @@ -0,0 +1,5 @@ +export interface Tag { + name: string; + createdAt: string; + updatedAt: string; +} \ No newline at end of file diff --git a/src/app/core/models/user.model.ts b/src/app/core/models/user.model.ts new file mode 100644 index 0000000..d785b1e --- /dev/null +++ b/src/app/core/models/user.model.ts @@ -0,0 +1,13 @@ +export interface User { + email: string; + username: string; + role: string; + firstname: string; + lastname: string; + phone: string; + token: string; + licence?: number; + poids?: number; + image?: string; + bg_image?: string; +} diff --git a/src/app/core/resolvers/aeronefs-page-resolver.service.ts b/src/app/core/resolvers/aeronefs-page-resolver.service.ts new file mode 100644 index 0000000..f887fad --- /dev/null +++ b/src/app/core/resolvers/aeronefs-page-resolver.service.ts @@ -0,0 +1,10 @@ +import { inject } from '@angular/core'; +import { ResolveFn } from '@angular/router'; +import { take } from 'rxjs/operators'; + +import { AeronefsPageData } from '@models'; +import { PagesService } from '@services'; + +export const aeronefsPageResolver: ResolveFn = () => { + return inject(PagesService).getAeronefsPage().pipe(take(1)); +}; \ No newline at end of file diff --git a/src/app/core/resolvers/article-resolver.service.ts b/src/app/core/resolvers/article-resolver.service.ts new file mode 100644 index 0000000..09f4a12 --- /dev/null +++ b/src/app/core/resolvers/article-resolver.service.ts @@ -0,0 +1,12 @@ +import { inject } from '@angular/core'; +import { ActivatedRouteSnapshot, ResolveFn } from '@angular/router'; +import { take } from 'rxjs/operators'; + +import { ArticlePageData } from '@models'; +import { ArticlesService } from '@services'; + +export const articleResolver: ResolveFn = ( + route: ActivatedRouteSnapshot +) => { + return inject(ArticlesService).get(route.params['slug']).pipe(take(1)); +}; \ No newline at end of file diff --git a/src/app/core/resolvers/articles-resolver.service.ts b/src/app/core/resolvers/articles-resolver.service.ts new file mode 100644 index 0000000..726156a --- /dev/null +++ b/src/app/core/resolvers/articles-resolver.service.ts @@ -0,0 +1,10 @@ +import { inject } from '@angular/core'; +import { ResolveFn } from '@angular/router'; +import { take } from 'rxjs/operators'; + +import { Article } from '@models'; +import { ArticlesService } from '@services'; + +export const articlesResolver: ResolveFn> = () => { + return inject(ArticlesService).getAll().pipe(take(1)); +}; \ No newline at end of file diff --git a/src/app/core/resolvers/auth-resolver.service.ts b/src/app/core/resolvers/auth-resolver.service.ts new file mode 100644 index 0000000..0ed2d13 --- /dev/null +++ b/src/app/core/resolvers/auth-resolver.service.ts @@ -0,0 +1,9 @@ +import { inject } from '@angular/core'; +import { ResolveFn } from '@angular/router'; +import { take } from 'rxjs/operators'; + +import { UserService } from '@services'; + +export const authResolver: ResolveFn = () => { + return inject(UserService).isAuthenticated.pipe(take(1)); +}; \ No newline at end of file diff --git a/src/app/core/resolvers/canopies-page-resolver.service.ts b/src/app/core/resolvers/canopies-page-resolver.service.ts new file mode 100644 index 0000000..11b90e6 --- /dev/null +++ b/src/app/core/resolvers/canopies-page-resolver.service.ts @@ -0,0 +1,10 @@ +import { inject } from '@angular/core'; +import { ResolveFn } from '@angular/router'; +import { take } from 'rxjs/operators'; + +import { CanopiesPageData } from '@models'; +import { PagesService } from '@services'; + +export const canopiesPageResolver: ResolveFn = () => { + return inject(PagesService).getCanopiesPage().pipe(take(1)); +}; \ No newline at end of file diff --git a/src/app/core/resolvers/dropzones-page-resolver.service.ts b/src/app/core/resolvers/dropzones-page-resolver.service.ts new file mode 100644 index 0000000..3a3a8f0 --- /dev/null +++ b/src/app/core/resolvers/dropzones-page-resolver.service.ts @@ -0,0 +1,10 @@ +import { inject } from '@angular/core'; +import { ResolveFn } from '@angular/router'; +import { take } from 'rxjs/operators'; + +import { DropZonesPageData } from '@models'; +import { PagesService } from '@services'; + +export const dropZonesPageResolver: ResolveFn = () => { + return inject(PagesService).getDropZonesPage().pipe(take(1)); +}; \ No newline at end of file diff --git a/src/app/core/resolvers/index.ts b/src/app/core/resolvers/index.ts new file mode 100644 index 0000000..cdb151a --- /dev/null +++ b/src/app/core/resolvers/index.ts @@ -0,0 +1,14 @@ +export * from './aeronefs-page-resolver.service'; +export * from './article-resolver.service'; +export * from './articles-resolver.service'; +export * from './auth-resolver.service'; +export * from './canopies-page-resolver.service'; +export * from './dropzones-page-resolver.service'; +export * from './jump-resolver.service'; +export * from './jumps-page-resolver.service'; +export * from './jumps-resolver.service'; +export * from './lastjump-resolver.service'; +export * from './product-resolver.service'; +export * from './products-resolver.service'; +export * from './profile-resolver.service'; +export * from './qcm-resolver.service'; diff --git a/src/app/core/resolvers/jump-resolver.service.ts b/src/app/core/resolvers/jump-resolver.service.ts new file mode 100644 index 0000000..81fcd95 --- /dev/null +++ b/src/app/core/resolvers/jump-resolver.service.ts @@ -0,0 +1,12 @@ +import { inject } from '@angular/core'; +import { ActivatedRouteSnapshot, ResolveFn } from '@angular/router'; +import { take } from 'rxjs/operators'; + +import { JumpPageData } from '@models'; +import { JumpsService } from '@services'; + +export const jumpResolver: ResolveFn = ( + route: ActivatedRouteSnapshot +) => { + return inject(JumpsService).get(route.params['slug']).pipe(take(1)); +}; \ No newline at end of file diff --git a/src/app/core/resolvers/jumps-page-resolver.service.ts b/src/app/core/resolvers/jumps-page-resolver.service.ts new file mode 100644 index 0000000..1949f4e --- /dev/null +++ b/src/app/core/resolvers/jumps-page-resolver.service.ts @@ -0,0 +1,10 @@ +import { inject } from '@angular/core'; +import { ResolveFn } from '@angular/router'; +import { take } from 'rxjs/operators'; + +import { JumpsPageData } from '@models'; +import { PagesService } from '@services'; + +export const jumpsPageResolver: ResolveFn = () => { + return inject(PagesService).getJumpsPage().pipe(take(1)); +}; \ No newline at end of file diff --git a/src/app/core/resolvers/jumps-resolver.service.ts b/src/app/core/resolvers/jumps-resolver.service.ts new file mode 100644 index 0000000..1151879 --- /dev/null +++ b/src/app/core/resolvers/jumps-resolver.service.ts @@ -0,0 +1,10 @@ +import { inject } from '@angular/core'; +import { ResolveFn } from '@angular/router'; +import { take } from 'rxjs/operators'; + +import { Jump } from '@models'; +import { JumpsService } from '@services'; + +export const jumpsResolver: ResolveFn> = () => { + return inject(JumpsService).getAll().pipe(take(1)); +}; \ No newline at end of file diff --git a/src/app/core/resolvers/lastjump-resolver.service.ts b/src/app/core/resolvers/lastjump-resolver.service.ts new file mode 100644 index 0000000..a118963 --- /dev/null +++ b/src/app/core/resolvers/lastjump-resolver.service.ts @@ -0,0 +1,10 @@ +import { inject } from '@angular/core'; +import { ResolveFn } from '@angular/router'; +import { take } from 'rxjs/operators'; + +import { Jump } from '@models'; +import { JumpsService } from '@services'; + +export const lastjumpResolver: ResolveFn = () => { + return inject(JumpsService).getLastJump().pipe(take(1)); +}; \ No newline at end of file diff --git a/src/app/core/resolvers/product-resolver.service.ts b/src/app/core/resolvers/product-resolver.service.ts new file mode 100644 index 0000000..8fd1aea --- /dev/null +++ b/src/app/core/resolvers/product-resolver.service.ts @@ -0,0 +1,12 @@ +import { inject } from '@angular/core'; +import { ActivatedRouteSnapshot, ResolveFn } from '@angular/router'; +import { take } from 'rxjs/operators'; + +import { ProductPageData } from '@models'; +import { ProductsService } from '@services'; + +export const productResolver: ResolveFn = ( + route: ActivatedRouteSnapshot +) => { + return inject(ProductsService).getProductBySlug(route.params['slug']).pipe(take(1)); +}; \ No newline at end of file diff --git a/src/app/core/resolvers/products-resolver.service.ts b/src/app/core/resolvers/products-resolver.service.ts new file mode 100644 index 0000000..986ce79 --- /dev/null +++ b/src/app/core/resolvers/products-resolver.service.ts @@ -0,0 +1,12 @@ +import { inject } from '@angular/core'; +import { ActivatedRouteSnapshot, ResolveFn } from '@angular/router'; +import { take } from 'rxjs/operators'; + +import { ProductsPageData } from '@models'; +import { ProductsService } from '@services'; + +export const productsResolver: ResolveFn = ( + route: ActivatedRouteSnapshot +) => { + return inject(ProductsService).getAllByCategory(route.params['category']).pipe(take(1)); +}; \ No newline at end of file diff --git a/src/app/core/resolvers/profile-resolver.service.ts b/src/app/core/resolvers/profile-resolver.service.ts new file mode 100644 index 0000000..773a588 --- /dev/null +++ b/src/app/core/resolvers/profile-resolver.service.ts @@ -0,0 +1,12 @@ +import { inject } from '@angular/core'; +import { ActivatedRouteSnapshot, ResolveFn } from '@angular/router'; +import { take } from 'rxjs/operators'; + +import { Profile } from '@models'; +import { ProfilesService } from '@services'; + +export const profileResolver: ResolveFn = ( + route: ActivatedRouteSnapshot +) => { + return inject(ProfilesService).get(route.params['username']).pipe(take(1)); +}; \ No newline at end of file diff --git a/src/app/core/resolvers/qcm-resolver.service.ts b/src/app/core/resolvers/qcm-resolver.service.ts new file mode 100644 index 0000000..72a001a --- /dev/null +++ b/src/app/core/resolvers/qcm-resolver.service.ts @@ -0,0 +1,12 @@ +import { inject } from '@angular/core'; +import { ActivatedRouteSnapshot, ResolveFn } from '@angular/router'; +import { take } from 'rxjs/operators'; + +import { Qcm } from '@models'; +import { QcmService } from '@services'; + +export const qcmResolver: ResolveFn = ( + route: ActivatedRouteSnapshot +) => { + return inject(QcmService).get(route.params['type']).pipe(take(1)); +}; \ No newline at end of file diff --git a/src/app/core/services/api.service.ts b/src/app/core/services/api.service.ts new file mode 100644 index 0000000..c6a634e --- /dev/null +++ b/src/app/core/services/api.service.ts @@ -0,0 +1,31 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { Injectable } from '@angular/core'; +import { HttpClient, HttpParams } from '@angular/common/http'; +import { Observable } from 'rxjs'; + +@Injectable({ providedIn: 'root' }) +export class ApiService { + constructor( + private http: HttpClient + ) { } + + /*private formatErrors(error: any) { + return throwError(error.error); + }*/ + + get(path: string, params: HttpParams = new HttpParams()): Observable { + return this.http.get(`${path}`, { params }); + } + + put(path: string, body: NonNullable = {}): Observable { + return this.http.put(`${path}`, JSON.stringify(body)); + } + + post(path: string, body: NonNullable = {}): Observable { + return this.http.post(`${path}`, JSON.stringify(body)); + } + + delete(path: string): Observable { + return this.http.delete(`${path}`); + } +} diff --git a/src/app/core/services/applications.service.ts b/src/app/core/services/applications.service.ts new file mode 100644 index 0000000..e08bcf8 --- /dev/null +++ b/src/app/core/services/applications.service.ts @@ -0,0 +1,54 @@ +import { Injectable } from '@angular/core'; +import { HttpParams } from '@angular/common/http'; +import { Observable } from 'rxjs'; + +import { ApiService } from './api.service'; +import { Application, ApplicationList, ApplicationListConfig, ApplicationListFilters } from '@models'; +import { map } from 'rxjs/operators'; + +@Injectable({ providedIn: 'root' }) +export class ApplicationsService { + private _apiDomain = '/skydive'; + constructor( + private apiService: ApiService + ) { } + + query(config: ApplicationListConfig): Observable { + // Convert any filters over to Angular's URLSearchParams + const params: ApplicationListFilters = { + apikey: config.filters.apikey, + author: config.filters.author, + limit: config.filters.limit, + offset: config.filters.offset + }; + return this.apiService + .get( + `${this._apiDomain}/applications` + ((config.type === 'feed') ? '/feed' : ''), + new HttpParams({ fromObject: <{ + [param: string]: string | number | boolean | readonly (string | number | boolean)[]; + }>params }) + ); + } + + get(slug: string): Observable { + return this.apiService.get(`${this._apiDomain}/applications/${slug}`) + .pipe(map(data => data.application)); + } + + destroy(slug: string): Observable { + return this.apiService.delete(`${this._apiDomain}/applications/${slug}`).pipe(map(data => data.deleted)); + } + + save(application: Application): Observable { + if (application.slug) { + // If we're updating an existing application + return this.apiService.put(`${this._apiDomain}/applications/${application.slug}`, { application: application }) + .pipe(map(data => data.application)); + } else { + // Otherwise, create a new application + return this.apiService.post(`${this._apiDomain}/applications/`, { application: application }) + .pipe(map(data => data.application)); + } + } + +} diff --git a/src/app/core/services/articles.service.ts b/src/app/core/services/articles.service.ts new file mode 100755 index 0000000..d746872 --- /dev/null +++ b/src/app/core/services/articles.service.ts @@ -0,0 +1,75 @@ +import { Injectable } from '@angular/core'; +import { HttpParams } from '@angular/common/http'; +import { Observable } from 'rxjs'; +import { map } from 'rxjs/operators'; + +import { ApiService } from './api.service'; +import { Article, ArticleList, ArticleListConfig, ArticleListFilters, ArticlePageData } from '@models'; + +@Injectable({ providedIn: 'root' }) +export class ArticlesService { + private _apiDomain = '/cms'; + constructor( + private apiService: ApiService + ) { } + + query(config: ArticleListConfig): Observable { + // Convert any filters over to Angular's URLSearchParams + const params: ArticleListFilters = {} as ArticleListFilters; + Object.assign(params, config.filters); + return this.apiService + .get( + `${this._apiDomain}/articles` + ((config.type === 'feed') ? '/feed' : ''), + new HttpParams({ fromObject: <{ + [param: string]: string | number | boolean | readonly (string | number | boolean)[]; + }>params }) + ); + } + + get(slug: string): Observable { + /*return this.apiService.get(`${this._apiDomain}/articles/${slug}`).pipe(map(data => { + data.article.tagList = data.article.tagNameTagTagLists; + delete data.article.tagNameTagTagLists; + return data; + }));*/ + return this.apiService.get(`${this._apiDomain}/articles/${slug}`); + } + + getAll(): Observable> { + return this.apiService.get(`${this._apiDomain}/articles`).pipe(map(data => data.articles)); + } + + create(article: Article): Observable
{ + return this.apiService.post(`${this._apiDomain}/articles/`, { article: article }).pipe(map(data => data.article)); + } + + update(article: Article): Observable
{ + return this.apiService.put(`${this._apiDomain}/articles/${article.slug}`, { article: article }).pipe(map(data => data.article)); + } + + destroy(slug: string): Observable { + return this.apiService.delete(`${this._apiDomain}/articles/${slug}`).pipe(map(data => data.deleted)); + } + + save(article: Article): Observable
{ + // If we're updating an existing article + if (article.slug) { + return this.apiService.put(`${this._apiDomain}/articles/${article.slug}`, { article: article }) + .pipe(map(data => data.article)); + + // Otherwise, create a new article + } else { + return this.apiService.post(`${this._apiDomain}/articles/`, { article: article }) + .pipe(map(data => data.article)); + } + } + + favorite(slug: string): Observable
{ + return this.apiService.post(`${this._apiDomain}/articles/${slug}/favorite`); + } + + unfavorite(slug: string): Observable
{ + return this.apiService.delete(`${this._apiDomain}/articles/${slug}/favorite`); + } + +} diff --git a/src/app/core/services/herowars/hw-clan.service.ts b/src/app/core/services/herowars/hw-clan.service.ts new file mode 100644 index 0000000..76742dd --- /dev/null +++ b/src/app/core/services/herowars/hw-clan.service.ts @@ -0,0 +1,127 @@ +import { Injectable } from '@angular/core'; +import { HttpParams } from '@angular/common/http'; +import { Observable } from 'rxjs'; +import { map } from 'rxjs/operators'; + +import { ApiService } from '../api.service'; +import { + HWActivityStat, HWClan, HWClanList, HWClanListConfig, + HWClanListFilters, HWClanPageData, HWGuildClan, + HWMember +} from '@models'; + +import guildData from 'src/files-data/hw-guild-data.json'; // page Membres + +@Injectable({ providedIn: 'root' }) +export class HWClanService { + private _apiDomain = '/herowars'; + constructor( + private apiService: ApiService + ) { } + + private _resetActivity(): HWActivityStat { + const activity: HWActivityStat = { activity: 0, prestige: 0, titanite: 0, war: 0, adventure: 0, gifts: 0, score: 0, scoreGifts: 0, warGifts: 0, rewards: 0 }; + return activity; + } + + query(config: HWClanListConfig): Observable { + // Convert any filters over to Angular's URLSearchParams + const params: HWClanListFilters = {} as HWClanListFilters; + Object.assign(params, config.filters); + return this.apiService + .get( + `${this._apiDomain}/clans`, + new HttpParams({ fromObject: <{ + [param: string]: string | number | boolean | readonly (string | number | boolean)[]; + }>params }) + ); + } + + get(id: string): Observable { + return this.apiService.get(`${this._apiDomain}/clans/${id}`); + } + + getAll(): Observable> { + return this.apiService.get(`${this._apiDomain}/clans`).pipe(map(data => data.clans)); + } + + create(clan: HWClan): Observable { + return this.apiService.post(`${this._apiDomain}/clans/`, { clan: clan }).pipe(map(data => data.clan)); + } + + update(clan: HWClan): Observable { + return this.apiService.put(`${this._apiDomain}/clans/${clan.id}`, { clan: clan }).pipe(map(data => data.clan)); + } + + destroy(id: string): Observable { + return this.apiService.delete(`${this._apiDomain}/clans/${id}`).pipe(map(data => data.deleted)); + } + + save(clan: HWClan): Observable { + // If we're updating an existing clan + if (clan.id) { + return this.apiService.put(`${this._apiDomain}/clans/${clan.id}`, { clan: clan }).pipe(map(data => data.clan)); + // Otherwise, create a new clan + } else { + return this.apiService.post(`${this._apiDomain}/clans/`, { clan: clan }).pipe(map(data => data.clan)); + } + } + + loadClan(): HWGuildClan { + const guildClan: HWGuildClan = {} as HWGuildClan; + Object.assign(guildClan, guildData.clan); + guildClan.sumAverages = this._resetActivity(); + guildClan.sumTotal = this._resetActivity(); + guildClan.todayAverages = this._resetActivity(); + guildClan.todayTotal = this._resetActivity(); + + return guildClan; + } + + loadClanStats(clan: HWGuildClan, members: HWMember[]): HWGuildClan { + members.map((member: HWMember) => { + clan.sumTotal.adventure += member.adventureSum; + clan.sumTotal.gifts += member.clanGiftsSum; + clan.sumTotal.war += member.clanWarSum; + clan.todayTotal.activity += member.stat.todayActivity; + clan.todayTotal.prestige += member.stat.todayPrestige; + clan.todayTotal.titanite += member.stat.todayDungeonActivity; + clan.todayTotal.score += (member.stat.todayDungeonActivity + member.stat.todayActivity + member.stat.todayPrestige); + clan.sumTotal.activity += member.stat.activitySum; + clan.sumTotal.prestige += member.stat.prestigeSum; + clan.sumTotal.titanite += member.stat.dungeonActivitySum; + clan.sumTotal.score += member.score; + clan.sumTotal.warGifts += member.warGifts; + }); + clan.sumTotal.scoreGifts = (clan.giftsCount - Math.floor(clan.sumTotal.warGifts)); + clan.todayAverages.activity = (clan.todayTotal.activity / members.length); + clan.todayAverages.prestige = (clan.todayTotal.prestige / members.length); + clan.todayAverages.titanite = (clan.todayTotal.titanite / members.length); + clan.todayAverages.score = (clan.todayTotal.score / members.length); + clan.sumAverages.activity = (clan.sumTotal.activity / members.length); + clan.sumAverages.prestige = (clan.sumTotal.prestige / members.length); + clan.sumAverages.titanite = (clan.sumTotal.titanite / members.length); + if (clan.league === '3') { + clan.sumAverages.war = (clan.sumTotal.war / 10); + } else if (clan.league === '2') { + clan.sumAverages.war = (clan.sumTotal.war / 15); + } else if (clan.league === '1') { + clan.sumAverages.war = (clan.sumTotal.war / 20); + } + clan.sumAverages.adventure = (clan.sumTotal.adventure / members.length); + clan.sumAverages.gifts = (clan.sumTotal.gifts / members.length); + clan.sumAverages.score = (clan.sumTotal.score / members.length); + clan.sumAverages.scoreGifts = (clan.sumTotal.scoreGifts / members.length); + clan.sumAverages.warGifts = (clan.sumTotal.warGifts / members.length); + members.map((data) => { + data.scoreGifts = ((data.score / clan.sumTotal.score) * clan.sumTotal.scoreGifts); + data.rewards = Math.floor((data.scoreGifts + data.warGifts)); + clan.sumTotal.rewards += data.rewards; + return data; + }); + clan.sumAverages.rewards = (clan.sumTotal.rewards / members.length); + + return clan; + } + +} diff --git a/src/app/core/services/herowars/hw-member.service.ts b/src/app/core/services/herowars/hw-member.service.ts new file mode 100644 index 0000000..9a0046c --- /dev/null +++ b/src/app/core/services/herowars/hw-member.service.ts @@ -0,0 +1,137 @@ +import { Injectable } from '@angular/core'; +import { HttpParams } from '@angular/common/http'; +import { Observable } from 'rxjs'; +import { map } from 'rxjs/operators'; + +import { ApiService, UtilitiesService } from '@services'; +import { + HWGuildClan, HWWeekStat, + HWMember, HWMemberList, HWMemberListConfig, + HWMemberListFilters, HWMemberPageData, HWMemberStat +} from '@models'; + +import guildData from 'src/files-data/hw-guild-data.json'; // page Membres +import guildStatistics from 'src/files-data/hw-guild-statistics.json'; // page Overview -> Statistics +@Injectable({ providedIn: 'root' }) +export class HWMemberService { + private _apiDomain = '/herowars'; + constructor( + private _apiService: ApiService, + private _utilitiesService: UtilitiesService + ) { } + + query(config: HWMemberListConfig): Observable { + // Convert any filters over to Angular's URLSearchParams + const params: HWMemberListFilters = {} as HWMemberListFilters; + Object.assign(params, config.filters); + return this._apiService + .get( + `${this._apiDomain}/members`, + new HttpParams({ fromObject: <{ + [param: string]: string | number | boolean | readonly (string | number | boolean)[]; + }>params }) + ); + } + + get(id: string): Observable { + return this._apiService.get(`${this._apiDomain}/members/${id}`); + } + + getAll(): Observable> { + return this._apiService.get(`${this._apiDomain}/members`).pipe(map(data => data.members)); + } + + create(member: HWMember): Observable { + return this._apiService.post(`${this._apiDomain}/members/`, { member: member }).pipe(map(data => data.member)); + } + + update(member: HWMember): Observable { + return this._apiService.put(`${this._apiDomain}/members/${member.id}`, { member: member }).pipe(map(data => data.member)); + } + + destroy(id: string): Observable { + return this._apiService.delete(`${this._apiDomain}/members/${id}`).pipe(map(data => data.deleted)); + } + + save(member: HWMember): Observable { + // If we're updating an existing member + if (member.id) { + return this._apiService.put(`${this._apiDomain}/members/${member.id}`, { member: member }).pipe(map(data => data.member)); + // Otherwise, create a new member + } else { + return this._apiService.post(`${this._apiDomain}/members/`, { member: member }).pipe(map(data => data.member)); + } + } + + loadMembers(clan: HWGuildClan): HWMember[] { + const guildMembers: HWMember[] = []; + const now = new Date(); + const oneDayInSec = (24 * 60 * 60); + const daysToKick = parseInt(guildData.clan.daysToKick); + for (const data of Object.entries(guildData.clan.members)) { + const member: HWMember = {} as HWMember; + Object.assign(member, data[1]); + if (guildData.clan.warriors.indexOf(parseInt(member.id)) !== -1) { + member.champion = true; + } else { + member.champion = false; + } + member.heroes = { power: 0, teams: []}; + member.titans = { power: 0, teams: []}; + guildMembers.push(member); + } + guildMembers.map((data: HWMember) => { + const last = new Date((parseInt(data.lastLoginTime) * 1000)); + const exp = new Date(last.getTime() + ((daysToKick * oneDayInSec) * 1000)); + const diff = Math.floor(((exp.getTime() - now.getTime()) / 1000)); + const daysLeft = Math.floor((diff / oneDayInSec)); + let timeLeft = diff; + if (daysLeft >= 1) { + timeLeft = (diff - (daysLeft * oneDayInSec)); + } + data.inactivity = { + daysLeft: daysLeft, + timeLeft: timeLeft, + dropDelay: `${daysLeft}d, ${this._utilitiesService.secondsToDuration(timeLeft)}`, + dropDate: Math.floor((exp.getTime() / 1000)) + }; + data.raids = []; + data.raidsInfo = { + variationAvg: 0, + variationSum: 0 + }; + data.stat = {} as HWMemberStat; + let index = guildData.membersStat.findIndex(stat => stat.userId === data.id); + if (index !== -1) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars + const { userId, ...memberStatWithoutUserId } = guildData.membersStat[index] as any; + Object.assign(data.stat, memberStatWithoutUserId); + } + index = guildStatistics.stat.findIndex(stat => stat.id === data.id); + if (index !== -1) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars + const { id, ...weekStatSource } = guildStatistics.stat[index] as any; + const stat: HWWeekStat = {} as HWWeekStat; + Object.assign(stat, weekStatSource); + data.weekStat = stat; + data.adventureSum = guildStatistics.stat[index].adventureStat.reduce((accumulator, currentValue) => accumulator + currentValue, 0); + data.clanGiftsSum = guildStatistics.stat[index].clanGifts.reduce((accumulator, currentValue) => accumulator + currentValue, 0); + data.clanWarSum = guildStatistics.stat[index].clanWarStat.reduce((accumulator, currentValue) => accumulator + currentValue, 0); + } else { + data.weekStat = {} as HWWeekStat; + data.adventureSum = 0; + data.clanGiftsSum = 0; + data.clanWarSum = 0; + } + + data.score = (data.stat.dungeonActivitySum + data.stat.activitySum + data.stat.prestigeSum); + data.warGifts = (((clan.giftsCount / 2) * ((data.clanWarSum * 10) / 100)) / 20); + data.scoreGifts = 0; + data.rewards = 0; + return data; + }); + + return guildMembers; + } + +} diff --git a/src/app/core/services/herowars/index.ts b/src/app/core/services/herowars/index.ts new file mode 100644 index 0000000..15eff80 --- /dev/null +++ b/src/app/core/services/herowars/index.ts @@ -0,0 +1,3 @@ + +export * from './hw-clan.service'; +export * from './hw-member.service'; \ No newline at end of file diff --git a/src/app/core/services/index.ts b/src/app/core/services/index.ts new file mode 100644 index 0000000..e32c527 --- /dev/null +++ b/src/app/core/services/index.ts @@ -0,0 +1,12 @@ +export * from './api.service'; +export * from './applications.service'; +export * from './articles.service'; +export * from './jwt.service'; +export * from './pages.service'; +export * from './products.service'; +export * from './profiles.service'; +export * from './user.service'; +export * from './utilities.service'; + +export * from './skydive/'; +export * from './herowars/'; \ No newline at end of file diff --git a/src/app/core/services/jwt.service.ts b/src/app/core/services/jwt.service.ts new file mode 100644 index 0000000..3c7abb9 --- /dev/null +++ b/src/app/core/services/jwt.service.ts @@ -0,0 +1,18 @@ +import { Injectable } from '@angular/core'; + +@Injectable({ providedIn: 'root' }) +export class JwtService { + + getToken(): string { + return window.localStorage['jwtToken']; + } + + saveToken(token: string) { + window.localStorage['jwtToken'] = token; + } + + destroyToken() { + window.localStorage.removeItem('jwtToken'); + } + +} diff --git a/src/app/core/services/pages.service.ts b/src/app/core/services/pages.service.ts new file mode 100644 index 0000000..76787f7 --- /dev/null +++ b/src/app/core/services/pages.service.ts @@ -0,0 +1,31 @@ +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs'; +import { take } from 'rxjs/operators'; + +import { ApiService } from './api.service'; +import { AeronefsPageData, CanopiesPageData, DropZonesPageData, JumpsPageData } from '@models'; + +@Injectable({ providedIn: 'root' }) +export class PagesService { + private _apiDomain = '/skydive'; + constructor( + private apiService: ApiService + ) { } + + getAeronefsPage(): Observable { + return this.apiService.get(`${this._apiDomain}/pages/aeronefs`).pipe(take(1)); + } + + getCanopiesPage(): Observable { + return this.apiService.get(`${this._apiDomain}/pages/canopies`).pipe(take(1)); + } + + getDropZonesPage(): Observable { + return this.apiService.get(`${this._apiDomain}/pages/dropzones`).pipe(take(1)); + } + + getJumpsPage(): Observable { + return this.apiService.get(`${this._apiDomain}/pages/jumps`).pipe(take(1)); + } + +} diff --git a/src/app/core/services/products.service.ts b/src/app/core/services/products.service.ts new file mode 100644 index 0000000..0f180b0 --- /dev/null +++ b/src/app/core/services/products.service.ts @@ -0,0 +1,68 @@ +import { Injectable } from '@angular/core'; +import { HttpParams } from '@angular/common/http'; +import { Observable } from 'rxjs'; +import { map } from 'rxjs/operators'; + +import { ApiService } from './api.service'; +import { Product, ProductList, ProductListConfig, ProductListFilters, ProductPageData, ProductsPageData } from '@models'; + +@Injectable({ providedIn: 'root' }) +export class ProductsService { + private _apiDomain = '/ecommerce'; + constructor( + private apiService: ApiService + ) { } + + query(config: ProductListConfig): Observable { + // Convert any filters over to Angular's URLSearchParams + const params: ProductListFilters = {} as ProductListFilters; + Object.assign(params, config.filters); + return this.apiService + .get( + `${this._apiDomain}/products` + ((config.type === 'feed') ? '/feed' : ''), + new HttpParams({ fromObject: <{ + [param: string]: string | number | boolean | readonly (string | number | boolean)[]; + }>params }) + ); + } + + get(slug: string): Observable { + return this.apiService.get(`${this._apiDomain}/product/${slug}`); + } + + getProductBySlug(slug: string): Observable { + return this.apiService.get(`${this._apiDomain}/product/${slug}`); + } + + getAll(): Observable> { + return this.apiService.get(`${this._apiDomain}/products`).pipe(map(data => data.products)); + } + + getAllByCategory(category: string): Observable { + return this.apiService.get(`${this._apiDomain}/products/${category}`); //.pipe(map(data => data.products)); + } + + create(product: Product): Observable { + return this.apiService.post(`${this._apiDomain}/products/`, { product: product }).pipe(map(data => data.product)); + } + + update(product: Product): Observable { + return this.apiService.put(`${this._apiDomain}/products/${product.slug}`, { product: product }).pipe(map(data => data.product)); + } + + destroy(slug: string): Observable { + return this.apiService.delete(`${this._apiDomain}/products/${slug}`).pipe(map(data => data.deleted)); + } + + save(product: Product): Observable { + // If we're updating an existing product + if (product.slug) { + return this.apiService.put(`${this._apiDomain}/products/${product.slug}`, { product: product }).pipe(map(data => data.product)); + + // Otherwise, create a new product + } else { + return this.apiService.post(`${this._apiDomain}/products/`, { product: product }).pipe(map(data => data.product)); + } + } + +} diff --git a/src/app/core/services/profiles.service.ts b/src/app/core/services/profiles.service.ts new file mode 100644 index 0000000..64f7fc7 --- /dev/null +++ b/src/app/core/services/profiles.service.ts @@ -0,0 +1,28 @@ +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs'; + +import { ApiService } from '@services'; +import { Profile } from '@models'; +import { map } from 'rxjs/operators'; + +@Injectable({ providedIn: 'root' }) +export class ProfilesService { + private _apiDomain = '/cms'; + constructor( + private apiService: ApiService + ) { } + + get(username: string): Observable { + return this.apiService.get(`${this._apiDomain}/profiles/${username}`) + .pipe(map((data: { profile: Profile }) => data.profile)); + } + + follow(username: string): Observable { + return this.apiService.post(`${this._apiDomain}/profiles/${username}/follow`); + } + + unfollow(username: string): Observable { + return this.apiService.delete(`${this._apiDomain}/profiles/${username}/follow`); + } + +} diff --git a/src/app/core/services/skydive/aeronefs.service.ts b/src/app/core/services/skydive/aeronefs.service.ts new file mode 100644 index 0000000..cc6772e --- /dev/null +++ b/src/app/core/services/skydive/aeronefs.service.ts @@ -0,0 +1,25 @@ +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs'; +import { map } from 'rxjs/operators'; + +import { ApiService } from '../api.service'; +import { AeronefByImat, AeronefByYear } from '@models'; + +@Injectable({ providedIn: 'root' }) +export class AeronefsService { + private _apiDomain = '/skydive'; + constructor( + private apiService: ApiService + ) { } + + getAllByImat(): Observable> { + return this.apiService.get(`${this._apiDomain}/aeronefs/allByImat`) + .pipe(map(data => data.aeronefs)); + } + + getAllByImatByYear(): Observable> { + return this.apiService.get(`${this._apiDomain}/aeronefs/allByImatByYear`) + .pipe(map(data => data.aeronefs)); + } + +} \ No newline at end of file diff --git a/src/app/core/services/skydive/calculator.service.ts b/src/app/core/services/skydive/calculator.service.ts new file mode 100644 index 0000000..b5ff60b --- /dev/null +++ b/src/app/core/services/skydive/calculator.service.ts @@ -0,0 +1,129 @@ +import { Injectable } from '@angular/core'; + +import { CalculatorResult, WeightSizeRange, weightSizes } from '@models'; +import { UtilitiesService } from '@services'; + +@Injectable({ providedIn: 'root' }) +export class CalculatorService { + public coeffKgLbs: number = this._utilitiesService.getCoeffKgLbs(); + public coeffFtM: number = this._utilitiesService.getCoeffFtM(); + + constructor( + private _utilitiesService: UtilitiesService + ) { } + + private _getTableColumn(jumps: number): number { + let column: number = 0; + weightSizes[0].ranges.some((range: WeightSizeRange) => { + if (jumps >= range.start && jumps <= range.end) { + column = (range.num-1) + return true; + } + return false; + }); + + return column; + } + + private _getTableLine(weight: number): number { + let line: number; + const min = 60; + const max = 110; + if (weight < min) { + line = min; + } else if (weight > max) { + line = max; + } else { + line = weight; + } + return line; + } + + private _isInRange(nb: number, range: WeightSizeRange): boolean { + return (nb >= range.start && nb <= range.end); + } + + private _reduceLimit(surface: number, percentOff: number): number { + return Math.ceil(surface * (100 - percentOff) / 100); + } + + public canopySizeCalc(weight: number, jumps: number): CalculatorResult { + /* DT48 - 13 mars 2020 */ + /* const maxRange = 2000; */ + /* DT48 - 08 février 2024 */ + const maxRange = 1600; + const result: CalculatorResult = { + min: 59, + min11: 34 + }; + if (jumps > maxRange) { + return result; + } + const index: number = (this._getTableLine(weight) - this._getTableLine(0)); + result.min = weightSizes[index].ranges[this._getTableColumn(jumps)].value!; + result.min11 = this._reduceLimit(result.min, 11); + + return result; + } + + public convertFeet2Meters(size: number): number { + return (size * this._utilitiesService.getCoeffFtM()); + } + + public getCanopySizes(weight: number, reduce = false): number[] { + if (weight < 60) { + weight = 60; + } + if (weight > 110) { + weight = 110; + } + const line = (weight - this._getTableLine(0)); + const data = weightSizes[line]; + if (reduce) { + return data.ranges.map((range: WeightSizeRange): number => { + return Math.ceil(range.value! * (100 - 11) / 100); + }); + } else { + return data.ranges.map((range: WeightSizeRange): number => { + return range.value!; + }); + } + } + + public getCharge(canopySize: number, nakedWeight: number, equipementWeight: number): number { + return (((nakedWeight + equipementWeight) * this.coeffKgLbs) / canopySize); + } + + public getRangeNum(jumps: number): number { + const data: WeightSizeRange[] = weightSizes[0].ranges; + let num: number = 1; + /* DT48 - 13 mars 2020 */ + /* const maxRange = 2000; */ + /* DT48 - 08 février 2024 */ + const maxRange = 1600; + data.some((range: WeightSizeRange): boolean => { + if (jumps >= range.start && jumps <= range.end) { + num = range.num; + return true; + } else if (jumps > maxRange) { + num = 9; + return true; + } + return false; + }); + return num; + } + + public getStateColor(values: CalculatorResult): string { + let color: string = 'danger'; + if (values.current! >= values.min11 && values.current! < values.min) { + color = 'warning'; + } + if (values.current! >= values.min) { + color = 'success'; + } + + return color; + } + +} \ No newline at end of file diff --git a/src/app/core/services/skydive/canopies.service.ts b/src/app/core/services/skydive/canopies.service.ts new file mode 100644 index 0000000..4ca358e --- /dev/null +++ b/src/app/core/services/skydive/canopies.service.ts @@ -0,0 +1,35 @@ +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs'; +import { map } from 'rxjs/operators'; + +import { ApiService } from '../api.service'; +import { CanopyBySize, CanopyByYear, CanopyModelBySize, CanopyModelByYear } from '@models'; + +@Injectable({ providedIn: 'root' }) +export class CanopiesService { + private _apiDomain = '/skydive'; + constructor( + private apiService: ApiService + ) { } + + getAllBySize(): Observable> { + return this.apiService.get(`${this._apiDomain}/canopies/allBySize`) + .pipe(map(data => data.canopies)); + } + + getAllBySizeByYear(): Observable> { + return this.apiService.get(`${this._apiDomain}/canopies/allBySizeByYear`) + .pipe(map(data => data.canopies)); + } + + getAllBySizeByModel(): Observable> { + return this.apiService.get(`${this._apiDomain}/canopies/allBySizeByModel`) + .pipe(map(data => data.canopies)); + } + + getAllBySizeByModelByYear(): Observable> { + return this.apiService.get(`${this._apiDomain}/canopies/allBySizeByModelByYear`) + .pipe(map(data => data.canopies)); + } + +} \ No newline at end of file diff --git a/src/app/core/services/skydive/dropzones.service.ts b/src/app/core/services/skydive/dropzones.service.ts new file mode 100644 index 0000000..9e39684 --- /dev/null +++ b/src/app/core/services/skydive/dropzones.service.ts @@ -0,0 +1,25 @@ +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs'; +import { map } from 'rxjs/operators'; + +import { ApiService } from '../api.service'; +import { DropZoneByOaci, DropZoneByYear } from '@models'; + +@Injectable({ providedIn: 'root' }) +export class DropZonesService { + private _apiDomain = '/skydive'; + constructor( + private apiService: ApiService + ) { } + + getAllByOaci(): Observable> { + return this.apiService.get(`${this._apiDomain}/dropzones/allByOaci`) + .pipe(map(data => data.dropzones)); + } + + getAllByOaciByYear(): Observable> { + return this.apiService.get(`${this._apiDomain}/dropzones/allByOaciByYear`) + .pipe(map(data => data.dropzones)); + } + +} \ No newline at end of file diff --git a/src/app/core/services/skydive/index.ts b/src/app/core/services/skydive/index.ts new file mode 100644 index 0000000..d23625b --- /dev/null +++ b/src/app/core/services/skydive/index.ts @@ -0,0 +1,7 @@ +export * from './aeronefs.service'; +export * from './calculator.service'; +export * from './canopies.service'; +export * from './dropzones.service'; +export * from './jumps.service'; +export * from './jump-table.service'; +export * from './qcm.service'; \ No newline at end of file diff --git a/src/app/core/services/skydive/jump-table.service.ts b/src/app/core/services/skydive/jump-table.service.ts new file mode 100644 index 0000000..f81f06f --- /dev/null +++ b/src/app/core/services/skydive/jump-table.service.ts @@ -0,0 +1,31 @@ +import { Injectable } from '@angular/core'; +import { BehaviorSubject } from "rxjs"; + +@Injectable({ providedIn: 'root' }) +export class JumpTableService { + + tableRefresh: boolean; + _tableRefreshBS = new BehaviorSubject(false); + + jumpRefresh: boolean; + _jumpRefreshBS = new BehaviorSubject(false); + + constructor() { + this.tableRefresh = false; + this.jumpRefresh = false; + + //this._tableRefreshBS.next(this.tableRefresh); + //this._jumpRefreshBS.next(this.jumpRefresh); + } + + updateTableRefresh(val: boolean) { + this.tableRefresh = val; + this._tableRefreshBS.next(this.tableRefresh); + } + + updateJumpRefresh(val: boolean) { + this.jumpRefresh = val; + this._jumpRefreshBS.next(this.jumpRefresh); + } + +} \ No newline at end of file diff --git a/src/app/core/services/skydive/jumps.service.ts b/src/app/core/services/skydive/jumps.service.ts new file mode 100644 index 0000000..a1750be --- /dev/null +++ b/src/app/core/services/skydive/jumps.service.ts @@ -0,0 +1,167 @@ +import { Injectable } from '@angular/core'; +import { HttpParams } from '@angular/common/http'; +import { Observable } from 'rxjs'; +import { map } from 'rxjs/operators'; + +import { ApiService } from '../api.service'; +import { + Jump, JumpByCategorie, JumpByDate, JumpByDay, JumpByModule, JumpFile, + JumpList, JumpListConfig, JumpListFilters, JumpPageData, + X2Data, SkydiverIdJumps +} from '@models'; + +@Injectable({ providedIn: 'root' }) +export class JumpsService { + private _apiDomain = '/skydive'; + constructor( + private apiService: ApiService + ) { } + + query(config: JumpListConfig): Observable { + // Convert any filters over to Angular's URLSearchParams + /* + const params: JumpListFilters = { + date: config.filters.date, + lieu: config.filters.lieu, + oaci: config.filters.oaci, + aeronef: config.filters.aeronef, + imat: config.filters.imat, + hauteur: config.filters.hauteur, + voile: config.filters.voile, + taille: config.filters.taille, + categorie: config.filters.categorie, + module: config.filters.module, + participants: config.filters.participants, + accessoires: config.filters.accessoires, + zone: config.filters.zone, + author: config.filters.author, + limit: config.filters.limit, + offset: config.filters.offset, + numeroRangeStart: config.filters.numeroRangeStart!, + numeroRangeEnd: config.filters.numeroRangeEnd!, + tailleRangeStart: config.filters.tailleRangeStart!, + tailleRangeEnd: config.filters.tailleRangeEnd!, + participantsRangeStart: config.filters.participantsRangeStart!, + participantsRangeEnd: config.filters.participantsRangeEnd!, + hauteurRangeStart: config.filters.hauteurRangeStart!, + hauteurRangeEnd: config.filters.hauteurRangeEnd! + }; + */ + const params: JumpListFilters = {} as JumpListFilters; + Object.assign(params, config.filters); + return this.apiService + .get( + `${this._apiDomain}/jumps`, + new HttpParams({ fromObject: <{ + [param: string]: string | number | boolean | readonly (string | number | boolean)[]; + }>params }) + ); + } + + get(slug: string): Observable { + /* return this.apiService.get(`/jumps/${slug}`) + .pipe(map(data => { + return { jump: data.jump, prevJump: data.prevJump, nextJump: data.nextJump }; + })); */ + return this.apiService.get(`${this._apiDomain}/jumps/${slug}`); + } + + getAll(): Observable> { + return this.apiService.get(`${this._apiDomain}/jumps`).pipe(map(data => data.jumps)); + } + + getAllByDate(): Observable> { + return this.apiService.get(`${this._apiDomain}/jumps/allByDate`).pipe(map(data => data.jumps)); + } + + getAllByCategorie(): Observable> { + return this.apiService.get(`${this._apiDomain}/jumps/allByCategorie`).pipe(map(data => data.jumps)); + } + + getAllByDay(config: JumpListConfig): Observable> { + const params: JumpListFilters = {} as JumpListFilters; + Object.assign(params, config.filters); + return this.apiService.get(`${this._apiDomain}/jumps/allByDay`, new HttpParams({ fromObject: <{ + [param: string]: string | number | boolean | readonly (string | number | boolean)[]; + }>params })) + .pipe(map(data => data.days)); + } + + getAllByModule(): Observable> { + return this.apiService.get(`${this._apiDomain}/jumps/allByModule`).pipe(map(data => data.jumps)); + } + + getAllFromSkydiverIdApi(config: JumpListConfig): Observable { + const params: JumpListFilters = {} as JumpListFilters; + Object.assign(params, config.filters); + return this.apiService.get(`${this._apiDomain}/jumps/allFromSkydiverIdApi`, new HttpParams({ fromObject: <{ + [param: string]: string | number | boolean | readonly (string | number | boolean)[]; + }>params })) + .pipe(map(data => data.jumps)); + } + + getLastJump(): Observable { + return this.apiService.get(`${this._apiDomain}/jumps/last`).pipe(map(data => data.jump)); + } + + create(jump: Jump): Observable { + return this.apiService.post(`${this._apiDomain}/jumps/`, { jump: jump }).pipe(map(data => data.jump)); + } + + update(jump: Jump): Observable { + return this.apiService.put(`${this._apiDomain}/jumps/${jump.slug}`, { jump: jump }).pipe(map(data => data.jump)); + } + + destroy(slug: string): Observable { + return this.apiService.delete(`${this._apiDomain}/jumps/${slug}`).pipe(map(data => data.deleted)); + } + + save(jump: Jump): Observable { + // If we're updating an existing jump + if (jump.slug) { + return this.apiService.put(`${this._apiDomain}/jumps/${jump.slug}`, { jump: jump }).pipe(map(data => data.jump)); + + // Otherwise, create a new jump + } else { + return this.apiService.post(`${this._apiDomain}/jumps/`, { jump: jump }).pipe(map(data => data.jump)); + } + } + + saveX2Data(slug: string, file: JumpFile, data: X2Data): Observable { + return this.apiService.post(`${this._apiDomain}/jumps/data/${slug}`, { file: file, data: data }) + .pipe(map(data => data.jump)); + } + + saveFile(slug: string, file: JumpFile): Observable { + return this.apiService.post(`${this._apiDomain}/jumps/file/${slug}`, { file: file }) + .pipe(map(data => data.file)); + } + + saveKml(slug: string, file: JumpFile): Observable { + return this.apiService.post(`${this._apiDomain}/jumps/kml/${slug}`, { file: file }) + .pipe(map(data => data.file)); + } + + getAeronefs() { + /* + [ + { + '$match': { + 'aeronef': 'Pilatus' + } + }, { + '$group': { + '_id': { + 'Aeronef': '$aeronef', + 'Imat': '$imat' + }, + 'count': { + '$sum': 1 + } + } + } + ] + */ + } + +} diff --git a/src/app/core/services/skydive/qcm.service.ts b/src/app/core/services/skydive/qcm.service.ts new file mode 100644 index 0000000..581cc97 --- /dev/null +++ b/src/app/core/services/skydive/qcm.service.ts @@ -0,0 +1,28 @@ +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs'; +import { map } from 'rxjs/operators'; + +import { ApiService } from '../api.service'; +import { Qcm, QcmCategory, QcmQuestion } from '@models'; + +@Injectable({ providedIn: 'root' }) +export class QcmService { + private _apiDomain = '/skydive'; + constructor( + private apiService: ApiService + ) { } + + get(type: string): Observable { + return this.apiService.get(`${this._apiDomain}/qcm/type/${type}`).pipe(map(data => data.qcm)); + } + + saveChoices(question: object): Observable { + return this.apiService.post(`${this._apiDomain}/qcm/choices`, { question: question }) + .pipe(map(data => data.question)); + } + + saveQuestions(category: object): Observable { + return this.apiService.post(`${this._apiDomain}/qcm/questions`, { category: category }) + .pipe(map(data => data.category)); + } +} diff --git a/src/app/core/services/user.service.ts b/src/app/core/services/user.service.ts new file mode 100644 index 0000000..1d6c46c --- /dev/null +++ b/src/app/core/services/user.service.ts @@ -0,0 +1,94 @@ +import { Injectable, OnDestroy } from '@angular/core'; +import { HttpClient } from "@angular/common/http"; +import { Observable, BehaviorSubject, ReplaySubject, Subscription } from 'rxjs'; +import { distinctUntilChanged, take, tap } from 'rxjs/operators'; + +import { User } from '@models'; +import { JwtService } from '@services'; + +@Injectable({ providedIn: 'root' }) +export class UserService implements OnDestroy { + private _subcriptions: Array = new Array(); + private _user: Subscription = new Subscription(); + private currentUserSubject = new BehaviorSubject({} as User); + public currentUser = this.currentUserSubject.asObservable().pipe(distinctUntilChanged()); + + private isAuthenticatedSubject = new ReplaySubject(1); + public isAuthenticated = this.isAuthenticatedSubject.asObservable(); + + + private _apiDomain = '/cms'; + constructor( + private readonly http: HttpClient, + private readonly jwtService: JwtService + ) { } + + ngOnDestroy() { + this._subcriptions.forEach((subscription: Subscription) => subscription.unsubscribe()); + } + + // Verify JWT in localstorage with server & load user's info. + // This runs once on application startup. + populate() { + // If JWT detected, attempt to get & store user's info + if (this.jwtService.getToken()) { + const user$: Observable<{ user: User }> = this.http.get<{ user: User }>(`${this._apiDomain}/user`).pipe(take(1)); + this._user = user$.subscribe({ + next: (data) => this.setAuth(data.user), + error: () => this.purgeAuth() + }); + this._subcriptions.push(this._user); + } else { + // Remove any potential remnants of previous auth states + this.purgeAuth(); + } + } + + setAuth(user: User) { + // Save JWT sent from server in localstorage + this.jwtService.saveToken(user.token); + // Set current user data into observable + this.currentUserSubject.next(user); + // Set isAuthenticated to true + this.isAuthenticatedSubject.next(true); + } + + purgeAuth() { + // Remove JWT from localstorage + this.jwtService.destroyToken(); + // Set current user to an empty object + this.currentUserSubject.next({} as User); + // Set auth status to false + this.isAuthenticatedSubject.next(false); + } + + attemptAuth(type: string, credentials?: { email: string; password: string; }): Observable<{ user: User }> { + const route = (type === 'login') ? '/login' : ''; + const user$: Observable<{ user: User }> = this.http.post<{ user: User }>(`${this._apiDomain}/user${route}`, { user: credentials }); + /*return user$.pipe(map( + (data: any) => { + this.setAuth(data.user); + return data; + } + ));*/ + return user$.pipe(tap(({ user }) => this.setAuth(user))); + } + + getCurrentUser(): User { + return this.currentUserSubject.value; + } + + canAdministrate(): boolean { + return (this.currentUserSubject.value.role == 'Admin') ? true : false; + } + + // Update the user on the server (email, pass, etc) + update(user: Partial): Observable<{ user: User }> { + return this.http.put<{ user: User }>(`${this._apiDomain}/user`, { user }).pipe( + tap(({ user }) => { + this.currentUserSubject.next(user); + }), + ); + } + +} diff --git a/src/app/core/services/utilities.service.ts b/src/app/core/services/utilities.service.ts new file mode 100644 index 0000000..da53100 --- /dev/null +++ b/src/app/core/services/utilities.service.ts @@ -0,0 +1,548 @@ +import { Injectable } from '@angular/core'; +import { Chart } from 'chart.js'; +import { Configuration } from 'ng-chartist'; + +import { BarConfig, CircleConfig, DoughnutConfig, LineConfig } from '@models'; + +@Injectable({ providedIn: 'root' }) +export class UtilitiesService { + private _coeffKgLbs: number = 2.20462; + private _coeffFtM: number = 0.092903; + + constructor() { } + + getCoeffKgLbs(): number { + return this._coeffKgLbs; + } + + getCoeffFtM(): number { + return this._coeffFtM; + } + + getBarConfig(): Configuration { + const config: Configuration = { + type: 'Bar', + data: { + 'labels': [], + 'series': [] + }, + options: {}, + responsiveOptions: [] + }; + return config; + } + + getChartColors(): string[] { + const colors: string[] = [ + 'ct-color-a', + 'ct-color-b', + 'ct-color-c', + 'ct-color-d', + 'ct-color-e', + 'ct-color-f', + 'ct-color-g', + 'ct-color-h', + 'ct-color-i', + 'ct-color-j', + 'ct-color-k', + 'ct-color-l', + 'ct-color-m', + 'ct-color-n', + 'ct-color-o', + 'ct-color-p', + 'ct-color-q', + 'ct-color-r', + 'ct-color-s', + 'ct-color-t', + 'ct-color-u', + 'ct-color-v', + 'ct-color-w', + 'ct-color-x', + 'ct-color-y', + 'ct-color-z' + ]; + return colors; + } + + getCurrentDateFr(): string { + return new Date().toLocaleDateString('fr'); + } + + secondsToDuration(seconds: number, delimiter: string = ':'): string { + return [ + Math.floor(seconds / 60 / 60), + Math.floor(seconds / 60 % 60), + Math.floor(seconds % 60) + ].join(delimiter) + .replace(/\b(\d)\b/g, "0$1")//.replace(/^00\:/, '') + } + + getSeriesColors(opacity: number, palette: string = 'all', offset: number = 0): string[] { + let colors: string[] = []; + switch (palette) { + case 'pastels': + colors = [ + `rgba(171, 222, 230, ${opacity})`, + `rgba(203, 170, 203, ${opacity})`, + `rgba(255, 255, 181, ${opacity})`, + `rgba(255, 204, 182, ${opacity})`, + `rgba(243, 176, 195, ${opacity})`, + `rgba(198, 219, 218, ${opacity})`, + `rgba(254, 225, 232, ${opacity})`, + `rgba(254, 215, 195, ${opacity})`, + `rgba(246, 234, 194, ${opacity})`, + `rgba(236, 213, 227, ${opacity})`, + `rgba(255, 150, 138, ${opacity})`, + `rgba(255, 174, 165, ${opacity})`, + `rgba(255, 197, 191, ${opacity})`, + `rgba(255, 216, 190, ${opacity})`, + `rgba(255, 200, 162, ${opacity})`, + `rgba(212, 240, 240, ${opacity})`, + `rgba(143, 202, 202, ${opacity})`, + `rgba(204, 226, 203, ${opacity})`, + `rgba(182, 207, 182, ${opacity})`, + `rgba(151, 193, 169, ${opacity})` + ]; + break; + case 'red': + colors = [ + `rgba(163, 0, 0, ${opacity})`, + `rgba(178, 47, 25, ${opacity})`, + `rgba(192, 74, 49, ${opacity})`, + `rgba(205, 99, 72, ${opacity})`, + `rgba(217, 122, 97, ${opacity})`, + `rgba(228, 145, 122, ${opacity})`, + `rgba(238, 168, 148, ${opacity})`, + `rgba(247, 192, 175, ${opacity})`, + `rgba(255, 215, 203, ${opacity})` + ]; + break; + case 'green': + colors = [ + `rgba(0, 109, 45, ${opacity})`, + `rgba(42, 124, 64, ${opacity})`, + `rgba(67, 140, 83, ${opacity})`, + `rgba(90, 155, 102, ${opacity})`, + `rgba(112, 171, 122, ${opacity})`, + `rgba(134, 187, 142, ${opacity})`, + `rgba(156, 203, 163, ${opacity})`, + `rgba(179, 219, 184, ${opacity})`, + `rgba(201, 235, 205, ${opacity})` + ]; + break; + case 'blue': + colors = [ + `rgba(0, 76, 109, ${opacity})`, + `rgba(37, 94, 126, ${opacity})`, + `rgba(61, 112, 143, ${opacity})`, + `rgba(83, 131, 161, ${opacity})`, + `rgba(105, 150, 179, ${opacity})`, + `rgba(127, 170, 198, ${opacity})`, + `rgba(148, 190, 217, ${opacity})`, + `rgba(171, 210, 236, ${opacity})`, + `rgba(193, 231, 255, ${opacity})` + ]; + break; + case 'all': + default: + colors = [ + `rgba(53, 162, 235, ${opacity})`, + `rgba(255, 99, 132, ${opacity})`, + `rgba(75, 192, 192, ${opacity})`, + `rgba(255, 159, 64, ${opacity})`, + `rgba(153, 102, 255, ${opacity})`, + `rgba(255, 205, 86, ${opacity})`, + `rgba(201, 203, 207, ${opacity})`, + `rgba(93, 204, 137, ${opacity})`, + `rgba(181, 17, 86, ${opacity})`, + `rgba(255, 226, 5, ${opacity})`, + `rgba(191, 101, 224, ${opacity})`, + `rgba(76, 174, 76, ${opacity})`, + `rgba(237, 80, 148, ${opacity})`, + `rgba(51, 122, 183, ${opacity})`, + `rgba(253, 24, 243, ${opacity})`, + `rgba(214, 31, 31, ${opacity})`, + `rgba(0, 137, 123, ${opacity})`, + `rgba(153, 171, 180, ${opacity})`, + `rgba(205, 186, 152, ${opacity})`, + `rgba(101, 224, 184, ${opacity})`, + `rgba(2, 191, 171, ${opacity})`, + `rgba(101, 218, 224, ${opacity})`, + `rgba(161, 199, 161, ${opacity})`, + `rgba(217, 202, 174, ${opacity})`, + `rgba(151, 136, 199, ${opacity})`, + `rgba(212, 206, 112, ${opacity})`, + `rgba(32, 182, 252, ${opacity})`, + `rgba(241, 80, 80, ${opacity})`, + `rgba(2, 191, 171, ${opacity})`, + `rgba(255, 153, 0, ${opacity})`, + `rgba(101, 218, 224, ${opacity})`, + `rgba(138, 101, 224, ${opacity})`, + `rgba(0, 137, 123, ${opacity})`, + `rgba(181, 17, 86, ${opacity})`, + `rgba(93, 204, 137, ${opacity})`, + `rgba(255, 226, 5, ${opacity})`, + `rgba(191, 101, 224, ${opacity})`, + `rgba(76, 174, 76, ${opacity})`, + `rgba(51, 122, 183, ${opacity})`, + `rgba(237, 80, 148, ${opacity})`, + `rgba(253, 24, 243, ${opacity})`, + `rgba(214, 31, 31, ${opacity})`, + `rgba(153, 171, 180, ${opacity})`, + `rgba(205, 186, 152, ${opacity})`, + `rgba(101, 224, 184, ${opacity})`, + `rgba(2, 191, 171, ${opacity})`, + `rgba(101, 218, 224, ${opacity})`, + `rgba(161, 199, 161, ${opacity})`, + `rgba(217, 202, 174, ${opacity})`, + `rgba(151, 136, 199, ${opacity})`, + `rgba(212, 206, 112, ${opacity})`, + `rgba(255, 255, 255, ${opacity})` + ]; + if (offset > 0 && offset < colors.length) { + colors = colors.slice(offset); + } + break; + } + return colors; + } + + getCircleChartConfig(): CircleConfig { + const config: CircleConfig = { + circleChartLabels: [], + circleChartDatasets: [ + { + data: [], + label: 'Nombre total de sauts', + backgroundColor: this.getSeriesColors(0.8), + borderColor: this.getSeriesColors(1), // 'rgba(255, 255, 255, 1)' + borderWidth: 2 + } + ], + circleChartOptions: { + cutout: '90%', + elements: { + arc: { + //spacing: -10, + borderJoinStyle: 'round', + borderRadius: 10, + borderWidth: 0 + } + }, + plugins: { + legend: { + display: false, + position: 'left' + } + }, + responsive: true, + maintainAspectRatio: false, + animation: { + onProgress: function (this: Chart) { + const width = this.width, height = this.height, ctx = this.ctx; + const count: number = parseInt(this.data.datasets[0].data[0]!.toString()); + const diff: number = parseInt(this.data.datasets[0].data[1]!.toString()); + const total: number = (count + diff); + const percent: number = Math.round((count/total*100)); + const lineHeight = (height / 8); + ctx.restore(); + let fontSize = (height / 120).toFixed(2); + ctx.font = `${fontSize}em sans-serif`; + //ctx.textAlign = 'center'; + ctx.textBaseline = 'middle'; + ctx.fillStyle = '#dddddd'; + //const text = `${percent} % (${count} ${this.data.datasets[0].label})`, textX = Math.round((width - ctx.measureText(text).width) / 2), textY = height / 2; + let text = this.data.datasets[0].label!; + let textX = Math.round((width - ctx.measureText(text).width) / 2); + let textY = height / 2; + ctx.fillText(text, textX, (textY-lineHeight)); + text = `${percent}%`; + textX = Math.round((width - ctx.measureText(text).width) / 2); + textY = height / 2; + ctx.fillText(text, textX, textY); + + ctx.restore(); + fontSize = (height / 180).toFixed(2); + ctx.font = `${fontSize}em sans-serif`; + ctx.textBaseline = 'middle'; + ctx.fillStyle = '#dddddd'; + text = `${count} / ${total}`; + textX = Math.round((width - ctx.measureText(text).width) / 2); + textY = height / 2; + ctx.fillText(text, textX, (textY+lineHeight)); + ctx.save(); + //console.log(width, height, fontSize); + }, + onComplete: function (this: Chart) { + const width = this.width, height = this.height, ctx = this.ctx; + const count: number = parseInt(this.data.datasets[0].data[0]!.toString()); + const diff: number = parseInt(this.data.datasets[0].data[1]!.toString()); + const total: number = (count + diff); + const percent: number = Math.round((count/total*100)); + const lineHeight = (height / 8); + ctx.restore(); + let fontSize = (height / 120).toFixed(2); + ctx.font = `${fontSize}em sans-serif`; + //ctx.textAlign = 'center'; + ctx.textBaseline = 'middle'; + ctx.fillStyle = '#dddddd'; + //ctx.fillStyle = this.data!.datasets[0].backgroundColor ? this.data.datasets[0].backgroundColor[0]!.toString() : '#dddddd'; + //const text = `${percent} % (${count} ${this.data.datasets[0].label})`, textX = Math.round((width - ctx.measureText(text).width) / 2), textY = height / 2; + let text = this.data.datasets[0].label!; + let textX = Math.round((width - ctx.measureText(text).width) / 2); + let textY = height / 2; + ctx.fillText(text, textX, (textY-lineHeight)); + text = `${percent}%`; + textX = Math.round((width - ctx.measureText(text).width) / 2); + textY = height / 2; + ctx.fillText(text, textX, textY); + + ctx.restore(); + fontSize = (height / 180).toFixed(2); + ctx.font = `${fontSize}em sans-serif`; + ctx.textBaseline = 'middle'; + ctx.fillStyle = '#dddddd'; + text = `${count} / ${total}`; + textX = Math.round((width - ctx.measureText(text).width) / 2); + textY = height / 2; + ctx.fillText(text, textX, (textY+lineHeight)); + ctx.save(); + //console.log(width, height, fontSize); + }, + }, + }, + circleChartPlugins: [ + /*{ + beforeInit: (chart: Chart<"doughnut", number[], unknown>) => { + const dataset = chart.data.datasets[0]; + chart.data.labels = [dataset.label]; + dataset.data = [dataset.data[0], 100 - dataset.data[0]]; + }, + id: 'beforeinit' + },*/ + { + beforeDatasetDraw: (chart: Chart<"doughnut", number[], unknown>) => { + const width = chart.width, height = chart.height, ctx = chart.ctx; + ctx.restore(); + const fontSize = (height / 150).toFixed(2); + ctx.font = fontSize + "em sans-serif"; + ctx.fillStyle = "#ffffff"; + ctx.textBaseline = "middle"; + const text = chart.data.datasets[0].data[0] + "%", textX = Math.round((width - ctx.measureText(text).width) / 2), textY = height / 2; + ctx.fillText(text, textX, textY); + ctx.save(); + console.log(width, height, fontSize); + }, + id: 'doughnutlabel' + } + ], + circleChartLegend: false + }; + return config; + } + + getDoughnutChartConfig(): DoughnutConfig { + const config: DoughnutConfig = { + doughnutChartLabels: [], + doughnutChartDatasets: [ + { + data: [], + label: 'Nombre total de sauts', + backgroundColor: this.getSeriesColors(0.8), + borderColor: this.getSeriesColors(1), // 'rgba(255, 255, 255, 1)' + borderWidth: 2 + } + ], + doughnutChartOptions: { + elements: { + arc: { + borderWidth: 2, + } + }, + plugins: { + legend: { + display: true, + position: 'left' + } + }, + responsive: true, + maintainAspectRatio: false + }, + doughnutChartLegend: false + }; + return config; + } + + getBarChartConfig(): BarConfig { + const config: BarConfig = { + barChartData: { + labels: [''], + datasets: [] + }, + barChartOptions: { + plugins: { + legend: { + display: true, + position: 'top' + } + }, + elements: { + bar: { + borderWidth: 1, + } + }, + /*interaction: { + intersect: false, + axis: 'x' + },*/ + scales: { + x: { + display: false, + beginAtZero: true, + ticks: { color: 'rgba(255,255,255,0.3)' }, + grid: { display: true, color: 'rgba(255,255,255,0.1)', tickBorderDash: [1,2], tickBorderDashOffset: 2 } + }, + y: { + display: true, + beginAtZero: true, + ticks: { color: 'rgba(255,255,255,0.3)' }, + grid: { display: true, color: 'rgba(255,255,255,0.2)', tickBorderDash: [1,2], tickBorderDashOffset: 2 } + } + }, + responsive: true, + maintainAspectRatio: false + }, + barChartPlugins: [], + barChartLegend: true + }; + return config; + } + + getHorizontalBarChartConfig(): BarConfig { + const config: BarConfig = { + barChartData: { + labels: [''], + datasets: [] + }, + barChartOptions: { + indexAxis: 'y', + elements: { + bar: { + borderWidth: 1, + } + }, + plugins: { + legend: { + display: true, + position: 'left' + }, + title: { + display: false, + text: 'Nombre total de sauts' + } + }, + responsive: true, + aspectRatio: 3, + scales: { + x: { + beginAtZero: true, + ticks: { color: 'rgba(255,255,255,0.3)' }, + grid: { display: true, color: 'rgba(255,255,255,0.1)', tickBorderDash: [1,2] } + }, + y: { + beginAtZero: true, + ticks: { color: 'rgba(255,255,255,0.3)' }, + grid: { display: false, color: 'rgba(255,255,255,0.2)' } + } + } + }, + barChartPlugins: [], + barChartLegend: false + }; + return config; + } + + getLineChartConfig(): LineConfig { + const config: LineConfig = { + lineChartData: { + labels: [], + datasets: [] + }, + lineChartOptions: { + plugins: { + legend: { + display: true, + position: 'top' + } + }, + /*interaction: { + intersect: false, + axis: 'x' + },*/ + scales: { + x: { + display: true, + beginAtZero: true, + ticks: { color: 'rgba(255,255,255,0.3)' }, + grid: { display: true, color: 'rgba(255,255,255,0.1)', tickBorderDash: [1,2], tickBorderDashOffset: 2 } + }, + y: { + display: true, + beginAtZero: true, + ticks: { color: 'rgba(255,255,255,0.3)' }, + grid: { display: true, color: 'rgba(255,255,255,0.2)', tickBorderDash: [1,2], tickBorderDashOffset: 2 } + } + }, + responsive: true, + maintainAspectRatio: false + }, + lineChartLegend: true + }; + return config; + } + + getMonthsList(): Array { + return ['Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre']; + } + + getStackedLineAreaChartConfig(): LineConfig { + const config: LineConfig = { + lineChartData: { + labels: [], + datasets: [] + }, + lineChartOptions: { + plugins: { + legend: { + display: true, + position: 'top' + } + }, + interaction: { + mode: 'nearest', + axis: 'x', + intersect: false + }, + scales: { + x: { + display: true, + beginAtZero: true, + ticks: { color: 'rgba(255,255,255,0.3)' }, + grid: { display: true, color: 'rgba(255,255,255,0.1)', tickBorderDash: [1,2] } + }, + y: { + display: true, + beginAtZero: true, + stacked: true, + ticks: { color: 'rgba(255,255,255,0.3)' }, + grid: { display: true, color: 'rgba(255,255,255,0.2)', tickBorderDash: [1,2] } + } + }, + responsive: true, + maintainAspectRatio: false + }, + lineChartLegend: true + }; + return config; + } +} diff --git a/src/app/core/viewmodels/herowars/clan.viewmodel.ts b/src/app/core/viewmodels/herowars/clan.viewmodel.ts new file mode 100644 index 0000000..0aaa8bd --- /dev/null +++ b/src/app/core/viewmodels/herowars/clan.viewmodel.ts @@ -0,0 +1,131 @@ +import { HWGuildClan } from '@models'; + +export class ClanViewModel { + clan: HWGuildClan; + + constructor(clan: HWGuildClan) { + this.clan = clan; + } + + getTitle(): string { + return this.clan.title; + } + + getServer(): string { + return this.clan.serverId; + } + + getMembersCount(): string { + return this.clan.membersCount; + } + + getCountry(): string { + return this.clan.country; + } + + getDescription(): string { + return this.clan.description; + } + + getLevel(): string { + return this.clan.level; + } + + getMinLevel(): string { + return this.clan.minLevel; + } + + getTopActivity(): number { + return +this.clan.topActivity; + } + + getTopDungeon(): number { + return +this.clan.topDungeon; + } + + getDisbanding(): boolean { + return this.clan.disbanding; + } + + getFrameId(): number { + return this.clan.frameId; + } + + getOwnerId(): string { + return this.clan.ownerId; + } +} + +export class ClansViewModel { + clans: ClanViewModel[]; + + constructor(clans: HWGuildClan[]) { + this.clans = clans.map(clan => new ClanViewModel(clan)); + } + + getClans(): ClanViewModel[] { + return this.clans; + } + + getClanCount(): number { + return this.clans.length; + } + + getClanByTitle(title: string): ClanViewModel | undefined { + return this.clans.find(clan => clan.getTitle() === title); + } + + getClansByCountry(country: string): ClanViewModel[] { + return this.clans.filter(clan => clan.getCountry() === country); + } + + getClansByServer(server: string): ClanViewModel[] { + return this.clans.filter(clan => clan.getServer() === server); + } + + getClansByLevel(level: string): ClanViewModel[] { + return this.clans.filter(clan => clan.getLevel() === level); + } + + getDisbandingClans(): ClanViewModel[] { + return this.clans.filter(clan => clan.getDisbanding()); + } + + getActiveDisbands(): ClanViewModel[] { + return this.clans.filter(clan => !clan.getDisbanding()); + } + + getClansByOwnerId(ownerId: string): ClanViewModel[] { + return this.clans.filter(clan => clan.getOwnerId() === ownerId); + } + + getClansByMinLevel(minLevel: string): ClanViewModel[] { + return this.clans.filter(clan => clan.getMinLevel() === minLevel); + } + + getAverageTopActivity(): number { + if (this.clans.length === 0) { + return 0; + } + const totalActivity = this.clans.reduce((sum, clan) => { + const activity = clan.getTopActivity() || 0; + return sum + activity; + }, 0); + return totalActivity / this.clans.length; + } + + getAverageTopDungeon(): number { + if (this.clans.length === 0) { + return 0; + } + const totalDungeon = this.clans.reduce((sum, clan) => { + const dungeon = clan.getTopDungeon() || 0; + return sum + dungeon; + }, 0); + return totalDungeon / this.clans.length; + } + + getClansByCountryAndServer(country: string, server: string): ClanViewModel[] { + return this.clans.filter(clan => clan.getCountry() === country && clan.getServer() === server); + } +} diff --git a/src/app/core/viewmodels/herowars/index.ts b/src/app/core/viewmodels/herowars/index.ts new file mode 100644 index 0000000..57818a3 --- /dev/null +++ b/src/app/core/viewmodels/herowars/index.ts @@ -0,0 +1,2 @@ +export * from './clan.viewmodel'; +export * from './members.viewmodel'; diff --git a/src/app/core/viewmodels/herowars/members.viewmodel.ts b/src/app/core/viewmodels/herowars/members.viewmodel.ts new file mode 100644 index 0000000..e66443a --- /dev/null +++ b/src/app/core/viewmodels/herowars/members.viewmodel.ts @@ -0,0 +1,209 @@ +import { + HWMember, HWMemberStat, HWWeekStat, + HWGuildRaid, HWMemberHeroes, HWMemberTitans +} from '@models'; + +export class MemberViewModel { + member: HWMember; + + constructor(member: HWMember) { + this.member = member; + } + + getId(): string { + return this.member.id; + } + + getName(): string { + return this.member.name; + } + + getClanTitle(): string { + return this.member.clanTitle; + } + + getServerId(): string { + return this.member.serverId; + } + + getLastLoginTime(): string { + return this.member.lastLoginTime; + } + + getLevel(): string { + return this.member.level; + } + + getAllowPm(): string { + return this.member.allowPm; + } + + getAvatarId(): string { + return this.member.avatarId; + } + + getClanIcon() { + return this.member.clanIcon; + } + + getClanId(): string { + return this.member.clanId; + } + + getClanRole(): string { + return this.member.clanRole; + } + + isCommander(): boolean { + return this.member.commander; + } + + getFrameId(): number { + return this.member.frameId; + } + + isChatModerator(): boolean { + return this.member.isChatModerator; + } + + getLeagueId(): number { + return this.member.leagueId; + } + + canShowProfile(): boolean { + return this.member.showProfile; + } + + isChampion(): boolean { + return this.member.champion; + } + + getMemberHeroes(): HWMemberHeroes { + return this.member.heroes; + } + + getMemberTitans(): HWMemberTitans { + return this.member.titans; + } + + getStat(): HWMemberStat { + return this.member.stat; + } + + getInactivity() { + return this.member.inactivity; + } + + getAdventureSum(): number { + return this.member.adventureSum; + } + + getClanGiftsSum(): number { + return this.member.clanGiftsSum; + } + + getClanWarSum(): number { + return this.member.clanWarSum; + } + + getWeekStat(): HWWeekStat { + return this.member.weekStat; + } + + getScore(): number { + return this.member.score; + } + + getScoreGifts(): number { + return this.member.scoreGifts; + } + + getWarGifts(): number { + return this.member.warGifts; + } + + getRewards(): number { + return this.member.rewards; + } + + getRaids(): HWGuildRaid[] { + return this.member.raids; + } + + getRaidsInfo() { + return this.member.raidsInfo; + } +} + +export class MembersViewModel { + members: MemberViewModel[]; + + constructor(members: HWMember[]) { + this.members = members.map(member => new MemberViewModel(member)); + } + + getMembers(): MemberViewModel[] { + return this.members; + } + + getMemberCount(): number { + return this.members.length; + } + + getMemberById(id: string): MemberViewModel | undefined { + return this.members.find(member => member.getId() === id); + } + + getMemberByName(name: string): MemberViewModel | undefined { + return this.members.find(member => member.getName() === name); + } + + getMembersByClanRole(clanRole: string): MemberViewModel[] { + return this.members.filter(member => member.getClanRole() === clanRole); + } + + getCommandeurs(): MemberViewModel[] { + return this.members.filter(member => member.isCommander()); + } + + getChampions(): MemberViewModel[] { + return this.members.filter(member => member.isChampion()); + } + + getMembersByLevel(level: string): MemberViewModel[] { + return this.members.filter(member => member.getLevel() === level); + } + + getMembersWithLowestScore(): MemberViewModel[] { + if (this.members.length === 0) return []; + const minScore = Math.min(...this.members.map(m => m.getScore())); + return this.members.filter(member => member.getScore() === minScore); + } + + getMembersWithHighestScore(): MemberViewModel[] { + if (this.members.length === 0) return []; + const maxScore = Math.max(...this.members.map(m => m.getScore())); + return this.members.filter(member => member.getScore() === maxScore); + } + + getTotalScore(): number { + return this.members.reduce((sum, member) => sum + member.getScore(), 0); + } + + getAverageScore(): number { + if (this.members.length === 0) return 0; + return this.getTotalScore() / this.members.length; + } + + getTotalAdventureSum(): number { + return this.members.reduce((sum, member) => sum + member.getAdventureSum(), 0); + } + + getTotalClanWarSum(): number { + return this.members.reduce((sum, member) => sum + member.getClanWarSum(), 0); + } + + getTotalClanGiftsSum(): number { + return this.members.reduce((sum, member) => sum + member.getClanGiftsSum(), 0); + } +} diff --git a/src/app/core/viewmodels/index.ts b/src/app/core/viewmodels/index.ts new file mode 100644 index 0000000..1b87bda --- /dev/null +++ b/src/app/core/viewmodels/index.ts @@ -0,0 +1 @@ +export * from './herowars/'; diff --git a/src/app/routes/auth.routes.ts b/src/app/routes/auth.routes.ts new file mode 100644 index 0000000..946f118 --- /dev/null +++ b/src/app/routes/auth.routes.ts @@ -0,0 +1,179 @@ +import { Routes } from '@angular/router'; + +import { + AeronefsComponent, CalculatorComponent, CanopiesComponent, CredentialsComponent, + HerowarsComponent, HerowarsGuildraidComponent, HerowarsGuildwarComponent, + DashboardComponent, DemoComponent, DropzonesComponent, JumpComponent, JumpsComponent, + LogbookComponent, PageComponent, PagesComponent, ProductComponent, ProductsComponent, ProfileComponent, QcmComponent, SettingsComponent +} from '@components'; +import { authGuard, adminGuard } from '@guards'; +import { + aeronefsPageResolver, articleResolver, articlesResolver, authResolver, canopiesPageResolver, dropZonesPageResolver, + jumpResolver, jumpsPageResolver, lastjumpResolver, productResolver, productsResolver, profileResolver, qcmResolver +} from '@resolvers'; + +export const AUTH_ROUTES: Routes = [ + { + path: 'demo', + component: DemoComponent, + canActivate: [ authGuard ] + }, + { + path: 'herowars', + component: HerowarsComponent, + canActivate: [ authGuard ] + }, + { + path: 'herowars/guildwar', + component: HerowarsGuildwarComponent, + canActivate: [ authGuard ] + }, + { + path: 'herowars/guildraid', + component: HerowarsGuildraidComponent, + canActivate: [ authGuard ] + }, + { + path: 'page/:slug', + component: PageComponent, + canActivate: [ authGuard ], + resolve: { + pageData: articleResolver + } + }, + { + path: 'pages', + component: PagesComponent, + canActivate: [ authGuard ], + resolve: { + pageData: articlesResolver + } + }, + { + path: 'product/:slug', + component: ProductComponent, + canActivate: [ authGuard ], + resolve: { + pageData: productResolver + } + }, + { + path: 'products/:category', + component: ProductsComponent, + canActivate: [ authGuard ], + resolve: { + pageData: productsResolver + } + }, + { + path: 'products', + component: ProductsComponent, + canActivate: [ authGuard ], + resolve: { + pageData: productsResolver + } + }, + { + path: 'profile', + component: ProfileComponent, + canActivate: [ authGuard ], + children: [ + { + path: ':username', + component: ProfileComponent, + canActivate: [ authGuard ], + resolve: { + profile: profileResolver + } + } + ] + }, + { + path: 'qcm/:type', + component: QcmComponent, + canActivate: [ authGuard ], + resolve: { + qcm: qcmResolver + } + }, + { + path: 'settings', + component: SettingsComponent, + canActivate: [ authGuard ] + }, + { + path: 'settings/credentials', + component: CredentialsComponent, + canActivate: [ authGuard ] + }, + { + path: 'skydive', + component: DemoComponent, + canActivate: [ authGuard ] + }, + { + path: 'skydive/aeronefs', + component: AeronefsComponent, + canActivate: [ authGuard, adminGuard ], + resolve: { + aeronefsPageData: aeronefsPageResolver + } + }, + { + path: 'skydive/calculator', + component: CalculatorComponent, + canActivate: [ authGuard ], + resolve: { + isAuthenticated: authResolver + } + }, + { + path: 'skydive/canopies', + component: CanopiesComponent, + canActivate: [ authGuard, adminGuard ], + resolve: { + canopiesPageData: canopiesPageResolver + } + }, + { + path: 'skydive/dashboard', + component: DashboardComponent, + canActivate: [ authGuard, adminGuard ], + resolve: { + isAuthenticated: authResolver + } + }, + { + path: 'skydive/dropzones', + component: DropzonesComponent, + canActivate: [ authGuard, adminGuard ], + resolve: { + dropZonesPageData: dropZonesPageResolver + } + }, + { + path: 'skydive/jumps', + component: JumpsComponent, + canActivate: [ authGuard, adminGuard ], + resolve: { + pageData: jumpsPageResolver + } + }, + { + path: 'skydive/jump/:slug', + component: JumpComponent, + canActivate: [ authGuard, adminGuard ], + resolve: { + pageData: jumpResolver + } + }, + { + path: 'skydive/logbook', + component: LogbookComponent, + canActivate: [ authGuard, adminGuard ], + resolve: { + isAuthenticated: authResolver, + lastjump: lastjumpResolver + } + } +]; \ No newline at end of file diff --git a/src/app/routes/index.ts b/src/app/routes/index.ts new file mode 100644 index 0000000..b6f32e0 --- /dev/null +++ b/src/app/routes/index.ts @@ -0,0 +1,2 @@ +export * from './auth.routes'; +export * from './noauth.routes'; \ No newline at end of file diff --git a/src/app/routes/noauth.routes.ts b/src/app/routes/noauth.routes.ts new file mode 100644 index 0000000..f4e7e89 --- /dev/null +++ b/src/app/routes/noauth.routes.ts @@ -0,0 +1,51 @@ +import { Routes } from '@angular/router'; + +import { AuthComponent, HomeComponent, PageComponent, PagesComponent, ProductComponent } from '@components'; +import { noauthGuard } from '@guards'; +import { articleResolver, articlesResolver, productResolver } from '@resolvers'; + +export const NOAUTH_ROUTES: Routes = [ + { + path: 'home', + component: HomeComponent + }, + { + path: 'login', + component: AuthComponent, + canActivate: [ noauthGuard ] + }, + { + path: 'register', + component: AuthComponent, + canActivate: [ noauthGuard ] + }, + { + path: 'pages', + component: PagesComponent, + canActivate: [ noauthGuard ], + resolve: { + pageData: articlesResolver + } + }, + { + path: 'page/:slug', + component: PageComponent, + canActivate: [ noauthGuard ], + resolve: { + pageData: articleResolver + } + }, + { + path: 'product/:slug', + component: ProductComponent, + canActivate: [ noauthGuard ], + resolve: { + pageData: productResolver + } + }, + { + path: '', + redirectTo: 'home', + pathMatch: 'full' + } +]; \ No newline at end of file diff --git a/src/assets/.gitkeep b/src/assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/assets/favicon/android-icon-144x144.png b/src/assets/favicon/android-icon-144x144.png new file mode 100644 index 0000000..1756cfa Binary files /dev/null and b/src/assets/favicon/android-icon-144x144.png differ diff --git a/src/assets/favicon/android-icon-192x192.png b/src/assets/favicon/android-icon-192x192.png new file mode 100644 index 0000000..005b8be Binary files /dev/null and b/src/assets/favicon/android-icon-192x192.png differ diff --git a/src/assets/favicon/android-icon-36x36.png b/src/assets/favicon/android-icon-36x36.png new file mode 100644 index 0000000..7950d61 Binary files /dev/null and b/src/assets/favicon/android-icon-36x36.png differ diff --git a/src/assets/favicon/android-icon-48x48.png b/src/assets/favicon/android-icon-48x48.png new file mode 100644 index 0000000..478ee74 Binary files /dev/null and b/src/assets/favicon/android-icon-48x48.png differ diff --git a/src/assets/favicon/android-icon-72x72.png b/src/assets/favicon/android-icon-72x72.png new file mode 100644 index 0000000..d1afc2a Binary files /dev/null and b/src/assets/favicon/android-icon-72x72.png differ diff --git a/src/assets/favicon/android-icon-96x96.png b/src/assets/favicon/android-icon-96x96.png new file mode 100644 index 0000000..5fbc574 Binary files /dev/null and b/src/assets/favicon/android-icon-96x96.png differ diff --git a/src/assets/favicon/apple-icon-114x114.png b/src/assets/favicon/apple-icon-114x114.png new file mode 100644 index 0000000..2144585 Binary files /dev/null and b/src/assets/favicon/apple-icon-114x114.png differ diff --git a/src/assets/favicon/apple-icon-120x120.png b/src/assets/favicon/apple-icon-120x120.png new file mode 100644 index 0000000..4de33fb Binary files /dev/null and b/src/assets/favicon/apple-icon-120x120.png differ diff --git a/src/assets/favicon/apple-icon-144x144.png b/src/assets/favicon/apple-icon-144x144.png new file mode 100644 index 0000000..1756cfa Binary files /dev/null and b/src/assets/favicon/apple-icon-144x144.png differ diff --git a/src/assets/favicon/apple-icon-152x152.png b/src/assets/favicon/apple-icon-152x152.png new file mode 100644 index 0000000..dd139b0 Binary files /dev/null and b/src/assets/favicon/apple-icon-152x152.png differ diff --git a/src/assets/favicon/apple-icon-180x180.png b/src/assets/favicon/apple-icon-180x180.png new file mode 100644 index 0000000..1a2bdd5 Binary files /dev/null and b/src/assets/favicon/apple-icon-180x180.png differ diff --git a/src/assets/favicon/apple-icon-57x57.png b/src/assets/favicon/apple-icon-57x57.png new file mode 100644 index 0000000..c67eb88 Binary files /dev/null and b/src/assets/favicon/apple-icon-57x57.png differ diff --git a/src/assets/favicon/apple-icon-60x60.png b/src/assets/favicon/apple-icon-60x60.png new file mode 100644 index 0000000..8b7b2e9 Binary files /dev/null and b/src/assets/favicon/apple-icon-60x60.png differ diff --git a/src/assets/favicon/apple-icon-72x72.png b/src/assets/favicon/apple-icon-72x72.png new file mode 100644 index 0000000..d1afc2a Binary files /dev/null and b/src/assets/favicon/apple-icon-72x72.png differ diff --git a/src/assets/favicon/apple-icon-76x76.png b/src/assets/favicon/apple-icon-76x76.png new file mode 100644 index 0000000..341eb7b Binary files /dev/null and b/src/assets/favicon/apple-icon-76x76.png differ diff --git a/src/assets/favicon/apple-icon-precomposed.png b/src/assets/favicon/apple-icon-precomposed.png new file mode 100644 index 0000000..d60cb69 Binary files /dev/null and b/src/assets/favicon/apple-icon-precomposed.png differ diff --git a/src/assets/favicon/apple-icon.png b/src/assets/favicon/apple-icon.png new file mode 100644 index 0000000..d60cb69 Binary files /dev/null and b/src/assets/favicon/apple-icon.png differ diff --git a/src/assets/favicon/browserconfig.xml b/src/assets/favicon/browserconfig.xml new file mode 100644 index 0000000..d4a6c5d --- /dev/null +++ b/src/assets/favicon/browserconfig.xml @@ -0,0 +1,11 @@ + + + + + + + + #da532c + + + \ No newline at end of file diff --git a/src/assets/favicon/favicon-128x128.png b/src/assets/favicon/favicon-128x128.png new file mode 100644 index 0000000..1f91574 Binary files /dev/null and b/src/assets/favicon/favicon-128x128.png differ diff --git a/src/assets/favicon/favicon-144x144.png b/src/assets/favicon/favicon-144x144.png new file mode 100644 index 0000000..016eb0f Binary files /dev/null and b/src/assets/favicon/favicon-144x144.png differ diff --git a/src/assets/favicon/favicon-152x152.png b/src/assets/favicon/favicon-152x152.png new file mode 100644 index 0000000..59410fb Binary files /dev/null and b/src/assets/favicon/favicon-152x152.png differ diff --git a/src/assets/favicon/favicon-16x16.png b/src/assets/favicon/favicon-16x16.png new file mode 100644 index 0000000..09101e0 Binary files /dev/null and b/src/assets/favicon/favicon-16x16.png differ diff --git a/src/assets/favicon/favicon-192x192.png b/src/assets/favicon/favicon-192x192.png new file mode 100644 index 0000000..94ce3c3 Binary files /dev/null and b/src/assets/favicon/favicon-192x192.png differ diff --git a/src/assets/favicon/favicon-32x32.png b/src/assets/favicon/favicon-32x32.png new file mode 100644 index 0000000..01cc8b1 Binary files /dev/null and b/src/assets/favicon/favicon-32x32.png differ diff --git a/src/assets/favicon/favicon-384x384.png b/src/assets/favicon/favicon-384x384.png new file mode 100644 index 0000000..e1b4663 Binary files /dev/null and b/src/assets/favicon/favicon-384x384.png differ diff --git a/src/assets/favicon/favicon-512x512.png b/src/assets/favicon/favicon-512x512.png new file mode 100644 index 0000000..e5c7e6d Binary files /dev/null and b/src/assets/favicon/favicon-512x512.png differ diff --git a/src/assets/favicon/favicon-72x72.png b/src/assets/favicon/favicon-72x72.png new file mode 100644 index 0000000..8792849 Binary files /dev/null and b/src/assets/favicon/favicon-72x72.png differ diff --git a/src/assets/favicon/favicon-96x96.png b/src/assets/favicon/favicon-96x96.png new file mode 100644 index 0000000..6224b2c Binary files /dev/null and b/src/assets/favicon/favicon-96x96.png differ diff --git a/src/assets/favicon/favicon.ico b/src/assets/favicon/favicon.ico new file mode 100644 index 0000000..2ebd85f Binary files /dev/null and b/src/assets/favicon/favicon.ico differ diff --git a/src/assets/favicon/favicon.png b/src/assets/favicon/favicon.png new file mode 100644 index 0000000..e5c7e6d Binary files /dev/null and b/src/assets/favicon/favicon.png differ diff --git a/src/assets/favicon/favicon.svg b/src/assets/favicon/favicon.svg new file mode 100644 index 0000000..de151f1 --- /dev/null +++ b/src/assets/favicon/favicon.svg @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/src/assets/favicon/ms-icon-144x144.png b/src/assets/favicon/ms-icon-144x144.png new file mode 100644 index 0000000..1756cfa Binary files /dev/null and b/src/assets/favicon/ms-icon-144x144.png differ diff --git a/src/assets/favicon/ms-icon-150x150.png b/src/assets/favicon/ms-icon-150x150.png new file mode 100644 index 0000000..af3a104 Binary files /dev/null and b/src/assets/favicon/ms-icon-150x150.png differ diff --git a/src/assets/favicon/ms-icon-310x310.png b/src/assets/favicon/ms-icon-310x310.png new file mode 100644 index 0000000..791acef Binary files /dev/null and b/src/assets/favicon/ms-icon-310x310.png differ diff --git a/src/assets/favicon/ms-icon-70x70.png b/src/assets/favicon/ms-icon-70x70.png new file mode 100644 index 0000000..c7185e6 Binary files /dev/null and b/src/assets/favicon/ms-icon-70x70.png differ diff --git a/src/assets/icons/favicon.ico b/src/assets/icons/favicon.ico new file mode 100644 index 0000000..57614f9 Binary files /dev/null and b/src/assets/icons/favicon.ico differ diff --git a/src/assets/icons/icon-128x128.png b/src/assets/icons/icon-128x128.png new file mode 100644 index 0000000..9f9241f Binary files /dev/null and b/src/assets/icons/icon-128x128.png differ diff --git a/src/assets/icons/icon-144x144.png b/src/assets/icons/icon-144x144.png new file mode 100644 index 0000000..4a5f8c1 Binary files /dev/null and b/src/assets/icons/icon-144x144.png differ diff --git a/src/assets/icons/icon-152x152.png b/src/assets/icons/icon-152x152.png new file mode 100644 index 0000000..34a1a8d Binary files /dev/null and b/src/assets/icons/icon-152x152.png differ diff --git a/src/assets/icons/icon-192x192.png b/src/assets/icons/icon-192x192.png new file mode 100644 index 0000000..9172e5d Binary files /dev/null and b/src/assets/icons/icon-192x192.png differ diff --git a/src/assets/icons/icon-384x384.png b/src/assets/icons/icon-384x384.png new file mode 100644 index 0000000..e54e8d3 Binary files /dev/null and b/src/assets/icons/icon-384x384.png differ diff --git a/src/assets/icons/icon-512x512.png b/src/assets/icons/icon-512x512.png new file mode 100644 index 0000000..51ee297 Binary files /dev/null and b/src/assets/icons/icon-512x512.png differ diff --git a/src/assets/icons/icon-72x72.png b/src/assets/icons/icon-72x72.png new file mode 100644 index 0000000..2814a3f Binary files /dev/null and b/src/assets/icons/icon-72x72.png differ diff --git a/src/assets/icons/icon-96x96.png b/src/assets/icons/icon-96x96.png new file mode 100644 index 0000000..d271025 Binary files /dev/null and b/src/assets/icons/icon-96x96.png differ diff --git a/src/assets/images/avatars/animal_001.jpg b/src/assets/images/avatars/animal_001.jpg new file mode 100644 index 0000000..2b43754 Binary files /dev/null and b/src/assets/images/avatars/animal_001.jpg differ diff --git a/src/assets/images/avatars/animal_002.jpg b/src/assets/images/avatars/animal_002.jpg new file mode 100644 index 0000000..1f21a93 Binary files /dev/null and b/src/assets/images/avatars/animal_002.jpg differ diff --git a/src/assets/images/avatars/animal_003.jpg b/src/assets/images/avatars/animal_003.jpg new file mode 100644 index 0000000..c061e18 Binary files /dev/null and b/src/assets/images/avatars/animal_003.jpg differ diff --git a/src/assets/images/avatars/animal_004.jpg b/src/assets/images/avatars/animal_004.jpg new file mode 100644 index 0000000..2686212 Binary files /dev/null and b/src/assets/images/avatars/animal_004.jpg differ diff --git a/src/assets/images/avatars/animal_005.jpg b/src/assets/images/avatars/animal_005.jpg new file mode 100644 index 0000000..e7a6b08 Binary files /dev/null and b/src/assets/images/avatars/animal_005.jpg differ diff --git a/src/assets/images/avatars/animal_006.jpg b/src/assets/images/avatars/animal_006.jpg new file mode 100644 index 0000000..e77da7a Binary files /dev/null and b/src/assets/images/avatars/animal_006.jpg differ diff --git a/src/assets/images/avatars/animal_007.jpg b/src/assets/images/avatars/animal_007.jpg new file mode 100644 index 0000000..e8b844a Binary files /dev/null and b/src/assets/images/avatars/animal_007.jpg differ diff --git a/src/assets/images/avatars/animal_008.jpg b/src/assets/images/avatars/animal_008.jpg new file mode 100644 index 0000000..ea09988 Binary files /dev/null and b/src/assets/images/avatars/animal_008.jpg differ diff --git a/src/assets/images/avatars/animal_009.jpg b/src/assets/images/avatars/animal_009.jpg new file mode 100644 index 0000000..6e25617 Binary files /dev/null and b/src/assets/images/avatars/animal_009.jpg differ diff --git a/src/assets/images/avatars/animal_010.jpg b/src/assets/images/avatars/animal_010.jpg new file mode 100644 index 0000000..387b181 Binary files /dev/null and b/src/assets/images/avatars/animal_010.jpg differ diff --git a/src/assets/images/avatars/animal_011.jpg b/src/assets/images/avatars/animal_011.jpg new file mode 100644 index 0000000..b51d80a Binary files /dev/null and b/src/assets/images/avatars/animal_011.jpg differ diff --git a/src/assets/images/avatars/animal_012.jpg b/src/assets/images/avatars/animal_012.jpg new file mode 100644 index 0000000..3a9a084 Binary files /dev/null and b/src/assets/images/avatars/animal_012.jpg differ diff --git a/src/assets/images/avatars/animal_013.jpg b/src/assets/images/avatars/animal_013.jpg new file mode 100644 index 0000000..e244959 Binary files /dev/null and b/src/assets/images/avatars/animal_013.jpg differ diff --git a/src/assets/images/avatars/animal_014.jpg b/src/assets/images/avatars/animal_014.jpg new file mode 100644 index 0000000..91c87b6 Binary files /dev/null and b/src/assets/images/avatars/animal_014.jpg differ diff --git a/src/assets/images/avatars/animal_015.jpg b/src/assets/images/avatars/animal_015.jpg new file mode 100644 index 0000000..3b57ac2 Binary files /dev/null and b/src/assets/images/avatars/animal_015.jpg differ diff --git a/src/assets/images/avatars/animal_016.jpg b/src/assets/images/avatars/animal_016.jpg new file mode 100644 index 0000000..22bba49 Binary files /dev/null and b/src/assets/images/avatars/animal_016.jpg differ diff --git a/src/assets/images/avatars/default.jpg b/src/assets/images/avatars/default.jpg new file mode 100644 index 0000000..2b43754 Binary files /dev/null and b/src/assets/images/avatars/default.jpg differ diff --git a/src/assets/images/background/bg-picture_000.jpg b/src/assets/images/background/bg-picture_000.jpg new file mode 100644 index 0000000..f838b3c Binary files /dev/null and b/src/assets/images/background/bg-picture_000.jpg differ diff --git a/src/assets/images/background/bg-picture_001.jpg b/src/assets/images/background/bg-picture_001.jpg new file mode 100644 index 0000000..0f62915 Binary files /dev/null and b/src/assets/images/background/bg-picture_001.jpg differ diff --git a/src/assets/images/background/bg-picture_002.jpg b/src/assets/images/background/bg-picture_002.jpg new file mode 100644 index 0000000..19a20ef Binary files /dev/null and b/src/assets/images/background/bg-picture_002.jpg differ diff --git a/src/assets/images/background/bg-picture_003.jpg b/src/assets/images/background/bg-picture_003.jpg new file mode 100644 index 0000000..55eee78 Binary files /dev/null and b/src/assets/images/background/bg-picture_003.jpg differ diff --git a/src/assets/images/background/bg-picture_004.jpg b/src/assets/images/background/bg-picture_004.jpg new file mode 100644 index 0000000..10024be Binary files /dev/null and b/src/assets/images/background/bg-picture_004.jpg differ diff --git a/src/assets/images/background/bg-picture_005.jpg b/src/assets/images/background/bg-picture_005.jpg new file mode 100644 index 0000000..60c9d1d Binary files /dev/null and b/src/assets/images/background/bg-picture_005.jpg differ diff --git a/src/assets/images/background/bg-picture_006.jpg b/src/assets/images/background/bg-picture_006.jpg new file mode 100644 index 0000000..e8dbb8b Binary files /dev/null and b/src/assets/images/background/bg-picture_006.jpg differ diff --git a/src/assets/images/background/bg-picture_007.jpg b/src/assets/images/background/bg-picture_007.jpg new file mode 100644 index 0000000..72f758e Binary files /dev/null and b/src/assets/images/background/bg-picture_007.jpg differ diff --git a/src/assets/images/background/bg-picture_008.jpg b/src/assets/images/background/bg-picture_008.jpg new file mode 100644 index 0000000..35096b3 Binary files /dev/null and b/src/assets/images/background/bg-picture_008.jpg differ diff --git a/src/assets/images/background/bg-picture_009.jpg b/src/assets/images/background/bg-picture_009.jpg new file mode 100644 index 0000000..2ef6767 Binary files /dev/null and b/src/assets/images/background/bg-picture_009.jpg differ diff --git a/src/assets/images/background/bg-picture_010.jpg b/src/assets/images/background/bg-picture_010.jpg new file mode 100644 index 0000000..eb67571 Binary files /dev/null and b/src/assets/images/background/bg-picture_010.jpg differ diff --git a/src/assets/images/background/bg-picture_011.jpg b/src/assets/images/background/bg-picture_011.jpg new file mode 100644 index 0000000..b81a231 Binary files /dev/null and b/src/assets/images/background/bg-picture_011.jpg differ diff --git a/src/assets/images/background/bg-picture_012.jpg b/src/assets/images/background/bg-picture_012.jpg new file mode 100644 index 0000000..fa71711 Binary files /dev/null and b/src/assets/images/background/bg-picture_012.jpg differ diff --git a/src/assets/images/background/bg-picture_013.jpg b/src/assets/images/background/bg-picture_013.jpg new file mode 100644 index 0000000..f7a276d Binary files /dev/null and b/src/assets/images/background/bg-picture_013.jpg differ diff --git a/src/assets/images/background/bg-picture_014.jpg b/src/assets/images/background/bg-picture_014.jpg new file mode 100644 index 0000000..4d4d2f3 Binary files /dev/null and b/src/assets/images/background/bg-picture_014.jpg differ diff --git a/src/assets/images/background/bg-picture_015.jpg b/src/assets/images/background/bg-picture_015.jpg new file mode 100644 index 0000000..c02cd6a Binary files /dev/null and b/src/assets/images/background/bg-picture_015.jpg differ diff --git a/src/assets/images/background/bg-picture_016.jpg b/src/assets/images/background/bg-picture_016.jpg new file mode 100755 index 0000000..4db376a Binary files /dev/null and b/src/assets/images/background/bg-picture_016.jpg differ diff --git a/src/assets/images/background/bg-picture_017.jpg b/src/assets/images/background/bg-picture_017.jpg new file mode 100755 index 0000000..e49cdf0 Binary files /dev/null and b/src/assets/images/background/bg-picture_017.jpg differ diff --git a/src/assets/images/background/bg-picture_018.jpg b/src/assets/images/background/bg-picture_018.jpg new file mode 100755 index 0000000..34a80cc Binary files /dev/null and b/src/assets/images/background/bg-picture_018.jpg differ diff --git a/src/assets/images/background/bg-picture_019.jpg b/src/assets/images/background/bg-picture_019.jpg new file mode 100644 index 0000000..daa680d Binary files /dev/null and b/src/assets/images/background/bg-picture_019.jpg differ diff --git a/src/assets/images/background/bg-picture_020.jpg b/src/assets/images/background/bg-picture_020.jpg new file mode 100644 index 0000000..dd67642 Binary files /dev/null and b/src/assets/images/background/bg-picture_020.jpg differ diff --git a/src/assets/images/background/bg-picture_021.jpg b/src/assets/images/background/bg-picture_021.jpg new file mode 100644 index 0000000..92728fc Binary files /dev/null and b/src/assets/images/background/bg-picture_021.jpg differ diff --git a/src/assets/images/background/bg-picture_022.png b/src/assets/images/background/bg-picture_022.png new file mode 100644 index 0000000..a5fec35 Binary files /dev/null and b/src/assets/images/background/bg-picture_022.png differ diff --git a/src/assets/images/background/bg_user.png b/src/assets/images/background/bg_user.png new file mode 100644 index 0000000..0903d2e Binary files /dev/null and b/src/assets/images/background/bg_user.png differ diff --git a/src/assets/images/background/profile-bg.jpg b/src/assets/images/background/profile-bg.jpg new file mode 100755 index 0000000..740c1cb Binary files /dev/null and b/src/assets/images/background/profile-bg.jpg differ diff --git a/src/assets/images/background/user-info.jpg b/src/assets/images/background/user-info.jpg new file mode 100755 index 0000000..b93009e Binary files /dev/null and b/src/assets/images/background/user-info.jpg differ diff --git a/src/assets/images/custom-select.png b/src/assets/images/custom-select.png new file mode 100755 index 0000000..5a5f9f4 Binary files /dev/null and b/src/assets/images/custom-select.png differ diff --git a/src/assets/images/logo-icon.png b/src/assets/images/logo-icon.png new file mode 100755 index 0000000..4ff1122 Binary files /dev/null and b/src/assets/images/logo-icon.png differ diff --git a/src/assets/images/logo-light-icon.png b/src/assets/images/logo-light-icon.png new file mode 100644 index 0000000..a9deda2 Binary files /dev/null and b/src/assets/images/logo-light-icon.png differ diff --git a/src/assets/images/logo-light-icon.svg b/src/assets/images/logo-light-icon.svg new file mode 100644 index 0000000..efe9e0b --- /dev/null +++ b/src/assets/images/logo-light-icon.svg @@ -0,0 +1,56 @@ + + + + + + diff --git a/src/assets/images/logo-light-text.png b/src/assets/images/logo-light-text.png new file mode 100644 index 0000000..26cc98c Binary files /dev/null and b/src/assets/images/logo-light-text.png differ diff --git a/src/assets/images/logo-light-text.svg b/src/assets/images/logo-light-text.svg new file mode 100644 index 0000000..4f3ba4c --- /dev/null +++ b/src/assets/images/logo-light-text.svg @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + diff --git a/src/assets/images/logo-text.png b/src/assets/images/logo-text.png new file mode 100755 index 0000000..83b3c09 Binary files /dev/null and b/src/assets/images/logo-text.png differ diff --git a/src/assets/images/logo_angular.svg b/src/assets/images/logo_angular.svg new file mode 100644 index 0000000..d8da76f --- /dev/null +++ b/src/assets/images/logo_angular.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/images/logo_headup.svg b/src/assets/images/logo_headup.svg new file mode 100644 index 0000000..139e0ae --- /dev/null +++ b/src/assets/images/logo_headup.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/assets/images/logo_headup_large.svg b/src/assets/images/logo_headup_large.svg new file mode 100644 index 0000000..3da5c60 --- /dev/null +++ b/src/assets/images/logo_headup_large.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/assets/images/logo_headup_rbw.svg b/src/assets/images/logo_headup_rbw.svg new file mode 100644 index 0000000..49110bb --- /dev/null +++ b/src/assets/images/logo_headup_rbw.svg @@ -0,0 +1,123 @@ + + + + + + + + + + diff --git a/src/assets/images/material-logo-light-icon.png b/src/assets/images/material-logo-light-icon.png new file mode 100755 index 0000000..22208dd Binary files /dev/null and b/src/assets/images/material-logo-light-icon.png differ diff --git a/src/assets/images/material-logo-light-text.png b/src/assets/images/material-logo-light-text.png new file mode 100755 index 0000000..82d84cb Binary files /dev/null and b/src/assets/images/material-logo-light-text.png differ diff --git a/src/assets/images/users/bg_solide.jpg b/src/assets/images/users/bg_solide.jpg new file mode 100644 index 0000000..0985df8 Binary files /dev/null and b/src/assets/images/users/bg_solide.jpg differ diff --git a/src/assets/images/users/bg_solide.png b/src/assets/images/users/bg_solide.png new file mode 100644 index 0000000..0903d2e Binary files /dev/null and b/src/assets/images/users/bg_solide.png differ diff --git a/src/assets/images/users/bg_user.jpg b/src/assets/images/users/bg_user.jpg new file mode 100644 index 0000000..bd780e9 Binary files /dev/null and b/src/assets/images/users/bg_user.jpg differ diff --git a/src/assets/images/users/solide.jpg b/src/assets/images/users/solide.jpg new file mode 100644 index 0000000..8f4ac92 Binary files /dev/null and b/src/assets/images/users/solide.jpg differ diff --git a/src/assets/images/users/user.jpg b/src/assets/images/users/user.jpg new file mode 100644 index 0000000..8f4ac92 Binary files /dev/null and b/src/assets/images/users/user.jpg differ diff --git a/src/assets/images/vector/ContainerA.png b/src/assets/images/vector/ContainerA.png new file mode 100644 index 0000000..392e147 Binary files /dev/null and b/src/assets/images/vector/ContainerA.png differ diff --git a/src/assets/images/vector/ContainerB.png b/src/assets/images/vector/ContainerB.png new file mode 100644 index 0000000..0d60202 Binary files /dev/null and b/src/assets/images/vector/ContainerB.png differ diff --git a/src/assets/images/vector/ContainerLength.png b/src/assets/images/vector/ContainerLength.png new file mode 100644 index 0000000..75fd2f1 Binary files /dev/null and b/src/assets/images/vector/ContainerLength.png differ diff --git a/src/assets/images/vector/Thickness.png b/src/assets/images/vector/Thickness.png new file mode 100644 index 0000000..e51f3f1 Binary files /dev/null and b/src/assets/images/vector/Thickness.png differ diff --git a/src/assets/images/vector/upt_logo.png b/src/assets/images/vector/upt_logo.png new file mode 100644 index 0000000..b541821 Binary files /dev/null and b/src/assets/images/vector/upt_logo.png differ diff --git a/src/assets/images/vector/v306_NWG_01.png b/src/assets/images/vector/v306_NWG_01.png new file mode 100644 index 0000000..b6caf21 Binary files /dev/null and b/src/assets/images/vector/v306_NWG_01.png differ diff --git a/src/assets/images/vector/v306_NWG_01.svg b/src/assets/images/vector/v306_NWG_01.svg new file mode 100644 index 0000000..199f27c --- /dev/null +++ b/src/assets/images/vector/v306_NWG_01.svg @@ -0,0 +1,11006 @@ + + + Custom Name + + + Custom Name + + + Custom + Name + + + + Custom + Name + + + + CUSTOM + NAME + + + + Custom + + + Custom + + + CUSTOM + NAME + + + + + + BACK + + FRONT + + RIGHT + + LEFT + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2 + + 5a + + 3b + + 5b + + 6a + + 6b + + 7c + + 3a + + 1a + + 1b + + 4 + + 7b + + 8b + + 7a + + 8a + + + 1c + + + + a + + b + + c + + d + + e + + f + + g + + + 2a + 4a + 1d + + 2b + + 7d + + 4b + + db + + + 2a + 1d + + 2b + + + + + 9a + + 9b + + 9c + + + 4a + 4b + + 1d + + 9a + + 9b + + 9c + + + 2a + 4a + 2b + + 4b + + 9a + + 9b + + + + 1d + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/kmls/dropzones.kml b/src/assets/kmls/dropzones.kml new file mode 100644 index 0000000..54ddc8b --- /dev/null +++ b/src/assets/kmls/dropzones.kml @@ -0,0 +1,156 @@ + + + + KmlDzFile + + + Arcachon Parachutisme + #dropzones_style + + +

]]>
+
+
+ + -1.115958,44.596408,0 + +
+ + La Réole Espace chute libre + #dropzones_style + + +

]]>
+
+
+ + -0.054606,44.566309,0 + +
+ + Soulac XLR Parachutisme + #dropzones_style + + +

]]>
+
+
+ + -1.081039,45.495395,0 + +
+ + Royan Europhénix 17 + #dropzones_style + + +

]]>
+
+
+ + -0.977096,45.632660,0 + +
+ + Rochefort Big Air Parachutisme + #dropzones_style + + +

]]>
+
+
+ + -0.984551,45.888477,0 + +
+ + Sables-d'Olonne Vendée Evasion Parachutisme + #dropzones_style + + +

]]>
+
+
+ + -1.722160,46.475393,0 + +
+ + Pamiers Parachutisme + #dropzones_style + + +

]]>
+
+
+ + 1.698546,43.091951,0 + +
+ + Pau Skydive + #dropzones_style + + +

]]>
+
+
+ + -0.288453,43.426255,0 + +
+ + Cahors Skydive + #dropzones_style + + +

]]>
+
+
+ + 1.478898,44.348635,0 + +
+ + Béni Mellal PACMA + #dropzones_style + + +

]]>
+
+
+ + -6.327999,32.394218,0 + +
+
+
diff --git a/src/assets/manifest.json b/src/assets/manifest.json new file mode 100644 index 0000000..2ce8d8d --- /dev/null +++ b/src/assets/manifest.json @@ -0,0 +1,71 @@ +{ + "name": "adastra-app", + "short_name": "adastra-app", + "theme_color": "#2c4aa3", + "background_color": "#fafafa", + "display": "standalone", + "scope": "./", + "start_url": "./", + "icons": [ + { + "src": "assets/favicon/favicon-16x16.png", + "sizes": "16x16", + "type": "image/png", + "purpose": "maskable any" + }, + { + "src": "assets/favicon/favicon-32x32.png", + "sizes": "32x32", + "type": "image/png", + "purpose": "maskable any" + }, + { + "src": "assets/favicon/favicon-72x72.png", + "sizes": "72x72", + "type": "image/png", + "purpose": "maskable any" + }, + { + "src": "assets/favicon/favicon-96x96.png", + "sizes": "96x96", + "type": "image/png", + "purpose": "maskable any" + }, + { + "src": "assets/favicon/favicon-128x128.png", + "sizes": "128x128", + "type": "image/png", + "purpose": "maskable any" + }, + { + "src": "assets/favicon/favicon-144x144.png", + "sizes": "144x144", + "type": "image/png", + "purpose": "maskable any" + }, + { + "src": "assets/favicon/favicon-152x152.png", + "sizes": "152x152", + "type": "image/png", + "purpose": "maskable any" + }, + { + "src": "assets/favicon/favicon-192x192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable any" + }, + { + "src": "assets/favicon/favicon-384x384.png", + "sizes": "384x384", + "type": "image/png", + "purpose": "maskable any" + }, + { + "src": "assets/favicon/favicon-512x512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable any" + } + ] +} diff --git a/src/environments/.gitignore b/src/environments/.gitignore new file mode 100644 index 0000000..e1a4046 --- /dev/null +++ b/src/environments/.gitignore @@ -0,0 +1,5 @@ +# Environment files - keep .example files only +environment.* + +# Keep example files for documentation +!environment.example.ts diff --git a/src/environments/environment.example.ts b/src/environments/environment.example.ts new file mode 100644 index 0000000..d1ab3aa --- /dev/null +++ b/src/environments/environment.example.ts @@ -0,0 +1,14 @@ +export const environment = { + // Used by build system to enable dev mode optimizations + production: false, + // Note: Currently used via apiInterceptor. Deprecated: duplicate of apiUrl, consider removing + apiBaseUrl: 'http://localhost:3200/api', + // Reserved for API key-based authentication (not currently used, see useApiKey) + apiKey: '', + // Reserved for toggling between JWT and API key authentication (not currently used) + useApiKey: true, + // Reserved for data polling/refresh intervals (not currently used) + refreshInterval: 30000, + // Reserved for Google Maps API integration (not currently used) + googleMapApiKey: '' +}; diff --git a/src/favicon.ico b/src/favicon.ico new file mode 100644 index 0000000..103fbbe Binary files /dev/null and b/src/favicon.ico differ diff --git a/src/files-data/.gitignore b/src/files-data/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/src/files-data/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/src/index.html b/src/index.html new file mode 100644 index 0000000..055f625 --- /dev/null +++ b/src/index.html @@ -0,0 +1,46 @@ + + + + + + Ad Astra + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/jumps.json b/src/jumps.json new file mode 100644 index 0000000..60fa133 --- /dev/null +++ b/src/jumps.json @@ -0,0 +1,14280 @@ +[ + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2018-08-18T00:00:00.000+00:00", + "numero": 1, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1500, + "voile": "Electra", + "taille": 210, + "categorie": "PAC", + "module": "", + "participants": 3, + "sautants": ["Iku", "Hugues"], + "programme": "Sortie face aile à 2 moniteurs. Position: bien. Resserrer et tendre les jambes. Lecture alti: OK. Simulation ouverture: OK. Ouverture 1500m élève.", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/PAC/", + "video": "2018-08-18_S0001.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2018-08-18T00:00:00.000+00:00", + "numero": 2, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1500, + "voile": "Electra", + "taille": 210, + "categorie": "PAC", + "module": "", + "participants": 2, + "sautants": ["Iku"], + "programme": "Sortie face aile à 1 moniteur. Position: mieux. Alti + simulation: OK. Oiuverture 1500m moniteur. Attention alti !", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/PAC/", + "video": "2018-08-18_S0002.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2018-08-18T00:00:00.000+00:00", + "numero": 3, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 2500, + "voile": "Electra", + "taille": 210, + "categorie": "PAC", + "module": "", + "participants": 2, + "sautants": ["Iku"], + "programme": "Sortie dos tenue, retournement + stabilisation: OK, alti + simulation: OK, petites orientations droite + gauche: OK, ouverture 2500m élève. Attention alti !", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/PAC/", + "video": "2018-08-18_S0003.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2018-08-19T00:00:00.000+00:00", + "numero": 4, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1500, + "voile": "Electra", + "taille": 210, + "categorie": "PAC", + "module": "", + "participants": 2, + "sautants": ["Iku"], + "programme": "Sortie boule avant, retournement + stabilisation: OK, alti + simulation: OK, 1 loop avant, retournement + stabilisation: OK, ouverture 1500m élève.", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/PAC/", + "video": "2018-08-19_S0004.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2018-08-19T00:00:00.000+00:00", + "numero": 5, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1500, + "voile": "Electra", + "taille": 210, + "categorie": "PAC", + "module": "", + "participants": 2, + "sautants": ["Iku"], + "programme": "Sortie boule arrière, retournement + stabilisation: OK, alti + simulation: OK, flèche super, ça avance!, ouverture 1500m élève.", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/PAC/", + "video": "2018-08-19_S0005.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2018-08-19T00:00:00.000+00:00", + "numero": 6, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1500, + "voile": "Electra", + "taille": 210, + "categorie": "PAC", + "module": "", + "participants": 2, + "sautants": ["Iku"], + "programme": "Sortie Gory, retournement + stabilisation: OK, alti + simulation: OK, tonneaux. Bon saut. Ouverture 1500 élève. Apte à sauter seul. Félicitations !!", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/PAC/", + "video": "2018-08-19_S0006.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2018-08-19T00:00:00.000+00:00", + "numero": 7, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1500, + "voile": "Electra", + "taille": 210, + "categorie": "Solo", + "module": "", + "participants": 1, + "sautants": [], + "programme": "1er Solo - Sortie boule avant, retournement, lecture alti, simulation, tonneau, 360, orientation, fleche, orientation", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-05-01T00:00:00.000+00:00", + "numero": 8, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1500, + "voile": "Electra", + "taille": 210, + "categorie": "PAC", + "module": "", + "participants": 2, + "sautants": ["Iku"], + "programme": "Saut de reprise - Sortie boule avant, rétablissement + stabilisation: OK, Alti + simulation ouverture: OK Stable, orientations 360 droite + gauche: OK, ouverture 1500m élève. Apte à sauter seul.", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/", + "video": "2019-05-01_S0008_reprise.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-05-01T00:00:00.000+00:00", + "numero": 9, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1500, + "voile": "Electra", + "taille": 210, + "categorie": "Solo", + "module": "", + "participants": 1, + "sautants": [], + "programme": "Sortie boule avant, retournement, stabilisation, orientation, boule avant, retablissement, orientation, fleche, 360, orientation", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-05-05T00:00:00.000+00:00", + "numero": 10, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1500, + "voile": "Electra", + "taille": 210, + "categorie": "Solo", + "module": "", + "participants": 1, + "sautants": [], + "programme": "Sortie boule avant, orientation, 360 gauche, 360 droite, boule arrière, stabilisation", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-05-05T00:00:00.000+00:00", + "numero": 11, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1500, + "voile": "Electra", + "taille": 210, + "categorie": "Solo", + "module": "", + "participants": 1, + "sautants": [], + "programme": "Sortie dos, retournement, orientation, fleche, orientation", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-05-05T00:00:00.000+00:00", + "numero": 12, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1500, + "voile": "Electra", + "taille": 210, + "categorie": "Solo", + "module": "", + "participants": 1, + "sautants": [], + "programme": "Sortie boule avant, stabilisation, fleche, tonneau, 360 gauche, 360 droite", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-05-12T00:00:00.000+00:00", + "numero": 13, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1500, + "voile": "Electra", + "taille": 230, + "categorie": "Solo", + "module": "", + "participants": 1, + "sautants": [], + "programme": "Sortie boule avant, stabilisation, 360 droite, orientation, 360 gauche, orientation", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-05-12T00:00:00.000+00:00", + "numero": 14, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1500, + "voile": "Electra", + "taille": 230, + "categorie": "Solo", + "module": "", + "participants": 1, + "sautants": [], + "programme": "Sortie boule avant, stabilisation, boule avant, stabilisation, boule arrière, stabilisation, 360 droite, tonneau, stabilisation", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-06-17T00:00:00.000+00:00", + "numero": 15, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1500, + "voile": "Electra", + "taille": 210, + "categorie": "A", + "module": "", + "participants": 1, + "sautants": [], + "programme": "Sortie face moteur, fleche, boule arrière, boule avant, tonneau droite, tonneau gauche, 360 droite, 360 gauche, fleche", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-07-03T00:00:00.000+00:00", + "numero": 16, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1200, + "voile": "Electra", + "taille": 210, + "categorie": "Solo", + "module": "", + "participants": 1, + "sautants": [], + "programme": "Sortie face moteur, dérive, boule arrière, tonneau, 360", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-07-03T00:00:00.000+00:00", + "numero": 17, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1200, + "voile": "Electra", + "taille": 210, + "categorie": "Solo", + "module": "", + "participants": 1, + "sautants": [], + "programme": "Sortie face moteur, boule arrière, boule avant, tonneau, dérive, orientation", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-07-03T00:00:00.000+00:00", + "numero": 18, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1200, + "voile": "Electra", + "taille": 210, + "categorie": "Solo", + "module": "", + "participants": 1, + "sautants": [], + "programme": "Sortie face moteur, boule arrière, chute sur le dos, tonneau, 360 droite, 360 gauche", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-07-05T00:00:00.000+00:00", + "numero": 19, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1200, + "voile": "Electra", + "taille": 210, + "categorie": "Solo", + "module": "", + "participants": 1, + "sautants": [], + "programme": "Sortie face moteur, dérive, position assis, boule avant, dérive", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-07-05T00:00:00.000+00:00", + "numero": 20, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1200, + "voile": "Electra", + "taille": 210, + "categorie": "Solo", + "module": "", + "participants": 1, + "sautants": [], + "programme": "Sortie face moteur, chutas, boule avant, boule arrière, dérive", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-07-05T00:00:00.000+00:00", + "numero": 21, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1200, + "voile": "Electra", + "taille": 210, + "categorie": "Solo", + "module": "", + "participants": 1, + "sautants": [], + "programme": "Sortie face moteur, dérive, chutas, boule avant, dérive", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-07-12T00:00:00.000+00:00", + "numero": 22, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1200, + "voile": "Electra", + "taille": 210, + "categorie": "Solo", + "module": "", + "participants": 1, + "sautants": [], + "programme": "Entrainement B - Sortie face moteur, boule arrière, tonneau droite, tonneau gauche, 360 droite, 360 gauche", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-07-12T00:00:00.000+00:00", + "numero": 23, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1200, + "voile": "Electra", + "taille": 210, + "categorie": "Solo", + "module": "", + "participants": 1, + "sautants": [], + "programme": "Entrainement B - Sortie face moteur, boule arrière, boule avant, tonneau droite, tonneau gauche, 360 droite, 360 gauche, fleche", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-07-12T00:00:00.000+00:00", + "numero": 24, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1200, + "voile": "Electra", + "taille": 210, + "categorie": "Solo", + "module": "", + "participants": 1, + "sautants": [], + "programme": "Entrainement B - Sortie face moteur, boule arrière, boule avant, tonneau droite, tonneau gauche, boule arrière, orientation", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-07-12T00:00:00.000+00:00", + "numero": 25, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1200, + "voile": "Electra", + "taille": 210, + "categorie": "Solo", + "module": "", + "participants": 1, + "sautants": [], + "programme": "Boule arrière, boule avant, chutas", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-07-19T00:00:00.000+00:00", + "numero": 26, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1200, + "voile": "Electra", + "taille": 210, + "categorie": "Solo", + "module": "", + "participants": 1, + "sautants": [], + "programme": "Entrainement B - Sortie face moteur, boule arrière, boule avant, tonneau droite, tonneau gauche, 360 droite, 360 gauche, fleche", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-07-19T00:00:00.000+00:00", + "numero": 27, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1200, + "voile": "Electra", + "taille": 210, + "categorie": "Solo", + "module": "", + "participants": 1, + "sautants": [], + "programme": "Entrainement B - Sortie face moteur, boule arrière, boule avant, tonneau droite, tonneau gauche, 360 droite, 360 gauche, fleche", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-07-19T00:00:00.000+00:00", + "numero": 28, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1200, + "voile": "Electra", + "taille": 210, + "categorie": "Solo", + "module": "", + "participants": 1, + "sautants": [], + "programme": "Entrainement B - Sortie face moteur, boule arrière, boule avant, tonneau droite, tonneau gauche, 360 droite, 360 gauche, fleche", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-07-28T00:00:00.000+00:00", + "numero": 29, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1200, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "", + "participants": 1, + "sautants": [], + "programme": "Entrainement B - Sortie face moteur, boule arrière, boule avant, tonneau droite, tonneau gauche, 360 droite, 360 gauche, derive", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-07-28T00:00:00.000+00:00", + "numero": 30, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1200, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "", + "participants": 1, + "sautants": [], + "programme": "Entrainement B - Sortie dos moteur, boule avant, boule arrière, 360 droite, tonneau droite, boule avant, boule arrière, 360 gauche, tonneau gauche, derive", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-07-28T00:00:00.000+00:00", + "numero": 31, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1200, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "", + "participants": 1, + "sautants": [], + "programme": "Entrainement B - Sortie dos moteur, boule arrière, boule avant, 360 droite, 360 gauche, tonneau droite, tonneau gauche, boule arrière, boule avant, derive", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-07-28T00:00:00.000+00:00", + "numero": 32, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1200, + "voile": "Electra", + "taille": 190, + "categorie": "B", + "module": "", + "participants": 1, + "sautants": [], + "programme": "Validation - Sortie dos moteur, boule avant, boule arrière, 360 droite, tonneau droite, boule avant, boule arrière, 360 gauche, tonneau gauche, derive", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-08-02T00:00:00.000+00:00", + "numero": 33, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1200, + "voile": "Electra", + "taille": 190, + "categorie": "B", + "module": "", + "participants": 1, + "sautants": [], + "programme": "Validation sortie face moteur, dérive", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-08-02T00:00:00.000+00:00", + "numero": 34, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Dérive", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-08-02T00:00:00.000+00:00", + "numero": 35, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Dérive", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-08-02T00:00:00.000+00:00", + "numero": 36, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Dérive", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-08-08T00:00:00.000+00:00", + "numero": 37, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Transition, dérive", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-08-08T00:00:00.000+00:00", + "numero": 38, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Transition, dérive", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-08-08T00:00:00.000+00:00", + "numero": 39, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Transition, dérive", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-08-08T00:00:00.000+00:00", + "numero": 40, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Sortie dos moteur, orientation, dérive", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-08-17T00:00:00.000+00:00", + "numero": 41, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Sortie dos moteur, dérive", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-08-17T00:00:00.000+00:00", + "numero": 42, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Dérive", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-08-17T00:00:00.000+00:00", + "numero": 43, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Transition", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-08-24T00:00:00.000+00:00", + "numero": 44, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-08-24T00:00:00.000+00:00", + "numero": 45, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-08-24T00:00:00.000+00:00", + "numero": 46, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-08-30T00:00:00.000+00:00", + "numero": 47, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-08-30T00:00:00.000+00:00", + "numero": 48, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-08-30T00:00:00.000+00:00", + "numero": 49, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Dérive", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-08-30T00:00:00.000+00:00", + "numero": 50, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Dérive", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-08-31T00:00:00.000+00:00", + "numero": 51, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Dérive", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-08-31T00:00:00.000+00:00", + "numero": 52, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Debout, dérive", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-08-31T00:00:00.000+00:00", + "numero": 53, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Debout, dérive", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-08-31T00:00:00.000+00:00", + "numero": 54, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Debout, dérive", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-09-14T00:00:00.000+00:00", + "numero": 55, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Track", + "participants": 1, + "sautants": [], + "programme": "Derive, demi tonneau", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-09-14T00:00:00.000+00:00", + "numero": 56, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Derive, Chutas", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-09-14T00:00:00.000+00:00", + "numero": 57, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 3300, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Nuage gris, petite pluie", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-09-18T00:00:00.000+00:00", + "numero": 58, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Caravan", + "imat": "F-HSVS", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Debout, dérive", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-09-18T00:00:00.000+00:00", + "numero": 59, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Caravan", + "imat": "F-HSVS", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Debout, dérive", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-09-19T00:00:00.000+00:00", + "numero": 60, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Caravan", + "imat": "F-HSVS", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Debout, dérive", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-09-19T00:00:00.000+00:00", + "numero": 61, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Debout, dérive", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-09-28T00:00:00.000+00:00", + "numero": 62, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Debout, dérive", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-09-28T00:00:00.000+00:00", + "numero": 63, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Debout, dérive, posé cible", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-09-28T00:00:00.000+00:00", + "numero": 64, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Debout, dérive", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-09-28T00:00:00.000+00:00", + "numero": 65, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Debout, dérive, posé cible", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-09-28T00:00:00.000+00:00", + "numero": 66, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Sunset", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-10-05T00:00:00.000+00:00", + "numero": 67, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Init B2", + "module": "", + "participants": 2, + "sautants": ["Charlotte"], + "programme": "Sortie piqueur, niveau, position, 180", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/B2/", + "video": "2019-10-05_S00067.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-10-05T00:00:00.000+00:00", + "numero": 68, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Init B2", + "module": "", + "participants": 2, + "sautants": ["Charlotte"], + "programme": "Sortie flotteur, niveau, déplacement, position, 180, derive", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/B2/", + "video": "2019-10-05_S00068.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-10-12T00:00:00.000+00:00", + "numero": 69, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Init B2", + "module": "", + "participants": 2, + "sautants": ["Charlotte"], + "programme": "Sortie piqueur libre, niveau, appontage, 180, derive, break", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/B2/", + "video": "2019-10-12_S00069.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-10-12T00:00:00.000+00:00", + "numero": 70, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Init B2", + "module": "", + "participants": 2, + "sautants": ["Charlotte"], + "programme": "Sortie piqueur libre, niveau, appontage, 360, derive", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/B2/", + "video": "2019-10-12_S00070.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-10-12T00:00:00.000+00:00", + "numero": 71, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "", + "participants": 1, + "sautants": [], + "programme": "Sortie piqueur, position, derive, niveau, derive", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-10-25T00:00:00.000+00:00", + "numero": 72, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "", + "participants": 1, + "sautants": [], + "programme": "Sortie piqueur, entrainement B2", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-10-25T00:00:00.000+00:00", + "numero": 73, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "", + "participants": 1, + "sautants": [], + "programme": "Sortie piqueur, entrainement B2", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-10-25T00:00:00.000+00:00", + "numero": 74, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "", + "participants": 1, + "sautants": [], + "programme": "Sortie piqueur, entrainement B2", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-10-25T00:00:00.000+00:00", + "numero": 75, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Sortie tête en haut, transition - Sunset", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-10-26T00:00:00.000+00:00", + "numero": 76, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "360 droite, 360 gauche, transitions", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-10-26T00:00:00.000+00:00", + "numero": 77, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Init B2", + "module": "", + "participants": 2, + "sautants": ["Charlotte"], + "programme": "Piqué frein, niveau, appontage, dérive", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/B2/", + "video": "2019-10-26_S00077.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-10-26T00:00:00.000+00:00", + "numero": 78, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Init B2", + "module": "", + "participants": 2, + "sautants": ["Charlotte"], + "programme": "Piqué frein, niveau, appontage, 360, dérive", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/B2/", + "video": "2019-10-26_S00078.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-10-26T00:00:00.000+00:00", + "numero": 79, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Init B2", + "module": "", + "participants": 2, + "sautants": ["Charlotte"], + "programme": "Piqué frein, niveau, 360, appontage, valise, dérive", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/B2/", + "video": "2019-10-26_S00079.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-10-27T00:00:00.000+00:00", + "numero": 80, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Init B2", + "module": "", + "participants": 2, + "sautants": ["Charlotte"], + "programme": "Entrainement", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/B2/", + "video": "2019-10-27_S00080.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-10-27T00:00:00.000+00:00", + "numero": 81, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "B2", + "module": "", + "participants": 2, + "sautants": ["Charlotte"], + "programme": "Validation", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/B2/", + "video": "2019-10-27_S00081.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-10-27T00:00:00.000+00:00", + "numero": 82, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "VR", + "module": "", + "participants": 2, + "sautants": ["Warren"], + "programme": "Sortie piqueur, appontage, niveau", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-10-27T00:00:00.000+00:00", + "numero": 83, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "VR", + "module": "", + "participants": 4, + "sautants": ["Warren", "Jeremy", "Lorie"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2019-10-27_S00083.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2019-10-27T00:00:00.000+00:00", + "numero": 84, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 5000, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "VR", + "module": "", + "participants": 4, + "sautants": ["Warren", "Jeremy", "Lorie"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2019-10-27_S00084.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-02-10T00:00:00.000+00:00", + "numero": 85, + "lieu": "Beni Mellal", + "oaci": "GMMD", + "aeronef": "Pilatus", + "imat": "F-GOSP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-02-10_S00085.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-02-10T00:00:00.000+00:00", + "numero": 86, + "lieu": "Beni Mellal", + "oaci": "GMMD", + "aeronef": "Pilatus", + "imat": "F-GEEO", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-02-10_S00086.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-02-10T00:00:00.000+00:00", + "numero": 87, + "lieu": "Beni Mellal", + "oaci": "GMMD", + "aeronef": "Pilatus", + "imat": "F-GOSP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "VR", + "module": "", + "participants": 3, + "sautants": ["?", "?"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-02-10_S00087.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-02-10T00:00:00.000+00:00", + "numero": 88, + "lieu": "Beni Mellal", + "oaci": "GMMD", + "aeronef": "Pilatus", + "imat": "F-GEEO", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "VR", + "module": "", + "participants": 5, + "sautants": ["?", "?", "?", "?"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-02-10_S00088.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-02-10T00:00:00.000+00:00", + "numero": 89, + "lieu": "Beni Mellal", + "oaci": "GMMD", + "aeronef": "Pilatus", + "imat": "F-GOSP", + "hauteur": 5000, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "VR", + "module": "", + "participants": 9, + "sautants": ["?", "?", "?", "?", "?", "?", "?", "?"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-02-10_S00089.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-02-11T00:00:00.000+00:00", + "numero": 90, + "lieu": "Beni Mellal", + "oaci": "GMMD", + "aeronef": "Pilatus", + "imat": "F-GEEO", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Init Bi4", + "module": "Chutas", + "participants": 2, + "sautants": ["?"], + "programme": "Tom", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-02-11_S00090.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-02-11T00:00:00.000+00:00", + "numero": 91, + "lieu": "Beni Mellal", + "oaci": "GMMD", + "aeronef": "Pilatus", + "imat": "F-GOSP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-02-11_S00091.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-02-11T00:00:00.000+00:00", + "numero": 92, + "lieu": "Beni Mellal", + "oaci": "GMMD", + "aeronef": "Pilatus", + "imat": "F-GEEO", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "VR", + "module": "", + "participants": 3, + "sautants": ["Warren", "Frigo"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-02-11_S00092.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-02-11T00:00:00.000+00:00", + "numero": 93, + "lieu": "Beni Mellal", + "oaci": "GMMD", + "aeronef": "Pilatus", + "imat": "F-GOSP", + "hauteur": 4800, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "VR", + "module": "", + "participants": 4, + "sautants": ["Steve", "Corentin", "Sabrina"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-02-11_S00093.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-02-12T00:00:00.000+00:00", + "numero": 94, + "lieu": "Beni Mellal", + "oaci": "GMMD", + "aeronef": "Pilatus", + "imat": "F-GEEO", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Track", + "participants": 1, + "sautants": [], + "programme": "Dérive", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2020-02-12_S00094.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-02-12T00:00:00.000+00:00", + "numero": 95, + "lieu": "Beni Mellal", + "oaci": "GMMD", + "aeronef": "Pilatus", + "imat": "F-GOSP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "VR", + "module": "", + "participants": 2, + "sautants": ["Chinois"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-02-12_S00095.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-02-12T00:00:00.000+00:00", + "numero": 96, + "lieu": "Beni Mellal", + "oaci": "GMMD", + "aeronef": "Pilatus", + "imat": "F-GEEO", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "VR", + "module": "", + "participants": 3, + "sautants": ["Chinois", "Warren"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-02-12_S00096.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-02-12T00:00:00.000+00:00", + "numero": 97, + "lieu": "Beni Mellal", + "oaci": "GMMD", + "aeronef": "Pilatus", + "imat": "F-GOSP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-02-12_S00097.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-02-12T00:00:00.000+00:00", + "numero": 98, + "lieu": "Beni Mellal", + "oaci": "GMMD", + "aeronef": "Pilatus", + "imat": "F-GEEO", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "VR", + "module": "", + "participants": 5, + "sautants": ["Charlotte", "Charles", "Vivi", "Warren"], + "programme": "", + "accessoires": "Drisse", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-02-12_S00098.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-02-12T00:00:00.000+00:00", + "numero": 99, + "lieu": "Beni Mellal", + "oaci": "GMMD", + "aeronef": "Pilatus", + "imat": "F-GOSP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-02-12_S00099.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-02-13T00:00:00.000+00:00", + "numero": 100, + "lieu": "Beni Mellal", + "oaci": "GMMD", + "aeronef": "Pilatus", + "imat": "F-GEEO", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-02-13_S00100.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-02-13T00:00:00.000+00:00", + "numero": 101, + "lieu": "Beni Mellal", + "oaci": "GMMD", + "aeronef": "Pilatus", + "imat": "F-GOSP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Track", + "participants": 1, + "sautants": [], + "programme": "Derive + transitions", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2020-02-13_S00101.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-02-13T00:00:00.000+00:00", + "numero": 102, + "lieu": "Beni Mellal", + "oaci": "GMMD", + "aeronef": "Pilatus", + "imat": "F-GEEO", + "hauteur": 4600, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "VR", + "module": "", + "participants": 8, + "sautants": ["Tom", "Charlotte", "Charles", "Lili", "Sabrina", "Vivi", "Warren"], + "programme": "", + "accessoires": "Tube", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-02-13_S00102.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-02-13T00:00:00.000+00:00", + "numero": 103, + "lieu": "Beni Mellal", + "oaci": "GMMD", + "aeronef": "Pilatus", + "imat": "F-GOSP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "VR", + "module": "", + "participants": 5, + "sautants": ["Corentin", "Charles", "Lili", "Warren"], + "programme": "Dragon Fly", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-02-13_S00103.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-02-13T00:00:00.000+00:00", + "numero": 104, + "lieu": "Beni Mellal", + "oaci": "GMMD", + "aeronef": "Pilatus", + "imat": "F-GEEO", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "VR", + "module": "", + "participants": 2, + "sautants": ["Warren"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-02-13_S00104.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-02-15T00:00:00.000+00:00", + "numero": 105, + "lieu": "Beni Mellal", + "oaci": "GMMD", + "aeronef": "Pilatus", + "imat": "F-GOSP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "VR", + "module": "", + "participants": 4, + "sautants": ["Charlotte", "Seb", "Warren"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-02-15_S00105.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-02-15T00:00:00.000+00:00", + "numero": 106, + "lieu": "Beni Mellal", + "oaci": "GMMD", + "aeronef": "Pilatus", + "imat": "F-GEEO", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Track", + "participants": 1, + "sautants": [], + "programme": "Derive + transitions", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2020-02-15_S00106.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-02-15T00:00:00.000+00:00", + "numero": 107, + "lieu": "Beni Mellal", + "oaci": "GMMD", + "aeronef": "Pilatus", + "imat": "F-GOSP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "VR", + "module": "", + "participants": 7, + "sautants": ["Tom", "Charlotte", "Charles", "Elo", "Seb", "Warren"], + "programme": "", + "accessoires": "Tube", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-02-15_S00107.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-02-15T00:00:00.000+00:00", + "numero": 108, + "lieu": "Beni Mellal", + "oaci": "GMMD", + "aeronef": "Pilatus", + "imat": "F-GEEO", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "VR", + "module": "", + "participants": 5, + "sautants": ["Charlotte", "Lio", "Corentin", "Seb"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-02-15_S00108.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-02-15T00:00:00.000+00:00", + "numero": 109, + "lieu": "Beni Mellal", + "oaci": "GMMD", + "aeronef": "Pilatus", + "imat": "F-GOSP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Track", + "participants": 1, + "sautants": [], + "programme": "Derive + transitions", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2020-02-15_S00109.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-02-16T00:00:00.000+00:00", + "numero": 110, + "lieu": "Beni Mellal", + "oaci": "GMMD", + "aeronef": "Pilatus", + "imat": "F-GEEO", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Track", + "participants": 1, + "sautants": [], + "programme": "Derive + transitions", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2020-02-16_S00110.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-02-16T00:00:00.000+00:00", + "numero": 111, + "lieu": "Beni Mellal", + "oaci": "GMMD", + "aeronef": "Pilatus", + "imat": "F-GOSP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Léo"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-02-16_S00111.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-02-16T00:00:00.000+00:00", + "numero": 112, + "lieu": "Beni Mellal", + "oaci": "GMMD", + "aeronef": "Pilatus", + "imat": "F-GEEO", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Léo"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-02-16_S00112.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-02-16T00:00:00.000+00:00", + "numero": 113, + "lieu": "Beni Mellal", + "oaci": "GMMD", + "aeronef": "Pilatus", + "imat": "F-GOSP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Léo"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-02-16_S00113.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-02-17T00:00:00.000+00:00", + "numero": 114, + "lieu": "Beni Mellal", + "oaci": "GMMD", + "aeronef": "Pilatus", + "imat": "F-GEEO", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Léo"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-02-17_S00114.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-02-17T00:00:00.000+00:00", + "numero": 115, + "lieu": "Beni Mellal", + "oaci": "GMMD", + "aeronef": "Pilatus", + "imat": "F-GOSP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-02-17_S00115.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-02-17T00:00:00.000+00:00", + "numero": 116, + "lieu": "Beni Mellal", + "oaci": "GMMD", + "aeronef": "Pilatus", + "imat": "F-GEEO", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-02-17_S00116.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-02-17T00:00:00.000+00:00", + "numero": 117, + "lieu": "Beni Mellal", + "oaci": "GMMD", + "aeronef": "Pilatus", + "imat": "F-GOSP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Track", + "participants": 1, + "sautants": [], + "programme": "Derive + transitions", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2020-02-17_S00117.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-02-17T00:00:00.000+00:00", + "numero": 118, + "lieu": "Beni Mellal", + "oaci": "GMMD", + "aeronef": "Pilatus", + "imat": "F-GEEO", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Track", + "participants": 1, + "sautants": [], + "programme": "Derive + transitions", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2020-02-17_S00118.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-02-17T00:00:00.000+00:00", + "numero": 119, + "lieu": "Beni Mellal", + "oaci": "GMMD", + "aeronef": "Pilatus", + "imat": "F-GOSP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Dérive + transitions", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-02-17_S00119.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-03-14T00:00:00.000+00:00", + "numero": 120, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 190, + "categorie": "VR", + "module": "", + "participants": 3, + "sautants": ["Corentin", "Théo"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-03-14_S00120.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-03-14T00:00:00.000+00:00", + "numero": 121, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-03-14_S00121.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-03-14T00:00:00.000+00:00", + "numero": 122, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Transitions", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-03-14_S00122.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-03-15T00:00:00.000+00:00", + "numero": 123, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 190, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Transitions", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-03-15_S00123.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-03-15T00:00:00.000+00:00", + "numero": 124, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 190, + "categorie": "VR", + "module": "", + "participants": 2, + "sautants": ["Frigo"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-03-15_S00124.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-03-15T00:00:00.000+00:00", + "numero": 125, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 190, + "categorie": "VR", + "module": "", + "participants": 3, + "sautants": ["Frigo", "Léa"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-03-15_S00125.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-03-15T00:00:00.000+00:00", + "numero": 126, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 190, + "categorie": "VR", + "module": "", + "participants": 2, + "sautants": ["Frigo"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-03-15_S00126.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-03-15T00:00:00.000+00:00", + "numero": 127, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 190, + "categorie": "VR", + "module": "", + "participants": 7, + "sautants": ["Corentin", "Théo", "Léa", "Frigo", "Débora", "Clémence"], + "programme": "Sortie embrouille", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-03-15_S00127.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-06-20T00:00:00.000+00:00", + "numero": 128, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "Solo", + "module": "", + "participants": 1, + "sautants": [], + "programme": "Reprise, à plat", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos//", + "video": "2020-06-20_S00128.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-06-20T00:00:00.000+00:00", + "numero": 129, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Reprise, chutas", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-06-20_S00129.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-06-20T00:00:00.000+00:00", + "numero": 130, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Accèlération", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-06-20_S00130.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-06-20T00:00:00.000+00:00", + "numero": 131, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-06-20_S00131.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-06-21T00:00:00.000+00:00", + "numero": 132, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-06-21_S00132.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-06-21T00:00:00.000+00:00", + "numero": 133, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 3, + "sautants": ["Warren", "Josh"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-06-21_S00133.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-06-21T00:00:00.000+00:00", + "numero": 134, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "Init Bi4", + "module": "Chutas", + "participants": 2, + "sautants": ["Matéo"], + "programme": "Tête en haut - Sortie dos, transitions, chutas", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-06-21_S00134.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-06-27T00:00:00.000+00:00", + "numero": 135, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 2, + "sautants": ["Loïc"], + "programme": "Premier saut de B2 de Loïc", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-06-27_S00135.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-06-27T00:00:00.000+00:00", + "numero": 136, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 2, + "sautants": ["Loïc"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-06-27_S00136.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-06-27T00:00:00.000+00:00", + "numero": 137, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 3, + "sautants": ["Loïc", "Pascal"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-06-27_S00137.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-07-04T00:00:00.000+00:00", + "numero": 138, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 2, + "sautants": ["Samuel"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-07-04_S00138.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-07-04T00:00:00.000+00:00", + "numero": 139, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 4, + "sautants": ["Samuel", "Simon", "Arnaud"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-07-04_S00139.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-07-04T00:00:00.000+00:00", + "numero": 140, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "Solo", + "module": "Track", + "participants": 1, + "sautants": [], + "programme": "Dérive", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2020-07-04_S00140.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-07-04T00:00:00.000+00:00", + "numero": 141, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 3, + "sautants": ["Tom", "Charlotte"], + "programme": "1ère track !", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2020-07-04_S00141.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-07-04T00:00:00.000+00:00", + "numero": 142, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Sortie tête en haut, transitions dos", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-07-04_S00142.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-07-05T00:00:00.000+00:00", + "numero": 143, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 3, + "sautants": ["Caro", "Warren"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-07-05_S00143.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-07-05T00:00:00.000+00:00", + "numero": 144, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 3, + "sautants": ["Caro", "Warren"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-07-05_S00144.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-07-05T00:00:00.000+00:00", + "numero": 145, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Transitions dos", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-07-05_S00145.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-07-05T00:00:00.000+00:00", + "numero": 146, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 5, + "sautants": ["Corentin", "Thomas", "Caro", "Warren"], + "programme": "", + "accessoires": "Drisse", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-07-05_S00146.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-07-05T00:00:00.000+00:00", + "numero": 147, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Transitions dos", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-07-05_S00147.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-07-11T00:00:00.000+00:00", + "numero": 148, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-07-11_S00148.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-07-11T00:00:00.000+00:00", + "numero": 149, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "Solo", + "module": "Track", + "participants": 1, + "sautants": [], + "programme": "Dérive", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2020-07-11_S00149.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-07-11T00:00:00.000+00:00", + "numero": 150, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "Solo", + "module": "Track", + "participants": 1, + "sautants": [], + "programme": "Dérive", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2020-07-11_S00150.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-07-11T00:00:00.000+00:00", + "numero": 151, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Accélération, freins", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-07-11_S00151.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-07-12T00:00:00.000+00:00", + "numero": 152, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-07-12_S00152.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-07-12T00:00:00.000+00:00", + "numero": 153, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 3, + "sautants": ["Loïc", "Koen"], + "programme": "Sortie step", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-07-12_S00153.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-07-12T00:00:00.000+00:00", + "numero": 154, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 2, + "sautants": ["Loïc"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-07-12_S00154.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-07-12T00:00:00.000+00:00", + "numero": 155, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 3, + "sautants": ["Loïc", "Koen"], + "programme": "Sortie step", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-07-12_S00155.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-07-13T00:00:00.000+00:00", + "numero": 156, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 2, + "sautants": ["Loïc"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-07-13_S00156.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-07-13T00:00:00.000+00:00", + "numero": 157, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 2, + "sautants": ["Loïc"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-07-13_S00157.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-07-13T00:00:00.000+00:00", + "numero": 158, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Debout 302 Km/h", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-07-13_S00158.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-07-25T00:00:00.000+00:00", + "numero": 159, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-07-25_S00159.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-07-25T00:00:00.000+00:00", + "numero": 160, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 2, + "sautants": ["Loïc"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-07-25_S00160.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-07-25T00:00:00.000+00:00", + "numero": 161, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 2, + "sautants": ["Loïc"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-07-25_S00161.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-07-25T00:00:00.000+00:00", + "numero": 162, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 4, + "sautants": ["Corentin", "Théo", "Loïc", "Aurelien"], + "programme": "Sortie Gory à 4", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-07-25_S00162.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-07-25T00:00:00.000+00:00", + "numero": 163, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "Bi4", + "module": "Chutas", + "participants": 2, + "sautants": ["Matéo"], + "programme": "Validation Bi4 - Tête en haut", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-07-25_S00163.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-07-25T00:00:00.000+00:00", + "numero": 164, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "Solo", + "module": "Track", + "participants": 1, + "sautants": [], + "programme": "Dérive, transition dos, prise d'angle", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2020-07-25_S00164.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-07-26T00:00:00.000+00:00", + "numero": 165, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 2, + "sautants": ["Loïc"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-07-26_S00165.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-07-26T00:00:00.000+00:00", + "numero": 166, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 2, + "sautants": ["Loïc"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-07-26_S00166.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-07-26T00:00:00.000+00:00", + "numero": 167, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 2, + "sautants": ["Loïc"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-07-26_S00167.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-07-26T00:00:00.000+00:00", + "numero": 168, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 3, + "sautants": ["Loïc", "Charles"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-07-26_S00168.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-01T00:00:00.000+00:00", + "numero": 169, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "Solo", + "module": "Track", + "participants": 1, + "sautants": [], + "programme": "Dérive", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2020-08-01_S00169.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-01T00:00:00.000+00:00", + "numero": 170, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-08-01_S00170.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-01T00:00:00.000+00:00", + "numero": 171, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 2, + "sautants": ["Samuel"], + "programme": "Carve", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-08-01_S00171.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-01T00:00:00.000+00:00", + "numero": 172, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 2, + "sautants": ["Samuel"], + "programme": "Dérive face sol", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2020-08-01_S00172.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-01T00:00:00.000+00:00", + "numero": 173, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 2, + "sautants": ["Samuel"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2020-08-01_S00173.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-01T00:00:00.000+00:00", + "numero": 174, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Samuel"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-08-01_S00174.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-02T00:00:00.000+00:00", + "numero": 175, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 2, + "sautants": ["Warren"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-08-02_S00175.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-02T00:00:00.000+00:00", + "numero": 176, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 2, + "sautants": ["Warren"], + "programme": "Dérive", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-08-02_S00176.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-02T00:00:00.000+00:00", + "numero": 177, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 3, + "sautants": ["Warren", "Jean Marc"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-08-02_S00177.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-02T00:00:00.000+00:00", + "numero": 178, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 3, + "sautants": ["Warren", "Jean Marc"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-08-02_S00178.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-02T00:00:00.000+00:00", + "numero": 179, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "Solo", + "module": "Track", + "participants": 1, + "sautants": [], + "programme": "Dérive", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2020-08-02_S00179.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-07T00:00:00.000+00:00", + "numero": 180, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-08-07_S00180.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-07T00:00:00.000+00:00", + "numero": 181, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Frein", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-08-07_S00181.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-07T00:00:00.000+00:00", + "numero": 182, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 2, + "sautants": ["Loïc"], + "programme": "Tonneau à 2 - short tee-shirt", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-08-07_S00182.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-07T00:00:00.000+00:00", + "numero": 183, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "Solo", + "module": "Track", + "participants": 1, + "sautants": [], + "programme": "Dérive", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2020-08-07_S00183.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-07T00:00:00.000+00:00", + "numero": 184, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-08-07_S00184.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-08T00:00:00.000+00:00", + "numero": 185, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "Solo", + "module": "Track", + "participants": 1, + "sautants": [], + "programme": "Dérive", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2020-08-08_S00185.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-08T00:00:00.000+00:00", + "numero": 186, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "Solo", + "module": "Track", + "participants": 1, + "sautants": [], + "programme": "Dérive", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2020-08-08_S00186.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-08T00:00:00.000+00:00", + "numero": 187, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "Init Bi4", + "module": "Track", + "participants": 2, + "sautants": ["Matéo"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2020-08-08_S00187.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-08T00:00:00.000+00:00", + "numero": 188, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "Init Bi4", + "module": "Track", + "participants": 2, + "sautants": ["Matéo"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2020-08-08_S00188.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-08T00:00:00.000+00:00", + "numero": 189, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 4, + "sautants": ["Mathieu", "Cyril", "?"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-08-08_S00189.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-09T00:00:00.000+00:00", + "numero": 190, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 3, + "sautants": ["Cyril", "Clément"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-08-09_S00190.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-09T00:00:00.000+00:00", + "numero": 191, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 3, + "sautants": ["Cyril", "Clément"], + "programme": "Formation init. B2", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-08-09_S00191.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-09T00:00:00.000+00:00", + "numero": 192, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "Solo", + "module": "Track", + "participants": 1, + "sautants": [], + "programme": "Dérive - Sortie dos (pluie)", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2020-08-09_S00192.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-09T00:00:00.000+00:00", + "numero": 193, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-08-09_S00193.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-10T00:00:00.000+00:00", + "numero": 194, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "Solo", + "module": "Track", + "participants": 1, + "sautants": [], + "programme": "Dérive", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2020-08-10_S00194.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-10T00:00:00.000+00:00", + "numero": 195, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "Bi4", + "module": "Track", + "participants": 2, + "sautants": ["Matéo"], + "programme": "Validation Bi4 - Track", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2020-08-10_S00195.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-10T00:00:00.000+00:00", + "numero": 196, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "Solo", + "module": "Track", + "participants": 1, + "sautants": [], + "programme": "Entrainement track - Sortie dos, chutas", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2020-08-10_S00196.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-13T00:00:00.000+00:00", + "numero": 197, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 3, + "sautants": ["Pascal", "Loïc"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-08-13_S00197.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-13T00:00:00.000+00:00", + "numero": 198, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Pascal"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-08-13_S00198.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-14T00:00:00.000+00:00", + "numero": 199, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 2, + "sautants": ["Pascal"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2020-08-14_S00199.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-14T00:00:00.000+00:00", + "numero": 200, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 3, + "sautants": ["Pascal", "Caro"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-08-14_S00200.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-14T00:00:00.000+00:00", + "numero": 201, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 4, + "sautants": ["Pascal", "Caro", "Loïc"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-08-14_S00201.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-14T00:00:00.000+00:00", + "numero": 202, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Pascal", "Charles"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-08-14_S00202.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-14T00:00:00.000+00:00", + "numero": 203, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Pascal", "Charles"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-08-14_S00203.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-14T00:00:00.000+00:00", + "numero": 204, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 3, + "sautants": ["Loïc", "Nico"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-08-14_S00204.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-15T00:00:00.000+00:00", + "numero": 205, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Entrainement grip", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-08-15_S00205.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-15T00:00:00.000+00:00", + "numero": 206, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 4, + "sautants": ["Pascal", "Koen", "Sandra"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-08-15_S00206.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-15T00:00:00.000+00:00", + "numero": 207, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 3, + "sautants": ["Koen", "Sandra"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-08-15_S00207.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-21T00:00:00.000+00:00", + "numero": 208, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Entrainement grip", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-08-21_S00208.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-21T00:00:00.000+00:00", + "numero": 209, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Entrainement grip", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-08-21_S00209.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-21T00:00:00.000+00:00", + "numero": 210, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Entrainement grip", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-08-21_S00210.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-21T00:00:00.000+00:00", + "numero": 211, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Entrainement grip", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-08-21_S00211.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-21T00:00:00.000+00:00", + "numero": 212, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Entrainement grip", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-08-21_S00212.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-22T00:00:00.000+00:00", + "numero": 213, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 2, + "sautants": ["Loïc"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-08-22_S00213.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-22T00:00:00.000+00:00", + "numero": 214, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 3, + "sautants": ["Pascal", "Loïc"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-08-22_S00214.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-22T00:00:00.000+00:00", + "numero": 215, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 3, + "sautants": ["Pascal", "Loïc"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-08-22_S00215.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-22T00:00:00.000+00:00", + "numero": 216, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 3, + "sautants": ["Pascal", "Loïc"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-08-22_S00216.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-22T00:00:00.000+00:00", + "numero": 217, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 3, + "sautants": ["Pascal", "Loïc"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-08-22_S00217.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-22T00:00:00.000+00:00", + "numero": 218, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 3, + "sautants": ["Pascal", "Loïc"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-08-22_S00218.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-23T00:00:00.000+00:00", + "numero": 219, + "lieu": "Royan", + "oaci": "LFCY", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Charlotte"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-08-23_S00219.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-23T00:00:00.000+00:00", + "numero": 220, + "lieu": "Royan", + "oaci": "LFCY", + "aeronef": "Pilatus", + "imat": "F-GTOP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["AK", "Charlotte"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-08-23_S00220.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-23T00:00:00.000+00:00", + "numero": 221, + "lieu": "Royan", + "oaci": "LFCY", + "aeronef": "Pilatus", + "imat": "F-GTOP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["AK", "Charlotte"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-08-23_S00221.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-24T00:00:00.000+00:00", + "numero": 222, + "lieu": "Royan", + "oaci": "LFCY", + "aeronef": "Pilatus", + "imat": "F-GTOP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Charlotte", "Cédric"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-08-24_S00222.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-24T00:00:00.000+00:00", + "numero": 223, + "lieu": "Royan", + "oaci": "LFCY", + "aeronef": "Pilatus", + "imat": "F-GTOP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Charlotte", "Cédric"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-08-24_S00223.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-24T00:00:00.000+00:00", + "numero": 224, + "lieu": "Royan", + "oaci": "LFCY", + "aeronef": "Pilatus", + "imat": "F-GTOP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 6, + "sautants": ["Charlotte", "Erwann", "Lucie", "Claudie", "Cédric"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-08-24_S00224.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-24T00:00:00.000+00:00", + "numero": 225, + "lieu": "Royan", + "oaci": "LFCY", + "aeronef": "Pilatus", + "imat": "F-GTOP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 5, + "sautants": ["Charlotte", "Claudie", "Lucie", "Cédric"], + "programme": "", + "accessoires": "Drisse", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-08-24_S00225.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-25T00:00:00.000+00:00", + "numero": 226, + "lieu": "Royan", + "oaci": "LFCY", + "aeronef": "Pilatus", + "imat": "F-GTOP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["AK", "Charlotte"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-08-25_S00226.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-26T00:00:00.000+00:00", + "numero": 227, + "lieu": "Royan", + "oaci": "LFCY", + "aeronef": "Pilatus", + "imat": "F-GTOP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["AK"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-08-26_S00227.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-26T00:00:00.000+00:00", + "numero": 228, + "lieu": "Royan", + "oaci": "LFCY", + "aeronef": "Pilatus", + "imat": "F-GTOP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["AK"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-08-26_S00228.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-26T00:00:00.000+00:00", + "numero": 229, + "lieu": "Royan", + "oaci": "LFCY", + "aeronef": "Pilatus", + "imat": "F-GTOP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["AK"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-08-26_S00229.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-30T00:00:00.000+00:00", + "numero": 230, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-08-30_S00230.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-30T00:00:00.000+00:00", + "numero": 231, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-08-30_S00231.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-30T00:00:00.000+00:00", + "numero": 232, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-08-30_S00232.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-30T00:00:00.000+00:00", + "numero": 233, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 4, + "sautants": ["Cédric", "Charles", "Paul"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2020-08-30_S00233.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-30T00:00:00.000+00:00", + "numero": 234, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 4, + "sautants": ["Cédric", "Charles", "Paul"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2020-08-30_S00234.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-08-30T00:00:00.000+00:00", + "numero": 235, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 4, + "sautants": ["Cédric", "Charles", "Paul"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2020-08-30_S00235.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-09-05T00:00:00.000+00:00", + "numero": 236, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 2, + "sautants": ["Loïc"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-09-05_S00236.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-09-05T00:00:00.000+00:00", + "numero": 237, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 3, + "sautants": ["Pascal", "Loïc"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-09-05_S00237.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-09-05T00:00:00.000+00:00", + "numero": 238, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Pascal", "Koen"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-09-05_S00238.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-09-05T00:00:00.000+00:00", + "numero": 239, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Pascal", "Koen"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-09-05_S00239.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-09-05T00:00:00.000+00:00", + "numero": 240, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Pascal"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-09-05_S00240.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-09-05T00:00:00.000+00:00", + "numero": 241, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Pascal"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-09-05_S00241.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-09-06T00:00:00.000+00:00", + "numero": 242, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 4, + "sautants": ["Loïc", "Pascal", "Simon"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-09-06_S00242.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-09-06T00:00:00.000+00:00", + "numero": 243, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 5, + "sautants": ["Loïc", "Pascal", "Simon", "Warren"], + "programme": "", + "accessoires": "Drisse", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-09-06_S00243.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-09-06T00:00:00.000+00:00", + "numero": 244, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 3, + "sautants": ["Pascal", "Vincent"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2020-09-06_S00244.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-09-06T00:00:00.000+00:00", + "numero": 245, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Pascal", "Vincent"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-09-06_S00245.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-09-06T00:00:00.000+00:00", + "numero": 246, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Pascal", "Vincent"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-09-06_S00246.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-09-12T00:00:00.000+00:00", + "numero": 247, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Romain"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-09-12_S00247.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-09-12T00:00:00.000+00:00", + "numero": 248, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Romain"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-09-12_S00248.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-09-12T00:00:00.000+00:00", + "numero": 249, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 2, + "sautants": ["Romain"], + "programme": "Lapin", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2020-09-12_S00249.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-09-12T00:00:00.000+00:00", + "numero": 250, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 4, + "sautants": ["Aurelien", "Fred", "Fredy"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2020-09-12_S00250.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-09-12T00:00:00.000+00:00", + "numero": 251, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 4, + "sautants": ["Aurelien", "Fred", "Fredy"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2020-09-12_S00251.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-09-19T00:00:00.000+00:00", + "numero": 252, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Fred"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-09-19_S00252.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-09-19T00:00:00.000+00:00", + "numero": 253, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Fred"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-09-19_S00253.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-09-19T00:00:00.000+00:00", + "numero": 254, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Fred", "Aurelien"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-09-19_S00254.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-09-19T00:00:00.000+00:00", + "numero": 255, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Fred", "Aurelien"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-09-19_S00255.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-09-19T00:00:00.000+00:00", + "numero": 256, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Fred", "Aurelien"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-09-19_S00256.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-09-20T00:00:00.000+00:00", + "numero": 257, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Loïc", "Antoine"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-09-20_S00257.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-09-20T00:00:00.000+00:00", + "numero": 258, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Loïc"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-09-20_S00258.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-09-20T00:00:00.000+00:00", + "numero": 259, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Loïc", "Antoine"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-09-20_S00259.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-09-20T00:00:00.000+00:00", + "numero": 260, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Loïc"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-09-20_S00260.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-09-20T00:00:00.000+00:00", + "numero": 261, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Loïc", "Antoine"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-09-20_S00261.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-10-11T00:00:00.000+00:00", + "numero": 262, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Pascal"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-10-11_S00262.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-10-11T00:00:00.000+00:00", + "numero": 263, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Pascal"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-10-11_S00263.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-10-11T00:00:00.000+00:00", + "numero": 264, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 2, + "sautants": ["Pascal"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2020-10-11_S00264.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-10-11T00:00:00.000+00:00", + "numero": 265, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 2, + "sautants": ["Pascal"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2020-10-11_S00265.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-10-17T00:00:00.000+00:00", + "numero": 266, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Charles", "Cédric"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-10-17_S00266.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-10-17T00:00:00.000+00:00", + "numero": 267, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Charles", "Cédric"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-10-17_S00267.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-10-17T00:00:00.000+00:00", + "numero": 268, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 4, + "sautants": ["Charles", "Cédric", "Stéphane"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-10-17_S00268.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-10-17T00:00:00.000+00:00", + "numero": 269, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 7, + "sautants": ["Corentin", "Théo", "Charles", "Frigo", "Cédric", "Stéphane"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2020-10-17_S00269.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-10-17T00:00:00.000+00:00", + "numero": 270, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 7, + "sautants": ["Corentin", "Théo", "Charles", "Frigo", "Cédric", "Stéphane"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2020-10-17_S00270.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-10-17T00:00:00.000+00:00", + "numero": 271, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 4, + "sautants": ["Corentin", "Théo", "Charles"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2020-10-17_S00271.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-10-18T00:00:00.000+00:00", + "numero": 272, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Pascal"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-10-18_S00272.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-10-18T00:00:00.000+00:00", + "numero": 273, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Pascal"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-10-18_S00273.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-10-18T00:00:00.000+00:00", + "numero": 274, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Pascal"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-10-18_S00274.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-10-18T00:00:00.000+00:00", + "numero": 275, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 2, + "sautants": ["Pascal"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2020-10-18_S00275.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-10-18T00:00:00.000+00:00", + "numero": 276, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Pascal"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-10-18_S00276.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-10-18T00:00:00.000+00:00", + "numero": 277, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 2, + "sautants": ["Pascal"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2020-10-18_S00277.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-10-24T00:00:00.000+00:00", + "numero": 278, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 5, + "sautants": ["Aurelien", "Charles", "Fredy", "Steven"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2020-10-24_S00278.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-10-24T00:00:00.000+00:00", + "numero": 279, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 6, + "sautants": ["Aurelien", "Charles", "Fred", "Fredy", "Steven"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2020-10-24_S00279.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-10-24T00:00:00.000+00:00", + "numero": 280, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 8, + "sautants": ["Aurelien", "Charles", "Fred", "Fredy", "Steve", "Steven", "Samuel"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2020-10-24_S00280.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-10-29T00:00:00.000+00:00", + "numero": 281, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 3, + "sautants": ["Pascal", "Vincent"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2020-10-29_S00281.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-10-29T00:00:00.000+00:00", + "numero": 282, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 4, + "sautants": ["Pascal", "Vincent", "?"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2020-10-29_S00282.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-10-29T00:00:00.000+00:00", + "numero": 283, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 2, + "sautants": ["Pascal"], + "programme": "(trace ?)", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2020-10-29_S00283.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-10-29T00:00:00.000+00:00", + "numero": 284, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 5, + "sautants": ["Pascal", "Loïc", "Camille", "?"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-10-29_S00284.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2020-10-29T00:00:00.000+00:00", + "numero": 285, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Pulse", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 5, + "sautants": ["Pascal", "Loïc", "Stéphane", "Maude"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2020-10-29_S00285.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-06-05T00:00:00.000+00:00", + "numero": 286, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 190, + "categorie": "VR", + "module": "", + "participants": 6, + "sautants": ["Charlotte", "Cédric", "Pascal", "Samuel", "Waren"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2021-06-05_S00286.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-06-05T00:00:00.000+00:00", + "numero": 287, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 190, + "categorie": "VR", + "module": "", + "participants": 5, + "sautants": ["Charlotte", "Cédric", "Pascal", "Waren"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2021-06-05_S00287.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-06-06T00:00:00.000+00:00", + "numero": 288, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 190, + "categorie": "VR", + "module": "", + "participants": 4, + "sautants": ["Loïc", "Corentin", "Steve"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2021-06-06_S00288.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-06-06T00:00:00.000+00:00", + "numero": 289, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 190, + "categorie": "VR", + "module": "", + "participants": 4, + "sautants": ["Loïc", "Corentin", "Steve"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2021-06-06_S00289.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-06-06T00:00:00.000+00:00", + "numero": 290, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 190, + "categorie": "VR", + "module": "", + "participants": 4, + "sautants": ["Loïc", "Corentin", "Steve"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2021-06-06_S00290.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-06-12T00:00:00.000+00:00", + "numero": 291, + "lieu": "Sables d'Olonne", + "oaci": "LFOO", + "aeronef": "Caravan", + "imat": "F-HSVS", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 210, + "categorie": "VR", + "module": "", + "participants": 4, + "sautants": ["Corentin", "Steve", "Théo"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2021-06-12_S00291.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-06-12T00:00:00.000+00:00", + "numero": 292, + "lieu": "Sables d'Olonne", + "oaci": "LFOO", + "aeronef": "Caravan", + "imat": "F-HMVA", + "hauteur": 7700, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 210, + "categorie": "VR", + "module": "", + "participants": 4, + "sautants": ["Corentin", "Steve", "Théo"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2021-06-12_S00292.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-06-13T00:00:00.000+00:00", + "numero": 293, + "lieu": "Sables d'Olonne", + "oaci": "LFOO", + "aeronef": "Caravan", + "imat": "F-HMVA", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "FF", + "module": "Track", + "participants": 4, + "sautants": ["Corentin", "Steve", "Théo"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2021-06-13_S00293.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-06-13T00:00:00.000+00:00", + "numero": 294, + "lieu": "Sables d'Olonne", + "oaci": "LFOO", + "aeronef": "Caravan", + "imat": "F-HMVA", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "FF", + "module": "Track", + "participants": 3, + "sautants": ["Steve", "Théo"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2021-06-13_S00294.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-07-17T00:00:00.000+00:00", + "numero": 295, + "lieu": "Royan", + "oaci": "LFCY", + "aeronef": "Dornier", + "imat": "D-ISCO", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "FF", + "module": "Track", + "participants": 3, + "sautants": ["Corentin", "Steve"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2021-07-17_S00295.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-07-17T00:00:00.000+00:00", + "numero": 296, + "lieu": "Royan", + "oaci": "LFCY", + "aeronef": "Pilatus", + "imat": "F-GTOP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "FF", + "module": "Track", + "participants": 6, + "sautants": ["Charles", "Corentin", "Pascal", "Samuel", "Steve"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2021-07-17_S00296.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-07-17T00:00:00.000+00:00", + "numero": 297, + "lieu": "Royan", + "oaci": "LFCY", + "aeronef": "Dornier", + "imat": "D-ISCO", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "FF", + "module": "Track", + "participants": 6, + "sautants": ["Charles", "Corentin", "Pascal", "Samuel", "Steve"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2021-07-17_S00297.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-07-17T00:00:00.000+00:00", + "numero": 298, + "lieu": "Royan", + "oaci": "LFCY", + "aeronef": "Dornier", + "imat": "D-ISCO", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Pascal", "Samuel"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2021-07-17_S00298.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-07-17T00:00:00.000+00:00", + "numero": 299, + "lieu": "Royan", + "oaci": "LFCY", + "aeronef": "Pilatus", + "imat": "F-GTOP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "FF", + "module": "Track", + "participants": 6, + "sautants": ["Charlotte", "Corentin", "Pascal", "Samuel", "Steve"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2021-07-17_S00299.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-07-18T00:00:00.000+00:00", + "numero": 300, + "lieu": "Rochefort", + "oaci": "LFDN", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "FF", + "module": "Track", + "participants": 7, + "sautants": ["Cédric", "Charles", "Corentin", "Pascal", "Samuel", "Steve"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2021-07-18_S00300.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-07-18T00:00:00.000+00:00", + "numero": 301, + "lieu": "Rochefort", + "oaci": "LFDN", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 190, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Charlotte"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2021-07-18_S00301.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-07-24T00:00:00.000+00:00", + "numero": 302, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GJBP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Electra", + "taille": 170, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Posé vent dans le dos, fracture 2éme metacarpien main gauche", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2021-07-24_S00302.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-09-05T00:00:00.000+00:00", + "numero": 303, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 3, + "sautants": ["Charles", "Samuel"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2021-09-05_S00303.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-09-05T00:00:00.000+00:00", + "numero": 304, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 5, + "sautants": ["Charles", "Corentin", "Samuel", "Cédric"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2021-09-05_S00304.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-09-05T00:00:00.000+00:00", + "numero": 305, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Charlotte", "Mariette"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2021-09-05_S00305.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-09-11T00:00:00.000+00:00", + "numero": 306, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 5, + "sautants": ["Charles", "Pascal", "Nitro", "Pitou"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2021-09-11_S00306.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-09-19T00:00:00.000+00:00", + "numero": 307, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Camille", "Murat"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2021-09-19_S00307.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-09-19T00:00:00.000+00:00", + "numero": 308, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Corentin"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2021-09-19_S00308.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-09-19T00:00:00.000+00:00", + "numero": 309, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Corentin"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2021-09-19_S00309.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-09-19T00:00:00.000+00:00", + "numero": 310, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Corentin"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2021-09-19_S00310.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-09-19T00:00:00.000+00:00", + "numero": 311, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Corentin"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2021-09-19_S00311.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-09-25T00:00:00.000+00:00", + "numero": 312, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Rémi"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2021-09-25_S00312.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-09-25T00:00:00.000+00:00", + "numero": 313, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Loïc", "Emilien"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2021-09-25_S00313.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-10-09T00:00:00.000+00:00", + "numero": 314, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 4, + "sautants": ["Camille", "Pascal", "Samuel"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2021-10-09_S00314.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-10-09T00:00:00.000+00:00", + "numero": 315, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 5, + "sautants": ["Lucie", "Samuel", "Pascal", "Steve"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2021-10-09_S00315.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-10-09T00:00:00.000+00:00", + "numero": 316, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 5, + "sautants": ["Lucie", "Samuel", "Pascal", "Steve"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2021-10-09_S00316.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-10-09T00:00:00.000+00:00", + "numero": 317, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 8, + "sautants": ["Pauline", "Lucie", "Samuel", "Pascal", "Ponpon", "Nanar", "Claude"], + "programme": "", + "accessoires": "", + "zone": "Plage", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2021-10-09_S00317.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-10-10T00:00:00.000+00:00", + "numero": 318, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4400, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 4, + "sautants": ["Mathias", "Lucie", "Pascal"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2021-10-10_S00318.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-10-10T00:00:00.000+00:00", + "numero": 319, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4300, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 5, + "sautants": ["Corentin", "Lucie", "Steve", "Pascal"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2021-10-10_S00319.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-10-10T00:00:00.000+00:00", + "numero": 320, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 5, + "sautants": ["Corentin", "Lucie", "Steve", "Pascal"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2021-10-10_S00320.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-10-10T00:00:00.000+00:00", + "numero": 321, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 5000, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 6, + "sautants": ["Corentin", "Lucie", "Steve", "Pascal", "Sylvain"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2021-10-10_S00321.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-10-16T00:00:00.000+00:00", + "numero": 322, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 5, + "sautants": ["Corentin", "Fred", "Rodolphe", "Samuel"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2021-10-16_S00322.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-10-16T00:00:00.000+00:00", + "numero": 323, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 7, + "sautants": ["Corentin", "Fred", "Rodolphe", "Samuel", "Lucie", "Issa"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2021-10-16_S00323.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-10-16T00:00:00.000+00:00", + "numero": 324, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 5, + "sautants": ["Corentin", "Fred", "Rodolphe", "Lucie"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2021-10-16_S00324.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-10-16T00:00:00.000+00:00", + "numero": 325, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 7, + "sautants": ["Corentin", "Fred", "Rodolphe", "Lucie", "Pascal", "Issa"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2021-10-16_S00325.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-10-16T00:00:00.000+00:00", + "numero": 326, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 8, + "sautants": ["Corentin", "Fred", "Rodolphe", "Lucie", "Pascal", "Issa", "Charlotte"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2021-10-16_S00326.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-10-16T00:00:00.000+00:00", + "numero": 327, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 6, + "sautants": ["Corentin", "Fred", "Rodolphe", "Steve", "Pascal"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2021-10-16_S00327.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-10-17T00:00:00.000+00:00", + "numero": 328, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 7, + "sautants": ["Corentin", "Fred", "Rodolphe", "Cédric", "Pascal", "Issa"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2021-10-17_S00328.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-10-17T00:00:00.000+00:00", + "numero": 329, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 10, + "sautants": ["Charlotte", "Tom", "Lucie", "Corentin", "Fred", "Rodolphe", "Cédric", "Pascal", "Issa"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2021-10-17_S00329.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-10-17T00:00:00.000+00:00", + "numero": 330, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 5, + "sautants": ["Corentin", "Lucie", "Issa", "Pascal"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2021-10-17_S00330.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-10-17T00:00:00.000+00:00", + "numero": 331, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 3, + "sautants": ["Corentin", "Lucie"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2021-10-17_S00331.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-10-23T00:00:00.000+00:00", + "numero": 332, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Toi Nous", "Cédric"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2021-10-23_S00332.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-10-23T00:00:00.000+00:00", + "numero": 333, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 3, + "sautants": ["Toi Nous", "Cédric"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2021-10-23_S00333.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-10-23T00:00:00.000+00:00", + "numero": 334, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 4, + "sautants": ["Cédric", "Steve", "Regis"], + "programme": "", + "accessoires": "", + "zone": "Plage", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2021-10-23_S00334.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-10-24T00:00:00.000+00:00", + "numero": 335, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 4, + "sautants": ["Charles", "Loïc", "Tiffany"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2021-10-24_S00335.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-10-24T00:00:00.000+00:00", + "numero": 336, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Loïc", "Kevin"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2021-10-24_S00336.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-10-24T00:00:00.000+00:00", + "numero": 337, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 5, + "sautants": ["Cédric", "Charles", "Loïc", "Kevin"], + "programme": "", + "accessoires": "", + "zone": "Plage", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2021-10-24_S00337.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-11-04T00:00:00.000+00:00", + "numero": 338, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 4, + "sautants": ["Cathy Bouette", "Aurelien", "Warren"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2021-11-04_S00338.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-11-04T00:00:00.000+00:00", + "numero": 339, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 4, + "sautants": ["Cathy Bouette", "Aurelien", "Warren"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2021-11-04_S00339.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-11-04T00:00:00.000+00:00", + "numero": 340, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 10, + "sautants": ["Cathy Bouette", "Eliot Pothet", "Nico Villemin", "Aurelien", "Axel", "Pitou", "Quentin ", "Alexandre", "Warren"], + "programme": "Hybride", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2021-11-04_S00340.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-11-04T00:00:00.000+00:00", + "numero": 341, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 4, + "sautants": ["Cathy Bouette", "Aurelien", "Warren"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2021-11-04_S00341.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-11-05T00:00:00.000+00:00", + "numero": 342, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 5, + "sautants": ["Eliot Pothet", "Guillaume", "Stéphane", "Cédric"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2021-11-05_S00342.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-11-05T00:00:00.000+00:00", + "numero": 343, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 4, + "sautants": ["Eliot Pothet", "Guillaume", "Cédric"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2021-11-05_S00343.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-11-05T00:00:00.000+00:00", + "numero": 344, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 4, + "sautants": ["Eliot Pothet", "Guillaume", "Cédric"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2021-11-05_S00344.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-11-05T00:00:00.000+00:00", + "numero": 345, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 5, + "sautants": ["Stephan", "Guillaume /Cédric", "Stéphane"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2021-11-05_S00345.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-11-06T00:00:00.000+00:00", + "numero": 346, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 5, + "sautants": ["Mathias", "Corentin", "Pascal", "Eric"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2021-11-06_S00346.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-11-06T00:00:00.000+00:00", + "numero": 347, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 5, + "sautants": ["Mathias", "Corentin", "Pascal", "Eric"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2021-11-06_S00347.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-11-06T00:00:00.000+00:00", + "numero": 348, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 5, + "sautants": ["Mathias", "Corentin", "Pascal", "Eric"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2021-11-06_S00348.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-11-06T00:00:00.000+00:00", + "numero": 349, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 5, + "sautants": ["Mathias", "Corentin", "Pascal", "Charlotte", "Eric"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2021-11-06_S00349.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-11-06T00:00:00.000+00:00", + "numero": 350, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 10, + "sautants": ["Cathy Bouette", "Charlotte", "Corentin ", "Nicolas", "Stéphane", "Alexnddre", "Eric", "Jolane", "Sebastien"], + "programme": "", + "accessoires": "", + "zone": "Plage", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2021-11-06_S00350.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-11-20T00:00:00.000+00:00", + "numero": 351, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 7, + "sautants": ["Tom", "Charlotte", "Charles", "Pascal", "Samuel", "Romain"], + "programme": "", + "accessoires": "Tube", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2021-11-20_S00351.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-11-20T00:00:00.000+00:00", + "numero": 352, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 7, + "sautants": ["Tom", "Charlotte", "Charles", "Pascal", "Samuel", "Romain"], + "programme": "", + "accessoires": "Tube", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2021-11-20_S00352.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-11-20T00:00:00.000+00:00", + "numero": 353, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 6, + "sautants": ["Tom", "Charlotte", "Charles", "Pitou", "Samuel"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2021-11-20_S00353.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-11-20T00:00:00.000+00:00", + "numero": 354, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 7, + "sautants": ["Tom", "Charlotte", "Charles", "Pitou", "Pascal", "Murat"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2021-11-20_S00354.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-12-18T00:00:00.000+00:00", + "numero": 355, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 4, + "sautants": ["Samuel", "Loïc", "Guillaume"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2021-12-18_S00355.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-12-18T00:00:00.000+00:00", + "numero": 356, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 4, + "sautants": ["Samuel", "Loïc", "Guillaume"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2021-12-18_S00356.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-12-18T00:00:00.000+00:00", + "numero": 357, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 4, + "sautants": ["Samuel", "Loïc", "Guillaume"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2021-12-18_S00357.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2021-12-18T00:00:00.000+00:00", + "numero": 358, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 5, + "sautants": ["Jerôme", "Cédric", "Charlotte", "Guillaume"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2021-12-18_S00358.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-04-02T00:00:00.000+00:00", + "numero": 359, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Solo - Reprise ", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-04-02_S00359.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-04-02T00:00:00.000+00:00", + "numero": 360, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 3, + "sautants": ["Charles", "Samuel"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2022-04-02_S00360.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-04-02T00:00:00.000+00:00", + "numero": 361, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Charles", "Samuel"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-04-02_S00361.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-04-03T00:00:00.000+00:00", + "numero": 362, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 10, + "sautants": ["Tom", "Charlotte", "Hassan", "Camille", "Romain", "Sylvain", "Cédric", "Magalie", "Warren"], + "programme": "100ème Magalie", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2022-04-03_S00362.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-04-03T00:00:00.000+00:00", + "numero": 363, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Cédric"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-04-03_S00363.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-04-09T00:00:00.000+00:00", + "numero": 364, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Transitions - Tentative Head Down", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-04-09_S00364.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-04-09T00:00:00.000+00:00", + "numero": 365, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Romain"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-04-09_S00365.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-04-09T00:00:00.000+00:00", + "numero": 366, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 4, + "sautants": ["Hassan", "Charlotte", "Romain"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-04-09_S00366.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-04-09T00:00:00.000+00:00", + "numero": 367, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 4, + "sautants": ["Hassan", "Charlotte", "Romain"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-04-09_S00367.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-04-10T00:00:00.000+00:00", + "numero": 368, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 5, + "sautants": ["Hassan", "Charles", "Pascal", "Romain"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-04-10_S00368.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-04-10T00:00:00.000+00:00", + "numero": 369, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 5, + "sautants": ["Hassan", "Charles", "Pascal", "Romain"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-04-10_S00369.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-04-10T00:00:00.000+00:00", + "numero": 370, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 8, + "sautants": ["Hassan", "Charles", "Pascal", "Romain", "Sylvain", "Audrey", "Romain G."], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-04-10_S00370.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-04-10T00:00:00.000+00:00", + "numero": 371, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Charles"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-04-10_S00371.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-04-10T00:00:00.000+00:00", + "numero": 372, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Charles"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-04-10_S00372.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-04-16T00:00:00.000+00:00", + "numero": 373, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 4, + "sautants": ["Charles", "Corentin", "Steve"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-04-16_S00373.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-04-16T00:00:00.000+00:00", + "numero": 374, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 5, + "sautants": ["Charles", "Corentin", "Steve", "Quentin"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-04-16_S00374.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-04-16T00:00:00.000+00:00", + "numero": 375, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 4, + "sautants": ["Charles", "Corentin", "Steve"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-04-16_S00375.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-04-16T00:00:00.000+00:00", + "numero": 376, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 5, + "sautants": ["Charles", "Corentin", "Steve", "Paulo"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-04-16_S00376.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-04-16T00:00:00.000+00:00", + "numero": 377, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Charles"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-04-16_S00377.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-04-17T00:00:00.000+00:00", + "numero": 378, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Loïc", "Samuel"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-04-17_S00378.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-04-17T00:00:00.000+00:00", + "numero": 379, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Charlotte", "Samuel"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-04-17_S00379.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-04-17T00:00:00.000+00:00", + "numero": 380, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 5, + "sautants": ["Hassan", "Charlotte", "Samuel", "Warren"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-04-17_S00380.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-04-17T00:00:00.000+00:00", + "numero": 381, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 5, + "sautants": ["Hassan", "Charlotte", "Samuel", "Warren"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-04-17_S00381.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-04-17T00:00:00.000+00:00", + "numero": 382, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4600, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Charlotte"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-04-17_S00382.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-04-30T00:00:00.000+00:00", + "numero": 383, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 4, + "sautants": ["Corentin", "Pascal", "Jèrôme"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-04-30_S00383.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-04-30T00:00:00.000+00:00", + "numero": 384, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 3, + "sautants": ["Corentin", "Pascal"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-04-30_S00384.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-04-30T00:00:00.000+00:00", + "numero": 385, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Transitions - Tentative Head Down", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-04-30_S00385.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-04-30T00:00:00.000+00:00", + "numero": 386, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Corentin"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-04-30_S00386.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-04-30T00:00:00.000+00:00", + "numero": 387, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Transitions - Tentative Head Down", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-04-30_S00387.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-05-01T00:00:00.000+00:00", + "numero": 388, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Samuel"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-05-01_S00388.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-05-01T00:00:00.000+00:00", + "numero": 389, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "Solo", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Transitions - Tentative Head Down", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-05-01_S00389.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-05-01T00:00:00.000+00:00", + "numero": 390, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 5, + "sautants": ["Tom", "Samuel", "Romain", "Warren"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-05-01_S00390.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-05-06T00:00:00.000+00:00", + "numero": 391, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 5, + "sautants": ["Charles", "Guillaume", "Jean Pierre", "Stéphane"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-05-06_S00391.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-05-06T00:00:00.000+00:00", + "numero": 392, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 7, + "sautants": ["Hassan", "Charles", "Guillaume", "Jean Pierre", "Stéphane", "Michel"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-05-06_S00392.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-05-07T00:00:00.000+00:00", + "numero": 393, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 5, + "sautants": ["Hassan", "Romain", "Guillaume", "Steve"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-05-07_S00393.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-05-07T00:00:00.000+00:00", + "numero": 394, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 5, + "sautants": ["Mathias", "Romain", "Guillaume", "Steve"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-05-07_S00394.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-05-07T00:00:00.000+00:00", + "numero": 395, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 10, + "sautants": ["Michel", "Bernard", "Ponpon", "Claude", "Charlotte", "Sylvain /Sylvain", "?", "?"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2022-05-07_S00395.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-05-08T00:00:00.000+00:00", + "numero": 396, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["?"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-05-08_S00396.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-05-08T00:00:00.000+00:00", + "numero": 397, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 4, + "sautants": ["Corentin", "Steve", "Many"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-05-08_S00397.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-05-08T00:00:00.000+00:00", + "numero": 398, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 7, + "sautants": ["Hassan", "Corentin", "Charles", "Steve", "Romain", "Many"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-05-08_S00398.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-05-08T00:00:00.000+00:00", + "numero": 399, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 4, + "sautants": ["Mathias", "Steve", "Warren"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-05-08_S00399.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-05-08T00:00:00.000+00:00", + "numero": 400, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 10, + "sautants": ["Hassan", "Tom", "Sylvain", "Mathias", "Corentin", "Charles", "Steve", "Romain", "Warren"], + "programme": "", + "accessoires": "Tube", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2022-05-08_S00400.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-05-14T00:00:00.000+00:00", + "numero": 401, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 4, + "sautants": ["Corentin", "Charles", "Romain"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-05-14_S00401.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-05-14T00:00:00.000+00:00", + "numero": 402, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 5, + "sautants": ["Corentin", "Théo", "Steve", "Charles"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-05-14T00:00:00.000+00:00", + "numero": 403, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 6, + "sautants": ["Hassan", "Charles", "Steve", "Théo", "Denis"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-05-14_S00403.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-05-14T00:00:00.000+00:00", + "numero": 404, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 5, + "sautants": ["Corentin /Steve", "Théo", "Charles"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-05-14_S00404.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-05-14T00:00:00.000+00:00", + "numero": 405, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 10, + "sautants": ["Charlotte", "Corentin", "Charles", "Steve", "Pascal", "Théo", "Denis", "Alexis", "Régis"], + "programme": "", + "accessoires": "Tube", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2022-05-14_S00405.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-05-21T00:00:00.000+00:00", + "numero": 406, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 2, + "sautants": ["?"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-05-21_S00406.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-05-21T00:00:00.000+00:00", + "numero": 407, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 1, + "sautants": [], + "programme": "Feeling", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-05-21_S00407.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-05-21T00:00:00.000+00:00", + "numero": 408, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Romain"], + "programme": "Romain (head down)", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-05-21_S00408.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-05-21T00:00:00.000+00:00", + "numero": 409, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 5, + "sautants": ["Romain", "Loïc", "?", "?"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-05-21_S00409.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-05-21T00:00:00.000+00:00", + "numero": 410, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 4, + "sautants": ["Hassan", "Romain", "Loic"], + "programme": "Track - Trace - Head Up", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-05-21_S00410.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-05-22T00:00:00.000+00:00", + "numero": 411, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 2, + "sautants": ["Corentin"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-05-22_S00411.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-05-22T00:00:00.000+00:00", + "numero": 412, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Corentin", "Romain"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-05-22_S00412.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-05-22T00:00:00.000+00:00", + "numero": 413, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 2, + "sautants": ["Corentin"], + "programme": "Track - Head", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-05-22_S00413.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-05-22T00:00:00.000+00:00", + "numero": 414, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 4, + "sautants": ["Corentin", "Romain", "Loïc"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-05-22_S00414.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-05-27T00:00:00.000+00:00", + "numero": 415, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Cédric", "Denis"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-05-27_S00415.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-05-27T00:00:00.000+00:00", + "numero": 416, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 4, + "sautants": ["Cédric", "Charlotte", "Denis"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-05-27_S00416.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-05-27T00:00:00.000+00:00", + "numero": 417, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 4, + "sautants": ["Cédric", "Charlotte", "Denis"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-05-27_S00417.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-05-27T00:00:00.000+00:00", + "numero": 418, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 6, + "sautants": ["Charlotte", "Cédric", "Denis", "?", "?"], + "programme": "", + "accessoires": "Tube", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2022-05-27_S00418.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-05-27T00:00:00.000+00:00", + "numero": 419, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 3, + "sautants": ["Cédric", "Denis"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-05-27_S00419.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-05-27T00:00:00.000+00:00", + "numero": 420, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 3, + "sautants": ["Cédric", "Denis"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-05-27_S00420.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-05-28T00:00:00.000+00:00", + "numero": 421, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Charles"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-05-28_S00421.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-05-28T00:00:00.000+00:00", + "numero": 422, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Charles"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-05-28_S00422.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-05-28T00:00:00.000+00:00", + "numero": 423, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Charles"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-05-28_S00423.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-05-28T00:00:00.000+00:00", + "numero": 424, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Charles"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-05-28_S00424.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-06-05T00:00:00.000+00:00", + "numero": 425, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Track", + "participants": 6, + "sautants": ["Hassan", "Charlotte", "Romain", "Cédric", "Rodolphe"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-06-05_S00425.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-06-05T00:00:00.000+00:00", + "numero": 426, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Romain", "Cédric"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-06-05_S00426.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-06-05T00:00:00.000+00:00", + "numero": 427, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 10, + "sautants": ["Charlotte", "Sylvain", "Cédric", "Warren", "Ponpon", "Edouard", "Timothé", "?", "?"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2022-06-05_S00427.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-06-12T00:00:00.000+00:00", + "numero": 428, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOCC", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "FF", + "module": "Chutas", + "participants": 5, + "sautants": ["Charlotte", "Camille", "Romain", "Nico"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-06-12_S00428.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-06-12T00:00:00.000+00:00", + "numero": 429, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOCC", + "hauteur": 4200, + "deploiement": 1000, + "voile": "X-Fun", + "taille": 170, + "categorie": "VR", + "module": "", + "participants": 7, + "sautants": ["Warren", "Charlotte", "Camille", "Nico", "Romain", "Sylvain"], + "programme": "200ème Warren", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2022-06-12_S00429.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-06-12T00:00:00.000+00:00", + "numero": 430, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOCC", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["?"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-06-12_S00430.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-06-12T00:00:00.000+00:00", + "numero": 431, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOCC", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Track", + "participants": 4, + "sautants": ["Mathias", "Murat", "Warren"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-06-12_S00431.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-06-26T00:00:00.000+00:00", + "numero": 432, + "lieu": "Soulac", + "oaci": "LFDK", + "aeronef": "Pilatus", + "imat": "F-GIXX", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Charles"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-06-26_S00432.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-06-26T00:00:00.000+00:00", + "numero": 433, + "lieu": "Soulac", + "oaci": "LFDK", + "aeronef": "Pilatus", + "imat": "F-GIXX", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Charles"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-06-26_S00433.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-06-26T00:00:00.000+00:00", + "numero": 434, + "lieu": "Soulac", + "oaci": "LFDK", + "aeronef": "Pilatus", + "imat": "F-GIXX", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Charles"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-06-26_S00434.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-06-26T00:00:00.000+00:00", + "numero": 435, + "lieu": "Soulac", + "oaci": "LFDK", + "aeronef": "Pilatus", + "imat": "F-GIXX", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Charles", "Gromite (Nico)"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-06-26_S00435.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-07-03T00:00:00.000+00:00", + "numero": 436, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Track", + "participants": 5, + "sautants": ["Hassan", "Thomas SR", "Charles", "Pascal"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-07-03_S00436.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-07-03T00:00:00.000+00:00", + "numero": 437, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 6, + "sautants": ["Hassan", "Loïc", "Jocelyn", "Bastiane", "Rubens"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-07-03_S00437.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-07-03T00:00:00.000+00:00", + "numero": 438, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Track", + "participants": 5, + "sautants": ["Charles", "Thomas SR", "Pascal", "Edouard"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-07-03_S00438.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-07-03T00:00:00.000+00:00", + "numero": 439, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Charles", "Pascal"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-07-03_S00439.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-07-03T00:00:00.000+00:00", + "numero": 440, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "VR", + "module": "", + "participants": 10, + "sautants": ["Timothé", "Edouard", "Eliott", "Warren", "Ponpon", "Michel", "?", "?", "?"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2022-07-03_S00440.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-07-09T00:00:00.000+00:00", + "numero": 441, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 4, + "sautants": ["Mathias", "Stéphane", "Corentin"], + "programme": "Mathias (Head down) - Stéphane (Head down)", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-07-09_S00441.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-07-09T00:00:00.000+00:00", + "numero": 442, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Corentin", "Loïc"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-07-09_S00442.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-07-09T00:00:00.000+00:00", + "numero": 443, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Trace", + "participants": 5, + "sautants": ["Mathias", "Stéphane", "Corentin", "Jocelyn"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Trace/", + "video": "2022-07-09_S00443.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-07-09T00:00:00.000+00:00", + "numero": 444, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 5, + "sautants": ["Mathias", "Stéphane", "Corentin", "Jocelyn"], + "programme": "", + "accessoires": "Tube", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-07-09_S00444.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-07-10T00:00:00.000+00:00", + "numero": 445, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Corentin"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-07-10_S00445.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-07-10T00:00:00.000+00:00", + "numero": 446, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Track", + "participants": 3, + "sautants": ["Corentin", "Issa"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-07-10_S00446.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-07-10T00:00:00.000+00:00", + "numero": 447, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Corentin", "Issa"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-07-10_S00447.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-07-10T00:00:00.000+00:00", + "numero": 448, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Issa"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-07-10_S00448.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-07-10T00:00:00.000+00:00", + "numero": 449, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Track", + "participants": 6, + "sautants": ["Tom", "Sylvain", "Edouard", "Warren", "?"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-07-10_S00449.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-07-23T00:00:00.000+00:00", + "numero": 450, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GMEL", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Charles", "Fred"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-07-23_S00450.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-07-23T00:00:00.000+00:00", + "numero": 451, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GMEL", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Charles", "Fred"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-07-23_S00451.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-07-23T00:00:00.000+00:00", + "numero": 452, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GMEL", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Track", + "participants": 4, + "sautants": ["Charles", "Fred", "Patrice"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-07-23_S00452.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-07-23T00:00:00.000+00:00", + "numero": 453, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GMEL", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Charles", "Fred"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-07-23_S00453.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-07-24T00:00:00.000+00:00", + "numero": 454, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GMEL", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 4, + "sautants": ["Charles", "Samuel", "Koen"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-07-24_S00454.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-07-24T00:00:00.000+00:00", + "numero": 455, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GMEL", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 4, + "sautants": ["Charles", "Samuel", "Koen"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-07-24_S00455.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-07-24T00:00:00.000+00:00", + "numero": 456, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GMEL", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 4, + "sautants": ["Charles", "Samuel", "Koen"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-07-24_S00456.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-07-24T00:00:00.000+00:00", + "numero": 457, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GMEL", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 5, + "sautants": ["Charles", "Samuel", "Koen", "Lolo"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-07-24_S00457.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-08-06T00:00:00.000+00:00", + "numero": 458, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Corentin"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-08-06_S00458.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-08-06T00:00:00.000+00:00", + "numero": 459, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Corentin"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-08-06_S00459.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-08-13T00:00:00.000+00:00", + "numero": 460, + "lieu": "Soulac", + "oaci": "LFDK", + "aeronef": "Pilatus", + "imat": "F-GRCP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 4, + "sautants": ["Charles", "Pascal", "Loïc"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-08-13_S00460.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-08-13T00:00:00.000+00:00", + "numero": 461, + "lieu": "Soulac", + "oaci": "LFDK", + "aeronef": "Pilatus", + "imat": "F-GRCP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 4, + "sautants": ["Charles", "Pascal", "Loïc"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-08-13_S00461.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-08-13T00:00:00.000+00:00", + "numero": 462, + "lieu": "Soulac", + "oaci": "LFDK", + "aeronef": "Pilatus", + "imat": "F-GRCP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 4, + "sautants": ["Charles", "Pascal", "Loïc"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-08-13_S00462.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-08-13T00:00:00.000+00:00", + "numero": 463, + "lieu": "Soulac", + "oaci": "LFDK", + "aeronef": "Pilatus", + "imat": "F-GRCP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 4, + "sautants": ["Charles", "Pascal", "Loïc"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-08-13_S00463.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-08-13T00:00:00.000+00:00", + "numero": 464, + "lieu": "Soulac", + "oaci": "LFDK", + "aeronef": "Pilatus", + "imat": "F-GRCP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 4, + "sautants": ["Charles", "Pascal", "Loïc"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-08-13_S00464.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-08-13T00:00:00.000+00:00", + "numero": 465, + "lieu": "Soulac", + "oaci": "LFDK", + "aeronef": "Pilatus", + "imat": "F-GRCP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Track", + "participants": 3, + "sautants": ["Charles", "Loïc"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-08-13_S00465.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-08-13T00:00:00.000+00:00", + "numero": 466, + "lieu": "Soulac", + "oaci": "LFDK", + "aeronef": "Pilatus", + "imat": "F-GRCP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Loïc"], + "programme": "", + "accessoires": "", + "zone": "Plage", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-08-13_S00466.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-08-15T00:00:00.000+00:00", + "numero": 467, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 4, + "sautants": ["Hassan", "Samuel", "Gaspar"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-08-15_S00467.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-08-15T00:00:00.000+00:00", + "numero": 468, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Track", + "participants": 6, + "sautants": ["Sylvain", "Charles", "Samuel", "Bastiane", "Gaspar"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-08-15_S00468.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-08-15T00:00:00.000+00:00", + "numero": 469, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Track", + "participants": 7, + "sautants": ["Sylvain", "Charles", "Charlotte", "Samuel", "Bastiane", "Gaspar"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-08-15_S00469.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-08-20T00:00:00.000+00:00", + "numero": 470, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Charlotte", "Jèrôme"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-08-20_S00470.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-08-20T00:00:00.000+00:00", + "numero": 471, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Tom"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-08-20_S00471.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-08-20T00:00:00.000+00:00", + "numero": 472, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "VR", + "module": "", + "participants": 8, + "sautants": ["Charlotte", "Eliott", "Timothé", "Ponpon", "Bernard", "Claude", "Michel"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2022-08-20_S00472.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-08-27T00:00:00.000+00:00", + "numero": 473, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Fabrice"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-08-27_S00473.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-08-27T00:00:00.000+00:00", + "numero": 474, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Corentin"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-08-27_S00474.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-08-28T00:00:00.000+00:00", + "numero": 475, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Cédric"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-08-28_S00475.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-08-28T00:00:00.000+00:00", + "numero": 476, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Cédric", "Romain"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-08-28_S00476.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-08-28T00:00:00.000+00:00", + "numero": 477, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Track", + "participants": 5, + "sautants": ["Hassan", "Cédric", "Edouard", "Warren"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-08-28_S00477.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-09-03T00:00:00.000+00:00", + "numero": 478, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GMEL", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "VR", + "module": "", + "participants": 5, + "sautants": ["Corentin", "Théo", "Charles", "Fab"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-09-03T00:00:00.000+00:00", + "numero": 479, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GMEL", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Track", + "participants": 5, + "sautants": ["Charles", "Corentin /Théo", "Frigo"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-09-03_S00479.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-09-03T00:00:00.000+00:00", + "numero": 480, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GMEL", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 4, + "sautants": ["Corentin", "Charles", "Firgo"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-09-03_S00480.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-09-03T00:00:00.000+00:00", + "numero": 481, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GMEL", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 4, + "sautants": ["Corentin", "Charles", "Firgo"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-09-03_S00481.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-09-03T00:00:00.000+00:00", + "numero": 482, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GMEL", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 6, + "sautants": ["Yannick", "Charles", "Théo", "Corentin", "Frigo"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-09-03_S00482.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-09-03T00:00:00.000+00:00", + "numero": 483, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GMEL", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Track", + "participants": 6, + "sautants": ["Stéphane", "Charles", "Corentin", "Théo", "Frigo"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-09-03_S00483.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-09-04T00:00:00.000+00:00", + "numero": 484, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GMEL", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 6, + "sautants": ["Corentin /Cahrles", "Théo", "Frigo", "Samuel"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-09-04_S00484.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-09-04T00:00:00.000+00:00", + "numero": 485, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GMEL", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Track", + "participants": 6, + "sautants": ["Corentin /Cahrles", "Théo", "Frigo", "Samuel"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-09-04_S00485.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-09-04T00:00:00.000+00:00", + "numero": 486, + "lieu": "La Reole", + "oaci": "LFDR", + "aeronef": "Pilatus", + "imat": "F-GMEL", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Track", + "participants": 4, + "sautants": ["Charles", "Samuel", "Frigo"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-09-04_S00486.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-09-17T00:00:00.000+00:00", + "numero": 487, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 4, + "sautants": ["Mickael Babylone", "AK", "Charlotte"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-09-17_S00487.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-09-17T00:00:00.000+00:00", + "numero": 488, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Nico", "?"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-09-17_S00488.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-09-17T00:00:00.000+00:00", + "numero": 489, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 5, + "sautants": ["Stéphane F", "Nico", "Denis", "Erwan"], + "programme": "", + "accessoires": "", + "zone": "Plage", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-09-17_S00489.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-09-18T00:00:00.000+00:00", + "numero": 490, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Track", + "participants": 4, + "sautants": ["Mickael Babylone", "?", "?"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-09-18_S00490.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-09-18T00:00:00.000+00:00", + "numero": 491, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Track", + "participants": 4, + "sautants": ["Stéphane Babylone", "Warren", "?"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-09-18_S00491.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-09-18T00:00:00.000+00:00", + "numero": 492, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Track", + "participants": 4, + "sautants": ["Stéphane Babylone", "Warren", "?"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-09-18_S00492.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-09-18T00:00:00.000+00:00", + "numero": 493, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Track", + "participants": 5, + "sautants": ["Stéphane Babylone", "Warren", "?", "?"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-09-18_S00493.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-09-18T00:00:00.000+00:00", + "numero": 494, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Trace", + "participants": 10, + "sautants": ["Mickael Babylone", "Tom", "Mathias", "Pitou", "Nico", "Erwan", "Julie", "Murat", "?"], + "programme": "Accident Mathias", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Trace/", + "video": "2022-09-18_S00494.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-10-08T00:00:00.000+00:00", + "numero": 495, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "VR", + "module": "", + "participants": 2, + "sautants": ["David"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2022-10-08_S00495.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-10-08T00:00:00.000+00:00", + "numero": 496, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 1500, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "Bi5", + "module": "", + "participants": 1, + "sautants": [], + "programme": "Sous voile Exercice 1", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Bi5/", + "video": "2022-10-08_S00496.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-10-08T00:00:00.000+00:00", + "numero": 497, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 1500, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "Bi5", + "module": "", + "participants": 1, + "sautants": [], + "programme": "Sous voile Exercice 2", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Bi5/", + "video": "2022-10-08_S00497.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-10-08T00:00:00.000+00:00", + "numero": 498, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 1500, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "Bi5", + "module": "", + "participants": 1, + "sautants": [], + "programme": "Sous voile Exercice 3", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Bi5/", + "video": "2022-10-08_S00498.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-10-08T00:00:00.000+00:00", + "numero": 499, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Track", + "participants": 7, + "sautants": ["Hassan", "Sylvain", "Edouard", "Loïc", "Warren", "Younes"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-10-08_S00499.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-10-09T00:00:00.000+00:00", + "numero": 500, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 5, + "sautants": ["Sylvain", "Romain", "Samuel", "Denis"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-10-09_S00500.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-10-09T00:00:00.000+00:00", + "numero": 501, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Track", + "participants": 5, + "sautants": ["Hassan", "Denis", "Edouard", "Romain"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-10-09_S00501.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-10-09T00:00:00.000+00:00", + "numero": 502, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Track", + "participants": 9, + "sautants": ["Hassan", "Sylvain", "Romain", "Edouard", "Eliott", "Charlotte", "Denis", "Kevin"], + "programme": "Saut du 500ème", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-10-09_S00502.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-10-15T00:00:00.000+00:00", + "numero": 503, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Track", + "participants": 6, + "sautants": ["Sylvain", "Romain", "Pascal", "Corentin", "Eliott"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-10-15_S00503.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-10-15T00:00:00.000+00:00", + "numero": 504, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Track", + "participants": 6, + "sautants": ["Sylvain", "Romain", "Pascal", "Corentin", "Eliott"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2022-10-15_S00504.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-10-15T00:00:00.000+00:00", + "numero": 505, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 6, + "sautants": ["Sylvain", "Romain", "Pascal", "Corentin", "Eliott"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-10-15_S00505.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-10-15T00:00:00.000+00:00", + "numero": 506, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 6, + "sautants": ["Sylvain", "Romain", "Pascal", "Corentin", "Eliott"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-10-15_S00506.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-10-15T00:00:00.000+00:00", + "numero": 507, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 5, + "sautants": ["Sylvain", "Romain", "Pascal", "Eliott"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2022-10-15_S00507.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-11-11T00:00:00.000+00:00", + "numero": 508, + "lieu": "Pamiers", + "oaci": "LFDJ", + "aeronef": "Grand Caravan", + "imat": "OY-PBK", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Track", + "participants": 6, + "sautants": ["Hassan", "Sylvain", "Edouard", "Romain", "Eliott"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-11-11T00:00:00.000+00:00", + "numero": 509, + "lieu": "Pamiers", + "oaci": "LFDJ", + "aeronef": "Grand Caravan", + "imat": "OY-PBK", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 4, + "sautants": ["Hassan", "Sylvain", "Romain"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-11-11T00:00:00.000+00:00", + "numero": 510, + "lieu": "Pamiers", + "oaci": "LFDJ", + "aeronef": "Grand Caravan", + "imat": "OY-PBK", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Trace", + "participants": 3, + "sautants": ["Sylvain", "Romain"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-11-11T00:00:00.000+00:00", + "numero": 511, + "lieu": "Pamiers", + "oaci": "LFDJ", + "aeronef": "Grand Caravan", + "imat": "OY-PBK", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Sylvain", "Romain"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-11-12T00:00:00.000+00:00", + "numero": 512, + "lieu": "Pamiers", + "oaci": "LFDJ", + "aeronef": "Grand Caravan", + "imat": "OY-PBK", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Track", + "participants": 7, + "sautants": ["Hassan", "Sylvain", "Edouard", "Romain", "Eliott", "Warren"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-11-12T00:00:00.000+00:00", + "numero": 513, + "lieu": "Pamiers", + "oaci": "LFDJ", + "aeronef": "Grand Caravan", + "imat": "OY-PBK", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Track", + "participants": 6, + "sautants": ["Hassan", "Sylvain", "Edouard", "Romain", "Eliott"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-11-12T00:00:00.000+00:00", + "numero": 514, + "lieu": "Pamiers", + "oaci": "LFDJ", + "aeronef": "Grand Caravan", + "imat": "OY-PBK", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Trace", + "participants": 4, + "sautants": ["Sylvain", "Romain", "?"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-11-12T00:00:00.000+00:00", + "numero": 515, + "lieu": "Pamiers", + "oaci": "LFDJ", + "aeronef": "Grand Caravan", + "imat": "OY-PBK", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Sylvain", "Romain"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-11-12T00:00:00.000+00:00", + "numero": 516, + "lieu": "Pamiers", + "oaci": "LFDJ", + "aeronef": "Grand Caravan", + "imat": "OY-PBK", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Sylvain", "Romain"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-11-13T00:00:00.000+00:00", + "numero": 517, + "lieu": "Pamiers", + "oaci": "LFDJ", + "aeronef": "Grand Caravan", + "imat": "OY-PBK", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Track", + "participants": 6, + "sautants": ["Sylvain", "Romain", "Edouard", "Eliott", "Warren"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-11-13T00:00:00.000+00:00", + "numero": 518, + "lieu": "Pamiers", + "oaci": "LFDJ", + "aeronef": "Grand Caravan", + "imat": "OY-PBK", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Track", + "participants": 6, + "sautants": ["Sylvain", "Romain", "Edouard", "Eliott", "Warren"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-11-13T00:00:00.000+00:00", + "numero": 519, + "lieu": "Pamiers", + "oaci": "LFDJ", + "aeronef": "Grand Caravan", + "imat": "OY-PBK", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Track", + "participants": 6, + "sautants": ["Sylvain", "Romain", "Edouard", "Eliott", "Warren"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2022-11-13T00:00:00.000+00:00", + "numero": 520, + "lieu": "Pamiers", + "oaci": "LFDJ", + "aeronef": "Grand Caravan", + "imat": "OY-PBK", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Trace", + "participants": 6, + "sautants": ["Hassan", "Sylvain", "Edouard", "Romain", "Eliott"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-02-25T00:00:00.000+00:00", + "numero": 521, + "lieu": "Beni Mellal", + "oaci": "GMMD", + "aeronef": "Pilatus", + "imat": "F-GTOP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "VR", + "module": "", + "participants": 4, + "sautants": ["Corentin", "Celine", "RomainX"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-02-25T00:00:00.000+00:00", + "numero": 522, + "lieu": "Beni Mellal", + "oaci": "GMMD", + "aeronef": "Pilatus", + "imat": "F-GTOP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Corentin"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-02-25T00:00:00.000+00:00", + "numero": 523, + "lieu": "Beni Mellal", + "oaci": "GMMD", + "aeronef": "Pilatus", + "imat": "F-GTOP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Corentin"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-02-25T00:00:00.000+00:00", + "numero": 524, + "lieu": "Beni Mellal", + "oaci": "GMMD", + "aeronef": "Pilatus", + "imat": "F-GTOP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "VR", + "module": "", + "participants": 4, + "sautants": ["Corentin", "RomainX", "Nico"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-02-27T00:00:00.000+00:00", + "numero": 525, + "lieu": "Beni Mellal", + "oaci": "GMMD", + "aeronef": "Pilatus", + "imat": "F-GTOP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Corentin"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-02-27T00:00:00.000+00:00", + "numero": 526, + "lieu": "Beni Mellal", + "oaci": "GMMD", + "aeronef": "Pilatus", + "imat": "F-GTOP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Corentin"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-02-27T00:00:00.000+00:00", + "numero": 527, + "lieu": "Beni Mellal", + "oaci": "GMMD", + "aeronef": "Pilatus", + "imat": "F-GTOP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Corentin"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-02-28T00:00:00.000+00:00", + "numero": 528, + "lieu": "Beni Mellal", + "oaci": "GMMD", + "aeronef": "Pilatus", + "imat": "F-GTOP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Hugo", "Corentin"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-02-28T00:00:00.000+00:00", + "numero": 529, + "lieu": "Beni Mellal", + "oaci": "GMMD", + "aeronef": "Pilatus", + "imat": "F-GTOP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "VR", + "module": "", + "participants": 5, + "sautants": ["Mishka", "Corentin", "Kelyan", "Baptiste"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-02-28T00:00:00.000+00:00", + "numero": 530, + "lieu": "Beni Mellal", + "oaci": "GMMD", + "aeronef": "Pilatus", + "imat": "F-GTOP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "VR", + "module": "", + "participants": 6, + "sautants": ["Corentin", "Kelyan", "Baptiste", "Oscar", "Ruben"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "video": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-04-15T00:00:00.000+00:00", + "numero": 531, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GYRY", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 4, + "sautants": ["Hassan", "Charles", "Romain"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-04-15_S00531.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-04-15T00:00:00.000+00:00", + "numero": 532, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GYRY", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Trace", + "participants": 6, + "sautants": ["Hassan", "Hugo", "Charles", "Romain", "Denis"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Trace/", + "video": "2023-04-15_S00532.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-04-15T00:00:00.000+00:00", + "numero": 533, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GYRY", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 5, + "sautants": ["Hassan", "Charles", "Romain", "Denis", "Eliott", "Godasse"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-04-15_S00533.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-04-15T00:00:00.000+00:00", + "numero": 534, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GYRY", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 5, + "sautants": ["Cédric", "Charles", "Romain", "Denis"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-04-15_S00534.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-04-15T00:00:00.000+00:00", + "numero": 535, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GYRY", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Trace", + "participants": 10, + "sautants": ["Hugo", "Pierre", "Sylvain", "Charles", "Romain", "Denis", "Eliott", "?", "?"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Trace/", + "video": "2023-04-15_S00535.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-04-16T00:00:00.000+00:00", + "numero": 536, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GYRY", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 6, + "sautants": ["Iku", "Eliott", "Charles", "Loïc", "Denis"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-04-16_S00536.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-04-16T00:00:00.000+00:00", + "numero": 537, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GYRY", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 4, + "sautants": ["Godasse", "Corentin", "Eliott"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-04-16_S00537.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-04-16T00:00:00.000+00:00", + "numero": 538, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GYRY", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Corentin"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-04-16_S00538.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-04-16T00:00:00.000+00:00", + "numero": 539, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GYRY", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 5, + "sautants": ["Corentin", "Edouard", "Eliott", "Denis"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-04-16_S00539.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-04-16T00:00:00.000+00:00", + "numero": 540, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GYRY", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Track", + "participants": 10, + "sautants": ["Tom", "Edouard", "Eliott", "Denis", "Charles", "Cédric", "Warren", "?", "?"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2023-04-16_S00540.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-04-22T00:00:00.000+00:00", + "numero": 541, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GLEU", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 5, + "sautants": ["Lucas", "Romain", "Axel /Jean"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-04-22_S00541.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-04-22T00:00:00.000+00:00", + "numero": 542, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GLEU", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 5, + "sautants": ["Lucas", "Romain", "Axel /Jean"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-04-22_S00542.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-04-22T00:00:00.000+00:00", + "numero": 543, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GLEU", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Track", + "participants": 10, + "sautants": ["Lucas", "Romain", "Axel /Jean", "Charles", "Julie", "Nico", "?", "?"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2023-04-22_S00543.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-04-22T00:00:00.000+00:00", + "numero": 544, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GLEU", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Track", + "participants": 10, + "sautants": ["Lucas", "Romain", "Axel /Jean", "Charles", "Julie", "Nico", "?", "?"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2023-04-22_S00544.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-05-13T00:00:00.000+00:00", + "numero": 545, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GLEU", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 6, + "sautants": ["Tom Babylone", "Edouard", "Eliott", "?", "?"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-05-13_S00545.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-05-13T00:00:00.000+00:00", + "numero": 546, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GLEU", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 4, + "sautants": ["Tom Babylone", "Charles", "Eliott"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-05-13_S00546.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-05-13T00:00:00.000+00:00", + "numero": 547, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GLEU", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 5, + "sautants": ["Tom Babylone", "Charles", "Edouard", "Eliott"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-05-13_S00547.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-05-13T00:00:00.000+00:00", + "numero": 548, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GLEU", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 5, + "sautants": ["Tom Babylone", "Charles", "Edouard", "Eliott"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-05-13_S00548.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-05-13T00:00:00.000+00:00", + "numero": 549, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GLEU", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 5, + "sautants": ["Tom Babylone", "Charles", "Edouard", "Eliott"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-05-13_S00549.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-05-13T00:00:00.000+00:00", + "numero": 550, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GLEU", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 10, + "sautants": ["Tom Babylone", "Tom", "Sylvain", "Romain", "Charles", "Edouard", "Eliott", "?", "?"], + "programme": "", + "accessoires": "Tube", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-05-13_S00550.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-05-14T00:00:00.000+00:00", + "numero": 551, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GLEU", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 4, + "sautants": ["Tom Babylone", "Charles", "Eliott"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-05-14_S00551.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-05-14T00:00:00.000+00:00", + "numero": 552, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GLEU", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 4, + "sautants": ["Tom Babylone", "Charles", "Eliott"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-05-14_S00552.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-05-14T00:00:00.000+00:00", + "numero": 553, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GLEU", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 5, + "sautants": ["Tom Babylone", "Charles", "?", "?"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-05-14_S00553.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-05-14T00:00:00.000+00:00", + "numero": 554, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GLEU", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 5, + "sautants": ["Tom Babylone", "Charles", "?", "?"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-05-14_S00554.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-05-14T00:00:00.000+00:00", + "numero": 555, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GLEU", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Track", + "participants": 6, + "sautants": ["Tom Babylone", "Charles", "Eliott", "?", "?"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2023-05-14_S00555.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-05-27T00:00:00.000+00:00", + "numero": 556, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOCC", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 6, + "sautants": ["Seb", "Romain", "Denis", "JP", "Cédric"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-05-27_S00556.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-05-27T00:00:00.000+00:00", + "numero": 557, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOCC", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 5, + "sautants": ["Seb", "Romain", "JP", "Cédric"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-05-27_S00557.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-05-28T00:00:00.000+00:00", + "numero": 558, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOCC", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Track", + "participants": 5, + "sautants": ["Seb", "Corentin", "Edouard", "?"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2023-05-28_S00558.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-05-28T00:00:00.000+00:00", + "numero": 559, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOCC", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Track", + "participants": 5, + "sautants": ["Seb", "Corentin", "Julie", "?"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2023-05-28_S00559.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-05-28T00:00:00.000+00:00", + "numero": 560, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOCC", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 4, + "sautants": ["Seb", "Corentin", "Julie"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-05-28_S00560.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-05-28T00:00:00.000+00:00", + "numero": 561, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOCC", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 4, + "sautants": ["Seb", "Corentin", "Julie"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-05-28_S00561.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-05-28T00:00:00.000+00:00", + "numero": 562, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOCC", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Trace", + "participants": 8, + "sautants": ["Seb", "Corentin", "Julie", "Sylvain", "Edouard", "?", "?"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Trace/", + "video": "2023-05-28_S00562.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-07-02T00:00:00.000+00:00", + "numero": 563, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Romain", "Charles"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-07-02_S00563.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-07-02T00:00:00.000+00:00", + "numero": 564, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 4, + "sautants": ["Romain", "Charles", "Edouard"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-07-02_S00564.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-07-02T00:00:00.000+00:00", + "numero": 565, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 4, + "sautants": ["Romain", "Charles", "Edouard"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-07-02_S00565.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-07-02T00:00:00.000+00:00", + "numero": 566, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 5, + "sautants": ["Romain", "Charles", "Edouard", "Denis"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-07-02_S00566.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-07-02T00:00:00.000+00:00", + "numero": 567, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Track", + "participants": 6, + "sautants": ["Brebz", "Charles", "Edouard", "Denis", "Warren"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2023-07-02_S00567.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-07-09T00:00:00.000+00:00", + "numero": 568, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 6, + "sautants": ["Lucas", "Romain", "Guillaume", "Charles", "Denis"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-07-09_S00568.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-07-09T00:00:00.000+00:00", + "numero": 569, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 7, + "sautants": ["Lucas", "Romain", "Guillaume", "Charles", "Denis", "?"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-07-09_S00569.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-07-09T00:00:00.000+00:00", + "numero": 570, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "VR", + "module": "", + "participants": 2, + "sautants": ["Lucie"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2023-07-09_S00570.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-07-09T00:00:00.000+00:00", + "numero": 571, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 6, + "sautants": ["Lucas", "Romain", "Charles", "Many", "?"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-07-09_S00571.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-07-09T00:00:00.000+00:00", + "numero": 572, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 5, + "sautants": ["Lucas", "Romain", "Charles", "?"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-07-09_S00572.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-07-09T00:00:00.000+00:00", + "numero": 573, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 4, + "sautants": ["Lucas", "Romain", "Charles"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-07-09_S00573.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-07-09T00:00:00.000+00:00", + "numero": 574, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Trace", + "participants": 9, + "sautants": ["Lucas", "Tom", "Sylvain", "Guillaume", "Denis"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Trace/", + "video": "2023-07-09_S00574.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-07-16T00:00:00.000+00:00", + "numero": 575, + "lieu": "Rochefort", + "oaci": "LFDN", + "aeronef": "Pilatus", + "imat": "F-GOSP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Hassan", "Charles"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-07-16_S00575.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-07-16T00:00:00.000+00:00", + "numero": 576, + "lieu": "Rochefort", + "oaci": "LFDN", + "aeronef": "Pilatus", + "imat": "F-GOSP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Charles"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-07-16_S00576.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-07-16T00:00:00.000+00:00", + "numero": 577, + "lieu": "Rochefort", + "oaci": "LFDN", + "aeronef": "Pilatus", + "imat": "F-GOSP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Charles"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-07-16_S00577.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-07-16T00:00:00.000+00:00", + "numero": 578, + "lieu": "Rochefort", + "oaci": "LFDN", + "aeronef": "Pilatus", + "imat": "F-GOSP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Charles"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-07-16_S00578.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-07-16T00:00:00.000+00:00", + "numero": 579, + "lieu": "Rochefort", + "oaci": "LFDN", + "aeronef": "Pilatus", + "imat": "F-GOSP", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Charles"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-07-16_S00579.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-07-22T00:00:00.000+00:00", + "numero": 580, + "lieu": "Soulac", + "oaci": "LFDK", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 4, + "sautants": ["Charles", "Loïc", "Pascal"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-07-22_S00580.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-07-22T00:00:00.000+00:00", + "numero": 581, + "lieu": "Soulac", + "oaci": "LFDK", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Track", + "participants": 5, + "sautants": ["Charles", "Loïc", "Pascal", "Lucie"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2023-07-22_S00581.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-07-22T00:00:00.000+00:00", + "numero": 582, + "lieu": "Soulac", + "oaci": "LFDK", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Track", + "participants": 5, + "sautants": ["Charles", "Loïc", "Pascal", "Lucie"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2023-07-22_S00582.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-07-22T00:00:00.000+00:00", + "numero": 583, + "lieu": "Soulac", + "oaci": "LFDK", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 4, + "sautants": ["Charles", "Loïc", "Pascal"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-07-22_S00583.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-07-22T00:00:00.000+00:00", + "numero": 584, + "lieu": "Soulac", + "oaci": "LFDK", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Track", + "participants": 5, + "sautants": ["Charles", "Loïc", "Pascal", "Lucie"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2023-07-22_S00584.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-07-22T00:00:00.000+00:00", + "numero": 585, + "lieu": "Soulac", + "oaci": "LFDK", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Track", + "participants": 5, + "sautants": ["Charles", "Loïc", "Pascal", "Lucie"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2023-07-22_S00585.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-07-22T00:00:00.000+00:00", + "numero": 586, + "lieu": "Soulac", + "oaci": "LFDK", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4700, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 6, + "sautants": ["Hybride - Lucie", "Loïc", "Charles", "Pascal", "Tifany"], + "programme": "", + "accessoires": "", + "zone": "Plage", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-07-22_S00586.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-07-23T00:00:00.000+00:00", + "numero": 587, + "lieu": "Soulac", + "oaci": "LFDK", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "VR", + "participants": 3, + "sautants": ["Charles", "Lucie"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/VR/", + "video": "2023-07-23_S00587.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-07-23T00:00:00.000+00:00", + "numero": 588, + "lieu": "Soulac", + "oaci": "LFDK", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Safire 2", + "taille": 149, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Hybride - Lucie", "Charles"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-07-23_S00588.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-06T00:00:00.000+00:00", + "numero": 589, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Trace", + "participants": 4, + "sautants": ["Guillaume Bnu", "Romain", "Nico Many"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Trace/", + "video": "2023-08-06_S00589.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-06T00:00:00.000+00:00", + "numero": 590, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Track", + "participants": 5, + "sautants": ["Guillaume Bnu", "Lucie", "Guillaume", "Denis"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2023-08-06_S00590.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-06T00:00:00.000+00:00", + "numero": 591, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Track", + "participants": 6, + "sautants": ["Guillaume Bnu", "Lucie", "Julie", "Guillaume", "Denis"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2023-08-06_S00591.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-06T00:00:00.000+00:00", + "numero": 592, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Chutas", + "participants": 7, + "sautants": ["Nico Many", "Guillaume Bnu", "Romain", "Julie", "Denis", "JP"], + "programme": "", + "accessoires": "Tube", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-08-06_S00592.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-06T00:00:00.000+00:00", + "numero": 593, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Track", + "participants": 6, + "sautants": ["Guillaume Bnu", "Lucie", "Julie", "Guillaume", "Denis"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2023-08-06_S00593.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-13T00:00:00.000+00:00", + "numero": 594, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Cédric"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-08-13_S00594.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-13T00:00:00.000+00:00", + "numero": 595, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Chutas", + "participants": 4, + "sautants": ["Julien Matha", "Cédric", "Jérémy"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-08-13_S00595.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-13T00:00:00.000+00:00", + "numero": 596, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Chutas", + "participants": 4, + "sautants": ["Julien Matha", "Cédric", "Edouard"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-08-13_S00596.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-13T00:00:00.000+00:00", + "numero": 597, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Chutas", + "participants": 4, + "sautants": ["Julien Matha", "Iku", "Cédric"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-08-13_S00597.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-15T00:00:00.000+00:00", + "numero": 598, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Pascal"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-08-15_S00598.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-15T00:00:00.000+00:00", + "numero": 599, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Pascal"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-08-15_S00599.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-15T00:00:00.000+00:00", + "numero": 600, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Pascal"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-08-15_S00600.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-15T00:00:00.000+00:00", + "numero": 601, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Wingsuit", + "participants": 2, + "sautants": ["Pascal"], + "programme": "Rodeo", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Wingsuit/", + "video": "2023-08-15_S00601.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-15T00:00:00.000+00:00", + "numero": 602, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Chutas", + "participants": 6, + "sautants": ["Bastiane", "Edouard", "?", "?", "?"], + "programme": "", + "accessoires": "Tube", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-08-15_S00602.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-15T00:00:00.000+00:00", + "numero": 603, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Track", + "participants": 3, + "sautants": ["Pascal", "Warren"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "video": "2023-08-15_S00603.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-17T00:00:00.000+00:00", + "numero": 604, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Loïc"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-08-17_S00604.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-17T00:00:00.000+00:00", + "numero": 605, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Loïc"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-08-17_S00605.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-17T00:00:00.000+00:00", + "numero": 606, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Loïc", "?"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-08-17_S00606.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-17T00:00:00.000+00:00", + "numero": 607, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Rémi", "Frank"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "video": "2023-08-17_S00607.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-18T00:00:00.000+00:00", + "numero": 608, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Chutas", + "participants": 5, + "sautants": ["Charles", "Guillaume", "Denis", "?"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "vidéo": "2023-08-18_S00608.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-18T00:00:00.000+00:00", + "numero": 609, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Chutas", + "participants": 4, + "sautants": ["Cédric", "Guillaume", "Denis"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "vidéo": "2023-08-18_S00609.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-18T00:00:00.000+00:00", + "numero": 610, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Chutas", + "participants": 4, + "sautants": ["Cédric", "Guillaume", "Denis"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "vidéo": "2023-08-18_S00610.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-19T00:00:00.000+00:00", + "numero": 611, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-19T00:00:00.000+00:00", + "numero": 612, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-19T00:00:00.000+00:00", + "numero": 613, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-19T00:00:00.000+00:00", + "numero": 614, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-19T00:00:00.000+00:00", + "numero": 615, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "VR", + "module": "", + "participants": 6, + "sautants": ["Lucie", "Julie", "Cédric", "Denis", "Guillaume", "$6"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-26T00:00:00.000+00:00", + "numero": 616, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": 1, + "sautants": ["Pascal", "Guillaume"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-26T00:00:00.000+00:00", + "numero": 617, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-26T00:00:00.000+00:00", + "numero": 618, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-26T00:00:00.000+00:00", + "numero": 619, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-26T00:00:00.000+00:00", + "numero": 620, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-27T00:00:00.000+00:00", + "numero": 621, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Chutas", + "participants": 1, + "sautants": ["Loïc"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "vidéo": "2023-08-27_S00621.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-27T00:00:00.000+00:00", + "numero": 622, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Chutas", + "participants": 1, + "sautants": ["Nitro", "Marine", "Mathilde"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "vidéo": "2023-08-27_S00622.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-03T00:00:00.000+00:00", + "numero": 623, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Pascal", "Guillaume"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "2023-09-03_S00623.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-03T00:00:00.000+00:00", + "numero": 624, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Pascal", "Guillaume"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "vidéo": "2023-09-03_S00624.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-03T00:00:00.000+00:00", + "numero": 625, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Track", + "participants": 4, + "sautants": ["Pascal", "Guillaume", "Lucie"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "vidéo": "2023-09-03_S00625.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-03T00:00:00.000+00:00", + "numero": 626, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Track", + "participants": 4, + "sautants": ["Pascal", "Guillaume", "Lucie"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "vidéo": "2023-09-03_S00626.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-03T00:00:00.000+00:00", + "numero": 627, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Track", + "participants": 5, + "sautants": ["Brebz", "Pascal", "Guillaume", "Lucie"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "vidéo": "2023-09-03_S00627.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-07T00:00:00.000+00:00", + "numero": 628, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-07T00:00:00.000+00:00", + "numero": 629, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-07T00:00:00.000+00:00", + "numero": 630, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-07T00:00:00.000+00:00", + "numero": 631, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-07T00:00:00.000+00:00", + "numero": 632, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-08T00:00:00.000+00:00", + "numero": 633, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-08T00:00:00.000+00:00", + "numero": 634, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-08T00:00:00.000+00:00", + "numero": 635, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 2000, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Corentin"], + "programme": "Saut Hélicoptère", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "vidéo": "2023-09-08_S00635.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-08T00:00:00.000+00:00", + "numero": 636, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-08T00:00:00.000+00:00", + "numero": 637, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-08T00:00:00.000+00:00", + "numero": 638, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-08T00:00:00.000+00:00", + "numero": 639, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-09T00:00:00.000+00:00", + "numero": 640, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-09T00:00:00.000+00:00", + "numero": 641, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-09T00:00:00.000+00:00", + "numero": 642, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-09T00:00:00.000+00:00", + "numero": 643, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": 1, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-09T00:00:00.000+00:00", + "numero": 644, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Track", + "participants": 1, + "sautants": ["Joliane", "Edouard", "Guillaume", "Corentin", "Julie", "Warren"], + "programme": "", + "accessoires": "", + "zone": "Plage", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "vidéo": "2023-09-09_S00644.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-24T00:00:00.000+00:00", + "numero": 645, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Edouard", "Jocelyn"], + "programme": "Sortie trace puis verticalisation tête en haut.", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "vidéo": "2023-09-29_S00645.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-24T00:00:00.000+00:00", + "numero": 646, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Chutas", + "participants": 4, + "sautants": ["Edouard", "Romain", "Jocelyn"], + "programme": "Sortie trace puis verticalisation tête en haut.", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "vidéo": "2023-09-29_S00646.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-24T00:00:00.000+00:00", + "numero": 647, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Trace", + "participants": 4, + "sautants": ["Edouard", "Romain", "Jocelyn"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Trace/", + "vidéo": "2023-09-29_S00647.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-24T00:00:00.000+00:00", + "numero": 648, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Trace", + "participants": 4, + "sautants": ["Edouard", "Romain", "Jocelyn"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Trace/", + "vidéo": "2023-09-29_S00648.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-24T00:00:00.000+00:00", + "numero": 649, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Trace", + "participants": 5, + "sautants": ["Cédric", "Edouard", "Romain", "Jocelyn"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Trace/", + "vidéo": "2023-09-29_S00649.mp4" + } +] \ No newline at end of file diff --git a/src/jumps_02.json b/src/jumps_02.json new file mode 100644 index 0000000..4a3661d --- /dev/null +++ b/src/jumps_02.json @@ -0,0 +1,926 @@ +[ + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-18T00:00:00.000+00:00", + "numero": 608, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Chutas", + "participants": 5, + "sautants": ["Charles", "Guillaume", "Denis", "?"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "vidéo": "2023-08-18_S00608.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-18T00:00:00.000+00:00", + "numero": 609, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Chutas", + "participants": 4, + "sautants": ["Cédric", "Guillaume", "Denis"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "vidéo": "2023-08-18_S00609.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-18T00:00:00.000+00:00", + "numero": 610, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Chutas", + "participants": 4, + "sautants": ["Cédric", "Guillaume", "Denis"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "vidéo": "2023-08-18_S00610.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-19T00:00:00.000+00:00", + "numero": 611, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": null, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-19T00:00:00.000+00:00", + "numero": 612, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": null, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-19T00:00:00.000+00:00", + "numero": 613, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": null, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-19T00:00:00.000+00:00", + "numero": 614, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": null, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-19T00:00:00.000+00:00", + "numero": 615, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "VR", + "module": "", + "participants": 6, + "sautants": ["Lucie", "Julie", "Cédric", "Denis", "Guillaume", "$6"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-26T00:00:00.000+00:00", + "numero": 616, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": null, + "sautants": ["Pascal", "Guillaume"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-26T00:00:00.000+00:00", + "numero": 617, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": null, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-26T00:00:00.000+00:00", + "numero": 618, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": null, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-26T00:00:00.000+00:00", + "numero": 619, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": null, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-26T00:00:00.000+00:00", + "numero": 620, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": null, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-27T00:00:00.000+00:00", + "numero": 621, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Chutas", + "participants": null, + "sautants": ["Loïc"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "vidéo": "2023-08-27_S00621.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-08-27T00:00:00.000+00:00", + "numero": 622, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Chutas", + "participants": null, + "sautants": ["Nitro", "Marine", "Mathilde"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "vidéo": "2023-08-27_S00622.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-03T00:00:00.000+00:00", + "numero": 623, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Pascal", "Guillaume"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "2023-09-03_S00623.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-03T00:00:00.000+00:00", + "numero": 624, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Pascal", "Guillaume"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "vidéo": "2023-09-03_S00624.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-03T00:00:00.000+00:00", + "numero": 625, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Track", + "participants": 4, + "sautants": ["Pascal", "Guillaume", "Lucie"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "vidéo": "2023-09-03_S00625.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-03T00:00:00.000+00:00", + "numero": 626, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Track", + "participants": 4, + "sautants": ["Pascal", "Guillaume", "Lucie"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "vidéo": "2023-09-03_S00626.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-03T00:00:00.000+00:00", + "numero": 627, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Track", + "participants": 5, + "sautants": ["Brebz", "Pascal", "Guillaume", "Lucie"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "vidéo": "2023-09-03_S00627.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-07T00:00:00.000+00:00", + "numero": 628, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": null, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-07T00:00:00.000+00:00", + "numero": 629, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": null, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-07T00:00:00.000+00:00", + "numero": 630, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": null, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-07T00:00:00.000+00:00", + "numero": 631, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": null, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-07T00:00:00.000+00:00", + "numero": 632, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": null, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-08T00:00:00.000+00:00", + "numero": 633, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": null, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-08T00:00:00.000+00:00", + "numero": 634, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": null, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-08T00:00:00.000+00:00", + "numero": 635, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 2000, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Chutas", + "participants": 2, + "sautants": ["Corentin"], + "programme": "Saut Hélicoptère", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "vidéo": "2023-09-08_S00635.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-08T00:00:00.000+00:00", + "numero": 636, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": null, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-08T00:00:00.000+00:00", + "numero": 637, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": null, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-08T00:00:00.000+00:00", + "numero": 638, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": null, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-08T00:00:00.000+00:00", + "numero": 639, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": null, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-09T00:00:00.000+00:00", + "numero": 640, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": null, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-09T00:00:00.000+00:00", + "numero": 641, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": null, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-09T00:00:00.000+00:00", + "numero": 642, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": null, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-09T00:00:00.000+00:00", + "numero": 643, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "", + "participants": null, + "sautants": [], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "", + "vidéo": "" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-09T00:00:00.000+00:00", + "numero": 644, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Track", + "participants": null, + "sautants": ["Joliane", "Edouard", "Guillaume", "Corentin", "Julie", "Warren"], + "programme": "", + "accessoires": "", + "zone": "Plage", + "dossier": "/Volumes/Storage/Skydive/Videos/Track/", + "vidéo": "2023-09-09_S00644.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-24T00:00:00.000+00:00", + "numero": 645, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Chutas", + "participants": 3, + "sautants": ["Edouard", "Jocelyn"], + "programme": "Sortie trace puis verticalisation tête en haut.", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "vidéo": "2023-09-29_S00645.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-24T00:00:00.000+00:00", + "numero": 646, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Chutas", + "participants": 4, + "sautants": ["Edouard", "Romain", "Jocelyn"], + "programme": "Sortie trace puis verticalisation tête en haut.", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Chutas/", + "vidéo": "2023-09-29_S00646.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-24T00:00:00.000+00:00", + "numero": 647, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Trace", + "participants": 4, + "sautants": ["Edouard", "Romain", "Jocelyn"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Trace/", + "vidéo": "2023-09-29_S00647.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-24T00:00:00.000+00:00", + "numero": 648, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Trace", + "participants": 4, + "sautants": ["Edouard", "Romain", "Jocelyn"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Trace/", + "vidéo": "2023-09-29_S00648.mp4" + }, + { + "author": {"$oid": "642c4459666702637dcb5066"}, + "date": "2023-09-24T00:00:00.000+00:00", + "numero": 649, + "lieu": "Arcachon", + "oaci": "LFCH", + "aeronef": "Pilatus", + "imat": "F-GOMB", + "hauteur": 4200, + "deploiement": 1000, + "voile": "Sabre 2", + "taille": 135, + "categorie": "FF", + "module": "Trace", + "participants": 5, + "sautants": ["Cédric", "Edouard", "Romain", "Jocelyn"], + "programme": "", + "accessoires": "", + "zone": "", + "dossier": "/Volumes/Storage/Skydive/Videos/Trace/", + "vidéo": "2023-09-29_S00649.mp4" + } +] \ No newline at end of file diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 0000000..58d4d57 --- /dev/null +++ b/src/main.ts @@ -0,0 +1,8 @@ +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; +import { appConfig } from './app/app.config'; +import '@angular/common/locales/global/fr'; + +bootstrapApplication(AppComponent, appConfig) + .then(() => console.log(`Bootstrap success`)) + .catch((err) => console.error(err)); diff --git a/src/manifest.webmanifest b/src/manifest.webmanifest new file mode 100644 index 0000000..2ce8d8d --- /dev/null +++ b/src/manifest.webmanifest @@ -0,0 +1,71 @@ +{ + "name": "adastra-app", + "short_name": "adastra-app", + "theme_color": "#2c4aa3", + "background_color": "#fafafa", + "display": "standalone", + "scope": "./", + "start_url": "./", + "icons": [ + { + "src": "assets/favicon/favicon-16x16.png", + "sizes": "16x16", + "type": "image/png", + "purpose": "maskable any" + }, + { + "src": "assets/favicon/favicon-32x32.png", + "sizes": "32x32", + "type": "image/png", + "purpose": "maskable any" + }, + { + "src": "assets/favicon/favicon-72x72.png", + "sizes": "72x72", + "type": "image/png", + "purpose": "maskable any" + }, + { + "src": "assets/favicon/favicon-96x96.png", + "sizes": "96x96", + "type": "image/png", + "purpose": "maskable any" + }, + { + "src": "assets/favicon/favicon-128x128.png", + "sizes": "128x128", + "type": "image/png", + "purpose": "maskable any" + }, + { + "src": "assets/favicon/favicon-144x144.png", + "sizes": "144x144", + "type": "image/png", + "purpose": "maskable any" + }, + { + "src": "assets/favicon/favicon-152x152.png", + "sizes": "152x152", + "type": "image/png", + "purpose": "maskable any" + }, + { + "src": "assets/favicon/favicon-192x192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable any" + }, + { + "src": "assets/favicon/favicon-384x384.png", + "sizes": "384x384", + "type": "image/png", + "purpose": "maskable any" + }, + { + "src": "assets/favicon/favicon-512x512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable any" + } + ] +} diff --git a/src/qcm-bpa.json b/src/qcm-bpa.json new file mode 100644 index 0000000..db38b5c --- /dev/null +++ b/src/qcm-bpa.json @@ -0,0 +1,3559 @@ +{ + "name": "bpa", + "categories": [ + { + "num": 1, + "name": "Aéronefs", + "questions": [ + { + "num": 1, + "libelle": "La position correcte du trim avant le décollage à pleine charge est :", + "choices": [ + {"index": "A", "libelle": "Extrémité vers le haut", "correct": false}, + {"index": "B", "libelle": "Extrémité vers le bas", "correct": true} + ] + }, + { + "num": 2, + "libelle": "A bord de l’avion :", + "choices": [ + {"index": "A", "libelle": "La répartition de masse a une influence directe sur le centrage et la stabilité de l’avion.", "correct": true}, + {"index": "B", "libelle": "La répartition de masse n’a pas d’importance pour le vol.", "correct": false} + ] + }, + { + "num": 3, + "libelle": "Peut-on se déplacer à bord de l’avion pendant le décollage ?", + "choices": [ + {"index": "A", "libelle": "Non car cela modifie le centrage de l’avion.", "correct": true}, + {"index": "B", "libelle": "Oui sans problème.", "correct": false} + ] + }, + { + "num": 4, + "libelle": "Lors du décollage, si les parachutistes se déplacent inconsidérément à bord de l’avion, celui ci peut décrocher.", + "choices": [ + {"index": "A", "libelle": "Vrai", "correct": true}, + {"index": "B", "libelle": "Faux", "correct": false} + ] + }, + { + "num": 5, + "libelle": "Un vent de travers est dangereux pour l’avion.", + "choices": [ + {"index": "A", "libelle": "Au décollage et à l’atterrissage si on dépasse la limite de vent recommandée pour l’avion.", "correct": true}, + {"index": "B", "libelle": "N’est pas dangereux si l’avion n’est pas en surcharge.", "correct": false} + ] + }, + { + "num": 6, + "libelle": "Durant les manœuvres de décollage et d’atterrissage, parler au pilote présente une gène, voir un risque.", + "choices": [ + {"index": "A", "libelle": "Faux", "correct": false}, + {"index": "B", "libelle": "Vrai", "correct": true} + ] + }, + { + "num": 7, + "libelle": "Une vitesse de largage trop faible peut entraîner :", + "choices": [ + {"index": "A", "libelle": "Un risque de percuter le plan fixe.", "correct": false}, + {"index": "B", "libelle": "Un risque de décrochage.", "correct": true}, + {"index": "C", "libelle": "Un meilleur confort pour la sortie.", "correct": false} + ] + }, + { + "num": 8, + "libelle": "Pour l’atterrissage et le décollage, la sortie des dispositifs hypersustentateurs (volets) est pour le pilote :", + "choices": [ + {"index": "A", "libelle": "Fonction de paramètres tels que vent, longueur de piste, etc.", "correct": true}, + {"index": "B", "libelle": "Obligatoire quel que soit le cas.", "correct": false}, + {"index": "C", "libelle": "Interdit quel que soit le cas.", "correct": false} + ] + }, + { + "num": 9, + "libelle": "A bord de l’avion, pendant la montée, vous remarquez un écoulement de liquide.", + "choices": [ + {"index": "A", "libelle": "Vous prévenez immédiatement le pilote.", "correct": true}, + {"index": "B", "libelle": "Vous sautez normalement et en arrivant au sol vous prévenez le directeur technique.", "correct": false}, + {"index": "C", "libelle": "Vous ne dites rien à personne.", "correct": false} + ] + }, + { + "num": 10, + "libelle": "En montant à bord de l’avion, vous remarquez une arrête coupante dans l’encadrement de porte.", + "choices": [ + {"index": "A", "libelle": "Vous sautez et vous prévenez le directeur technique une fois arrivé au sol.", "correct": false}, + {"index": "B", "libelle": "Vous ne dites rien et vous sautez en faisant attention en sortant.", "correct": false}, + {"index": "C", "libelle": "Vous prévenez immédiatement le pilote et les parachutistes.", "correct": true} + ] + }, + { + "num": 11, + "libelle": "En montant à bord de l’avion avec 9 parachutistes, vous remarquez que le trim du Pilatus est en position « plein cabré » avant le décollage.", + "choices": [ + {"index": "A", "libelle": "Vous ne dites rien car c’est une position de trim normale au décollage en pleine charge pour un Pilatus.", "correct": false}, + {"index": "B", "libelle": "Vous ne dites rien car cette position n’a pas d’influence sur le décollage, quelle que soit la charge et le centrage du Pilatus.", "correct": false}, + {"index": "C", "libelle": "Vous en informez immédiatement le pilote.", "correct": true} + ] + }, + { + "num": 12, + "libelle": "La vitesse de largage d’un avion est définie par le manuel de vol.", + "choices": [ + {"index": "A", "libelle": "Vrai", "correct": false}, + {"index": "B", "libelle": "Faux", "correct": true} + ] + }, + { + "num": 13, + "libelle": "Au moment de monter à bord de l’avion, vous remarquer une fuite de carburant venant d’un réservoir.", + "choices": [ + {"index": "A", "libelle": "Vous attendez d’avoir effectué le saut pour prévenir le directeur technique.", "correct": false}, + {"index": "B", "libelle": "C’est anormal, vous prévenez immédiatement le pilote.", "correct": true}, + {"index": "C", "libelle": "C’est normal à cause de la dilatation ; vous ne dites rien.", "correct": false} + ] + }, + { + "num": 14, + "libelle": "Les avions ayant une issue de saut à l’arrière de la carlingue sont très sensibles aux problèmes de centrage.", + "choices": [ + {"index": "A", "libelle": "Vrai", "correct": true}, + {"index": "B", "libelle": "Faux", "correct": false} + ] + }, + { + "num": 15, + "libelle": "Le centrage peut limiter le nombre de parachutistes pouvant effectuer une sortie de groupe.", + "choices": [ + {"index": "A", "libelle": "Vrai", "correct": true}, + {"index": "B", "libelle": "Faux", "correct": false} + ] + }, + { + "num": 16, + "libelle": "Un nombre trop important de parachutistes effectuant une sortie de groupe sur un avion ayant une issue de saut située à l’arrière peut induire :", + "choices": [ + {"index": "A", "libelle": "Uniquement un décrochage.", "correct": false}, + {"index": "B", "libelle": "Uniquement un départ en tonneaux.", "correct": false}, + {"index": "C", "libelle": "Uniquement une vrille à plat.", "correct": false}, + {"index": "D", "libelle": "Un des points précédents et éventuellement une combinaison des trois propositions précédentes.", "correct": true} + ] + }, + { + "num": 17, + "libelle": "Au moment d’embarquer, vous remarquez d’importantes traînées d’huile sous la carlingue de l’avion.", + "choices": [ + {"index": "A", "libelle": "C’est normal car il y a toujours des fuites.", "correct": false}, + {"index": "B", "libelle": "Vous prévenez immédiatement le pilote.", "correct": true} + ] + }, + { + "num": 18, + "libelle": "La vitesse de largage est définie par :", + "choices": [ + {"index": "A", "libelle": "Le constructeur et consignée dans le manuel de vol.", "correct": true}, + {"index": "B", "libelle": "Le pilote.", "correct": false}, + {"index": "C", "libelle": "Les parachutistes en fonction du type de saut.", "correct": false} + ] + }, + { + "num": 19, + "libelle": "Au moment d’embarquer, vous remarquez une crique (fissure) sur le plan fixe de l’avion.", + "choices": [ + {"index": "A", "libelle": "Vous attendez d’avoir effectué votre saut pour avertir le directeur technique.", "correct": false}, + {"index": "B", "libelle": "Vous avertissez immédiatement le pilote.", "correct": true}, + {"index": "C", "libelle": "Vous ne dites rien, le pilote ayant effectué une visite pré-vol sait ce qu’il fait.", "correct": false} + ] + }, + { + "num": 20, + "libelle": "La vitesse de largage d’un Pilatus est d’environ :", + "choices": [ + {"index": "A", "libelle": "110 kts.", "correct": false}, + {"index": "B", "libelle": "70 kts.", "correct": true}, + {"index": "C", "libelle": "45 kts.", "correct": false} + ] + }, + { + "num": 21, + "libelle": "La vitesse de largage d’un Cessna (206 ; 207) est d ‘environ :", + "choices": [ + {"index": "A", "libelle": "50 kts.", "correct": false}, + {"index": "B", "libelle": "80 kts.", "correct": true}, + {"index": "C", "libelle": "105 kts.", "correct": false} + ] + }, + { + "num": 22, + "libelle": "La vitesse de largage d’un Cessna Caravan est d ‘environ :", + "choices": [ + {"index": "A", "libelle": "100 kts.", "correct": false}, + {"index": "B", "libelle": "80 kts.", "correct": true}, + {"index": "C", "libelle": "70 kts.", "correct": false} + ] + }, + { + "num": 23, + "libelle": "La vitesse de largage d’un gros porteur Type Hercules est d’environ :", + "choices": [ + {"index": "A", "libelle": "200 kts.", "correct": false}, + {"index": "B", "libelle": "120 kts.", "correct": true}, + {"index": "C", "libelle": "70 kts.", "correct": false} + ] + }, + { + "num": 24, + "libelle": "Une vitesse de largage trop importante pour un avion léger de type CESSNA peut entraîner une collision d’un chuteur avec le plan fixe.", + "choices": [ + {"index": "A", "libelle": "Faux", "correct": false}, + {"index": "B", "libelle": "Vrai", "correct": true} + ] + } + ] + }, + { + "num": 2, + "name": "Altimètre", + "questions": [ + { + "num": 25, + "libelle": "Plus on monte en altitude.", + "choices": [ + {"index": "A", "libelle": "Plus un altimètre est précis.", "correct": false}, + {"index": "B", "libelle": "Moins un altimètre est précis.", "correct": true} + ] + }, + { + "num": 26, + "libelle": "A 1000 mètres, une précision de + ou – 200 mètres sur un altimètre est-elle satisfaisante ?", + "choices": [ + {"index": "A", "libelle": "C’est à la limite de l’acceptable.", "correct": false}, + {"index": "B", "libelle": "Non.", "correct": true}, + {"index": "C", "libelle": "Oui.", "correct": false} + ] + }, + { + "num": 27, + "libelle": "« Tapoter » sur un altimètre pour faire se déplacer l’aiguille :", + "choices": [ + {"index": "A", "libelle": "N’a aucune conséquence.", "correct": false}, + {"index": "B", "libelle": "Est indispensable pour remettre l’aiguille à zéro.", "correct": false}, + {"index": "C", "libelle": "Augmente le jeu normal du fonctionnement et n’apporte qu’un vieillissement prématuré de l’appareil.", "correct": true} + ] + }, + { + "num": 28, + "libelle": "Les « altisons » ont-ils tous une alarme sonore de non fonctionnement ou de mauvais fonctionnement ?", + "choices": [ + {"index": "A", "libelle": "Oui.", "correct": false}, + {"index": "B", "libelle": "Non.", "correct": true} + ] + } + ] + }, + { + "num": 3, + "name": "Déclencheurs et matériels", + "questions": [ + { + "num": 29, + "libelle": "La FXC 12000 :", + "choices": [ + {"index": "A", "libelle": "Déclenche à une hauteur fixe à partir d’une vitesse supérieure à 12 m/s.", "correct": false}, + {"index": "B", "libelle": "Déclenche à une hauteur que l’on règle avant chaque saut à partir d’une vitesse supérieure à 0,5 m/s.", "correct": false}, + {"index": "C", "libelle": "Déclenche à une hauteur fixe à partir d’une vitesse supérieure à 0,5 m/s.", "correct": false}, + {"index": "D", "libelle": "Déclenche à une hauteur que l’on règle avant chaque saut à partir d’une vitesse supérieure à 12 m/s 0", "correct": true} + ] + }, + { + "num": 30, + "libelle": "Sur une FXC 12000 réglé avant le saut si l’aiguille disparaît pendant la montée en avion :", + "choices": [ + {"index": "A", "libelle": "Elle est en panne, il ne faut pas sauter.", "correct": false}, + {"index": "B", "libelle": "Il faut le signaler à un moniteur après le saut.", "correct": false}, + {"index": "C", "libelle": "C’est normal, l’aiguille disparaît à la hauteur de réglage.", "correct": true} + ] + }, + { + "num": 31, + "libelle": "Un déclencheur FXC 12000 dont l’aiguille de réglage est sur le 1 signifie :", + "choices": [ + {"index": "A", "libelle": "Réglage à 100 m.", "correct": false}, + {"index": "B", "libelle": "Réglage à 1000 m.", "correct": false}, + {"index": "C", "libelle": "Réglage à 1000 pieds (soit sensiblement 300 m).", "correct": true} + ] + }, + { + "num": 32, + "libelle": "Le saut est annulé, l’avion redescend rapidement, les déclencheurs de sécurité de type FXC 12000 peuvent fonctionner dans l’avion.", + "choices": [ + {"index": "A", "libelle": "Faux.", "correct": false}, + {"index": "B", "libelle": "Vrai.", "correct": true} + ] + }, + { + "num": 33, + "libelle": "Les déclencheurs FXC 12000 réglés sur 1000 pieds peuvent déclencher à partir de 400 m.", + "choices": [ + {"index": "A", "libelle": "Vrai.", "correct": true}, + {"index": "B", "libelle": "Faux.", "correct": false} + ] + }, + { + "num": 34, + "libelle": "Le saut est annulé, l’avion redescend à pleine charge, les déclencheurs FXC 12000 doivent être neutralisés en plaçant la molette sur off (couleur verte).", + "choices": [ + {"index": "A", "libelle": "Vrai.", "correct": true}, + {"index": "B", "libelle": "Faux.", "correct": false} + ] + }, + { + "num": 35, + "libelle": "Si un Cypres 2 est mouillé suite à une courte immersion à moins de 1,5 m de profondeur :", + "choices": [ + {"index": "A", "libelle": "Il faut faire changer le filtre de l’appareil.", "correct": true}, + {"index": "B", "libelle": "Il n’y a pas d’opération particulière à faire effectuer.", "correct": false} + ] + }, + { + "num": 36, + "libelle": "Si un Cypres affiche le code 0, cela signifie :", + "choices": [ + {"index": "A", "libelle": "Qu’il faut faire changer les piles.", "correct": false}, + {"index": "B", "libelle": "Qu’il faut l’éteindre et le remettre en fonction.", "correct": false}, + {"index": "C", "libelle": "Que le déclencheur est prêt à être utilisé.", "correct": true} + ] + }, + { + "num": 37, + "libelle": "Lors d’un posé hors zone, si l’atterrissage se fait à une hauteur de ± 10 mètres par rapport à la zone de saut habituelle, il faut éteindre le Cypres et le remettre en route le avant le prochain saut.", + "choices": [ + {"index": "A", "libelle": "Faux.", "correct": false}, + {"index": "B", "libelle": "Faux. Seulement si la différence de hauteur excède ± 30 mètres.", "correct": false}, + {"index": "C", "libelle": "Vrai.", "correct": true} + ] + }, + { + "num": 38, + "libelle": "Au bout de combien de temps un Cypres doit-il être envoyé en révision ?", + "choices": [ + {"index": "A", "libelle": "Tous les ans.", "correct": false}, + {"index": "B", "libelle": "Il n’y a pas besoin de le faire réviser, il faut simplement changer les piles tous les deux ans.", "correct": true}, + {"index": "C", "libelle": "Il faut le faire réviser quand on change les piles.", "correct": false}, + {"index": "D", "libelle": "Il faut le faire réviser tous les quatre ans.", "correct": false} + ] + }, + { + "num": 39, + "libelle": "Le Cypres expert :", + "choices": [ + {"index": "A", "libelle": "Déclenche à une hauteur fixe à partir d’une vitesse supérieure à 35 m/s.", "correct": true}, + {"index": "B", "libelle": "Déclenche à une hauteur qu’il faut régler avant chaque saut à partir d’une vitesse supérieure à 13 m/s.", "correct": false}, + {"index": "C", "libelle": "Déclenche à une hauteur qu’il faut régler avant chaque saut à partir d’une vitesse supérieure à 35 m/s.", "correct": false}, + {"index": "D", "libelle": "Déclenche à une hauteur fixe à partir d’une vitesse supérieure à 13 m/s.", "correct": false} + ] + }, + { + "num": 40, + "libelle": "Le Cypres école :", + "choices": [ + {"index": "A", "libelle": "Déclenche à 300m à partir d’une vitesse supérieure à 35 m/s.", "correct": false}, + {"index": "B", "libelle": "Déclenche à 225m une à partir d’une vitesse supérieure à 13 m/s.", "correct": false}, + {"index": "C", "libelle": "Déclenche à une hauteur qu’il faut régler avant chaque saut à partir d’une vitesse supérieure à 35 m/s.", "correct": false}, + {"index": "D", "libelle": "Déclenche à 300m à partir d’une vitesse supérieure à 13 m/s, et à 225m à partir d’une vitesse supérieure à 35m/s.", "correct": true} + ] + }, + { + "num": 41, + "libelle": "Si la vitesse est suffisante, un déclencheur Cypres confirmé déclenche à une hauteur de :", + "choices": [ + {"index": "A", "libelle": "225 m.", "correct": true}, + {"index": "B", "libelle": "315 m.", "correct": false}, + {"index": "C", "libelle": "175 m.", "correct": false} + ] + }, + { + "num": 42, + "libelle": "En cas de descente rapide avec l’avion, un déclencheur Cypres confirmé peut-il déclencher ?", + "choices": [ + {"index": "A", "libelle": "Non.", "correct": false}, + {"index": "B", "libelle": "Oui.", "correct": true} + ] + }, + { + "num": 43, + "libelle": "La vitesse de chute minimum nécessaire pour déclencher un Cypres confirmé est supérieure ou égale à :", + "choices": [ + {"index": "A", "libelle": "30 m/s.", "correct": false}, + {"index": "B", "libelle": "35 m/s.", "correct": true}, + {"index": "C", "libelle": "25 m/s.", "correct": false} + ] + }, + { + "num": 44, + "libelle": "La vitesse de chute minimum nécessaire pour déclencher un Cypres élève est supérieure ou égale à :", + "choices": [ + {"index": "A", "libelle": "35 m/s à partir de 300m.", "correct": false}, + {"index": "B", "libelle": "13 m/s à partir de 225 m.", "correct": false}, + {"index": "C", "libelle": "13 m/s à partir de 300m.", "correct": true} + ] + }, + { + "num": 45, + "libelle": "En cas d’action du Cypres, il y a :", + "choices": [ + {"index": "A", "libelle": "Sectionnement de la bouclette de fermeture (loop) du conteneur secours.", "correct": true}, + {"index": "B", "libelle": "Extraction de l’aiguille du conteneur secours.", "correct": false}, + {"index": "C", "libelle": "Libération de la voilure principale.", "correct": false} + ] + }, + { + "num": 46, + "libelle": "Le Cypres 2 doit être renvoyé en révision :", + "choices": [ + {"index": "A", "libelle": "Tous les 4 ans.", "correct": true}, + {"index": "B", "libelle": "Tous les 2 ans ou tous les 800 sauts.", "correct": false}, + {"index": "C", "libelle": "Tous les 2 ans.", "correct": false} + ] + }, + { + "num": 47, + "libelle": "Les batteries d’un Cypres 2 sont changées :", + "choices": [ + {"index": "A", "libelle": "Tous les 2 ans ou tous les 800 sauts.", "correct": false}, + {"index": "B", "libelle": "Tous les 4 ans.", "correct": true}, + {"index": "C", "libelle": "Après chaque déclenchement.", "correct": false}, + {"index": "D", "libelle": "A chaque contrôle périodique du parachute.", "correct": false} + ] + }, + { + "num": 48, + "libelle": "Le boîtier de contrôle d’un Cypres élève en fonction indique :", + "choices": [ + {"index": "A", "libelle": "Student.", "correct": false}, + {"index": "B", "libelle": "Jump.", "correct": false}, + {"index": "C", "libelle": "Rien d’écrit.", "correct": false}, + {"index": "D", "libelle": "0.", "correct": true} + ] + }, + { + "num": 49, + "libelle": "Le Cypres doit être « réarmé » tous les matins même s’il est encore en marche.", + "choices": [ + {"index": "A", "libelle": "Vrai.", "correct": true}, + {"index": "B", "libelle": "Faux.", "correct": false} + ] + }, + { + "num": 50, + "libelle": "Le Cypres s’éteint automatiquement 14 heures après sa mise en route.", + "choices": [ + {"index": "A", "libelle": "Oui.", "correct": true}, + {"index": "B", "libelle": "Sauf si l’on resaute entre temps.", "correct": false}, + {"index": "C", "libelle": "Sauf si les batteries sont faibles.", "correct": false} + ] + }, + { + "num": 51, + "libelle": "En cas d’évacuation à 300m pendant la montée, le Cypres (confirmé et élève) peut déclencher.", + "choices": [ + {"index": "A", "libelle": "Vrai.", "correct": false}, + {"index": "B", "libelle": "Faux car il ne s’active que s’il a dépassé une hauteur de 450m.", "correct": true}, + {"index": "C", "libelle": "Faux car il ne s’active que s’il a dépassé une hauteur de 900m.", "correct": false} + ] + }, + { + "num": 52, + "libelle": "Le Vigile possède trois modes d’utilisation.", + "choices": [ + {"index": "A", "libelle": "Faux.", "correct": false}, + {"index": "B", "libelle": "Cela dépend des modèles.", "correct": false}, + {"index": "C", "libelle": "Vrai.", "correct": true} + ] + }, + { + "num": 53, + "libelle": "La révision du vigil doit être effectuée :", + "choices": [ + {"index": "A", "libelle": "Tous les quatre ans.", "correct": false}, + {"index": "B", "libelle": "Uniquement dans le cas d’un message d’erreur.", "correct": true}, + {"index": "C", "libelle": "Tous les 700 sauts.", "correct": false} + ] + }, + { + "num": 54, + "libelle": "Le changement des piles sur un vigil s’effectue :", + "choices": [ + {"index": "A", "libelle": "A l’apparition du message « bat low ».", "correct": true}, + {"index": "B", "libelle": "Tous les deux ans.", "correct": false}, + {"index": "C", "libelle": "Jamais.", "correct": false} + ] + }, + { + "num": 55, + "libelle": "Pour les versions confirmées, les hauteurs de déclenchement du Vigil et du Cypres sont sensiblement identiques.", + "choices": [ + {"index": "A", "libelle": "Faux.", "correct": false}, + {"index": "B", "libelle": "Vrai.", "correct": true} + ] + }, + { + "num": 56, + "libelle": "La vitesse de déclenchement du vigil en mode « pro » est de :", + "choices": [ + {"index": "A", "libelle": "20 m/s.", "correct": false}, + {"index": "B", "libelle": "12 m/s.", "correct": false}, + {"index": "C", "libelle": "35 m/s.", "correct": true} + ] + }, + { + "num": 57, + "libelle": "La hauteur de déclenchement du vigil en mode « pro » est de :", + "choices": [ + {"index": "A", "libelle": "256 mètres.", "correct": true}, + {"index": "B", "libelle": "216 mètres.", "correct": false}, + {"index": "C", "libelle": "225 mètres.", "correct": false} + ] + }, + { + "num": 58, + "libelle": "La vitesse de déclenchement du vigil en mode « student » est de :", + "choices": [ + {"index": "A", "libelle": "12 m/s.", "correct": false}, + {"index": "B", "libelle": "20 m/s.", "correct": true}, + {"index": "C", "libelle": "35 m/s.", "correct": false} + ] + }, + { + "num": 59, + "libelle": "Qu’est-ce qu’un système de rétraction ?", + "choices": [ + {"index": "A", "libelle": "C’est le système qui permet de déventer l’extracteur après l’ouverture.", "correct": false}, + {"index": "B", "libelle": "C’est l’action de tirer sur les élévateurs.", "correct": true} + ] + }, + { + "num": 60, + "libelle": "Lors du repliage du parachute de secours :", + "choices": [ + {"index": "A", "libelle": "Le plieur qualifié contrôle la voilure dans tous les cas mais ne contrôle rien d’autre.", "correct": false}, + {"index": "B", "libelle": "Le plieur qualifié ne contrôle la voilure que si elle a été ouverte en vol.", "correct": false}, + {"index": "C", "libelle": "Le plieur qualifié fait un contrôle détaillé de l’ensemble de l’équipement.", "correct": true} + ] + }, + { + "num": 61, + "libelle": "Le contrôle périodique d’un parachute doit être fait :", + "choices": [ + {"index": "A", "libelle": "Avec la même périodicité que le pliage du secours.", "correct": true}, + {"index": "B", "libelle": "Le contrôle périodique d’un parachute n’est pas réglementé, seul le pliage du secours l’est.", "correct": false}, + {"index": "C", "libelle": "Uniquement après une ouverture en vol.", "correct": false} + ] + }, + { + "num": 62, + "libelle": "Un contrôle détaillé et un entretien du système de libération de la voilure principale doit être effectué régulièrement entre deux opérations de contrôle périodique.", + "choices": [ + {"index": "A", "libelle": "Non.", "correct": false}, + {"index": "B", "libelle": "Oui.", "correct": true} + ] + }, + { + "num": 63, + "libelle": "Quels sont les contrôles et l’entretien à réaliser sur le système de libération trois anneaux ?", + "choices": [ + {"index": "A", "libelle": "Aucun contrôle particulier, le système étant visible en permanence.", "correct": false}, + {"index": "B", "libelle": "Manipuler les sangles et nettoyer les gaines de câbles et les joncs de la poignée de libération.", "correct": true}, + {"index": "C", "libelle": "Nettoyer les gaines de câbles et les joncs avec de l’essence avion uniquement.", "correct": false} + ] + }, + { + "num": 64, + "libelle": "Sur une sangle principale de harnais, une dégradation de 5 mm peut entraîner une perte de résistance de 50 %.", + "choices": [ + {"index": "A", "libelle": "Faux.", "correct": false}, + {"index": "B", "libelle": "Vrai.", "correct": true} + ] + }, + { + "num": 65, + "libelle": "Rallonger la longueur de la bouclette de verrouillage (loop) d’un parachute pour permettre une fermeture très aisée génère des risques d’ouverture intempestive.", + "choices": [ + {"index": "A", "libelle": "Faux.", "correct": false}, + {"index": "B", "libelle": "Vrai.", "correct": true} + ] + }, + { + "num": 66, + "libelle": "Utiliser une suspente d’un diamètre trop important pour la confection d’une bouclette de verrouillage (loop) peut générer une non ouverture du conteneur.", + "choices": [ + {"index": "A", "libelle": "Faux.", "correct": false}, + {"index": "B", "libelle": "Vrai.", "correct": true} + ] + }, + { + "num": 67, + "libelle": "Les loops de fermeture :", + "choices": [ + {"index": "A", "libelle": "Doivent être très courts pour éviter une ouverture intempestive.", "correct": false}, + {"index": "B", "libelle": "Doivent être tendus normalement pour éviter à la fois les blocages et les ouvertures intempestives.", "correct": true}, + {"index": "C", "libelle": "Doivent être relâché pour faciliter l’ouverture.", "correct": false} + ] + }, + { + "num": 68, + "libelle": "Quelle peut être la conséquence de l’utilisation d’un loop de fermeture trop long ?", + "choices": [ + {"index": "A", "libelle": "Un retard à l’ouverture.", "correct": false}, + {"index": "B", "libelle": "Une ouverture intempestive.", "correct": true} + ] + }, + { + "num": 69, + "libelle": "Quelle peut être la conséquence de l’utilisation d’un loop trop court ?", + "choices": [ + {"index": "A", "libelle": "Une ouverture intempestive.", "correct": false}, + {"index": "B", "libelle": "Un blocage du système d’ouverture (poignée, hand deploy, pull out).", "correct": true} + ] + }, + { + "num": 70, + "libelle": "Un parachute doit être stocké :", + "choices": [ + {"index": "A", "libelle": "Au sec et à l’abri du soleil.", "correct": true}, + {"index": "B", "libelle": "Les conditions de stockage n’ont pas d’importance.", "correct": false} + ] + }, + { + "num": 71, + "libelle": "L’exposition au soleil :", + "choices": [ + {"index": "A", "libelle": "Est un facteur de vieillissement des matières textiles.", "correct": true}, + {"index": "B", "libelle": "N’induit pas de vieillissement anormal.", "correct": false} + ] + }, + { + "num": 72, + "libelle": "Des expositions prolongées et répétées au soleil peuvent réduire la durée de vie d’une voilure de manière importante.", + "choices": [ + {"index": "A", "libelle": "Vrai.", "correct": true}, + {"index": "B", "libelle": "Faux.", "correct": false} + ] + }, + { + "num": 73, + "libelle": "Quels rayons, générés par le soleil, induisent un vieillissement prématuré des voilures ?", + "choices": [ + {"index": "A", "libelle": "Les rayons ultra-violets.", "correct": true}, + {"index": "B", "libelle": "Les rayons électromagnétiques.", "correct": false}, + {"index": "C", "libelle": "Les rayons gamma.", "correct": false} + ] + }, + { + "num": 74, + "libelle": "Vous remarquez un début de décousure entre deux sangles d’un sac harnais :", + "choices": [ + {"index": "A", "libelle": "Vous ne laissez pas sauter le parachute et vous consultez un moniteur ou un plieur réparateur.", "correct": true}, + {"index": "B", "libelle": "Cela n’est pas gênant si elle fait moins de 5 mm.", "correct": false}, + {"index": "C", "libelle": "Cela n’est pas gênant si elle fait moins de 8 mm.", "correct": false} + ] + }, + { + "num": 75, + "libelle": "Une déchirure dans un sac de déploiement (POD) :", + "choices": [ + {"index": "A", "libelle": "Nécessite un contrôle par une personne qualifiée quelque soit sa longueur.", "correct": true}, + {"index": "B", "libelle": "Ne nécessite pas de réparation si elle fait moins de 5 cm.", "correct": false}, + {"index": "C", "libelle": "Ne nécessite pas de réparation si elle fait moins de 2 cm.", "correct": false}, + {"index": "D", "libelle": "Ne nécessite pas de réparation si elle fait moins de 8 cm.", "correct": false} + ] + }, + { + "num": 76, + "libelle": "Une suspente présentant une amorce de rupture, même légère, peut voir sa résistance diminuée de façon importante.", + "choices": [ + {"index": "A", "libelle": "Vrai.", "correct": true}, + {"index": "B", "libelle": "Faux.", "correct": false} + ] + }, + { + "num": 77, + "libelle": "Une déchirure sur une voilure principale :", + "choices": [ + {"index": "A", "libelle": "Nécessite un contrôle par une personne qualifiée quelque soit sa longueur.", "correct": true}, + {"index": "B", "libelle": "Ne nécessite pas de réparation si elle fait moins de 8 cm.", "correct": false}, + {"index": "C", "libelle": "Ne nécessite pas de réparation si elle fait moins de 2 cm.", "correct": false}, + {"index": "D", "libelle": "Ne nécessite pas de réparation si elle fait moins de 5 cm.", "correct": false} + ] + } + ] + }, + { + "num": 4, + "name": "Largage", + "questions": [ + { + "num": 78, + "libelle": "Durant la montée en altitude, vers 1200 m, le moteur de l’avion s’arrête.", + "choices": [ + {"index": "A", "libelle": "Vous attendez les consignes du pilote pour ouvrir la porte et procéder à l’évacuation.", "correct": true}, + {"index": "B", "libelle": "Vous ouvrez la porte et vous sautez en enjoignant aux autres de vous suivre.", "correct": false} + ] + }, + { + "num": 79, + "libelle": "Lors de l’équipement pour un saut à 4000 mètres, le vent au sol est de 5 m/s. Au décollage le vent est de 7 m/s. A 2500 mètres le pilote vous annonce que le vent au sol est de 9 m/s avec rafales à 13 m/s.", + "choices": [ + {"index": "A", "libelle": "Il faut annuler le largage et demander au pilote de redescendre.", "correct": true}, + {"index": "B", "libelle": "Vous larguez tout de suite avant que le vent n’augmente encore.", "correct": false}, + {"index": "C", "libelle": "Vous poursuivez la montée et larguez à 4000 m.", "correct": false} + ] + }, + { + "num": 80, + "libelle": "L’avion est bloqué à 800 m par des nuages :", + "choices": [ + {"index": "A", "libelle": "Vous sautez et ouvrez immédiatement.", "correct": false}, + {"index": "B", "libelle": "Vous redescendez avec l’avion.", "correct": true}, + {"index": "C", "libelle": "Seuls les parachutistes titulaires du brevet C ou D peuvent sauter s’ils le désirent.", "correct": false} + ] + }, + { + "num": 81, + "libelle": "A 1500 m de hauteur, le pilote annonce que le largage est annulé et qu’il va redescendre et se poser à pleine charge.", + "choices": [ + {"index": "A", "libelle": "Il faut faire cela uniquement si l’avion vole porte ouverte.", "correct": false}, + {"index": "B", "libelle": "Il faut faire cela uniquement en dessous de 500 m.", "correct": false}, + {"index": "C", "libelle": "Il faut désarmer les déclencheurs de sécurité ou demander au pilote de respecter une vitesse de descente fonction du type de déclencheur.", "correct": true} + ] + }, + { + "num": 82, + "libelle": "A 1800 m de hauteur, le pilote réduit la puissance et se met à descendre.", + "choices": [ + {"index": "A", "libelle": "Ne sachant exactement ce qui se passe, vous sautez immédiatement.", "correct": false}, + {"index": "B", "libelle": "Il faut couper les déclencheurs de sécurité ou demander au pilote de respecter une vitesse de descente fonction du type de déclencheur.", "correct": true}, + {"index": "C", "libelle": "Vous désarmez les déclencheurs uniquement en dessous de 500 m.", "correct": false} + ] + }, + { + "num": 83, + "libelle": "Au moment du largage :", + "choices": [ + {"index": "A", "libelle": "Il ne faut pas sauter sans l’accord du pilote.", "correct": true}, + {"index": "B", "libelle": "C’est sans importance.", "correct": false} + ] + }, + { + "num": 84, + "libelle": "Pour embarquer dans l’avion.", + "choices": [ + {"index": "A", "libelle": "C’est sans importance.", "correct": false}, + {"index": "B", "libelle": "Il ne faut pas passer derrière l’avion.", "correct": false}, + {"index": "C", "libelle": "Il ne faut jamais passer devant l’hélice.", "correct": true} + ] + }, + { + "num": 85, + "libelle": "A 3000 m, vous remarquez que votre altimètre indique 3800 m.", + "choices": [ + {"index": "A", "libelle": "C’est normal si la température est supérieure à la normale.", "correct": false}, + {"index": "B", "libelle": "Vous le recalez à 3000 m.", "correct": false}, + {"index": "C", "libelle": "C’est normal s’il y a des inversions de pression atmosphérique.", "correct": false}, + {"index": "D", "libelle": "Vous ne sautez pas.", "correct": true} + ] + }, + { + "num": 86, + "libelle": "A bord de l’avion, vous remarquez lors de la vérification, que le système trois anneaux d’un parachutiste est mal monté.", + "choices": [ + {"index": "A", "libelle": "Le parachutiste ne doit pas sauter.", "correct": true}, + {"index": "B", "libelle": "La probabilité d’une procédure de secours étant très faible, vous ne dites rien pour ne pas l’inquiéter.", "correct": false}, + {"index": "C", "libelle": "Vous démonter et remonter l’élévateur en demandant au pilote de refaire un tour.", "correct": false} + ] + }, + { + "num": 87, + "libelle": "Lors de l’embarquement, vous constatez que les S.O.A. d’un largage précédant sont toujours accrochées.", + "choices": [ + {"index": "A", "libelle": "Vous pouvez les laisser accrochées.", "correct": false}, + {"index": "B", "libelle": "Vous devez les décrocher et les ranger avant d’embarquer.", "correct": true}, + {"index": "C", "libelle": "Vous les décrochez et les rangez après avoir embarqué.", "correct": false} + ] + }, + { + "num": 88, + "libelle": "Un G.P.S. dans l’avion :", + "choices": [ + {"index": "A", "libelle": "Indique que l’espace aérien est dégagé.", "correct": false}, + {"index": "B", "libelle": "Permet au pilote de prendre l’axe plus facilement.", "correct": true}, + {"index": "C", "libelle": "Calcule le point de largage.", "correct": false} + ] + }, + { + "num": 89, + "libelle": "La vitesse de vol et la trajectoire de l’avion par rapport au sol :", + "choices": [ + {"index": "A", "libelle": "Ne donne pas d’indications sur le vent en altitude.", "correct": false}, + {"index": "B", "libelle": "Donne des indications sur le vent en altitude.", "correct": true} + ] + }, + { + "num": 90, + "libelle": "Ceux qui ouvrent le plus bas :", + "choices": [ + {"index": "A", "libelle": "Partent généralement en premier de l’avion.", "correct": true}, + {"index": "B", "libelle": "Partent généralement en dernier de l’avion.", "correct": false}, + {"index": "C", "libelle": "La hauteur d’ouverture n’a pas d’importance pour l’ordre des départs.", "correct": false} + ] + }, + { + "num": 91, + "libelle": "Ceux qui ouvrent le plus haut :", + "choices": [ + {"index": "A", "libelle": "La hauteur d’ouverture n’a pas d’importance pour l’ordre des départs.", "correct": false}, + {"index": "B", "libelle": "Partent généralement en dernier de l’avion.", "correct": true}, + {"index": "C", "libelle": "Partent généralement en premier de l’avion.", "correct": false} + ] + }, + { + "num": 92, + "libelle": "Sur un même passage, les grands groupes partent généralement :", + "choices": [ + {"index": "A", "libelle": "En premier.", "correct": true}, + {"index": "B", "libelle": "En dernier.", "correct": false}, + {"index": "C", "libelle": "C’est sans importance.", "correct": false} + ] + }, + { + "num": 93, + "libelle": "Au moment du largage, il faut :", + "choices": [ + {"index": "A", "libelle": "Se contenter de vérifier que l’on saute au dessus du terrain et assurer l’espacement entre les départs.", "correct": false}, + {"index": "B", "libelle": "Contrôler l’axe, le point de largage et assurer l’espacement entre les départs.", "correct": true} + ] + }, + { + "num": 94, + "libelle": "Au moment du largage, s‘assurer que l’espace aérien est dégagé en dessous :", + "choices": [ + {"index": "A", "libelle": "Est de la responsabilité du pilote, du directeur de séance et du largueur.", "correct": true}, + {"index": "B", "libelle": "Est de la responsabilité du directeur de séance uniquement.", "correct": false}, + {"index": "C", "libelle": "Est de la responsabilité du pilote uniquement.", "correct": false} + ] + }, + { + "num": 95, + "libelle": "Si au moment du largage, on constate qu’il y a des voiles ouvertes en dessous de l’axe et assez haut.", + "choices": [ + {"index": "A", "libelle": "Chacun assure sa sécurité une fois en chute.", "correct": false}, + {"index": "B", "libelle": "On refait un passage ou/et on décale suffisamment l’axe de largage.", "correct": true} + ] + }, + { + "num": 96, + "libelle": "Quand on largue, si l’avion est en montée :", + "choices": [ + {"index": "A", "libelle": "Le fait que l’avion monte n’influence pas la visualisation du point de largage.", "correct": false}, + {"index": "B", "libelle": "On a tendance à larguer trop court (trop tôt).", "correct": true}, + {"index": "C", "libelle": "On a tendance à larguer trop long (trop loin).", "correct": false} + ] + }, + { + "num": 97, + "libelle": "Quand on largue, si l’avion est en descente :", + "choices": [ + {"index": "A", "libelle": "On a tendance à larguer trop long (trop loin).", "correct": true}, + {"index": "B", "libelle": "On a tendance à larguer trop court (trop tôt).", "correct": false}, + {"index": "C", "libelle": "Le fait que l’avion descende n’influence pas la visualisation du point de largage.", "correct": false} + ] + }, + { + "num": 98, + "libelle": "Quand on large, si l’avion est incliné à droite :", + "choices": [ + {"index": "A", "libelle": "Le fait que l’avion soit incliné n’influence pas la visualisation du point de largage.", "correct": false}, + {"index": "B", "libelle": "On a tendance à larguer trop à gauche.", "correct": true}, + {"index": "C", "libelle": "On a tendance à larguer trop à droite.", "correct": false} + ] + }, + { + "num": 99, + "libelle": "Si vous larguez au cap 270° :", + "choices": [ + {"index": "A", "libelle": "Vous larguez en direction du sud.", "correct": false}, + {"index": "B", "libelle": "Vous larguez en direction de l’est.", "correct": false}, + {"index": "C", "libelle": "Vous larguez en direction du nord.", "correct": false}, + {"index": "D", "libelle": "Vous larguez en direction de l’ouest.", "correct": true} + ] + }, + { + "num": 100, + "libelle": "Si vous larguez au cap 180° :", + "choices": [ + {"index": "A", "libelle": "Vous larguez en direction de l'ouest.", "correct": false}, + {"index": "B", "libelle": "Vous larguez en direction du sud.", "correct": true}, + {"index": "C", "libelle": "Vous larguez en direction de l'est.", "correct": false}, + {"index": "D", "libelle": "Vous larguez en direction du nord.", "correct": false} + ] + }, + { + "num": 101, + "libelle": "Si vous larguez au cap 225° :", + "choices": [ + {"index": "A", "libelle": "Vous larguez en direction du nord-est.", "correct": false}, + {"index": "B", "libelle": "Vous larguez en direction de sud-ouest.", "correct": true}, + {"index": "C", "libelle": "Vous larguez en direction du nord-ouest.", "correct": false}, + {"index": "D", "libelle": "Vous larguez en direction du sud-est.", "correct": false} + ] + }, + { + "num": 102, + "libelle": "En cas d’ouverture intempestive d’un parachute dans l’avion durant la montée :", + "choices": [ + {"index": "A", "libelle": "Il faut placer le parachutiste au fond de l’avion avant le largage.", "correct": false}, + {"index": "B", "libelle": "Il faut placer le parachutiste à un endroit où il ne gênera pas le largage.", "correct": false}, + {"index": "C", "libelle": "Il faut placer le parachutiste à coté du pilote avant le largage.", "correct": false}, + {"index": "D", "libelle": "Il faut suspendre la montée et se reposer.", "correct": true} + ] + }, + { + "num": 103, + "libelle": "En cas d’ouverture intempestive d’un parachute dans l’avion durant la montée :", + "choices": [ + {"index": "A", "libelle": "Il faut placer le parachutiste à un endroit où il ne gênera pas le largage.", "correct": false}, + {"index": "B", "libelle": "Il faut essayer de refermer le parachute avant le largage.", "correct": false}, + {"index": "C", "libelle": "On peut poursuivre la montée et effectuer le largage.", "correct": false}, + {"index": "D", "libelle": "Il faut suspendre la montée et se reposer.", "correct": true} + ] + }, + { + "num": 104, + "libelle": "Avec du vent, ceux qui chutent le plus vite, par exemple le « free-fly » :", + "choices": [ + {"index": "A", "libelle": "Subissent une dérive moins importante que ceux qui chutent à plat.", "correct": true}, + {"index": "B", "libelle": "Subissent une dérive plus importante que ceux qui chutent à plat.", "correct": false} + ] + }, + { + "num": 105, + "libelle": "Ceux qui ouvrent haut :", + "choices": [ + {"index": "A", "libelle": "Subissent une dérive sous voile moins grande que ceux qui ouvrent plus bas.", "correct": false}, + {"index": "B", "libelle": "Subissent une dérive sous voile plus grande que ceux qui ouvrent plus bas.", "correct": true} + ] + }, + { + "num": 106, + "libelle": "De quoi dépend la distance de séparation horizontale entre deux parachutistes qui ne sautent pas ensemble ?", + "choices": [ + {"index": "A", "libelle": "De la vitesse de l’avion uniquement.", "correct": false}, + {"index": "B", "libelle": "Du temps laissé entre deux départs uniquement.", "correct": false}, + {"index": "C", "libelle": "De la vitesse de l’avion et du temps entre deux départs.", "correct": true} + ] + }, + { + "num": 107, + "libelle": "Qu’est-ce que la projection ?", + "choices": [ + {"index": "A", "libelle": "C’est l’impulsion donnée en sortie d’avion.", "correct": false}, + {"index": "B", "libelle": "C’est la distance horizontale parcourue pendant les dix premières secondes de chute.", "correct": true}, + {"index": "C", "libelle": "C’est le temps mis pour atteindre la vitesse maximale de chute.", "correct": false} + ] + }, + { + "num": 108, + "libelle": "Qu’est- ce que la dérive totale due au vent au cours d’un saut ?", + "choices": [ + {"index": "A", "libelle": "C’est la dérive en chute / par la dérive parachute ouvert.", "correct": false}, + {"index": "B", "libelle": "C’est la dérive en chute – la dérive parachute ouvert.", "correct": false}, + {"index": "C", "libelle": "C’est la dérive en chute + la dérive parachute ouvert.", "correct": true} + ] + }, + { + "num": 109, + "libelle": "On appelle dérive totale :", + "choices": [ + {"index": "A", "libelle": "Le temps de chute + le temps de descente parachute ouvert.", "correct": false}, + {"index": "B", "libelle": "Le produit (temps de chute + temps de descente parachute ouvert) x vitesse du vent.", "correct": true}, + {"index": "C", "libelle": "La vitesse du vent.", "correct": false} + ] + }, + { + "num": 110, + "libelle": "En chute libre avec du vent :", + "choices": [ + {"index": "A", "libelle": "On subit une dérive égale à la distance parcourue multiplié par la vitesse du vent.", "correct": false}, + {"index": "B", "libelle": "On subit une dérive égale au temps de chute multiplié par la vitesse du vent.", "correct": true}, + {"index": "C", "libelle": "On ne subit aucune dérive.", "correct": false} + ] + }, + { + "num": 111, + "libelle": "Parachute ouvert :", + "choices": [ + {"index": "A", "libelle": "On subit une dérive égale au temps de descente multiplié par la vitesse du vent.", "correct": true}, + {"index": "B", "libelle": "On ne subit aucune dérive.", "correct": false}, + {"index": "C", "libelle": "On subit une dérive égale à la distance parcourue multiplié par la vitesse du vent.", "correct": false} + ] + }, + { + "num": 112, + "libelle": "Sans vent, sur un avion de type Pilatus, le temps entre deux départ doit être de :", + "choices": [ + {"index": "A", "libelle": "8 à 10 secondes.", "correct": true}, + {"index": "B", "libelle": "5 à 6 secondes.", "correct": false}, + {"index": "C", "libelle": "3 à 4 secondes.", "correct": false}, + {"index": "D", "libelle": "12 à 14 secondes.", "correct": false} + ] + }, + { + "num": 113, + "libelle": "Sans vent, sur un avion de type Pilatus, 5 départs successifs, en respectant les espacements recommandés implique une distance de largage de :", + "choices": [ + {"index": "A", "libelle": "Environ 800 m.", "correct": false}, + {"index": "B", "libelle": "Environ 300 m.", "correct": false}, + {"index": "C", "libelle": "Environ 500 m.", "correct": false}, + {"index": "D", "libelle": "Environ 1150 m.", "correct": true} + ] + }, + { + "num": 114, + "libelle": "Avec un avion gros porteur, comparativement à un avion de type Pilatus ou Cessna :", + "choices": [ + {"index": "A", "libelle": "La vitesse de largage est plus élevée, il faut diminuer l’espacement entre les départs.", "correct": true}, + {"index": "B", "libelle": "La vitesse de largage est plus élevée, il faut augmenter l’espacement entre les départs.", "correct": false}, + {"index": "C", "libelle": "La vitesse de largage est moins élevée, il faut diminuer l’espacement entre les départs.", "correct": false}, + {"index": "D", "libelle": "La vitesse de largage est moins élevée, il faut augmenter l’espacement entre les départs.", "correct": false} + ] + }, + { + "num": 115, + "libelle": "La météorologie vous donne un vent de 35 kts de 1000 à 4000 mètres. La dérive en chute de 4000 à 1000 mètres pour un parachutiste qui chute à plat sera de :", + "choices": [ + {"index": "A", "libelle": "Environ 600 m.", "correct": false}, + {"index": "B", "libelle": "Environ 300 m.", "correct": false}, + {"index": "C", "libelle": "Environ 1100 m.", "correct": true} + ] + }, + { + "num": 116, + "libelle": "L’avion avance lentement par rapport au sol :", + "choices": [ + {"index": "A", "libelle": "Il vole face à un vent fort. Je conserve l’espacement standard entre les départs, le vent en altitude n’ayant que peu d’influence.", "correct": false}, + {"index": "B", "libelle": "Il vole face à un vent fort. Il faut diminuer le temps entre les départs.", "correct": false}, + {"index": "C", "libelle": "Il vole face à un vent fort. Il faut augmenter le temps entre les départs.", "correct": true} + ] + }, + { + "num": 117, + "libelle": "Pour déterminer le point de largage, il faut observer :", + "choices": [ + {"index": "A", "libelle": "Le vent au sol et le vent en altitude.", "correct": true}, + {"index": "B", "libelle": "Surtout le vent au sol.", "correct": false}, + {"index": "C", "libelle": "Uniquement le vent en altitude.", "correct": false} + ] + }, + { + "num": 118, + "libelle": "Par vent fort, il faut larguer :", + "choices": [ + {"index": "A", "libelle": "Au vent du terrain, d’autant plus loin que le vent est fort.", "correct": true}, + {"index": "B", "libelle": "Au vent du terrain, d’autant moins loin que le vent est fort.", "correct": false}, + {"index": "C", "libelle": "Sous le vent du terrain, d’autant moins loin que le vent est fort.", "correct": false}, + {"index": "D", "libelle": "Sous le vent du terrain, d’autant plus loin que le vent est fort.", "correct": false} + ] + }, + { + "num": 119, + "libelle": "Par vent nul, il faut larguer :", + "choices": [ + {"index": "A", "libelle": "A la verticale du terrain.", "correct": true}, + {"index": "B", "libelle": "Loin de la verticale du terrain.", "correct": false} + ] + }, + { + "num": 120, + "libelle": "Si on largue vent arrière avec plusieurs départs au même passage, il faut :", + "choices": [ + {"index": "A", "libelle": "Anticiper le départ des premiers et espacer les départs au moins autant que vent de face.", "correct": true}, + {"index": "B", "libelle": "Espacer un peu moins les départs pour compenser la vitesse sol de l’avion.", "correct": false}, + {"index": "C", "libelle": "Larguer au même endroit que vent de face.", "correct": false} + ] + }, + { + "num": 121, + "libelle": "Par vent fort en larguant face au vent, il faut :", + "choices": [ + {"index": "A", "libelle": "On ne tient jamais compte du vent pour déterminer l’espacement des départs.", "correct": false}, + {"index": "B", "libelle": "Espacer davantage les départs que par vent faible.", "correct": true}, + {"index": "C", "libelle": "Espacer un peu moins les départs que par vent faible.", "correct": false} + ] + }, + { + "num": 122, + "libelle": "Quand le vent est fort entre 4000 m et 1000 m", + "choices": [ + {"index": "A", "libelle": "Il vaut mieux faire partir le groupe de FF avant le groupe de VR.", "correct": false}, + {"index": "B", "libelle": "Il vaut mieux faire partir le groupe de VR avant le groupe de FF.", "correct": true}, + {"index": "C", "libelle": "C’est sans importance.", "correct": false} + ] + }, + { + "num": 123, + "libelle": "Quand le vent est très faible entre 4000 m et 1000 m :", + "choices": [ + {"index": "A", "libelle": "Il vaut mieux faire partir le groupe de VR avant le groupe de FF", "correct": false}, + {"index": "B", "libelle": "Il vaut mieux faire partir le groupe de FF avant le groupe de VR", "correct": true}, + {"index": "C", "libelle": "C’est sans importance.", "correct": false} + ] + }, + { + "num": 124, + "libelle": "Quand on constate sur l’axe de largage que l’avion vole doucement par rapport au sol.", + "choices": [ + {"index": "A", "libelle": "On vole face à un vent fort, il faut partir loin et espacer davantage les départs.", "correct": true}, + {"index": "B", "libelle": "On vole face à un vent fort, il n’y a pas de précautions particulières à prendre.", "correct": false}, + {"index": "C", "libelle": "Cela ne signifie rien de particulier.", "correct": false} + ] + }, + { + "num": 125, + "libelle": "Après avoir vérifié son ouverture :", + "choices": [ + {"index": "A", "libelle": "Il faut s’orienter face au terrain dès que possible.", "correct": false}, + {"index": "B", "libelle": "Il faut s’orienter face au vent dès que possible.", "correct": false}, + {"index": "C", "libelle": "Il faut s’orienter perpendiculairement à l’axe de largage dès que possible.", "correct": true}, + {"index": "D", "libelle": "L’orientation n’a pas d’importance.", "correct": false} + ] + }, + { + "num": 126, + "libelle": "Parachute ouvert, ceux qui ont ouvert le plus haut :", + "choices": [ + {"index": "A", "libelle": "Ils n’ont pas à s’occuper des autres.", "correct": false}, + {"index": "B", "libelle": "Doivent essayer de ne pas descendre trop vite pour ne pas rattraper les autres.", "correct": true}, + {"index": "C", "libelle": "Doivent descendre le plus vite possible pour rattraper les autres.", "correct": false} + ] + }, + { + "num": 127, + "libelle": "Parachute ouvert :", + "choices": [ + {"index": "A", "libelle": "C’est possible si l’on passe juste derrière l’autre voilure.", "correct": false}, + {"index": "B", "libelle": "Il faut éviter de suivre des trajectoires convergentes avec une autre voilure.", "correct": true} + ] + }, + { + "num": 128, + "libelle": "Si deux parachutistes volent en direction l’un de l’autre, face à face :", + "choices": [ + {"index": "A", "libelle": "L’un des deux doit dégager sur sa gauche et l’autre sur sa droite.", "correct": false}, + {"index": "B", "libelle": "Les deux doivent dégager sur leur gauche.", "correct": false}, + {"index": "C", "libelle": "Les deux doivent dégager sur leur droite.", "correct": true} + ] + }, + { + "num": 129, + "libelle": "Si deux parachutistes volent en direction l’un de l’autre, face à face :", + "choices": [ + {"index": "A", "libelle": "Elle est égale à la somme des vitesses des deux voilures.", "correct": true}, + {"index": "B", "libelle": "Elle est égale à celle de la plus lente des deux voilures.", "correct": false}, + {"index": "C", "libelle": "Leur vitesse de rapprochement est égale à celle de la plus rapide des deux voilures.", "correct": false} + ] + }, + { + "num": 130, + "libelle": "Combien de temps mettront pour se rejoindre deux voilures dont les vitesses horizontales respective sont de 10 mètres par seconde, si elles sont ouvertes face à face à 100 mètres de distance ?", + "choices": [ + {"index": "A", "libelle": "20 secondes.", "correct": false}, + {"index": "B", "libelle": "15 secondes.", "correct": false}, + {"index": "C", "libelle": "10 secondes.", "correct": false}, + {"index": "D", "libelle": "5 secondes.", "correct": true} + ] + }, + { + "num": 131, + "libelle": "Deux parachutistes partent à 4000 mètres à 8 secondes d’intervalle d’un avion volant à la vitesse de 70 nœuds (vitesse sol). Ils chutent sans déplacement horizontal dans la masse d’air. Le vent est nul. Quelle est environ leur distance horizontale de séparation à l’ouverture ?", + "choices": [ + {"index": "A", "libelle": "330 m.", "correct": false}, + {"index": "B", "libelle": "280 m.", "correct": true}, + {"index": "C", "libelle": "200 m.", "correct": false}, + {"index": "D", "libelle": "160 m.", "correct": false} + ] + }, + { + "num": 132, + "libelle": "Avec une vitesse de largage de 70 kts et un vent de face de 40 kts de 1000 à 4000 mètres, quel est l’espacement souhaitable entre les départs lors d’un largage à 4000 mètres afin d’obtenir un espacement horizontal de 300 mètres entre chaque départ ?", + "choices": [ + {"index": "A", "libelle": "20 secondes.", "correct": true}, + {"index": "B", "libelle": "15 secondes.", "correct": false}, + {"index": "C", "libelle": "12 secondes.", "correct": false}, + {"index": "D", "libelle": "10 secondes.", "correct": false} + ] + }, + { + "num": 133, + "libelle": "Si un parachutiste évolue devant vous et un peu au-dessus :", + "choices": [ + {"index": "A", "libelle": "Il a la priorité parce qu’il ne vous voit pas.", "correct": true}, + {"index": "B", "libelle": "Vous avez la priorité parce que vous êtes le plus bas.", "correct": false} + ] + }, + { + "num": 134, + "libelle": "Si un parachutiste se trouve au-dessus d’un obstacle en bordure de la zone de poser, un peu au-dessus de vous :", + "choices": [ + {"index": "A", "libelle": "Vous avez la priorité car vous êtes en dessous.", "correct": false}, + {"index": "B", "libelle": "Il a la priorité et vous devez lui laisser la place pour rentrer la zone de poser.", "correct": true} + ] + }, + { + "num": 135, + "libelle": "Un élève débutant et un parachutiste confirmé se présentent en même temps dans le circuit d’atterrissage :", + "choices": [ + {"index": "A", "libelle": "C’est le plus expérimenté qui a la priorité.", "correct": false}, + {"index": "B", "libelle": "C’est le moins expérimenté qui a la priorité.", "correct": true} + ] + }, + { + "num": 136, + "libelle": "Entre un tandem et un élève débutant :", + "choices": [ + {"index": "A", "libelle": "C’est le tandem qui est prioritaire car il est moins manœuvrant.", "correct": false}, + {"index": "B", "libelle": "C’est l’élève qui est prioritaire car il est moins expérimenté.", "correct": true} + ] + } + ] + }, + { + "num": 5, + "name": "Règlementation", + "questions": [ + { + "num": 137, + "libelle": "Le pilote traverse une fine couche nuageuse à 2000 mètres pour monter larguer à 4000 mètres. Personne ne voit le sol au moment du largage. Celui-ci s’effectue à l’aide au GPS.", + "choices": [ + {"index": "A", "libelle": "C’est une infraction.", "correct": true}, + {"index": "B", "libelle": "Cela ne constitue pas une infraction si le pilote est qualifié IFR.", "correct": false}, + {"index": "C", "libelle": "Si le pilote est qualifié IFR et titulaire d’une licence professionnelle ce n’est pas une infraction.", "correct": false}, + {"index": "D", "libelle": "Cela ne constitue pas une infraction car l’avion est équipé d’un GPS.", "correct": false} + ] + }, + { + "num": 138, + "libelle": "Une couche de nuageuse soudée est à 3000 mètres. Vous demandez au pilote de la traverser et de larguer à l’aide du GPS.", + "choices": [ + {"index": "A", "libelle": "Si le pilote est qualifié IFR et titulaire d’une licence professionnelle ce n’est pas une infraction.", "correct": false}, + {"index": "B", "libelle": "Cela ne constitue pas une infraction car l’avion est équipé d’un GPS", "correct": false}, + {"index": "C", "libelle": "Cela ne constitue pas une infraction si le pilote est qualifié IFR.", "correct": false}, + {"index": "D", "libelle": "C’est une infraction.", "correct": true} + ] + }, + { + "num": 139, + "libelle": "En VFR, la traversée d’une couche nuageuse, même mince, est interdite :", + "choices": [ + {"index": "A", "libelle": "Vrai.", "correct": true}, + {"index": "B", "libelle": "Faux.", "correct": false} + ] + }, + { + "num": 140, + "libelle": "Un pilote titulaire d’une licence professionnelle ou privée en conditions de vol VMC peut se voir retirer sa licence temporairement ou à vie s’il traverse une couche nuageuse ou s’il pénètre dans un nuage.", + "choices": [ + {"index": "A", "libelle": "Vrai.", "correct": true}, + {"index": "B", "libelle": "Faux.", "correct": false} + ] + }, + { + "num": 141, + "libelle": "Dans l’avion, la présence d’un « coupe sangle » est obligatoire.", + "choices": [ + {"index": "A", "libelle": "Uniquement si l’avion est équipé pour le largage des élèves en ouverture automatique.", "correct": false}, + {"index": "B", "libelle": "Uniquement lors du largage d’élèves en ouverture automatique.", "correct": false}, + {"index": "C", "libelle": "Dans tous les cas quelque soit le type de largage effectué.", "correct": true} + ] + }, + { + "num": 142, + "libelle": "Quel est le brevet minimum nécessaire afin d’effectuer des sauts de nuit ?", + "choices": [ + {"index": "A", "libelle": "Le brevet B.", "correct": false}, + {"index": "B", "libelle": "Le BPA.", "correct": true}, + {"index": "C", "libelle": "Le brevet C ou D.", "correct": false} + ] + }, + { + "num": 143, + "libelle": "Quel est le brevet qui donne l’autorisation d’effectuer des sauts à haute altitude ?", + "choices": [ + {"index": "A", "libelle": "Le BPA.", "correct": true}, + {"index": "B", "libelle": "Le brevet A.", "correct": false}, + {"index": "C", "libelle": "Le brevet B.", "correct": false} + ] + }, + { + "num": 144, + "libelle": "Quel est le brevet qui donne l’autorisation d’effectuer des sauts de ballon ?", + "choices": [ + {"index": "A", "libelle": "Le brevet A.", "correct": false}, + {"index": "B", "libelle": "Le brevet B.", "correct": false}, + {"index": "C", "libelle": "Le BPA.", "correct": false}, + {"index": "D", "libelle": "Le brevet C ou D.", "correct": true} + ] + }, + { + "num": 145, + "libelle": "Quel est le brevet qui donne la possibilité de participer à des compétitions ?", + "choices": [ + {"index": "A", "libelle": "Le brevet A.", "correct": false}, + {"index": "B", "libelle": "Le brevet B dans la spécialité correspondante.", "correct": true}, + {"index": "C", "libelle": "Le brevet C.", "correct": false} + ] + }, + { + "num": 146, + "libelle": "La durée de la validité du contrôle périodique d’un parachute est de :", + "choices": [ + {"index": "A", "libelle": "24 mois.", "correct": false}, + {"index": "B", "libelle": "12 mois.", "correct": true}, + {"index": "C", "libelle": "6 mois.", "correct": false}, + {"index": "D", "libelle": "3 mois.", "correct": false} + ] + }, + { + "num": 147, + "libelle": "La vitesse de vent maximale autorisée au sol pour des parachutistes titulaires uniquement du brevet A est de :", + "choices": [ + {"index": "A", "libelle": "12 m/s.", "correct": false}, + {"index": "B", "libelle": "11 m/s.", "correct": true}, + {"index": "C", "libelle": "9 m/s.", "correct": false}, + {"index": "D", "libelle": "7 m/s.", "correct": false} + ] + }, + { + "num": 148, + "libelle": "La vitesse de vent maximale autorisée au sol pour des parachutistes titulaires uniquement du brevet B est de :", + "choices": [ + {"index": "A", "libelle": "12 m/s.", "correct": false}, + {"index": "B", "libelle": "11 m/s.", "correct": true}, + {"index": "C", "libelle": "9 m/s.", "correct": false}, + {"index": "D", "libelle": "7 m/s.", "correct": false} + ] + }, + { + "num": 149, + "libelle": "La vitesse de vent maximale autorisée au sol pour des sauts en tandem est de :", + "choices": [ + {"index": "A", "libelle": "13 m/s.", "correct": false}, + {"index": "B", "libelle": "15 m/s.", "correct": false}, + {"index": "C", "libelle": "12 m/s.", "correct": false}, + {"index": "D", "libelle": "11 m/s.", "correct": true} + ] + }, + { + "num": 150, + "libelle": "La vitesse de vent maximale autorisée au sol pour des élèves non titulaires du brevet A est de :", + "choices": [ + {"index": "A", "libelle": "5 m/s.", "correct": false}, + {"index": "B", "libelle": "7 m/s.", "correct": true}, + {"index": "C", "libelle": "8 m/s.", "correct": false}, + {"index": "D", "libelle": "6 m/s.", "correct": false} + ] + }, + { + "num": 151, + "libelle": "Un parachutiste titulaire uniquement du BPA et totalisant 300 sauts peut-il sauter avec une voile de la surface de son choix ?", + "choices": [ + {"index": "A", "libelle": "Non.", "correct": true}, + {"index": "B", "libelle": "Oui.", "correct": false} + ] + }, + { + "num": 152, + "libelle": "Un parachutiste titulaire uniquement du BPA et totalisant 700 sauts peut-il sauter avec une voile de la surface de son choix ?", + "choices": [ + {"index": "A", "libelle": "Non.", "correct": true}, + {"index": "B", "libelle": "Oui.", "correct": false} + ] + }, + { + "num": 153, + "libelle": "Peut-on poursuivre une séance de sauts si le vent au sol est constant à 10 m/s avec des rafales à 13 m/s ?", + "choices": [ + {"index": "A", "libelle": "Uniquement pour les sauts en tandem.", "correct": false}, + {"index": "B", "libelle": "Non.", "correct": true}, + {"index": "C", "libelle": "Oui.", "correct": false}, + {"index": "D", "libelle": "Uniquement pour les parachutistes titulaires du BPA.", "correct": false} + ] + }, + { + "num": 154, + "libelle": "Quel est l’encadrement minimum nécessaire au sol lors d’une séance de pratique autonome ?", + "choices": [ + {"index": "A", "libelle": "Un parachutiste titulaire du Brevet C.", "correct": true}, + {"index": "B", "libelle": "Un moniteur titulaire au minimum du monitorat fédéral.", "correct": false}, + {"index": "C", "libelle": "Un parachutiste titulaire du Brevet BPA.", "correct": false}, + {"index": "D", "libelle": "Un parachutiste titulaire du Brevet D.", "correct": false} + ] + }, + { + "num": 155, + "libelle": "Une assurance responsabilité civile est-elle obligatoire pour les parachutistes qui pratiquent dans les structures de la FFP ?", + "choices": [ + {"index": "A", "libelle": "Uniquement pour les moniteurs.", "correct": false}, + {"index": "B", "libelle": "Oui.", "correct": true}, + {"index": "C", "libelle": "Uniquement pour les compétiteurs.", "correct": false}, + {"index": "D", "libelle": "Non.", "correct": false} + ] + }, + { + "num": 156, + "libelle": "La hauteur minimale d’ouverture imposé par la réglementation fédérale pour les parachutistes titulaire du BPA est de :", + "choices": [ + {"index": "A", "libelle": "850 m.", "correct": true}, + {"index": "B", "libelle": "1200 m.", "correct": false}, + {"index": "C", "libelle": "650 m.", "correct": false}, + {"index": "D", "libelle": "1000 m.", "correct": false} + ] + }, + { + "num": 157, + "libelle": "Quel est le document attestant l’affiliation à la FFP ?", + "choices": [ + {"index": "A", "libelle": "L’assurance responsabilité civile.", "correct": false}, + {"index": "B", "libelle": "Le livret de progression et un des brevets fédéraux.", "correct": false}, + {"index": "C", "libelle": "La licence assurance de l’année en cours", "correct": true} + ] + }, + { + "num": 158, + "libelle": "Les documents de saut qu’un parachutiste doit présenter pour sauter dans les structures fédérales sont :", + "choices": [ + {"index": "A", "libelle": "Le livret de parachute uniquement.", "correct": false}, + {"index": "B", "libelle": "La licence assurance uniquement.", "correct": false}, + {"index": "C", "libelle": "Le carnet de sauts uniquement.", "correct": false}, + {"index": "D", "libelle": "L’ensemble de ces documents.", "correct": true} + ] + }, + { + "num": 159, + "libelle": "L’assurance en responsabilité civile :", + "choices": [ + {"index": "A", "libelle": "Garantie la réparation des dommages causés aux tiers.", "correct": true}, + {"index": "B", "libelle": "Garantie le remboursement des frais médicaux et chirurgicaux de l’assuré.", "correct": false} + ] + }, + { + "num": 160, + "libelle": "L’assurance individuelle :", + "choices": [ + {"index": "A", "libelle": "Garantie la réparation des dommages causés aux tiers.", "correct": false}, + {"index": "B", "libelle": "Garantie le remboursement des frais médicaux et chirurgicaux de l’assuré.", "correct": true} + ] + }, + { + "num": 161, + "libelle": "Le titulaire du BPA peut effectuer tous les sauts spéciaux.", + "choices": [ + {"index": "A", "libelle": "Uniquement les sauts de nuit et les sauts à haute altitude avec l’accord du directeur technique.", "correct": false}, + {"index": "B", "libelle": "Faux.", "correct": true}, + {"index": "C", "libelle": "Vrai.", "correct": false} + ] + }, + { + "num": 162, + "libelle": "Le titulaire du brevet B peut-il effectuer des sauts spéciaux ?", + "choices": [ + {"index": "A", "libelle": "Oui.", "correct": false}, + {"index": "B", "libelle": "Non.", "correct": true}, + {"index": "C", "libelle": "Uniquement les sauts de nuit et les sauts à haute altitude avec l’accord du directeur technique.", "correct": false} + ] + }, + { + "num": 163, + "libelle": "Le titulaire du BPA peut-il effectuer des sauts de démonstration hors école de parachutisme ?", + "choices": [ + {"index": "A", "libelle": "Oui.", "correct": false}, + {"index": "B", "libelle": "Non.", "correct": true}, + {"index": "C", "libelle": "Oui si les sauts ne se déroulent pas lors d’une manifestation aérienne.", "correct": false} + ] + } + ] + }, + { + "num": 6, + "name": "Pilotage et mécanique de vol", + "questions": [ + { + "num": 164, + "libelle": "Plus je fais un mouvement brusque et ample pour tourner :", + "choices": [ + {"index": "A", "libelle": "L’inclinaison de la voile est indépendante de la manœuvre de mise en virage.", "correct": false}, + {"index": "B", "libelle": "Moins l’inclinaison de voile augmente.", "correct": false}, + {"index": "C", "libelle": "Plus l’inclinaison de la voile augmente.", "correct": true} + ] + }, + { + "num": 165, + "libelle": "Plus la vitesse initiale est élevée avant le virage :", + "choices": [ + {"index": "A", "libelle": "Moins le rayon de virage augmente.", "correct": false}, + {"index": "B", "libelle": "Plus le rayon de virage augmente.", "correct": true}, + {"index": "C", "libelle": "Le rayon de virage est indépendant de la vitesse initiale.", "correct": false} + ] + }, + { + "num": 166, + "libelle": "Plus la voile s’incline en virage :", + "choices": [ + {"index": "A", "libelle": "Plus la vitesse verticale diminue.", "correct": false}, + {"index": "B", "libelle": "Plus la vitesse verticale augmente.", "correct": true}, + {"index": "C", "libelle": "La vitesse verticale est indépendante de l’inclinaison de la voile.", "correct": false} + ] + }, + { + "num": 167, + "libelle": "Pour faire un virage ‘’à plat’’ :", + "choices": [ + {"index": "A", "libelle": "Il faut manœuvrer très rapidement à pleine vitesse.", "correct": false}, + {"index": "B", "libelle": "Il faut manœuvrer doucement et en ½ frein.", "correct": true} + ] + }, + { + "num": 168, + "libelle": "Qu’appelle-t-on vitesse sur trajectoire d’une aile ?", + "choices": [ + {"index": "A", "libelle": "La vitesse qui résulte de la somme vectoriel de la vitesse horizontale et de la vitesse verticale.", "correct": true}, + {"index": "B", "libelle": "La vitesse verticale.", "correct": false}, + {"index": "C", "libelle": "La vitesse horizontale.", "correct": false} + ] + }, + { + "num": 169, + "libelle": "La vitesse propre d’une aile, dans la masse d’air :", + "choices": [ + {"index": "A", "libelle": "Est plus grande vent arrière que vent de face.", "correct": false}, + {"index": "B", "libelle": "Est plus grande vent de face que vent arrière.", "correct": false}, + {"index": "C", "libelle": "Est indépendante du vent.", "correct": true} + ] + }, + { + "num": 170, + "libelle": "La vitesse sol d’une aile :", + "choices": [ + {"index": "A", "libelle": "Est plus grande vent arrière que vent de face.", "correct": true}, + {"index": "B", "libelle": "Est plus grande vent de face que vent arrière.", "correct": false}, + {"index": "C", "libelle": "Est indépendante du vent.", "correct": false} + ] + }, + { + "num": 171, + "libelle": "En faisant un virage rapide :", + "choices": [ + {"index": "A", "libelle": "La vitesse verticale diminue.", "correct": false}, + {"index": "B", "libelle": "La vitesse verticale augmente beaucoup.", "correct": true}, + {"index": "C", "libelle": "La vitesse verticale augmente peu.", "correct": false} + ] + }, + { + "num": 172, + "libelle": "Pour augmenter la pénétration dans l’air par vent fort :", + "choices": [ + {"index": "A", "libelle": "Il faut faire une légère traction sur les élévateurs avants.", "correct": true}, + {"index": "B", "libelle": "Il faut faire une légère traction sur les élévateurs arrières.", "correct": false}, + {"index": "C", "libelle": "On ne peut pas améliorer la pénétration par vent fort.", "correct": false} + ] + }, + { + "num": 173, + "libelle": "Avec un vent de face égal à la vitesse horizontale de la voile, si on fait une traction sur les élévateurs avants :", + "choices": [ + {"index": "A", "libelle": "La finesse sol augmente.", "correct": true}, + {"index": "B", "libelle": "La finesse sol diminue.", "correct": false}, + {"index": "C", "libelle": "La finesse sol reste la même.", "correct": false} + ] + }, + { + "num": 174, + "libelle": "Par vent nul, si l’on tire sur les élévateurs avant :", + "choices": [ + {"index": "A", "libelle": "La vitesse diminue et la finesse augmente.", "correct": false}, + {"index": "B", "libelle": "La vitesse augmente et la finesse diminue.", "correct": true}, + {"index": "C", "libelle": "La vitesse et la finesse diminuent.", "correct": false}, + {"index": "D", "libelle": "La vitesse et la finesse augmentent.", "correct": false} + ] + }, + { + "num": 175, + "libelle": "Tirer sur les élévateurs avant peut être utile :", + "choices": [ + {"index": "A", "libelle": "Pour revenir sur le terrain par vent nul ou vent arrière, si l’on est loin.", "correct": false}, + {"index": "B", "libelle": "Pour contrer un fort vent de face.", "correct": true}, + {"index": "C", "libelle": "En aucune circonstance.", "correct": false} + ] + }, + { + "num": 176, + "libelle": "Une traction sur un élévateur avant provoque.", + "choices": [ + {"index": "A", "libelle": "Un virage lent à petit rayon et enfoncement important.", "correct": false}, + {"index": "B", "libelle": "Un virage lent à grand rayon et faible enfoncement.", "correct": false}, + {"index": "C", "libelle": "Un virage rapide à petit rayon et enfoncement important.", "correct": true}, + {"index": "D", "libelle": "Un virage rapide à grand rayon et faible enfoncement.", "correct": false} + ] + }, + { + "num": 177, + "libelle": "Par vent nul, si l’on tire modérément sur les élévateurs arrière :", + "choices": [ + {"index": "A", "libelle": "La vitesse augmente et la finesse diminue.", "correct": false}, + {"index": "B", "libelle": "La vitesse et la finesse diminuent.", "correct": false}, + {"index": "C", "libelle": "La vitesse diminue et la finesse augmente.", "correct": true}, + {"index": "D", "libelle": "La vitesse et la finesse augmentent.", "correct": false} + ] + }, + { + "num": 178, + "libelle": "Tirer sur les élévateurs arrière peut être utile :", + "choices": [ + {"index": "A", "libelle": "Pour revenir sur le terrain par vent nul ou vent arrière, si l’on est loin.", "correct": true}, + {"index": "B", "libelle": "Pour contrer un fort vent de face.", "correct": false}, + {"index": "C", "libelle": "En aucune circonstance.", "correct": false} + ] + }, + { + "num": 179, + "libelle": "Une traction modérée sur un élévateur arrière provoque :", + "choices": [ + {"index": "A", "libelle": "Un virage rapide à grand rayon et faible enfoncement.", "correct": false}, + {"index": "B", "libelle": "Un virage lent à grand rayon et faible enfoncement.", "correct": true}, + {"index": "C", "libelle": "Un virage rapide à petit rayon et enfoncement important.", "correct": false}, + {"index": "D", "libelle": "Un virage lent à petit rayon et enfoncement important.", "correct": false} + ] + }, + { + "num": 180, + "libelle": "Pour piloter avec les élévateurs :", + "choices": [ + {"index": "A", "libelle": "L’effort à fournir est le même que pour piloter avec les commandes.", "correct": false}, + {"index": "B", "libelle": "L’effort à fournir est plus faible que pour piloter avec les commandes.", "correct": false}, + {"index": "C", "libelle": "L’effort à fournir est plus important que pour piloter avec les commandes.", "correct": true} + ] + }, + { + "num": 181, + "libelle": "Quand on pilote avec les élévateurs :", + "choices": [ + {"index": "A", "libelle": "Il est plus bas.", "correct": false}, + {"index": "B", "libelle": "Il est plus haut.", "correct": true}, + {"index": "C", "libelle": "Le point de décrochage est au même niveau que quand on pilote avec les commandes.", "correct": false} + ] + }, + { + "num": 182, + "libelle": "Qu’appelle-t-on finesse ?", + "choices": [ + {"index": "A", "libelle": "Le rapport entre la surface et la masse du parachutiste équipé.", "correct": false}, + {"index": "B", "libelle": "L’épaisseur du profil d’une aile.", "correct": false}, + {"index": "C", "libelle": "Le rapport entre la vitesse horizontale et la vitesse verticale de la voilure.", "correct": true} + ] + }, + { + "num": 183, + "libelle": "On appelle finesse air :", + "choices": [ + {"index": "A", "libelle": "Le rapport vitesse sur trajectoire / vitesse verticale.", "correct": false}, + {"index": "B", "libelle": "Le rapport vitesse verticale / vitesse horizontale.", "correct": false}, + {"index": "C", "libelle": "Le rapport vitesse horizontale / vitesse verticale.", "correct": true} + ] + }, + { + "num": 184, + "libelle": "Dans la masse d’air, la finesse air est égale :", + "choices": [ + {"index": "A", "libelle": "Au rapport perte de hauteur / distance parcourue.", "correct": false}, + {"index": "B", "libelle": "Au rapport distance parcourue / perte de hauteur.", "correct": true} + ] + }, + { + "num": 185, + "libelle": "La finesse sol est égale à :", + "choices": [ + {"index": "A", "libelle": "Vitesse sur trajectoire par rapport au sol / vitesse verticale par rapport au sol.", "correct": false}, + {"index": "B", "libelle": "Vitesse sur trajectoire dans la masse d’air / vitesse verticale dans la masse d’air.", "correct": false}, + {"index": "C", "libelle": "Vitesse horizontale par rapport au sol / vitesse verticale par rapport au sol.", "correct": true}, + {"index": "D", "libelle": "Vitesse horizontale dans la masse d’air / vitesse verticale dans la masse d’air.", "correct": false} + ] + }, + { + "num": 186, + "libelle": "La finesse sol :", + "choices": [ + {"index": "A", "libelle": "Augmente avec un vent de face.", "correct": false}, + {"index": "B", "libelle": "Diminue avec un vent de face.", "correct": true}, + {"index": "C", "libelle": "Reste constante quelque soit le vent.", "correct": false} + ] + }, + { + "num": 187, + "libelle": "Par vent nul, avec une perte de hauteur de 1000 mètres et une finesse de 2,5 quelle est la distance parcourue?", + "choices": [ + {"index": "A", "libelle": "500 m", "correct": false}, + {"index": "B", "libelle": "2500 m", "correct": true}, + {"index": "C", "libelle": "1500 m", "correct": false} + ] + }, + { + "num": 188, + "libelle": "Comment se nomme la force aérodynamique qui est parallèle à la trajectoire ?", + "choices": [ + {"index": "A", "libelle": "La traînée.", "correct": true}, + {"index": "B", "libelle": "La résultante aérodynamique.", "correct": false}, + {"index": "C", "libelle": "La portance.", "correct": false} + ] + }, + { + "num": 189, + "libelle": "Comment se nomme la force aérodynamique qui est perpendiculaire à la trajectoire ?", + "choices": [ + {"index": "A", "libelle": "La portance.", "correct": true}, + {"index": "B", "libelle": "La traînée.", "correct": false}, + {"index": "C", "libelle": "La résultante aérodynamique.", "correct": false} + ] + }, + { + "num": 190, + "libelle": "En vol stable, quelle est la force qui équilibre le poids ?", + "choices": [ + {"index": "A", "libelle": "La portance.", "correct": false}, + {"index": "B", "libelle": "La traînée.", "correct": false}, + {"index": "C", "libelle": "La résultante aérodynamique.", "correct": true} + ] + }, + { + "num": 191, + "libelle": "Qu‘appelle-t-on angle d’incidence ?", + "choices": [ + {"index": "A", "libelle": "L’angle entre l’aile et l’axe du cône de suspension.", "correct": false}, + {"index": "B", "libelle": "L’angle entre la trajectoire et l’horizontale.", "correct": false}, + {"index": "C", "libelle": "L’angle entre la trajectoire et la corde de profil de l’aile.", "correct": true} + ] + }, + { + "num": 192, + "libelle": "La charge alaire :", + "choices": [ + {"index": "A", "libelle": "Est la masse du parachutiste équipé.", "correct": false}, + {"index": "B", "libelle": "Est la masse du parachute.", "correct": false}, + {"index": "C", "libelle": "Est la masse de la voilure.", "correct": false}, + {"index": "D", "libelle": "Est le rapport entre la masse du parachutiste équipé et la surface de voile.", "correct": true} + ] + }, + { + "num": 193, + "libelle": "On appelle charge alaire :", + "choices": [ + {"index": "A", "libelle": "Le rapport surface de voile / masse du parachutiste équipé.", "correct": false}, + {"index": "B", "libelle": "Le rapport masse du parachutiste équipé / surface de voile.", "correct": true}, + {"index": "C", "libelle": "La résistance du tissu de voile.", "correct": false} + ] + }, + { + "num": 194, + "libelle": "La charge alaire :", + "choices": [ + {"index": "A", "libelle": "Est un paramètre important.", "correct": true}, + {"index": "B", "libelle": "Est un paramètre négligeable.", "correct": false} + ] + }, + { + "num": 195, + "libelle": "Une finesse de 2.5 signifie :", + "choices": [ + {"index": "A", "libelle": "Que pour une perte de hauteur de 1000 m. La distance horizontale parcourue sera de 2500 m.", "correct": true}, + {"index": "B", "libelle": "Que pour une perte de hauteur de 2500 m. La distance horizontale parcourue sera de 1000 m.", "correct": false} + ] + }, + { + "num": 196, + "libelle": "Lors d’un virage, la vitesse verticale :", + "choices": [ + {"index": "A", "libelle": "Diminue.", "correct": false}, + {"index": "B", "libelle": "Augmente.", "correct": true}, + {"index": "C", "libelle": "Ne change pas.", "correct": false} + ] + }, + { + "num": 197, + "libelle": "Lors d’un décrochage, la vitesse verticale d’une voilure de type aile :", + "choices": [ + {"index": "A", "libelle": "Ne change pas.", "correct": false}, + {"index": "B", "libelle": "Augmente un petit peu.", "correct": false}, + {"index": "C", "libelle": "Augmente beaucoup.", "correct": true} + ] + }, + { + "num": 198, + "libelle": "Le décrochage :", + "choices": [ + {"index": "A", "libelle": "Survient uniquement suite à une action sur les commandes de manœuvre.", "correct": false}, + {"index": "B", "libelle": "Peut survenir quand on passe dans une zone de fortes turbulences.", "correct": true} + ] + }, + { + "num": 199, + "libelle": "Une voilure de type aile peut décrocher même si l’on n’a pas atteint les 100% de frein.", + "choices": [ + {"index": "A", "libelle": "Faux.", "correct": false}, + {"index": "B", "libelle": "Vrai.", "correct": true} + ] + }, + { + "num": 200, + "libelle": "Dans un écoulement laminaire, le point de décrochage :", + "choices": [ + {"index": "A", "libelle": "Varie en fonction de l’orientation et de la vitesse du vent.", "correct": false}, + {"index": "B", "libelle": "Est indépendant du vent.", "correct": true} + ] + }, + { + "num": 201, + "libelle": "Un décrochage dynamique :", + "choices": [ + {"index": "A", "libelle": "Peut survenir lors d’un freinage brusque.", "correct": true}, + {"index": "B", "libelle": "N’est possible qu’en condition de vent laminaire.", "correct": false}, + {"index": "C", "libelle": "N’est possible qu’en conditions turbulentes.", "correct": false} + ] + }, + { + "num": 202, + "libelle": "Si on augmente la masse sous un parachute, les vitesses verticales et horizontales :", + "choices": [ + {"index": "A", "libelle": "Diminuent.", "correct": false}, + {"index": "B", "libelle": "Augmentent.", "correct": true}, + {"index": "C", "libelle": "Ne changent pas.", "correct": false} + ] + }, + { + "num": 203, + "libelle": "Avec une voilure donnée, la vitesse sur trajectoire :", + "choices": [ + {"index": "A", "libelle": "C’est uniquement la vitesse verticale qui augmente.", "correct": false}, + {"index": "B", "libelle": "Ne varie pas quand la masse du parachutiste augmente.", "correct": false}, + {"index": "C", "libelle": "Augmente quand la masse du parachutiste augmente.", "correct": true} + ] + }, + { + "num": 204, + "libelle": "L’avant d’une voilure de type aile s’appelle :", + "choices": [ + {"index": "A", "libelle": "Le bord d’attaque.", "correct": true}, + {"index": "B", "libelle": "Le bord de fuite.", "correct": false}, + {"index": "C", "libelle": "Le saumon.", "correct": false} + ] + }, + { + "num": 205, + "libelle": "L’arrière d’une voilure de type aile s’appelle :", + "choices": [ + {"index": "A", "libelle": "L’intrados.", "correct": false}, + {"index": "B", "libelle": "Le bord d’attaque.", "correct": false}, + {"index": "C", "libelle": "Le bord de fuite.", "correct": true} + ] + }, + { + "num": 206, + "libelle": "Lors d’un décrochage, la vitesse horizontale :", + "choices": [ + {"index": "A", "libelle": "Augmente.", "correct": false}, + {"index": "B", "libelle": "Ne change pas.", "correct": false}, + {"index": "C", "libelle": "Diminue.", "correct": true} + ] + }, + { + "num": 207, + "libelle": "Si votre voilure décroche lors d’un freinage excessif :", + "choices": [ + {"index": "A", "libelle": "Il faut relâcher doucement les commandes de manœuvre.", "correct": true}, + {"index": "B", "libelle": "Il faut attendre que la voilure se remette en pression toute seule.", "correct": false}, + {"index": "C", "libelle": "Il faut agir sur les commandes par tractions répétées.", "correct": false} + ] + }, + { + "num": 208, + "libelle": "Le point de décrochage :", + "choices": [ + {"index": "A", "libelle": "Dépend des caractéristiques de l’aile et du réglage des commandes de manœuvre.", "correct": true}, + {"index": "B", "libelle": "Ne dépend que des caractéristiques de l’aile.", "correct": false} + ] + }, + { + "num": 209, + "libelle": "Le point de décrochage :", + "choices": [ + {"index": "A", "libelle": "Est toujours au même niveau.", "correct": false}, + {"index": "B", "libelle": "Peut varier en fonction des conditions aérologiques et des manœuvres effectuées.", "correct": true} + ] + }, + { + "num": 210, + "libelle": "Le décrochage survient :", + "choices": [ + {"index": "A", "libelle": "Eventuellement avant le point de décrochage dans une zone de turbulences.", "correct": true}, + {"index": "B", "libelle": "Uniquement quand on freine au-delà du point de décrochage.", "correct": false} + ] + }, + { + "num": 211, + "libelle": "En cas de décrochage :", + "choices": [ + {"index": "A", "libelle": "Il faut maintenir la voilure en freins.", "correct": false}, + {"index": "B", "libelle": "Il faut relâcher progressivement les commandes de manœuvre.", "correct": true}, + {"index": "C", "libelle": "Il faut relâcher le plus vite possible les commandes de manœuvre.", "correct": false} + ] + }, + { + "num": 212, + "libelle": "Lors d’un freinage, si on relâche les commandes brusquement :", + "choices": [ + {"index": "A", "libelle": "La voile reprend progressivement sa trajectoire initiale de vol.", "correct": false}, + {"index": "B", "libelle": "La voile subit un balancement et une accélération.", "correct": true} + ] + }, + { + "num": 213, + "libelle": "En cas de décrochage près du sol :", + "choices": [ + {"index": "A", "libelle": "Il faut relâcher un tout petit peu les commandes de manœuvre, très doucement.", "correct": true}, + {"index": "B", "libelle": "Il faut relâcher le plus vite possible les commandes de manœuvre.", "correct": false}, + {"index": "C", "libelle": "Il faut maintenir les commandes enfoncées.", "correct": false} + ] + }, + { + "num": 214, + "libelle": "En décrochage :", + "choices": [ + {"index": "A", "libelle": "Il est toujours possible de contrôler la voile avec les commandes de manœuvre.", "correct": false}, + {"index": "B", "libelle": "L’aile n’est plus pilotable normalement.", "correct": true} + ] + }, + { + "num": 215, + "libelle": "Après un décrochage, il faut plusieurs secondes pour que la voilure reprenne sa ligne de vol.", + "choices": [ + {"index": "A", "libelle": "Faux.", "correct": false}, + {"index": "B", "libelle": "Vrai.", "correct": true} + ] + }, + { + "num": 216, + "libelle": "Après un décrochage, la perte de hauteur avant le retour à un vol normal peut être supérieur à:", + "choices": [ + {"index": "A", "libelle": "Pas de perte de hauteur.", "correct": false}, + {"index": "B", "libelle": "20 m.", "correct": false}, + {"index": "C", "libelle": "100 m.", "correct": true} + ] + }, + { + "num": 217, + "libelle": "La vitesse de descente d’une voilure pour une masse et un pourcentage de frein donné :", + "choices": [ + {"index": "A", "libelle": "Dépend du gradient turbulo-laminaire de vent", "correct": false}, + {"index": "B", "libelle": "Est supérieure dans le vent.", "correct": false}, + {"index": "C", "libelle": "Est identique quel que soit le vent.", "correct": true}, + {"index": "D", "libelle": "Est supérieure face au vent.", "correct": false} + ] + }, + { + "num": 218, + "libelle": "Si il y a du vent, une voilure de type aile se met naturellement dans le vent.", + "choices": [ + {"index": "A", "libelle": "Vrai.", "correct": false}, + {"index": "B", "libelle": "Faux.", "correct": true}, + {"index": "C", "libelle": "Uniquement si le vent est fort.", "correct": false} + ] + }, + { + "num": 219, + "libelle": "Si il y a du vent, une voilure de type aile se met naturellement contre le vent.", + "choices": [ + {"index": "A", "libelle": "Uniquement si le vent est fort.", "correct": false}, + {"index": "B", "libelle": "Faux.", "correct": true}, + {"index": "C", "libelle": "Vrai.", "correct": false} + ] + } + ] + }, + { + "num": 7, + "name": "Physiologie", + "questions": [ + { + "num": 220, + "libelle": "Avec l’altitude, les problèmes lié à l’hypoxie sont dus à :", + "choices": [ + {"index": "A", "libelle": "Une augmentation de la pression partielle d’oxygène.", "correct": false}, + {"index": "B", "libelle": "Une diminution de la pression partielle d’oxygène.", "correct": true} + ] + }, + { + "num": 221, + "libelle": "Est-il important d’être en bonne condition physique pour sauter en parachute ?", + "choices": [ + {"index": "A", "libelle": "Uniquement pour les compétiteurs.", "correct": false}, + {"index": "B", "libelle": "Oui car elle atténue les conséquences de microtraumatismes répétés.", "correct": true}, + {"index": "C", "libelle": "Non car le saut ne requiert pas beaucoup d’efforts.", "correct": false} + ] + }, + { + "num": 222, + "libelle": "Avant de débuter une journée de sauts :", + "choices": [ + {"index": "A", "libelle": "Il faut s’alimenter.", "correct": true}, + {"index": "B", "libelle": "Mieux vaut ne rien manger.", "correct": false} + ] + }, + { + "num": 223, + "libelle": "L’absorption d’alcool pendant une journée de saut :", + "choices": [ + {"index": "A", "libelle": "Est sans importance tant que l’on reste dans des limites raisonnables.", "correct": false}, + {"index": "B", "libelle": "Est à proscrire absolument.", "correct": true}, + {"index": "C", "libelle": "Donne un peu de courage.", "correct": false} + ] + }, + { + "num": 224, + "libelle": "Comment appelle t’ont le phénomène physiologique dû à une insuffisance en oxygène ?", + "choices": [ + {"index": "A", "libelle": "L’hypoxie.", "correct": true}, + {"index": "B", "libelle": "L’hypoglycémie.", "correct": false}, + {"index": "C", "libelle": "L’hyperventilation.", "correct": false} + ] + }, + { + "num": 225, + "libelle": "Quelle est la partie du corps qui, souffrant du manque d’oxygène, est la plus problématique pour le parachutisme ?", + "choices": [ + {"index": "A", "libelle": "Le cerveau.", "correct": true}, + {"index": "B", "libelle": "L’estomac.", "correct": false}, + {"index": "C", "libelle": "Les poumons.", "correct": false}, + {"index": "D", "libelle": "Les oreilles.", "correct": false} + ] + }, + { + "num": 226, + "libelle": "A 6000 mètres, ne pas avoir d’oxygène à bord présente un risque de troubles physiologiques importants pouvant aller jusqu’à la perte de connaissance.", + "choices": [ + {"index": "A", "libelle": "Faux.", "correct": false}, + {"index": "B", "libelle": "Vrai.", "correct": true} + ] + }, + { + "num": 227, + "libelle": "En cas d’hypoxie, le froid est un facteur aggravant vis à vis des problèmes rencontrés.", + "choices": [ + {"index": "A", "libelle": "Vrai.", "correct": true}, + {"index": "B", "libelle": "Faux, les deux sont complètement indépendants.", "correct": false} + ] + }, + { + "num": 228, + "libelle": "Les problèmes d’hypoxie peuvent apparaître à partir de 3500 m.", + "choices": [ + {"index": "A", "libelle": "Vrai.", "correct": true}, + {"index": "B", "libelle": "Faux.", "correct": false} + ] + }, + { + "num": 229, + "libelle": "Les problèmes liés à l’hypoxie sont dépendant du temps passé en altitude.", + "choices": [ + {"index": "A", "libelle": "Faux.", "correct": false}, + {"index": "B", "libelle": "Vrai.", "correct": true} + ] + } + ] + }, + { + "num": 8, + "name": "Connaissances générales", + "questions": [ + { + "num": 230, + "libelle": "Pour embarquer dans un hélicoptère léger :", + "choices": [ + {"index": "A", "libelle": "C’est sans importance.", "correct": false}, + {"index": "B", "libelle": "Il faut aborder l’appareil par l’arrière.", "correct": false}, + {"index": "C", "libelle": "Il faut aborder l’appareil par l’avant.", "correct": true} + ] + }, + { + "num": 231, + "libelle": "En montant dans l’avion :", + "choices": [ + {"index": "A", "libelle": "On risque d’accrocher quelque chose sur son équipement si l’on ne fait pas attention.", "correct": true}, + {"index": "B", "libelle": "Ce risque est négligeable.", "correct": false} + ] + }, + { + "num": 232, + "libelle": "Quand l’avion prend l’axe de largage :", + "choices": [ + {"index": "A", "libelle": "Il est inutile de contrôler son équipement.", "correct": false}, + {"index": "B", "libelle": "Il faut contrôler quelques points essentiels de son équipement avant de sauter.", "correct": true} + ] + }, + { + "num": 233, + "libelle": "En sortie d’avion", + "choices": [ + {"index": "A", "libelle": "Il ne faut plus s’occuper de problèmes de matériel.", "correct": false}, + {"index": "B", "libelle": "Il faut veiller à ne rien accrocher sur son équipement.", "correct": true} + ] + }, + { + "num": 234, + "libelle": "Pour sauter la première fois d’un avion gros porteur :", + "choices": [ + {"index": "A", "libelle": "Je m’informe des consignes particulières.", "correct": true}, + {"index": "B", "libelle": "Inutile, je suivrai les autres.", "correct": false} + ] + }, + { + "num": 235, + "libelle": "En chute, la vitesse moyenne à plat face au sol :", + "choices": [ + {"index": "A", "libelle": "Est proche de 150 km/h.", "correct": false}, + {"index": "B", "libelle": "Est proche de 200 km/h.", "correct": true}, + {"index": "C", "libelle": "Est proche de 250 km/h.", "correct": false} + ] + }, + { + "num": 236, + "libelle": "La perte de hauteur en chute libre à plat face sol est de :", + "choices": [ + {"index": "A", "libelle": "Approximativement 300 m pendant les 10 premières secondes puis 50 m/s.", "correct": true}, + {"index": "B", "libelle": "Approximativement 50 m/s pendant toute la chute.", "correct": false}, + {"index": "C", "libelle": "Approximativement 500 m pendant les 10 premières secondes puis 50 m/s.", "correct": false} + ] + }, + { + "num": 237, + "libelle": "La vitesse verticale de chute est en moyenne de :", + "choices": [ + {"index": "A", "libelle": "50 m/s et ne dépasse jamais 60 m/s.", "correct": false}, + {"index": "B", "libelle": "50 m/s, elle peut dépasser 70 m/s en piqué ou tête en bas.", "correct": true} + ] + }, + { + "num": 238, + "libelle": "Quand on chute à plat face au sol, après 15 secondes de chute, on a perdu :", + "choices": [ + {"index": "A", "libelle": "700 m de hauteur.", "correct": false}, + {"index": "B", "libelle": "550 m de hauteur.", "correct": true}, + {"index": "C", "libelle": "400 m de hauteur.", "correct": false} + ] + }, + { + "num": 239, + "libelle": "La vitesse de chute tête en bas ou debout :", + "choices": [ + {"index": "A", "libelle": "Peut atteindre 300 km/h.", "correct": true}, + {"index": "B", "libelle": "Est sensiblement la même qu’à plat face sol.", "correct": false}, + {"index": "C", "libelle": "Ne dépasse pas 250 km/h.", "correct": false} + ] + }, + { + "num": 240, + "libelle": "Lors d’un saut de groupe :", + "choices": [ + {"index": "A", "libelle": "Il faut toujours assurer la sécurité en chute pour éviter tout risque de collisions.", "correct": true}, + {"index": "B", "libelle": "Les risques de collision sont faibles car tout le monde chute à la même vitesse.", "correct": false} + ] + }, + { + "num": 241, + "libelle": "Lors d’un saut de groupe :", + "choices": [ + {"index": "A", "libelle": "Avant d’ouvrir, il suffit de dériver longtemps pour éviter tout risque de collision.", "correct": false}, + {"index": "B", "libelle": "Il faut dériver en contrôlant sa trajectoire et garder si possible le contact visuel sur les autres parachutistes pour s’assurer que la séparation est suffisante.", "correct": true} + ] + }, + { + "num": 242, + "libelle": "Si vous n’avez pas sauté depuis plusieurs mois, vous programmez :", + "choices": [ + {"index": "A", "libelle": "Un saut de reprise, sans exercice particulier, avec un matériel que vous connaissez et en adaptant la hauteur d’ouverture.", "correct": true}, + {"index": "B", "libelle": "Un saut de VR ou de free fly afin de ne pas être seul.", "correct": false}, + {"index": "C", "libelle": "N’importe quel type de saut.", "correct": false} + ] + }, + { + "num": 243, + "libelle": "En faisant des virages rapides et enchaînés en dessous de 500 mètres :", + "choices": [ + {"index": "A", "libelle": "Il n’y a pas de risques particuliers.", "correct": false}, + {"index": "B", "libelle": "On risque de faire fonctionner le déclencheur de sécurité ou d’entrer en collision avec d’autres parachutistes.", "correct": true} + ] + }, + { + "num": 244, + "libelle": "L’atterrissage dans une pente prononcée, par temps calme sur un grand terrain ou rien n’indique le vent se fait de préférence :", + "choices": [ + {"index": "A", "libelle": "En travers de la pente.", "correct": true}, + {"index": "B", "libelle": "Face à la pente.", "correct": false}, + {"index": "C", "libelle": "Dans le sens de la pente.", "correct": false} + ] + }, + { + "num": 245, + "libelle": "En finale, hors zone, vous vous rapprochez dangereusement d’une ligne électrique face à vous.", + "choices": [ + {"index": "A", "libelle": "Vous conservez votre trajectoire en freinant au maximum et en espérant que ça va passer.", "correct": false}, + {"index": "B", "libelle": "Il faut l’éviter à tout prix, vous changez de trajectoire.", "correct": true} + ] + }, + { + "num": 246, + "libelle": "Lors d’un atterrissage hors zone, l’objectif prioritaire est de :", + "choices": [ + {"index": "A", "libelle": "Se poser face au vent.", "correct": false}, + {"index": "B", "libelle": "Se poser hors obstacles avec une trajectoire dégagée.", "correct": true} + ] + }, + { + "num": 247, + "libelle": "Parachute ouvert, vous constatez que vous ne pourrez pas rejoindre la zone de sauts. Il faut :", + "choices": [ + {"index": "A", "libelle": "Ne pas survoler d’obstacles, surtout à basse hauteur.", "correct": true}, + {"index": "B", "libelle": "Se rapprocher au maximum au plus près de la zone, quel que soit le terrain survolé.", "correct": false} + ] + }, + { + "num": 248, + "libelle": "Parachute ouvert, vous constatez que vous ne pourrez pas rejoindre la zone d’atterrissage prévue. Il faut :", + "choices": [ + {"index": "A", "libelle": "Trouver rapidement une zone de dégagement facile à atteindre même si elle est très éloignée de la zone d’atterrissage prévue.", "correct": true}, + {"index": "B", "libelle": "Se rapprocher au maximum au plus près de la zone d’atterrissage prévue.", "correct": false} + ] + }, + { + "num": 249, + "libelle": "Parachute ouvert, vous constatez que vous ne pourrez pas rejoindre la zone de saut. Il faut :", + "choices": [ + {"index": "A", "libelle": "Attendre d’être près du sol pour bien voir les obstacles.", "correct": false}, + {"index": "B", "libelle": "Repérer dès que possible les obstacles et les zones dégagées.", "correct": true} + ] + }, + { + "num": 250, + "libelle": "Piste 27 en service signifie :", + "choices": [ + {"index": "A", "libelle": "Que l’avion va décoller face au sud.", "correct": false}, + {"index": "B", "libelle": "Que l’avion va décoller face à l’est.", "correct": false}, + {"index": "C", "libelle": "Que l’avion va décoller face au nord.", "correct": false}, + {"index": "D", "libelle": "Que l’avion va décoller face à l’ouest.", "correct": true} + ] + }, + { + "num": 251, + "libelle": "Piste 09 en service signifie :", + "choices": [ + {"index": "A", "libelle": "Que l’avion va décoller face à l’ouest.", "correct": false}, + {"index": "B", "libelle": "Que l’avion va décoller face à l’est.", "correct": true}, + {"index": "C", "libelle": "Que l’avion va décoller face au nord.", "correct": false}, + {"index": "D", "libelle": "Que l’avion va décoller face au sud.", "correct": false} + ] + }, + { + "num": 252, + "libelle": "Piste 18 en service signifie :", + "choices": [ + {"index": "A", "libelle": "Que l’avion va décoller face au nord.", "correct": false}, + {"index": "B", "libelle": "Que l’avion va décoller face à l’est.", "correct": false}, + {"index": "C", "libelle": "Que l’avion va décoller face au sud.", "correct": true}, + {"index": "D", "libelle": "Que l’avion va décoller face à l’ouest.", "correct": false} + ] + }, + { + "num": 253, + "libelle": "Piste 36 en service signifie :", + "choices": [ + {"index": "A", "libelle": "Que l’avion va décoller face au nord.", "correct": true}, + {"index": "B", "libelle": "Que l’avion va décoller face à l’est.", "correct": false}, + {"index": "C", "libelle": "Que l’avion va décoller face au sud.", "correct": false}, + {"index": "D", "libelle": "Que l’avion va décoller face à l’ouest.", "correct": false} + ] + }, + { + "num": 254, + "libelle": "En embarquant dans l’avion si vous remarquez quelque chose d’anormal :", + "choices": [ + {"index": "A", "libelle": "Il faut le signaler immédiatement au pilote.", "correct": true}, + {"index": "B", "libelle": "Il ne faut rien lui dire pour ne pas le perturber.", "correct": false} + ] + }, + { + "num": 255, + "libelle": "Quand l’avion prend l’axe de largage :", + "choices": [ + {"index": "A", "libelle": "Il faut contrôler ou faire contrôler son équipement pour éviter une ouverture intempestive en chute ou à la mise en place.", "correct": true}, + {"index": "B", "libelle": "Il est inutile de contrôler ou de faire contrôler son équipement car cela a été fait au sol.", "correct": false} + ] + }, + { + "num": 256, + "libelle": "En sortie d’avion en position flotteur :", + "choices": [ + {"index": "A", "libelle": "Il est possible de se tenir à n’importe quelle partie de la cellule.", "correct": false}, + {"index": "B", "libelle": "Des équipements spécifiques doivent être mis en place pour se tenir.", "correct": true} + ] + }, + { + "num": 257, + "libelle": "Lors d’un largage par vent nul, vous sortez troisième du passage.", + "choices": [ + {"index": "A", "libelle": "Vous laissez environ 8 secondes, vous surveillez le précèdent et vous contrôlez la zone et l’axe sur lesquels vous partez.", "correct": true}, + {"index": "B", "libelle": "Seul le temps de séparation compte.", "correct": false} + ] + }, + { + "num": 258, + "libelle": "Vous partez premier du passage ; le pilote donne l’autorisation de sortie.", + "choices": [ + {"index": "A", "libelle": "Vous ouvrez la porte et vous sautez.", "correct": false}, + {"index": "B", "libelle": "Vous ouvrez la porte, vous contrôlez la zone et l’axe sur lesquels vous allez partir avant de sautez.", "correct": true} + ] + }, + { + "num": 259, + "libelle": "Contrôler ou faire contrôler son équipement avant la sortie d’avion est :", + "choices": [ + {"index": "A", "libelle": "Inutile puisque déjà fait au sol.", "correct": false}, + {"index": "B", "libelle": "Conseillé juste pour les élèves.", "correct": false}, + {"index": "C", "libelle": "Indispensable quel que soit le niveau du parachutiste.", "correct": true} + ] + }, + { + "num": 260, + "libelle": "Avant de s’équiper faut-il effectuer une vérification de son parachute ?", + "choices": [ + {"index": "A", "libelle": "Non c’est inutile car cela sera fait lors de la vérification d’embarquement.", "correct": false}, + {"index": "B", "libelle": "Oui c’est important.", "correct": true} + ] + }, + { + "num": 261, + "libelle": "Que signifient les deux chiffres placés à l’entrée d’une piste ?", + "choices": [ + {"index": "A", "libelle": "L’orientation de la piste", "correct": true}, + {"index": "B", "libelle": "La longueur de la piste.", "correct": false}, + {"index": "C", "libelle": "Le code OACI de l’aérodrome.", "correct": false} + ] + } + ] + }, + { + "num": 9, + "name": "Unités de mesure", + "questions": [ + { + "num": 262, + "libelle": "Pour convertir des pieds/ minute (ft/min) en m/s on utilise la règle suivante :", + "choices": [ + {"index": "A", "libelle": "1000 ft/min = 3 m/s", "correct": false}, + {"index": "B", "libelle": "1000 ft/min = 5 m/s", "correct": true}, + {"index": "C", "libelle": "1000 ft/min = 30 m/s", "correct": false} + ] + }, + { + "num": 263, + "libelle": "Une vitesse verticale de 13 m/s correspond à environ :", + "choices": [ + {"index": "A", "libelle": "7000 ft/min.", "correct": false}, + {"index": "B", "libelle": "1000 ft/min.", "correct": false}, + {"index": "C", "libelle": "2500 ft/min.", "correct": true}, + {"index": "D", "libelle": "3500 ft/min.", "correct": false} + ] + }, + { + "num": 264, + "libelle": "Une vitesse verticale de 35 m/s correspond approximativement à :", + "choices": [ + {"index": "A", "libelle": "3500 ft/min.", "correct": false}, + {"index": "B", "libelle": "2500 ft/min.", "correct": false}, + {"index": "C", "libelle": "7000 ft/min.", "correct": true}, + {"index": "D", "libelle": "8500 ft/min.", "correct": false} + ] + }, + { + "num": 265, + "libelle": "Dire qu’un mètre est égale à trois pieds est :", + "choices": [ + {"index": "A", "libelle": "Parfaitement Juste.", "correct": false}, + {"index": "B", "libelle": "Approximatif mais acceptable.", "correct": true}, + {"index": "C", "libelle": "Trop approximatif.", "correct": false} + ] + }, + { + "num": 266, + "libelle": "Un mètre est égale à :", + "choices": [ + {"index": "A", "libelle": "32,808 pieds soit environ 33 pieds.", "correct": false}, + {"index": "B", "libelle": "3,2808 pieds soit environ 3.3 pieds.", "correct": true}, + {"index": "C", "libelle": "3 pieds.", "correct": false} + ] + }, + { + "num": 267, + "libelle": "Un pied est égal à :", + "choices": [ + {"index": "A", "libelle": "33 cm.", "correct": false}, + {"index": "B", "libelle": "34,08 cm.", "correct": false}, + {"index": "C", "libelle": "30,48 cm.", "correct": true}, + {"index": "D", "libelle": "30 cm.", "correct": false} + ] + }, + { + "num": 268, + "libelle": "Un pied carré est sensiblement égale à :", + "choices": [ + {"index": "A", "libelle": "1,2m2", "correct": false}, + {"index": "B", "libelle": "0,09 m2", "correct": true}, + {"index": "C", "libelle": "0,9 m2", "correct": false} + ] + }, + { + "num": 269, + "libelle": "1 mille terrestre est égal à :", + "choices": [ + {"index": "A", "libelle": "1609 m.", "correct": true}, + {"index": "B", "libelle": "2185 m.", "correct": false}, + {"index": "C", "libelle": "1852 m.", "correct": false} + ] + }, + { + "num": 270, + "libelle": "1 mille nautique est égale à :", + "choices": [ + {"index": "A", "libelle": "1609 m.", "correct": false}, + {"index": "B", "libelle": "2185 m.", "correct": false}, + {"index": "C", "libelle": "1852 m.", "correct": true} + ] + }, + { + "num": 271, + "libelle": "Une vitesse d’un mètre par seconde (1 m/s) est égale à :", + "choices": [ + {"index": "A", "libelle": "3,6 km/h.", "correct": true}, + {"index": "B", "libelle": "36 km/h.", "correct": false}, + {"index": "C", "libelle": "6,3 km/h.", "correct": false} + ] + }, + { + "num": 272, + "libelle": "Une vitesse de 36 km/h est égale à :", + "choices": [ + {"index": "A", "libelle": "16 m/s.", "correct": false}, + {"index": "B", "libelle": "10 m/s.", "correct": true}, + {"index": "C", "libelle": "6 m/s.", "correct": false}, + {"index": "D", "libelle": "3.6 m/s.", "correct": false} + ] + } + ] + }, + { + "num": 10, + "name": "Altimétrie", + "questions": [ + { + "num": 273, + "libelle": "L’altimètre fournit au parachutiste des informations d’altitude en mesurant des différences :", + "choices": [ + {"index": "A", "libelle": "De pression.", "correct": true}, + {"index": "B", "libelle": "De température.", "correct": false}, + {"index": "C", "libelle": "De masse volumique.", "correct": false} + ] + }, + { + "num": 274, + "libelle": "Un niveau de vol c’est :", + "choices": [ + {"index": "A", "libelle": "L’indication donnée par l’altimètre quand il est réglé à zéro au sol.", "correct": false}, + {"index": "B", "libelle": "L’indication donnée par l’altimètre quand il est réglé au QNH au sol.", "correct": false}, + {"index": "C", "libelle": "L’indication donnée par l’altimètre quand il est réglé à 1013.25 hPa au sol.", "correct": true} + ] + }, + { + "num": 275, + "libelle": "Voler au niveau 115 signifie :", + "choices": [ + {"index": "A", "libelle": "Que l’on vole à une hauteur réelle de 11500 pieds.", "correct": false}, + {"index": "B", "libelle": "Qu’un altimètre calé à 1013,25 hPa indique 11500 pieds.", "correct": true}, + {"index": "C", "libelle": "Que l’on vole à une altitude de 11500 mètres.", "correct": false}, + {"index": "D", "libelle": "Qu’un altimètre calé à 1013,25 hPa indique 11500 mètres.", "correct": false} + ] + }, + { + "num": 276, + "libelle": "En atmosphère standard :", + "choices": [ + {"index": "A", "libelle": "La pression est de 1013,25 hPa au niveau de la mer.", "correct": true}, + {"index": "B", "libelle": "La pression est de 1013,25 hPa au sol.", "correct": false} + ] + }, + { + "num": 277, + "libelle": "L’altitude :", + "choices": [ + {"index": "A", "libelle": "Est la distance sur un axe vertical entre un point et le sol.", "correct": false}, + {"index": "B", "libelle": "Est la distance sur un axe vertical entre un point et le niveau de la mer.", "correct": true}, + {"index": "C", "libelle": "Est la distance sur un axe vertical entre un point et la surface isobare 1013.25 hPa.", "correct": false} + ] + }, + { + "num": 278, + "libelle": "La hauteur :", + "choices": [ + {"index": "A", "libelle": "Est la distance sur un axe vertical entre un point et le niveau de la mer.", "correct": false}, + {"index": "B", "libelle": "Est la distance sur un axe vertical entre un point et le sol.", "correct": true}, + {"index": "C", "libelle": "Est la distance sur un axe vertical entre un point et la surface isobare 1013.25 hPa.", "correct": false} + ] + }, + { + "num": 279, + "libelle": "La distance verticale entre un point et le sol est :", + "choices": [ + {"index": "A", "libelle": "La hauteur.", "correct": true}, + {"index": "B", "libelle": "L’altitude.", "correct": false}, + {"index": "C", "libelle": "Un niveau de vol.", "correct": false} + ] + }, + { + "num": 280, + "libelle": "La distance verticale entre un point et le niveau de la mer est :", + "choices": [ + {"index": "A", "libelle": "La hauteur.", "correct": false}, + {"index": "B", "libelle": "L’altitude.", "correct": true}, + {"index": "C", "libelle": "Un niveau de vol.", "correct": false} + ] + }, + { + "num": 281, + "libelle": "La distance verticale entre un point et la surface isobare 1013.25 hPa est :", + "choices": [ + {"index": "A", "libelle": "L’altitude.", "correct": false}, + {"index": "B", "libelle": "Un niveau de vol.", "correct": true}, + {"index": "C", "libelle": "La hauteur.", "correct": false} + ] + }, + { + "num": 282, + "libelle": "Une hauteur de 3000 pieds en atmosphère standard est approximativement égale à :", + "choices": [ + {"index": "A", "libelle": "1000 m.", "correct": false}, + {"index": "B", "libelle": "900 m.", "correct": true}, + {"index": "C", "libelle": "1100 m.", "correct": false} + ] + }, + { + "num": 283, + "libelle": "Le pied (ft) est une unité de mesure qui est égale à :", + "choices": [ + {"index": "A", "libelle": "0.30 cm.", "correct": false}, + {"index": "B", "libelle": "33 cm.", "correct": false}, + {"index": "C", "libelle": "30,48 cm.", "correct": true} + ] + }, + { + "num": 284, + "libelle": "Le soir, au sol, votre altimètre indique 0. Le lendemain matin il indique + 100 m. Qu’en déduisez-vous ?", + "choices": [ + {"index": "A", "libelle": "Une dépression arrive ou la pression baisse.", "correct": true}, + {"index": "B", "libelle": "On va vers une situation anticyclonique.", "correct": false}, + {"index": "C", "libelle": "Le sol est monté.", "correct": false} + ] + }, + { + "num": 285, + "libelle": "Le soir, au sol, votre altimètre indique 0. Le lendemain matin il indique – 100 m. Qu’en déduisez-vous ?", + "choices": [ + {"index": "A", "libelle": "Une dépression arrive.", "correct": false}, + {"index": "B", "libelle": "On va vers une situation anticyclonique ou la pression augmente.", "correct": true}, + {"index": "C", "libelle": "Le sol est plus bas qu’hier.", "correct": false} + ] + }, + { + "num": 286, + "libelle": "Lorsqu’il y a une baisse de température :", + "choices": [ + {"index": "A", "libelle": "L’altimètre sous estime la hauteur.", "correct": false}, + {"index": "B", "libelle": "L’altimètre surestime la hauteur.", "correct": true}, + {"index": "C", "libelle": "La température n’a pas d’influence sur l’altimètre.", "correct": false} + ] + }, + { + "num": 287, + "libelle": "Lorsqu’il y a une hausse de température :", + "choices": [ + {"index": "A", "libelle": "L’altimètre sous-estime la hauteur.", "correct": true}, + {"index": "B", "libelle": "L’altimètre surestime la hauteur.", "correct": false}, + {"index": "C", "libelle": "La température n’a pas d’influence sur l’altimètre.", "correct": false} + ] + }, + { + "num": 288, + "libelle": "Lorsqu’il y a une baisse de pression (arrivé d’une dépression) :", + "choices": [ + {"index": "A", "libelle": "L’altimètre surestime la hauteur.", "correct": true}, + {"index": "B", "libelle": "Les changements de pression dues à la météorologie n’ont pas d’influence sur l’altimètre.", "correct": false}, + {"index": "C", "libelle": "L’altimètre sous-estime la hauteur.", "correct": false} + ] + }, + { + "num": 289, + "libelle": "Lorsqu’il y a une hausse de pression (arrivé d’un anticyclone) :", + "choices": [ + {"index": "A", "libelle": "L’altimètre surestime la hauteur.", "correct": false}, + {"index": "B", "libelle": "L’altimètre sous-estime la hauteur.", "correct": true}, + {"index": "C", "libelle": "Les changements de pression dues à la météorologie n’ont pas d’influence sur l’altimètre.", "correct": false} + ] + }, + { + "num": 290, + "libelle": "Quand vous sautez au niveau 135 (FL 135) :", + "choices": [ + {"index": "A", "libelle": "Vous sautez toujours à une altitude de 4115 mètres.", "correct": false}, + {"index": "B", "libelle": "Pour connaitre la hauteur précise du saut il faut déduire l’altitude terrain.", "correct": false}, + {"index": "C", "libelle": "La hauteur du saut va varier en fonction des conditions météorologique et de l’altitude du terrain.", "correct": true}, + {"index": "D", "libelle": "Vous sautez toujours à une hauteur de 4000 mètres.", "correct": false} + ] + }, + { + "num": 291, + "libelle": "Votre zone de saut est à 500 mètres d’altitude. Quand vous sautez au niveau 145 (FL 145) :", + "choices": [ + {"index": "A", "libelle": "Vous sautez toujours à une altitude de 3920 mètres.", "correct": false}, + {"index": "B", "libelle": "a hauteur du saut va varier en fonction des conditions météorologique et de l’altitude du terrain.", "correct": true}, + {"index": "C", "libelle": "Vous sautez toujours à une hauteur de 3920 mètres.", "correct": false}, + {"index": "D", "libelle": "Vous sautez toujours à une altitude de 4420 mètres.", "correct": false} + ] + } + ] + }, + { + "num": 11, + "name": "Météorologie et aérologie", + "questions": [ + { + "num": 292, + "libelle": "En atmosphère standard :", + "choices": [ + {"index": "A", "libelle": "La température décroît de 8.5° c tous les 1000 m.", "correct": false}, + {"index": "B", "libelle": "La température décroît de 6.5° c tous les 1000 m.", "correct": true}, + {"index": "C", "libelle": "La température décroît de 10° c tous les 1000 m.", "correct": false} + ] + }, + { + "num": 293, + "libelle": "En atmosphère standard, quelle température fera-t-il à 4000 mètres si la température au sol est de 20° c ?", + "choices": [ + {"index": "A", "libelle": "+13.5° c.", "correct": false}, + {"index": "B", "libelle": "-6° c.", "correct": true}, + {"index": "C", "libelle": "–20° c.", "correct": false} + ] + }, + { + "num": 294, + "libelle": "En atmosphère standard, quelle température fera-t-il à 3000 mètres si la température au sol est de 10° c ?", + "choices": [ + {"index": "A", "libelle": "0° c.", "correct": false}, + {"index": "B", "libelle": "– 9.5° c.", "correct": true}, + {"index": "C", "libelle": "+ 6.5° c.", "correct": false} + ] + }, + { + "num": 295, + "libelle": "En atmosphère standard, quelle température fera-t-il à 4000 mètres si la température au sol est de 0° c ?", + "choices": [ + {"index": "A", "libelle": "–26° c.", "correct": true}, + {"index": "B", "libelle": "–54° c.", "correct": false}, + {"index": "C", "libelle": "–10° c.", "correct": false} + ] + }, + { + "num": 296, + "libelle": "Comment s’appellent Les lignes d’égale pression représentées sur les cartes météo ?", + "choices": [ + {"index": "A", "libelle": "Les lignes isohypses.", "correct": false}, + {"index": "B", "libelle": "Les lignes isothermes.", "correct": false}, + {"index": "C", "libelle": "Les lignes isobares.", "correct": true} + ] + }, + { + "num": 297, + "libelle": "Sur une carte météo, plus les lignes isobares sont serrées :", + "choices": [ + {"index": "A", "libelle": "Plus le vent est fort.", "correct": true}, + {"index": "B", "libelle": "Moins le vent est fort.", "correct": false}, + {"index": "C", "libelle": "La vitesse du vent ne dépend pas du resserrement des isobares.", "correct": false} + ] + }, + { + "num": 298, + "libelle": "Comment appelle-t-on une zone de hautes pressions généralisées ?", + "choices": [ + {"index": "A", "libelle": "Une dépression.", "correct": false}, + {"index": "B", "libelle": "Un thalweg.", "correct": false}, + {"index": "C", "libelle": "Un anticyclone.", "correct": true}, + {"index": "D", "libelle": "Une dorsale.", "correct": false} + ] + }, + { + "num": 299, + "libelle": "Comment appelle-t-on une zone de basses pressions généralisées ?", + "choices": [ + {"index": "A", "libelle": "Une dépression.", "correct": true}, + {"index": "B", "libelle": "Un thalweg.", "correct": false}, + {"index": "C", "libelle": "Un anticyclone.", "correct": false}, + {"index": "D", "libelle": "Une dorsale.", "correct": false} + ] + }, + { + "num": 300, + "libelle": "Comment appelle-t-on une crête de haute pression ?", + "choices": [ + {"index": "A", "libelle": "Une dépression.", "correct": false}, + {"index": "B", "libelle": "Un thalweg.", "correct": false}, + {"index": "C", "libelle": "Un anticyclone.", "correct": false}, + {"index": "D", "libelle": "Une dorsale.", "correct": true} + ] + }, + { + "num": 301, + "libelle": "Comment appelle-t-on une vallée de basse pression ?", + "choices": [ + {"index": "A", "libelle": "Une dépression.", "correct": false}, + {"index": "B", "libelle": "Un thalweg.", "correct": true}, + {"index": "C", "libelle": "Un anticyclone.", "correct": false}, + {"index": "D", "libelle": "Une dorsale.", "correct": false} + ] + }, + { + "num": 302, + "libelle": "Quand on monte en altitude, la pression atmosphérique :", + "choices": [ + {"index": "A", "libelle": "Augmente ou diminue suivant la situation météo.", "correct": false}, + {"index": "B", "libelle": "Diminue.", "correct": true}, + {"index": "C", "libelle": "Augmente.", "correct": false} + ] + }, + { + "num": 303, + "libelle": "La variation de pression entre le sol et 500 m. Est en moyenne de :", + "choices": [ + {"index": "A", "libelle": "1 hPa tous les 17 m.", "correct": false}, + {"index": "B", "libelle": "1 hPa tous les 11 m.", "correct": false}, + {"index": "C", "libelle": "1 hPa tous les 8.5 m.", "correct": true} + ] + }, + { + "num": 304, + "libelle": "Quand on monte en altitude en dessous de 500 m. La pression atmosphérique", + "choices": [ + {"index": "A", "libelle": "Augmente de 1 hPa tous les 8.5 m.", "correct": false}, + {"index": "B", "libelle": "Diminue de 1 hPa tous les 8.5 m.", "correct": true}, + {"index": "C", "libelle": "Diminue de 1 hPa tous les 11 m.", "correct": false} + ] + }, + { + "num": 305, + "libelle": "Un nuage est constitué :", + "choices": [ + {"index": "A", "libelle": "D’eau à l’état liquide ou solide.", "correct": true}, + {"index": "B", "libelle": "De vapeur d’eau uniquement.", "correct": false} + ] + }, + { + "num": 306, + "libelle": "On parle de brouillard :", + "choices": [ + {"index": "A", "libelle": "Quand la visibilité est inférieure à 100 m.", "correct": false}, + {"index": "B", "libelle": "Quand la visibilité est inférieure à 1 km.", "correct": true}, + {"index": "C", "libelle": "Quand la visibilité est réduite mais supérieure à 1 km.", "correct": false} + ] + }, + { + "num": 307, + "libelle": "On parle de brume :", + "choices": [ + {"index": "A", "libelle": "Quand la visibilité est inférieure à 100 m.", "correct": false}, + {"index": "B", "libelle": "Quand la visibilité est inférieure à 1 km.", "correct": false}, + {"index": "C", "libelle": "Quand la visibilité est réduite mais supérieure à 1 km.", "correct": true} + ] + }, + { + "num": 308, + "libelle": "A 5600 mètres d’altitude, la pression partielle d’oxygène :", + "choices": [ + {"index": "A", "libelle": "N’a pas changée.", "correct": false}, + {"index": "B", "libelle": "A diminué de 30%", "correct": false}, + {"index": "C", "libelle": "A diminué de moitié", "correct": true} + ] + }, + { + "num": 309, + "libelle": "Le vent est dû :", + "choices": [ + {"index": "A", "libelle": "Essentiellement aux phénomènes orageux.", "correct": false}, + {"index": "B", "libelle": "Aux différences de pression atmosphérique et aux différences de température.", "correct": true}, + {"index": "C", "libelle": "Aux marées.", "correct": false} + ] + }, + { + "num": 310, + "libelle": "Le vent en altitude est dû :", + "choices": [ + {"index": "A", "libelle": "Surtout à l’influence du sol et du relief.", "correct": false}, + {"index": "B", "libelle": "Aux anticyclones et aux dépressions.", "correct": true} + ] + }, + { + "num": 311, + "libelle": "Le vent au sol est dû :", + "choices": [ + {"index": "A", "libelle": "Uniquement à la nature du sol et au relief.", "correct": false}, + {"index": "B", "libelle": "Uniquement aux anticyclones et aux dépressions.", "correct": false}, + {"index": "C", "libelle": "A la situation météorologique générale et à l’influence du sol et du relief.", "correct": true} + ] + }, + { + "num": 312, + "libelle": "Dans une zone d’étranglement (col, vallée).", + "choices": [ + {"index": "A", "libelle": "La vitesse du vent augmente.", "correct": true}, + {"index": "B", "libelle": "La vitesse du vent diminue.", "correct": false}, + {"index": "C", "libelle": "Le relief n’a pas d’influence sur la vitesse du vent.", "correct": false} + ] + }, + { + "num": 313, + "libelle": "Un vent du sud-ouest :", + "choices": [ + {"index": "A", "libelle": "Souffle du sud au sol et de l’ouest en altitude.", "correct": false}, + {"index": "B", "libelle": "Souffle en provenance du sud-ouest.", "correct": true}, + {"index": "C", "libelle": "Souffle en direction du sud-ouest.", "correct": false} + ] + }, + { + "num": 314, + "libelle": "Le vent du nord :", + "choices": [ + {"index": "A", "libelle": "Souffle en provenance du nord.", "correct": true}, + {"index": "B", "libelle": "Souffle en direction du nord.", "correct": false} + ] + }, + { + "num": 315, + "libelle": "Un vent de 10 kts souffle à environ :", + "choices": [ + {"index": "A", "libelle": "5 m/s.", "correct": true}, + {"index": "B", "libelle": "10 m/s.", "correct": false}, + {"index": "C", "libelle": "20 m/s.", "correct": false} + ] + }, + { + "num": 316, + "libelle": "Un vent de 10 kts souffle à environ :", + "choices": [ + {"index": "A", "libelle": "36 km/h.", "correct": false}, + {"index": "B", "libelle": "18 km/h.", "correct": true}, + {"index": "C", "libelle": "10 km/h.", "correct": false} + ] + }, + { + "num": 317, + "libelle": "Un vent de 10 m/s souffle à environ :", + "choices": [ + {"index": "A", "libelle": "36 km/h.", "correct": true}, + {"index": "B", "libelle": "18 km/h.", "correct": false}, + {"index": "C", "libelle": "10 km/h.", "correct": false} + ] + }, + { + "num": 318, + "libelle": "Un vent de 18 kts souffle à environ :", + "choices": [ + {"index": "A", "libelle": "18 m/s.", "correct": false}, + {"index": "B", "libelle": "9 m/s.", "correct": true}, + {"index": "C", "libelle": "5 m/s.", "correct": false} + ] + }, + { + "num": 319, + "libelle": "Un vent de 7 m/s souffle à environ :", + "choices": [ + {"index": "A", "libelle": "36 km/h.", "correct": false}, + {"index": "B", "libelle": "18 km/h.", "correct": false}, + {"index": "C", "libelle": "25 km/h.", "correct": true} + ] + }, + { + "num": 320, + "libelle": "Un vent de 5 m/s souffle à environ :", + "choices": [ + {"index": "A", "libelle": "5 km/h.", "correct": false}, + {"index": "B", "libelle": "10 km/h.", "correct": false}, + {"index": "C", "libelle": "18 km/h.", "correct": true} + ] + }, + { + "num": 321, + "libelle": "Quelle est la vitesse du vent en m/s quand il souffle à 20 kts :", + "choices": [ + {"index": "A", "libelle": "10 m/s.", "correct": true}, + {"index": "B", "libelle": "5 m/s.", "correct": false}, + {"index": "C", "libelle": "18 m/s.", "correct": false} + ] + }, + { + "num": 322, + "libelle": "La météo annonce un vent du 270° ; cela veut dire qu’il vient :", + "choices": [ + {"index": "A", "libelle": "De l’ouest.", "correct": true}, + {"index": "B", "libelle": "Du nord.", "correct": false}, + {"index": "C", "libelle": "Du sud ouest.", "correct": false} + ] + }, + { + "num": 323, + "libelle": "Qu’appelle-t-on inversion de vent ?", + "choices": [ + {"index": "A", "libelle": "Le vent change de direction en altitude par rapport au vent au sol.", "correct": true}, + {"index": "B", "libelle": "C’est l’ordre de saut des parachutistes qui est inversé à cause du vent.", "correct": false}, + {"index": "C", "libelle": "Le vent souffle de façon irrégulière dans toutes les directions.", "correct": false} + ] + }, + { + "num": 324, + "libelle": "Qu’appelle-t-on cisaillement de vent ?", + "choices": [ + {"index": "A", "libelle": "C’est un vent suffisamment fort pour couper la cime des arbres.", "correct": false}, + {"index": "B", "libelle": "C’est la zone de séparation entre deux vents de sens contraire.", "correct": true} + ] + }, + { + "num": 325, + "libelle": "Qu’est-ce qu’une zone de cisaillement ?", + "choices": [ + {"index": "A", "libelle": "C’est une zone comprise entre deux couches d’air où la température est différente.", "correct": false}, + {"index": "B", "libelle": "C’est une zone comprise entre deux couches d’air où la pression est différente.", "correct": false}, + {"index": "C", "libelle": "C’est une zone comprise entre deux couches d’air où le vent n’a pas la même direction.", "correct": true} + ] + }, + { + "num": 326, + "libelle": "Le vent en altitude et le vent au sol :", + "choices": [ + {"index": "A", "libelle": "Peuvent souffler en sens contraire.", "correct": true}, + {"index": "B", "libelle": "Soufflent toujours dans le même sens.", "correct": false} + ] + }, + { + "num": 327, + "libelle": "Dans l’hémisphère nord, le vent :", + "choices": [ + {"index": "A", "libelle": "Tourne autour des dépressions dans le sens des aiguilles d’une montre et autour des anticyclones en sens inverse.", "correct": false}, + {"index": "B", "libelle": "Tourne autour des anticyclones dans le sens des aiguilles d’une montre et autour des dépressions en sens inverse.", "correct": true} + ] + }, + { + "num": 328, + "libelle": "Dans quel sens le vent tourne-t-il autour des anticyclones dans l’hémisphère nord ?", + "choices": [ + {"index": "A", "libelle": "Il tourne dans le sens des aiguilles d’une montre.", "correct": true}, + {"index": "B", "libelle": "Il tourne dans le sens inverse des aiguilles d’une montre.", "correct": false} + ] + }, + { + "num": 329, + "libelle": "Dans quel sens le vent tourne-t-il autour des dépressions dans l’hémisphère nord ?", + "choices": [ + {"index": "A", "libelle": "Il tourne dans le sens des aiguilles d’une montre.", "correct": false}, + {"index": "B", "libelle": "Il tourne dans le sens inverse des aiguilles d’une montre.", "correct": true} + ] + }, + { + "num": 330, + "libelle": "En altitude, le vent météo :", + "choices": [ + {"index": "A", "libelle": "Est dévié sur la droite dans l’hémisphère nord.", "correct": true}, + {"index": "B", "libelle": "Est dévié sur la gauche dans l’hémisphère nord.", "correct": false}, + {"index": "C", "libelle": "Ne subit aucune déviation.", "correct": false} + ] + }, + { + "num": 331, + "libelle": "En bord de mer, par ciel couvert sans vent météorologique :", + "choices": [ + {"index": "A", "libelle": "Il y aura probablement une brise soufflant de la mer vers la terre.", "correct": false}, + {"index": "B", "libelle": "Il y aura probablement une brise soufflant de la terre vers la mer.", "correct": false}, + {"index": "C", "libelle": "Il n’y aura probablement pas de brise.", "correct": true} + ] + }, + { + "num": 332, + "libelle": "En bord de mer, en été, en milieu d’après midi et par temps ensoleillé sans vent météorologique :", + "choices": [ + {"index": "A", "libelle": "Il y aura probablement une brise soufflant de la mer vers la terre.", "correct": true}, + {"index": "B", "libelle": "Il y aura probablement une brise soufflant de la terre vers la mer.", "correct": false}, + {"index": "C", "libelle": "Il n’y aura probablement pas de brise.", "correct": false} + ] + }, + { + "num": 333, + "libelle": "En milieu de journée, par temps ensoleillé, la brise souffle.", + "choices": [ + {"index": "A", "libelle": "De la terre vers la mer.", "correct": false}, + {"index": "B", "libelle": "De la mer vers la terre.", "correct": true} + ] + }, + { + "num": 334, + "libelle": "En bord de mer, la nuit, on risque d’avoir.", + "choices": [ + {"index": "A", "libelle": "De la brise de mer.", "correct": false}, + {"index": "B", "libelle": "De la brise de terre.", "correct": true}, + {"index": "C", "libelle": "Aucune brise.", "correct": false} + ] + }, + { + "num": 335, + "libelle": "Dans une vallée étroite, en milieu d’après midi et par temps ensoleillé, il y aura probablement :", + "choices": [ + {"index": "A", "libelle": "Une forte brise de vallée montante qui risque d’empêcher les sauts.", "correct": true}, + {"index": "B", "libelle": "Une forte brise de vallée montante mais il est toujours possible de sauter.", "correct": false}, + {"index": "C", "libelle": "Une forte brise de vallée descendante.", "correct": false} + ] + }, + { + "num": 336, + "libelle": "Sur une pente, par temps ensoleillé, on rencontre en milieu de journée :", + "choices": [ + {"index": "A", "libelle": "Des brises descendantes.", "correct": false}, + {"index": "B", "libelle": "Des brises montantes.", "correct": true} + ] + }, + { + "num": 337, + "libelle": "Les brises de vallée soufflent dans la même direction toute la journée :", + "choices": [ + {"index": "A", "libelle": "Vrai.", "correct": false}, + {"index": "B", "libelle": "Faux.", "correct": true} + ] + }, + { + "num": 338, + "libelle": "Les brises sont des vents :", + "choices": [ + {"index": "A", "libelle": "Bien établis, qui changent lentement.", "correct": false}, + {"index": "B", "libelle": "Qui soufflent dans tous les sens et changent sans cesse de direction.", "correct": false}, + {"index": "C", "libelle": "Bien établis, mais qui changent de direction en peu de temps.", "correct": true} + ] + }, + { + "num": 339, + "libelle": "Avec du vent, le risque de turbulences est maximum :", + "choices": [ + {"index": "A", "libelle": "Sur un relief accidenté.", "correct": true}, + {"index": "B", "libelle": "En plaine dans une zone dégagée.", "correct": false} + ] + }, + { + "num": 340, + "libelle": "Par fort vent, derrière un hangar :", + "choices": [ + {"index": "A", "libelle": "Il n’y a pas de turbulences.", "correct": false}, + {"index": "B", "libelle": "Il y a des turbulences.", "correct": true} + ] + }, + { + "num": 341, + "libelle": "Par fort vent derrière une haie d’arbres :", + "choices": [ + {"index": "A", "libelle": "Il n’y a pas de turbulences.", "correct": false}, + {"index": "B", "libelle": "Il y a des turbulences.", "correct": true} + ] + }, + { + "num": 342, + "libelle": "On risque de rencontrer des turbulences :", + "choices": [ + {"index": "A", "libelle": "En présence de stratus.", "correct": false}, + {"index": "B", "libelle": "En présence de cumulus.", "correct": true}, + {"index": "C", "libelle": "En présence de cirrus.", "correct": false} + ] + }, + { + "num": 343, + "libelle": "On risque surtout de rencontrer des turbulences :", + "choices": [ + {"index": "A", "libelle": "Par vent faible.", "correct": false}, + {"index": "B", "libelle": "Par vent fort.", "correct": true} + ] + }, + { + "num": 344, + "libelle": "On risque surtout de rencontrer des turbulences :", + "choices": [ + {"index": "A", "libelle": "Par temps chaud et ensoleillé.", "correct": true}, + {"index": "B", "libelle": "Par ciel couvert.", "correct": false} + ] + }, + { + "num": 345, + "libelle": "On risque surtout de rencontrer des turbulences :", + "choices": [ + {"index": "A", "libelle": "Au dessus des surfaces froides.", "correct": false}, + {"index": "B", "libelle": "Au dessus des surfaces chaudes.", "correct": true}, + {"index": "C", "libelle": "La température du sol n’a pas d’influence sur les turbulences.", "correct": false} + ] + }, + { + "num": 346, + "libelle": "Avec un vent de 5 m/s, les turbulences derrière une haie d’arbres ou un bâtiment de même hauteur sont dangereuses :", + "choices": [ + {"index": "A", "libelle": "Juste derrière sur quelques mètres.", "correct": false}, + {"index": "B", "libelle": "Jusqu’à plus de 50 m.", "correct": true}, + {"index": "C", "libelle": "Ne sont pas dangereuse avec un vent de 5 m/s.", "correct": false} + ] + }, + { + "num": 347, + "libelle": "Les vents rabattants en montagne :", + "choices": [ + {"index": "A", "libelle": "Ne sont pas dangereux car ils nous font dévier en plaine.", "correct": false}, + {"index": "B", "libelle": "Sont seulement dangereux pour les avions.", "correct": false}, + {"index": "C", "libelle": "Sont dangereux et risquent de nous plaquer contre le relief.", "correct": true} + ] + }, + { + "num": 348, + "libelle": "En été par temps chaud et en présence de cumulus bien développés :", + "choices": [ + {"index": "A", "libelle": "Il n’y a pas de turbulences.", "correct": false}, + {"index": "B", "libelle": "Il y a probablement des turbulences.", "correct": true} + ] + }, + { + "num": 349, + "libelle": "L’aérologie en montagne :", + "choices": [ + {"index": "A", "libelle": "Est bien moins turbulente qu’en plaine car l’air est frais.", "correct": false}, + {"index": "B", "libelle": "Est souvent plus turbulentes qu’en plaine.", "correct": true} + ] + }, + { + "num": 350, + "libelle": "Par temps chaud, les turbulences sont plus importantes :", + "choices": [ + {"index": "A", "libelle": "Au dessus d’un terrain en herbe.", "correct": false}, + {"index": "B", "libelle": "Au dessus des hangars et des parkings goudronnés.", "correct": true} + ] + }, + { + "num": 351, + "libelle": "Le risque de rencontrer des courants ascendants est maximum :", + "choices": [ + {"index": "A", "libelle": "Au-dessus des surfaces froides par temps couvert.", "correct": false}, + {"index": "B", "libelle": "Au-dessus des surfaces froides par temps ensoleillé.", "correct": false}, + {"index": "C", "libelle": "Au-dessus des surfaces chaudes par temps couvert.", "correct": false}, + {"index": "D", "libelle": "Au-dessus des surfaces chaudes par temps ensoleillé.", "correct": true} + ] + }, + { + "num": 352, + "libelle": "On risque de rencontrer des courants ascendants.", + "choices": [ + {"index": "A", "libelle": "Sous le vent d’un relief.", "correct": false}, + {"index": "B", "libelle": "Au vent d’un relief.", "correct": true} + ] + }, + { + "num": 353, + "libelle": "Á quel étage rencontre-t-on les nuages dont le nom comporte le préfixe « Cirro. » ?", + "choices": [ + {"index": "A", "libelle": "Á l’étage supérieur.", "correct": true}, + {"index": "B", "libelle": "Á l’étage moyen.", "correct": false}, + {"index": "C", "libelle": "Á l’étage inférieur.", "correct": false} + ] + }, + { + "num": 354, + "libelle": "Á quel étage rencontre-t-on les nuages dont le nom comporte le préfixe « Strato. » ?", + "choices": [ + {"index": "A", "libelle": "Á l’étage supérieur.", "correct": false}, + {"index": "B", "libelle": "Á l’étage moyen.", "correct": false}, + {"index": "C", "libelle": "Á l’étage inférieur.", "correct": true} + ] + }, + { + "num": 355, + "libelle": "Les cumulus sont des nuages :", + "choices": [ + {"index": "A", "libelle": "Isolés et de forme bien marqués.", "correct": true}, + {"index": "B", "libelle": "En voile ou en nappe continue avec des contours flous.", "correct": false}, + {"index": "C", "libelle": "En filaments.", "correct": false} + ] + }, + { + "num": 356, + "libelle": "Les nuages de type « cumulo. » se forment :", + "choices": [ + {"index": "A", "libelle": "Dans des conditions d’instabilité verticale.", "correct": true}, + {"index": "B", "libelle": "Dans des conditions de stabilité verticale.", "correct": false} + ] + }, + { + "num": 357, + "libelle": "Les stratus sont des nuages :", + "choices": [ + {"index": "A", "libelle": "Isolés et de forme bien marqués.", "correct": false}, + {"index": "B", "libelle": "En voile ou en nappe continue avec des contours flous.", "correct": true}, + {"index": "C", "libelle": "En filaments.", "correct": false} + ] + }, + { + "num": 358, + "libelle": "Les nuages de type « strato. » se forment", + "choices": [ + {"index": "A", "libelle": "Dans des conditions d’instabilité verticale.", "correct": false}, + {"index": "B", "libelle": "Dans des conditions de stabilité verticale.", "correct": true} + ] + }, + { + "num": 359, + "libelle": "Les cirrus sont des nuages :", + "choices": [ + {"index": "A", "libelle": "Isolés et de forme bien marqués.", "correct": false}, + {"index": "B", "libelle": "En voile ou en nappe continue avec des contours flous.", "correct": false}, + {"index": "C", "libelle": "En filaments.", "correct": true} + ] + }, + { + "num": 360, + "libelle": "Le nimbostratus :", + "choices": [ + {"index": "A", "libelle": "Un nuage de beau temps.", "correct": false}, + {"index": "B", "libelle": "Est un nuage épais associé à des précipitations durables.", "correct": true} + ] + }, + { + "num": 361, + "libelle": "La présence d’une couche nuageuse en altitude (cirrocumulus ou cirrostratus) :", + "choices": [ + {"index": "A", "libelle": "Indique que le mauvais temps est passé.", "correct": false}, + {"index": "B", "libelle": "Annonce l ‘arrivée d’une perturbation.", "correct": true} + ] + }, + { + "num": 362, + "libelle": "Les strato-cumulus :", + "choices": [ + {"index": "A", "libelle": "Sont des nuages bas.", "correct": true}, + {"index": "B", "libelle": "Sont des nuages de l’étage moyen.", "correct": false}, + {"index": "C", "libelle": "Sont des nuages d’altitude.", "correct": false} + ] + }, + { + "num": 363, + "libelle": "Quel est le nuage le plus dangereux pour le parachutisme ?", + "choices": [ + {"index": "A", "libelle": "Le cumulonimbus.", "correct": true}, + {"index": "B", "libelle": "Le cirro-stratus.", "correct": false}, + {"index": "C", "libelle": "Le cumulus.", "correct": false} + ] + }, + { + "num": 364, + "libelle": "A l’approche d’un orage :", + "choices": [ + {"index": "A", "libelle": "Le vent est stable en vitesse et en direction.", "correct": false}, + {"index": "B", "libelle": "S’il y a une accalmie de vent, c’est que le risque d’orage a disparu.", "correct": false}, + {"index": "C", "libelle": "Le vent peut s’inverser très rapidement de 180°.", "correct": true} + ] + }, + { + "num": 365, + "libelle": "A l’approche d’un orage :", + "choices": [ + {"index": "A", "libelle": "Il faut arrêter immédiatement les largages s’il y a des éclairs ou du tonnerre.", "correct": true}, + {"index": "B", "libelle": "On peut sauter tant que le vent ne dépasse pas la limite réglementaire.", "correct": false}, + {"index": "C", "libelle": "On peut sauter tant qu’il ne pleut pas.", "correct": false} + ] + }, + { + "num": 366, + "libelle": "Le risque d’orage est plus important :", + "choices": [ + {"index": "A", "libelle": "Au printemps et en été.", "correct": true}, + {"index": "B", "libelle": "En hiver.", "correct": false} + ] + }, + { + "num": 367, + "libelle": "En saison chaude, le risque d’orage est plus important :", + "choices": [ + {"index": "A", "libelle": "L’après-midi.", "correct": true}, + {"index": "B", "libelle": "Le matin.", "correct": false}, + {"index": "C", "libelle": "La nuit.", "correct": false} + ] + }, + { + "num": 368, + "libelle": "Lequel de ces nuages est un nuage d’orage ?", + "choices": [ + {"index": "A", "libelle": "Le strato-cumulus.", "correct": false}, + {"index": "B", "libelle": "Le cumulonimbus.", "correct": true}, + {"index": "C", "libelle": "L’altocumulus.", "correct": false} + ] + }, + { + "num": 369, + "libelle": "Voler près d’un cumulonimbus :", + "choices": [ + {"index": "A", "libelle": "Peux se faire tout de suite après le moment le plus fort de l’orage.", "correct": false}, + {"index": "B", "libelle": "N’est jamais dangereux tant que l’orage n’a pas éclaté.", "correct": false}, + {"index": "C", "libelle": "Est très dangereux.", "correct": true} + ] + }, + { + "num": 370, + "libelle": "Un nuage d’orage :", + "choices": [ + {"index": "A", "libelle": "Evolue toujours très lentement.", "correct": false}, + {"index": "B", "libelle": "Peut évoluer rapidement.", "correct": true} + ] + }, + { + "num": 371, + "libelle": "Un nuage d’orage :", + "choices": [ + {"index": "A", "libelle": "Peut être masqué par d’autres nuages.", "correct": true}, + {"index": "B", "libelle": "Est toujours visible de loin.", "correct": false} + ] + }, + { + "num": 372, + "libelle": "A l’approche d’un orage, il faut cesser les sauts :", + "choices": [ + {"index": "A", "libelle": "Uniquement si le vent au sol dépasse la limite autorisée.", "correct": false}, + {"index": "B", "libelle": "Dès que l’on a un doute sur la situation.", "correct": true} + ] + }, + { + "num": 373, + "libelle": "A proximité d’un cumulonimbus :", + "choices": [ + {"index": "A", "libelle": "Il y a toujours de fortes turbulences.", "correct": true}, + {"index": "B", "libelle": "Il n’y a pas de turbulences.", "correct": false} + ] + }, + { + "num": 374, + "libelle": "En situation orageuse, on rencontre :", + "choices": [ + {"index": "A", "libelle": "Des vents forts et en rafales qui peuvent atteindre des vitesses très élevées.", "correct": true}, + {"index": "B", "libelle": "Des vents forts mais réguliers.", "correct": false}, + {"index": "C", "libelle": "Des vents faibles.", "correct": false} + ] + }, + { + "num": 375, + "libelle": "L’orage est un phénomène :", + "choices": [ + {"index": "A", "libelle": "Très dangereux pour toutes les activités aéronautiques.", "correct": true}, + {"index": "B", "libelle": "Dangereux pour le parachutisme mais pas pour les avions.", "correct": false} + ] + }, + { + "num": 376, + "libelle": "Un nuage d’orage :", + "choices": [ + {"index": "A", "libelle": "Se déplace parfois en sens contraire au vent dominant.", "correct": true}, + {"index": "B", "libelle": "Se déplace toujours dans le sens du vent dominant.", "correct": false} + ] + }, + { + "num": 377, + "libelle": "Un cumulonimbus :", + "choices": [ + {"index": "A", "libelle": "Dépasse rarement 5000 mètres d’altitude à son sommet.", "correct": false}, + {"index": "B", "libelle": "Peut dépasser 5000 mètres d’altitude mais jamais 10000 mètres.", "correct": false}, + {"index": "C", "libelle": "Peut dépasser 10000 mètres d’altitude.", "correct": true} + ] + }, + { + "num": 378, + "libelle": "Le vent donne-t-il une indication sur l’évolution d’un cumulonimbus ?", + "choices": [ + {"index": "A", "libelle": "Oui.", "correct": false}, + {"index": "B", "libelle": "Non.", "correct": true} + ] + }, + { + "num": 379, + "libelle": "Une station météo proche du terrain passe un avis de tempête :", + "choices": [ + {"index": "A", "libelle": "Il faut arrêter la séance quand le vent atteint la limite autorisée.", "correct": false}, + {"index": "B", "libelle": "On peut continuer à sauter encore quelques temps en surveillant le vent.", "correct": false}, + {"index": "C", "libelle": "Il faut arrêter immédiatement la séance de sauts.", "correct": true} + ] + }, + { + "num": 380, + "libelle": "Au passage d’un cumulonimbus, on peut s’attendre :", + "choices": [ + {"index": "A", "libelle": "A un renforcement soudain du vent sans changement de direction.", "correct": false}, + {"index": "B", "libelle": "A un renforcement soudain du vent faisant suite à un changement de direction.", "correct": true} + ] + }, + { + "num": 381, + "libelle": "Sous un cumulonimbus, les précipitations sont souvent :", + "choices": [ + {"index": "A", "libelle": "Faibles.", "correct": false}, + {"index": "B", "libelle": "Inexistantes.", "correct": false}, + {"index": "C", "libelle": "Violentes.", "correct": true} + ] + } + ] + }, + { + "num": 12, + "name": "Sauts spéciaux", + "questions": [ + { + "num": 382, + "libelle": "Pour effectuer un saut de nuit, il faut au minimum :", + "choices": [ + {"index": "A", "libelle": "Un altimètre fluorescent ou éclairé.", "correct": false}, + {"index": "B", "libelle": "Une lampe et un altimètre fluorescent ou éclairé.", "correct": true}, + {"index": "C", "libelle": "Une lampe.", "correct": false} + ] + }, + { + "num": 383, + "libelle": "Pour effectuer un saut de nuit, en plus de l’autorisation du directeur technique, il faut au minimum :", + "choices": [ + {"index": "A", "libelle": "Etre titulaire du brevet C ou D et avoir effectué 10 sauts dans les 3 derniers mois.", "correct": false}, + {"index": "B", "libelle": "Etre titulaire du BPA et avoir effectué 50 sauts dans les 12 derniers mois.", "correct": true}, + {"index": "C", "libelle": "Etre titulaire du BPA.", "correct": false} + ] + }, + { + "num": 384, + "libelle": "Pour effectuer un saut à haute altitude, outre l’autorisation du directeur technique, il faut au minimum :", + "choices": [ + {"index": "A", "libelle": "Etre titulaire du brevet C ou D et avoir effectué 10 sauts dans les 3 derniers mois.", "correct": false}, + {"index": "B", "libelle": "Etre titulaire du BPA et avoir effectué 50 sauts dans les 12 derniers mois.", "correct": true}, + {"index": "C", "libelle": "Etre titulaire du BPA.", "correct": false} + ] + }, + { + "num": 385, + "libelle": "Lors d’un saut à 4500 mètres, si l’on doit attendre 15 minutes à la hauteur de largage :", + "choices": [ + {"index": "A", "libelle": "Cela ne pose pas de problèmes particuliers.", "correct": false}, + {"index": "B", "libelle": "Les problèmes physiologiques dus à l’altitude sont beaucoup plus conséquents que si l’on n’a pas d’attente.", "correct": true} + ] + }, + { + "num": 386, + "libelle": "Pour effectuer un saut à 5000 mètres d’altitude, l’oxygène à bord :", + "choices": [ + {"index": "A", "libelle": "Est obligatoire.", "correct": true}, + {"index": "B", "libelle": "N’est pas obligatoire.", "correct": false} + ] + }, + { + "num": 387, + "libelle": "Lors d’un saut à 6000 mètres, l’oxygène à bord :", + "choices": [ + {"index": "A", "libelle": "Est obligatoire parce que la réglementation l’impose.", "correct": false}, + {"index": "B", "libelle": "N’est pas nécessaire.", "correct": false}, + {"index": "C", "libelle": "Est physiologiquement indispensable et réglementairement obligatoire.", "correct": true} + ] + }, + { + "num": 388, + "libelle": "Lors d’un saut à 6000 mètres, la prise d’oxygène à partir de 4000 mètres est :", + "choices": [ + {"index": "A", "libelle": "Nécessaire uniquement pour ceux qui en ressentent le besoin.", "correct": false}, + {"index": "B", "libelle": "Obligatoire uniquement pour les personnes mineures.", "correct": false}, + {"index": "C", "libelle": "Indispensable quel que soit le niveau des pratiquants.", "correct": true} + ] + }, + { + "num": 389, + "libelle": "L’emport à bord d’un aéronef d’un système individuel d’oxygène est-il obligatoire pour effectuer des sauts à haute altitude ?", + "choices": [ + {"index": "A", "libelle": "Uniquement pour les sauts s’effectuant au dessus de 5000 mètres.", "correct": false}, + {"index": "B", "libelle": "Uniquement pour les sauts s’effectuant au dessus de 6000 mètres.", "correct": false}, + {"index": "C", "libelle": "Oui.", "correct": true} + ] + }, + { + "num": 390, + "libelle": "Le contrôle des équipements au sol et avant la sortie à 6000 mètres doit être particulièrement rigoureux pour :", + "choices": [ + {"index": "A", "libelle": "Minimiser les risques d’ouverture en altitude.", "correct": true}, + {"index": "B", "libelle": "Ne pas risquer une ouverture intempestive à bord et payer un saut non fait.", "correct": false}, + {"index": "C", "libelle": "Cela n’est pas nécessaire.", "correct": false} + ] + }, + { + "num": 391, + "libelle": "Le temps de chute (à plat) pour un départ à 6000 m est d’environ", + "choices": [ + {"index": "A", "libelle": "1 minute et 40 secondes. ", "correct": true}, + {"index": "B", "libelle": "1 minute et 10 secondes.", "correct": false}, + {"index": "C", "libelle": "2 minutes et 30 secondes.", "correct": false} + ] + }, + { + "num": 392, + "libelle": "Quelle sera la dérive en chute lors d’un saut à 6000 mètres avec un vent de 10 m/s ?", + "choices": [ + {"index": "A", "libelle": "Environ 1500 m.", "correct": false}, + {"index": "B", "libelle": "Environ 1000 m.", "correct": true}, + {"index": "C", "libelle": "Environ 400 m.", "correct": false} + ] + }, + { + "num": 393, + "libelle": "Quelle sera la dérive en chute lors d’un saut à 6000 mètres avec un vent de 40 kts ?", + "choices": [ + {"index": "A", "libelle": "Environ 1200 m.", "correct": false}, + {"index": "B", "libelle": "Environ 2000 m.", "correct": true}, + {"index": "C", "libelle": "Environ 500 m.", "correct": false} + ] + }, + { + "num": 394, + "libelle": "Pour sauter d’un ULM il faut au minimum :", + "choices": [ + {"index": "A", "libelle": "Le brevet C ou D.", "correct": true}, + {"index": "B", "libelle": "Le BPA.", "correct": false}, + {"index": "C", "libelle": "Le brevet B.", "correct": false} + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/src/styles/_charts.scss b/src/styles/_charts.scss new file mode 100644 index 0000000..ed65b57 --- /dev/null +++ b/src/styles/_charts.scss @@ -0,0 +1,456 @@ +/********************* +* Chartist chart css * +*********************/ +.ct-label { + fill: rgba(255, 255, 255, 0.4); + color:rgba(255, 255, 255, 0.4); + font-size: 0.75rem; + line-height: 1; +} + +.ct-grid { + stroke: rgba(255, 255, 255, 0.2); +} +.linechart { + max-height: 350px; + margin-top:20px; + .ct-series-a .ct-line, + .ct-series-a .ct-point { + stroke: $chart-color-a; + } + .ct-series-b .ct-line, + .ct-series-b .ct-point { + stroke: $chart-color-b; + } + .ct-series-c .ct-line, + .ct-series-c .ct-point { + stroke: $chart-color-c; + } + .ct-series-d .ct-line, + .ct-series-d .ct-point { + stroke: $chart-color-d; + } + .ct-series-e .ct-line, + .ct-series-e .ct-point { + stroke: $chart-color-e; + } + .ct-series-f .ct-line, + .ct-series-f .ct-point { + stroke:$chart-color-f; + } + .ct-series-g .ct-line, + .ct-series-g .ct-point { + stroke:$chart-color-g; + } + .ct-series-h .ct-line, + .ct-series-h .ct-point { + stroke:$chart-color-h; + } + .ct-series-i .ct-line, + .ct-series-i .ct-point { + stroke:$chart-color-i; + } + .ct-series-j .ct-line, + .ct-series-j .ct-point { + stroke:$chart-color-j; + } + .ct-series-k .ct-line, + .ct-series-k .ct-point { + stroke:$chart-color-k; + } + .ct-series-l .ct-line, + .ct-series-l .ct-point { + stroke:$chart-color-l; + } + .ct-series-m .ct-line, + .ct-series-m .ct-point { + stroke:$chart-color-m; + } + .ct-series-n .ct-line, + .ct-series-n .ct-point { + stroke:$chart-color-n; + } + .ct-series-o .ct-line, + .ct-series-o .ct-point { + stroke:$chart-color-o; + } + .ct-series-p .ct-line, + .ct-series-p .ct-point { + stroke:$chart-color-p; + } + .ct-series-q .ct-line, + .ct-series-q .ct-point { + stroke:$chart-color-q; + } + .ct-series-r .ct-line, + .ct-series-r .ct-point { + stroke:$chart-color-r; + } + .ct-series-s .ct-line, + .ct-series-s .ct-point { + stroke:$chart-color-s; + } + .ct-series-t .ct-line, + .ct-series-t .ct-point { + stroke:$chart-color-t; + } + .ct-series-u .ct-line, + .ct-series-u .ct-point { + stroke:$chart-color-u; + } + .ct-series-v .ct-line, + .ct-series-v .ct-point { + stroke:$chart-color-v; + } + .ct-series-w .ct-line, + .ct-series-w .ct-point { + stroke:$chart-color-w; + } + .ct-series-x .ct-line, + .ct-series-x .ct-point { + stroke:$chart-color-x; + } + .ct-series-y .ct-line, + .ct-series-y .ct-point { + stroke:$chart-color-y; + } + .ct-series-z .ct-line, + .ct-series-z .ct-point { + stroke:$chart-color-z; + } +} + +.barchart { + max-height: 350px; + &.bar-xs .ct-bar { + stroke-width: 5px; + } + .ct-series-a .ct-bar { + stroke:$chart-color-a; + } + .ct-series-b .ct-bar { + stroke:$chart-color-b; + } + .ct-series-c .ct-bar { + stroke:$chart-color-c; + } + .ct-series-d .ct-bar { + stroke:$chart-color-d; + } + .ct-series-e .ct-bar { + stroke:$chart-color-e; + } + .ct-series-f .ct-bar { + stroke:$chart-color-f; + } + .ct-series-g .ct-bar { + stroke:$chart-color-g; + } + .ct-series-h .ct-bar { + stroke:$chart-color-h; + } + .ct-series-i .ct-bar { + stroke:$chart-color-i; + } + .ct-series-j .ct-bar { + stroke:$chart-color-j; + } + .ct-series-k .ct-bar { + stroke:$chart-color-k; + } + .ct-series-l .ct-bar { + stroke:$chart-color-l; + } + .ct-series-m .ct-bar { + stroke:$chart-color-m; + } + .ct-series-n .ct-bar { + stroke:$chart-color-n; + } + .ct-series-o .ct-bar { + stroke:$chart-color-o; + } + .ct-series-p .ct-bar { + stroke:$chart-color-p; + } + .ct-series-q .ct-bar { + stroke:$chart-color-q; + } + .ct-series-r .ct-bar { + stroke:$chart-color-r; + } + .ct-series-s .ct-bar { + stroke:$chart-color-s; + } + .ct-series-t .ct-bar { + stroke:$chart-color-t; + } + .ct-series-u .ct-bar { + stroke:$chart-color-u; + } + .ct-series-v .ct-bar { + stroke:$chart-color-v; + } + .ct-series-w .ct-bar { + stroke:$chart-color-w; + } + .ct-series-x .ct-bar { + stroke:$chart-color-x; + } + .ct-series-y .ct-bar { + stroke:$chart-color-y; + } + .ct-series-z .ct-bar { + stroke:$chart-color-z; + } +} + +.circlechart { + max-height: 200px; +} + +.piechart { + max-height: 350px; + .ct-label { + fill: rgba(255, 255, 255, 0.8); + color:rgba(255, 255, 255, 0.8); + } + .ct-series-a .ct-slice-donut { + stroke:$chart-color-a; + } + .ct-series-b .ct-slice-donut { + stroke:$chart-color-b; + } + .ct-series-c .ct-slice-donut { + stroke:$chart-color-c; + } + .ct-series-d .ct-slice-donut { + stroke:$chart-color-d; + } + .ct-series-e .ct-slice-donut { + stroke:$chart-color-e; + } + .ct-series-f .ct-slice-donut { + stroke:$chart-color-f; + } + .ct-series-g .ct-slice-donut { + stroke:$chart-color-g; + } + .ct-series-h .ct-slice-donut { + stroke:$chart-color-h; + } + .ct-series-i .ct-slice-donut { + stroke:$chart-color-i; + } + .ct-series-j .ct-slice-donut { + stroke:$chart-color-j; + } + .ct-series-k .ct-slice-donut { + stroke:$chart-color-k; + } + .ct-series-l .ct-slice-donut { + stroke:$chart-color-l; + } + .ct-series-m .ct-slice-donut { + stroke:$chart-color-m; + } + .ct-series-n .ct-slice-donut { + stroke:$chart-color-n; + } + .ct-series-o .ct-slice-donut { + stroke:$chart-color-o; + } + .ct-series-p .ct-slice-donut { + stroke:$chart-color-p; + } + .ct-series-q .ct-slice-donut { + stroke:$chart-color-q; + } + .ct-series-r .ct-slice-donut { + stroke:$chart-color-r; + } + .ct-series-s .ct-slice-donut { + stroke:$chart-color-s; + } + .ct-series-t .ct-slice-donut { + stroke:$chart-color-t; + } + .ct-series-u .ct-slice-donut { + stroke:$chart-color-u; + } + .ct-series-v .ct-slice-donut { + stroke:$chart-color-v; + } + .ct-series-w .ct-slice-donut { + stroke:$chart-color-w; + } + .ct-series-x .ct-slice-donut { + stroke:$chart-color-x; + } + .ct-series-y .ct-slice-donut { + stroke:$chart-color-y; + } + .ct-series-z .ct-slice-donut { + stroke:$chart-color-z; + } + + .ct-series-a .ct-slice-donut-solid { + fill:$chart-color-a; + } + .ct-series-b .ct-slice-donut-solid { + fill:$chart-color-b; + } + .ct-series-c .ct-slice-donut-solid { + fill:$chart-color-c; + } + .ct-series-d .ct-slice-donut-solid { + fill:$chart-color-d; + } + .ct-series-e .ct-slice-donut-solid { + fill:$chart-color-e; + } + .ct-series-f .ct-slice-donut-solid { + fill:$chart-color-f; + } + .ct-series-g .ct-slice-donut-solid { + fill:$chart-color-g; + } + .ct-series-h .ct-slice-donut-solid { + fill:$chart-color-h; + } + .ct-series-i .ct-slice-donut-solid { + fill:$chart-color-i; + } + .ct-series-j .ct-slice-donut-solid { + fill:$chart-color-j; + } + .ct-series-k .ct-slice-donut-solid { + fill:$chart-color-k; + } + .ct-series-l .ct-slice-donut-solid { + fill:$chart-color-l; + } + .ct-series-m .ct-slice-donut-solid { + fill:$chart-color-m; + } + .ct-series-n .ct-slice-donut-solid { + fill:$chart-color-n; + } + .ct-series-o .ct-slice-donut-solid { + fill:$chart-color-o; + } + .ct-series-p .ct-slice-donut-solid { + fill:$chart-color-p; + } + .ct-series-q .ct-slice-donut-solid { + fill:$chart-color-q; + } + .ct-series-r .ct-slice-donut-solid { + fill:$chart-color-r; + } + .ct-series-s .ct-slice-donut-solid { + fill:$chart-color-s; + } + .ct-series-t .ct-slice-donut-solid { + fill:$chart-color-t; + } + .ct-series-u .ct-slice-donut-solid { + fill:$chart-color-u; + } + .ct-series-v .ct-slice-donut-solid { + fill:$chart-color-v; + } + .ct-series-w .ct-slice-donut-solid { + fill:$chart-color-w; + } + .ct-series-x .ct-slice-donut-solid { + fill:$chart-color-x; + } + .ct-series-y .ct-slice-donut-solid { + fill:$chart-color-y; + } + .ct-series-z .ct-slice-donut-solid { + fill:$chart-color-z; + } +} + +html body { + .ct-color-a { + color: $chart-color-a; + } + .ct-color-b { + color: $chart-color-b; + } + .ct-color-c { + color: $chart-color-c; + } + .ct-color-d { + color: $chart-color-d; + } + .ct-color-e { + color: $chart-color-e; + } + .ct-color-f { + color: $chart-color-f; + } + .ct-color-g { + color: $chart-color-g; + } + .ct-color-h { + color: $chart-color-h; + } + .ct-color-i { + color: $chart-color-i; + } + .ct-color-j { + color: $chart-color-j; + } + .ct-color-k { + color: $chart-color-k; + } + .ct-color-l { + color: $chart-color-l; + } + .ct-color-m { + color: $chart-color-m; + } + .ct-color-n { + color: $chart-color-n; + } + .ct-color-o { + color: $chart-color-o; + } + .ct-color-p { + color: $chart-color-p; + } + .ct-color-q { + color: $chart-color-q; + } + .ct-color-r { + color: $chart-color-r; + } + .ct-color-s { + color: $chart-color-s; + } + .ct-color-t { + color: $chart-color-t; + } + .ct-color-u { + color: $chart-color-u; + } + .ct-color-v { + color: $chart-color-v; + } + .ct-color-w { + color: $chart-color-w; + } + .ct-color-x { + color: $chart-color-x; + } + .ct-color-y { + color: $chart-color-y; + } + .ct-color-z { + color: $chart-color-z; + } +} \ No newline at end of file diff --git a/src/styles/_header.scss b/src/styles/_header.scss new file mode 100755 index 0000000..24a8ac2 --- /dev/null +++ b/src/styles/_header.scss @@ -0,0 +1,46 @@ +/* +Template Name: Material Ad Astra +Author: UnEspace +Email: rampeur@gmail.com +File: scss +*/ + + +/******************* + Topbar +*******************/ +mat-toolbar{ + box-shadow: 1px 0px 10px rgba(0, 0, 0, 0.5); + &.topbar{ + position: relative; + padding: 0px 15px; + background-color: $headingtext; + color: $sidebar-light; + /* Make sure the toolbar will stay on top of the content as it scrolls past. */ + z-index: 2; + .navbar-header { + text-align: center; + .navbar-brand { + display: flex; + line-height: 18px; + align-items: center; + .logo.fill svg path { + fill: $sidebar-light; + } + } + } + .mdc-button .mdc-button__label { + color: #D9D9D9; + } + .profile-pic { + border-radius: 100%; + vertical-align: baseline; + } + } +} +.app-sidenav-container { + /* When the sidenav is fixed, don't constrain the height of the sidenav container. This allows the + `` to be our scrolling element for mobile layouts. */ + flex: 1 0 auto; +} + diff --git a/src/styles/_palettes.scss b/src/styles/_palettes.scss new file mode 100644 index 0000000..b35af69 --- /dev/null +++ b/src/styles/_palettes.scss @@ -0,0 +1,809 @@ + +/* Custom Theme Palettes */ + + +$md-custom-primary: ( + 50 : #e6e9f3, + 100 : #c0c7e3, + 200 : #97a3d0, + 300 : #6e80bd, + 400 : #4f64af, + 500 : #2c4aa3, + 600 : #264399, + 700 : #1c398e, + 800 : #123082, + 900 : #001f6c, + A100 : #77a9ff, + A200 : #4489ff, + A400 : #1169ff, + A700 : #005bf6, + contrast: ( + 50 : #000000, + 100 : #000000, + 200 : #000000, + 300 : #000000, + 400 : #ffffff, + 500 : #ffffff, + 600 : #ffffff, + 700 : #ffffff, + 800 : #ffffff, + 900 : #ffffff, + A100 : #000000, + A200 : #000000, + A400 : #ffffff, + A700 : #ffffff, + ) +); + +$md-custom-primary-blue: ( + 50 : #e3f0fa, + 100 : #bad9f3, + 200 : #90c2ea, + 300 : #67aae1, + 400 : #4b99dc, + 500 : #3389d6, + 600 : #2d7cc9, + 700 : #266bb7, + 800 : #205aa5, + 900 : #163e86, + A100 : #77a9ff, + A200 : #4489ff, + A400 : #1169ff, + A700 : #005bf6, + contrast: ( + 50 : #000000, + 100 : #000000, + 200 : #000000, + 300 : #000000, + 400 : #000000, + 500 : #000000, + 600 : #000000, + 700 : #ffffff, + 800 : #ffffff, + 900 : #ffffff, + A100 : #000000, + A200 : #000000, + A400 : #ffffff, + A700 : #ffffff, + ) +); + +$md-custom-primary-green: ( + 50 : #f6fbf9, + 100 : #e9f5f1, + 200 : #dbeee8, + 300 : #cde7de, + 400 : #c2e2d7, + 500 : #b7ddd0, + 600 : #b0d9cb, + 700 : #a7d4c4, + 800 : #9fcfbe, + 900 : #90c7b3, + A100 : #ffffff, + A200 : #ffffff, + A400 : #f8fffc, + A700 : #dffff3, + contrast: ( + 50 : #000000, + 100 : #000000, + 200 : #000000, + 300 : #000000, + 400 : #000000, + 500 : #000000, + 600 : #000000, + 700 : #000000, + 800 : #ffffff, + 900 : #ffffff, + A100 : #000000, + A200 : #000000, + A400 : #000000, + A700 : #000000, + ) +); +$md-custom-accent: ( + 50 : #fbfaf7, + 100 : #f6f2eb, + 200 : #f0eade, + 300 : #eae2d1, + 400 : #e6dbc7, + 500 : #e1d5bd, + 600 : #ddd0b7, + 700 : #d9caae, + 800 : #d5c4a6, + 900 : #cdba98, + A100 : #eae2d1, + A200 : #e6dbc7, + A400 : #e1d5bd, + A700 : #ddd0b7, + contrast: ( + 50 : #000000, + 100 : #000000, + 200 : #000000, + 300 : #000000, + 400 : #000000, + 500 : #000000, + 600 : #000000, + 700 : #000000, + 800 : #ffffff, + 900 : #ffffff, + A100 : #000000, + A200 : #000000, + A400 : #000000, + A700 : #000000, + ) +); +$md-custom-warn: ( + 50 : #f3f2f9, + 100 : #e2def0, + 200 : #cfc8e6, + 300 : #bcb1db, + 400 : #ada1d4, + 500 : #9f90cc, + 600 : #9788c7, + 700 : #8d7dc0, + 800 : #8373b9, + 900 : #7261ad, + A100 : #ffffff, + A200 : #eee9ff, + A400 : #c6b6ff, + A700 : #b29cff, + contrast: ( + 50 : #000000, + 100 : #000000, + 200 : #000000, + 300 : #000000, + 400 : #000000, + 500 : #ffffff, + 600 : #ffffff, + 700 : #ffffff, + 800 : #ffffff, + 900 : #ffffff, + A100 : #000000, + A200 : #000000, + A400 : #000000, + A700 : #000000, + ) +); +$md-custom-megna: ( + 50 : #e0f1ef, + 100 : #b3dcd7, + 200 : #80c4bd, + 300 : #4daca3, + 400 : #269b8f, + 500 : #00897b, + 600 : #008173, + 700 : #007668, + 800 : #006c5e, + 900 : #00594b, + A100 : #8bffe9, + A200 : #58ffdf, + A400 : #25ffd5, + A700 : #0bffd0, + contrast: ( + 50 : #000000, + 100 : #000000, + 200 : #000000, + 300 : #000000, + 400 : #ffffff, + 500 : #ffffff, + 600 : #ffffff, + 700 : #ffffff, + 800 : #ffffff, + 900 : #ffffff, + A100 : #000000, + A200 : #000000, + A400 : #000000, + A700 : #000000, + ) +); +$md-custom-teal: ( + 50 : #ecf9f1, + 100 : #cef0dc, + 200 : #aee6c4, + 300 : #8edbac, + 400 : #75d49b, + 500 : #5dcc89, + 600 : #55c781, + 700 : #4bc076, + 800 : #41b96c, + 900 : #30ad59, + A100 : #f3fff7, + A200 : #c0ffd3, + A400 : #8dffb0, + A700 : #74ff9e, + contrast: ( + 50 : #000000, + 100 : #000000, + 200 : #000000, + 300 : #000000, + 400 : #000000, + 500 : #000000, + 600 : #000000, + 700 : #000000, + 800 : #000000, + 900 : #000000, + A100 : #000000, + A200 : #000000, + A400 : #000000, + A700 : #000000, + ) +); +$md-custom-turquoise: ( + 50 : #e1f7f5, + 100 : #b3ece6, + 200 : #81dfd5, + 300 : #4ed2c4, + 400 : #28c9b8, + 500 : #02bfab, + 600 : #02b9a4, + 700 : #01b19a, + 800 : #01a991, + 900 : #019b80, + A100 : #c6fff3, + A200 : #93ffe9, + A400 : #60ffdf, + A700 : #47ffda, + contrast: ( + 50 : #000000, + 100 : #000000, + 200 : #000000, + 300 : #000000, + 400 : #000000, + 500 : #000000, + 600 : #ffffff, + 700 : #ffffff, + 800 : #ffffff, + 900 : #ffffff, + A100 : #000000, + A200 : #000000, + A400 : #000000, + A700 : #000000, + ) +); +$md-custom-cyan: ( + 50 : #edfbfb, + 100 : #d1f4f6, + 200 : #b2edf0, + 300 : #93e5e9, + 400 : #7ce0e5, + 500 : #65dae0, + 600 : #5dd6dc, + 700 : #53d0d8, + 800 : #49cbd3, + 900 : #37c2cb, + A100 : #ffffff, + A200 : #e2fdff, + A400 : #affaff, + A700 : #96f8ff, + contrast: ( + 50 : #000000, + 100 : #000000, + 200 : #000000, + 300 : #000000, + 400 : #000000, + 500 : #000000, + 600 : #000000, + 700 : #000000, + 800 : #000000, + 900 : #000000, + A100 : #000000, + A200 : #000000, + A400 : #000000, + A700 : #000000, + ) +); +$md-custom-navy: ( + 50 : #e3e9ee, + 100 : #b9c8d4, + 200 : #8ba3b7, + 300 : #5d7e9a, + 400 : #3a6285, + 500 : #17466f, + 600 : #143f67, + 700 : #11375c, + 800 : #0d2f52, + 900 : #072040, + A100 : #77a9ff, + A200 : #4489ff, + A400 : #1169ff, + A700 : #005bf6, + contrast: ( + 50 : #000000, + 100 : #000000, + 200 : #000000, + 300 : #000000, + 400 : #ffffff, + 500 : #ffffff, + 600 : #ffffff, + 700 : #ffffff, + 800 : #ffffff, + 900 : #ffffff, + A100 : #000000, + A200 : #000000, + A400 : #ffffff, + A700 : #ffffff, + ) +); +$md-custom-navy-light: ( + 50 : #e7eff6, + 100 : #c2d7e9, + 200 : #99bddb, + 300 : #70a2cd, + 400 : #528ec2, + 500 : #337ab7, + 600 : #2e72b0, + 700 : #2767a7, + 800 : #205d9f, + 900 : #144a90, + A100 : #c4dcff, + A200 : #91bdff, + A400 : #5e9eff, + A700 : #458fff, + contrast: ( + 50 : #000000, + 100 : #000000, + 200 : #000000, + 300 : #000000, + 400 : #000000, + 500 : #ffffff, + 600 : #ffffff, + 700 : #ffffff, + 800 : #ffffff, + 900 : #ffffff, + A100 : #000000, + A200 : #000000, + A400 : #000000, + A700 : #000000, + ) +); +$md-custom-purple: ( + 50 : #eeecfd, + 100 : #d5cffa, + 200 : #bab0f7, + 300 : #9e90f3, + 400 : #8978f1, + 500 : #7460ee, + 600 : #6c58ec, + 700 : #614ee9, + 800 : #5744e7, + 900 : #4433e2, + A100 : #ffffff, + A200 : #f6f5ff, + A400 : #c7c2ff, + A700 : #b0a8ff, + contrast: ( + 50 : #000000, + 100 : #000000, + 200 : #000000, + 300 : #000000, + 400 : #000000, + 500 : #000000, + 600 : #ffffff, + 700 : #ffffff, + 800 : #ffffff, + 900 : #ffffff, + A100 : #000000, + A200 : #000000, + A400 : #000000, + A700 : #000000, + ) +); +$md-custom-purple-light: ( + 50 : #f1edfb, + 100 : #dcd1f6, + 200 : #c5b2f0, + 300 : #ad93e9, + 400 : #9c7ce5, + 500 : #8a65e0, + 600 : #825ddc, + 700 : #7753d8, + 800 : #6d49d3, + 900 : #5a37cb, + A100 : #ffffff, + A200 : #e8e2ff, + A400 : #c1afff, + A700 : #ad96ff, + contrast: ( + 50 : #000000, + 100 : #000000, + 200 : #000000, + 300 : #000000, + 400 : #000000, + 500 : #ffffff, + 600 : #ffffff, + 700 : #ffffff, + 800 : #ffffff, + 900 : #ffffff, + A100 : #000000, + A200 : #000000, + A400 : #000000, + A700 : #000000, + ) +); +$md-custom-raspberry: ( + 50 : #f6e2eb, + 100 : #e9b8cc, + 200 : #da88ab, + 300 : #cb5889, + 400 : #c0356f, + 500 : #b51156, + 600 : #ae0f4f, + 700 : #a50c45, + 800 : #9d0a3c, + 900 : #8d052b, + A100 : #ffbac9, + A200 : #ff87a2, + A400 : #ff547a, + A700 : #ff3b66, + contrast: ( + 50 : #000000, + 100 : #000000, + 200 : #000000, + 300 : #000000, + 400 : #ffffff, + 500 : #ffffff, + 600 : #ffffff, + 700 : #ffffff, + 800 : #ffffff, + 900 : #ffffff, + A100 : #000000, + A200 : #000000, + A400 : #000000, + A700 : #000000, + ) +); +$md-custom-orange: ( + 50 : #fff3e0, + 100 : #ffe0b3, + 200 : #ffcc80, + 300 : #ffb84d, + 400 : #ffa826, + 500 : #ff9900, + 600 : #ff9100, + 700 : #ff8600, + 800 : #ff7c00, + 900 : #ff6b00, + A100 : #ffffff, + A200 : #fff7f2, + A400 : #ffd6bf, + A700 : #ffc6a6, + contrast: ( + 50 : #000000, + 100 : #000000, + 200 : #000000, + 300 : #000000, + 400 : #000000, + 500 : #000000, + 600 : #000000, + 700 : #000000, + 800 : #000000, + 900 : #000000, + A100 : #000000, + A200 : #000000, + A400 : #000000, + A700 : #000000, + ) +); +$md-custom-yellow: ( + 50 : #fffce1, + 100 : #fff6b4, + 200 : #fff182, + 300 : #ffeb50, + 400 : #ffe62b, + 500 : #ffe205, + 600 : #ffdf04, + 700 : #ffda04, + 800 : #ffd603, + 900 : #ffcf01, + A100 : #ffffff, + A200 : #fffcf2, + A400 : #fff1bf, + A700 : #ffeca6, + contrast: ( + 50 : #000000, + 100 : #000000, + 200 : #000000, + 300 : #000000, + 400 : #000000, + 500 : #000000, + 600 : #000000, + 700 : #000000, + 800 : #000000, + 900 : #000000, + A100 : #000000, + A200 : #000000, + A400 : #000000, + A700 : #000000, + ) +); +$md-custom-magenta: ( + 50 : #ffeaff, + 100 : #ffcaff, + 200 : #ffa6ff, + 300 : #ff82ff, + 400 : #ff68ff, + 500 : #ff4dff, + 600 : #ff46ff, + 700 : #ff3dff, + 800 : #ff34ff, + 900 : #ff25ff, + A100 : #ffffff, + A200 : #ffffff, + A400 : #ffd3ff, + A700 : #ffb9ff, + contrast: ( + 50 : #000000, + 100 : #000000, + 200 : #000000, + 300 : #000000, + 400 : #000000, + 500 : #000000, + 600 : #000000, + 700 : #000000, + 800 : #000000, + 900 : #ffffff, + A100 : #000000, + A200 : #000000, + A400 : #000000, + A700 : #000000, + ) +); +$md-custom-pink: ( + 50 : #fdeaf2, + 100 : #facbdf, + 200 : #f6a8ca, + 300 : #f285b4, + 400 : #f06aa4, + 500 : #ed5094, + 600 : #eb498c, + 700 : #e84081, + 800 : #e53777, + 900 : #e02765, + A100 : #ffffff, + A200 : #ffeaf0, + A400 : #ffb7cd, + A700 : #ff9dbb, + contrast: ( + 50 : #000000, + 100 : #000000, + 200 : #000000, + 300 : #000000, + 400 : #000000, + 500 : #000000, + 600 : #000000, + 700 : #ffffff, + 800 : #ffffff, + 900 : #ffffff, + A100 : #000000, + A200 : #000000, + A400 : #000000, + A700 : #000000, + ) +); + +$md-custom-jinza: ( + 50 : #ffecef, + 100 : #ffd0d4, + 200 : #f3a09d, + 300 : #eb7a77, + 400 : #f65e54, + 500 : #fa5039, + 600 : #ed4739, + 700 : #da3d33, + 800 : #cd372c, + 900 : #be2c20, + A100 : #fdf1f1, + A200 : #fbe4e4, + A400 : #f7cac9, + A700 : #f1a19f, + contrast: ( + 50 : #000000, + 100 : #000000, + 200 : #000000, + 300 : #000000, + 400 : #000000, + 500 : #000000, + 600 : #000000, + 700 : #ffffff, + 800 : #ffffff, + 900 : #ffffff, + A100 : #000000, + A200 : #000000, + A400 : #000000, + A700 : #000000, + ) +); + +$md-custom-red: ( + 50: #ffebee, + 100: #ffcdd2, + 200: #ef9a9a, + 300: #e57373, + 400: #ef5350, + 500: #f44336, + 600: #e53935, + 700: #d32f2f, + 800: #c62828, + 900: #b71c1c, + A100: #ff8a80, + A200: #ff5252, + A400: #ff1744, + A700: #d50000, + contrast: ( + 50 : #000000, + 100 : #000000, + 200 : #000000, + 300 : #000000, + 400 : #000000, + 500 : #ffffff, + 600 : #ffffff, + 700 : #ffffff, + 800 : #ffffff, + 900 : #ffffff, + A100 : #000000, + A200 : #000000, + A400 : #000000, + A700 : #000000, + ) +); +$md-custom-green: ( + 50: #e8f5e9, + 100: #c8e6c9, + 200: #a5d6a7, + 300: #81c784, + 400: #66bb6a, + 500: #4caf50, + 600: #43a047, + 700: #388e3c, + 800: #2e7d32, + 900: #1b5e20, + A100: #b9f6ca, + A200: #69f0ae, + A400: #00e676, + A700: #00c853, + contrast: ( + 50 : #000000, + 100 : #000000, + 200 : #000000, + 300 : #000000, + 400 : #000000, + 500 : #ffffff, + 600 : #ffffff, + 700 : #ffffff, + 800 : #ffffff, + 900 : #ffffff, + A100 : #000000, + A200 : #000000, + A400 : #000000, + A700 : #000000, + ) +); +$md-custom-blue: ( + 50: #e3f2fd, + 100: #bbdefb, + 200: #90caf9, + 300: #64b5f6, + 400: #42a5f5, + 500: #2196f3, + 600: #1e88e5, + 700: #1976d2, + 800: #1565c0, + 900: #0d47a1, + A100: #82b1ff, + A200: #448aff, + A400: #2979ff, + A700: #2962ff, + contrast: ( + 50 : #000000, + 100 : #000000, + 200 : #000000, + 300 : #000000, + 400 : #000000, + 500 : #ffffff, + 600 : #ffffff, + 700 : #ffffff, + 800 : #ffffff, + 900 : #ffffff, + A100 : #000000, + A200 : #000000, + A400 : #000000, + A700 : #000000, + ) +); + +$md-complementary-green: ( + 50 : #f6faf6, + 100 : #e8f2e8, + 200 : #d8e9d8, + 300 : #c8e0c8, + 400 : #bdd9bd, + 500 : #b1d2b1, + 600 : #aacdaa, + 700 : #a1c7a1, + 800 : #98c198, + 900 : #88b688, + A100 : #ffffff, + A200 : #ffffff, + A400 : #e0ffe0, + A700 : #c7ffc7, + contrast: ( + 50 : #000000, + 100 : #000000, + 200 : #000000, + 300 : #000000, + 400 : #000000, + 500 : #000000, + 600 : #000000, + 700 : #000000, + 800 : #ffffff, + 900 : #ffffff, + A100 : #000000, + A200 : #000000, + A400 : #000000, + A700 : #000000, + ) +); +$md-complementary-purple: ( + 50 : #f7f6fb, + 100 : #ebe9f5, + 200 : #dedbee, + 300 : #d1cde7, + 400 : #c7c2e2, + 500 : #bdb7dd, + 600 : #b7b0d9, + 700 : #aea7d4, + 800 : #a69fcf, + 900 : #9890c7, + A100 : #ffffff, + A200 : #ffffff, + A400 : #f9f8ff, + A700 : #e4dfff, + contrast: ( + 50 : #000000, + 100 : #000000, + 200 : #000000, + 300 : #000000, + 400 : #000000, + 500 : #000000, + 600 : #000000, + 700 : #000000, + 800 : #ffffff, + 900 : #ffffff, + A100 : #000000, + A200 : #000000, + A400 : #000000, + A700 : #000000, + ) +); +$md-complementary-blue: ( + 50 : #f6f8fb, + 100 : #e9edf5, + 200 : #dbe2ee, + 300 : #cdd6e7, + 400 : #c2cde2, + 500 : #b7c4dd, + 600 : #b0bed9, + 700 : #a7b6d4, + 800 : #9fafcf, + 900 : #90a2c7, + A100 : #ffffff, + A200 : #ffffff, + A400 : #f8faff, + A700 : #dfe9ff, + contrast: ( + 50 : #000000, + 100 : #000000, + 200 : #000000, + 300 : #000000, + 400 : #000000, + 500 : #000000, + 600 : #000000, + 700 : #000000, + 800 : #ffffff, + 900 : #ffffff, + A100 : #000000, + A200 : #000000, + A400 : #000000, + A700 : #000000, + ) +); diff --git a/src/styles/_sidebar.scss b/src/styles/_sidebar.scss new file mode 100755 index 0000000..b54dea4 --- /dev/null +++ b/src/styles/_sidebar.scss @@ -0,0 +1,228 @@ +/* +Template Name: Material Ad Astra +Author: UnEspace +Email: rampeur@gmail.com +File: scss +*/ +@use 'sass:color'; + +/******************* +Main sidebar +******************/ + +#snav mat-list-item.mat-mdc-list-item.selected:after { + border-right: 18px solid color.scale($sidebar-light, $lightness: 50%); + border-top: 18px solid $sidebar-text; + border-bottom: 18px solid $sidebar-text; + content: ""; + display: inline-block; + position: absolute; + right: -1px; + top: 8px; +} + +#snav { + /*box-shadow: 1px 0px 20px rgba(0, 0, 0, 0.08);*/ + box-shadow: 0px 2px 4px -1px rgba(0, 0, 0, 0.2), 0px 4px 5px 0px rgba(0, 0, 0, 0.14), 0px 1px 10px 0px rgba(0, 0, 0, 0.12); + &.mat-drawer{ + width: $sidenav-width; + padding-top: 0px; + } + &.mat-drawer-side{ + border-right: 0px solid $sidebar; + } + mat-list-item { + height: auto; + padding: 0px 10px; + &:hover{ + background: none; + &::before { + background-color: transparent; + opacity: 1; + } + } + .mdc-list-item__content{ + display: block; + &:hover{ + background: none; + span > a{ + color:$white; + background: $sidebar-selected; + border-radius: $radius; + mat-icon{ + color:$white; + } + } + } + } + a{ + height: 36px; + padding: 0 10px; + margin-top: 8px; + margin-bottom: 8px; + align-items: center; + display: flex; + font-size: 1rem; + font-weight: 300; + white-space: nowrap; + mat-icon:not(.dd-icon){ + margin-right: 8px; + } + .dd-icon{ + font-size: 16px; + width: 16px; + transition: 0.2s ease-in; + margin: 5px 0 5px 5px; + height: 16px; + } + } + &.selected:after { + border-right: 18px solid color.scale($sidebar, $lightness: 4%); + border-top: 18px solid $headingtext; + border-bottom: 18px solid $headingtext; + content: ""; + display: inline-block; + position: absolute; + right: -1px; + top: 8px; + } + &.selected > .mdc-list-item__content span > a{ + background: $sidebar-selected; + border-radius: $radius; + .dd-icon{ + -webkit-transform: rotate(-180deg); + transform: rotate(-180deg); + } + + } + &.selected .sub-item .mdc-list-item__content a.selected{ + background: transparent; + font-weight: 500; + } + } +} + +.light-theme #snav { + &.mat-drawer{ + background-color: $sidebar-light; + } + mat-list-item { + a{ + color:$sidebar-text; + mat-icon{ + color:$sidebar-icons; + } + } + &.selected > .mdc-list-item__content span > a{ + color:$white; + mat-icon{ + color:$white; + } + } + &.selected .sub-item .mdc-list-item__content a.selected{ + color: $white; + } + } +} +/******************* +use profile section +*******************/ + +.user-profile { + position: relative; + height: $sidenav-height; + width: $sidenav-width; + background-image: none; + background-size: cover; + background-repeat: no-repeat; + .profile-img { + width: 50px; + margin-left: 30px; + padding: 30px 0; + border-radius: 100%; + &::before { + -webkit-animation: 2.5s blow 0s linear infinite; + animation: 2.5s blow 0s linear infinite; + position: absolute; + content: ''; + width: 50px; + height: 50px; + top: 31px; + margin: 0 auto; + border-radius: 50%; + z-index: 0; + } + @-webkit-keyframes blow { + 0% { + box-shadow: 0 0 0 0px rgba(0, 0, 0, 0.1); + opacity: 1; + -webkit-transform: scale3d(1, 1, 0.5); + transform: scale3d(1, 1, 0.5); + } + 50% { + box-shadow: 0 0 0 10px rgba(0, 0, 0, 0.1); + opacity: 1; + -webkit-transform: scale3d(1, 1, 0.5); + transform: scale3d(1, 1, 0.5); + } + 100% { + box-shadow: 0 0 0 20px rgba(0, 0, 0, 0.1); + opacity: 0; + -webkit-transform: scale3d(1, 1, 0.5); + transform: scale3d(1, 1, 0.5); + } + } + @keyframes blow { + 0% { + box-shadow: 0 0 0 0px rgba(0, 0, 0, 0.1); + opacity: 1; + -webkit-transform: scale3d(1, 1, 0.5); + transform: scale3d(1, 1, 0.5); + } + 50% { + box-shadow: 0 0 0 10px rgba(0, 0, 0, 0.1); + opacity: 1; + -webkit-transform: scale3d(1, 1, 0.5); + transform: scale3d(1, 1, 0.5); + } + 100% { + box-shadow: 0 0 0 20px rgba(0, 0, 0, 0.1); + opacity: 0; + -webkit-transform: scale3d(1, 1, 0.5); + transform: scale3d(1, 1, 0.5); + } + } + img { + width: 100%; + border-radius: 100%; + } + } + .profile-text { + position: absolute; + cursor: pointer; + white-space: nowrap; + width: 100%; + bottom: 0; + > a { + color: $sidebar !important; + width: 100%; + padding: 4px 10px 7px 22px; + background-color: rgba(217, 202, 174, 0.5); + display: block; + white-space: nowrap; + &:after{ + position: absolute; + right: 20px; + top:20px; + } + } + .mat-icon { + line-height: var(--bs-body-line-height); + } + } +} +.sidebar-closed #snav{ + &.mat-sidenav ~ .mat-drawer-content { + margin-left: 0px!important; + } +} \ No newline at end of file diff --git a/src/styles/_spinner.scss b/src/styles/_spinner.scss new file mode 100755 index 0000000..28217f7 --- /dev/null +++ b/src/styles/_spinner.scss @@ -0,0 +1,49 @@ +/* Spinner */ +.preloader{ + position: absolute; + margin: 0 auto; + width: calc(100% - 30px); + height: calc(100% - 30px); + z-index: 100; + background: map.get($background, background); +} +.spinner { + width: 42px; + height: 42px; + top:35%; + position: relative; + margin: 100px auto; +} + +.double-bounce1, .double-bounce2 { + width: 100%; + height: 100%; + border-radius: 50%; + background-color: mat.m2-get-color-from-palette($md-custom-warn, 700);; + opacity: 0.6; + position: absolute; + top: 0; + left: 0; + -webkit-animation: sk-bounce 2.0s infinite ease-in-out; + animation: sk-bounce 2.0s infinite ease-in-out; +} + +.double-bounce2 { + -webkit-animation-delay: -1.0s; + animation-delay: -1.0s; +} + +@-webkit-keyframes sk-bounce { + 0%, 100% { -webkit-transform: scale(0.0) } + 50% { -webkit-transform: scale(1.0) } +} + +@keyframes sk-bounce { + 0%, 100% { + transform: scale(0.0); + -webkit-transform: scale(0.0); + } 50% { + transform: scale(1.0); + -webkit-transform: scale(1.0); + } +} \ No newline at end of file diff --git a/src/styles/app.scss b/src/styles/app.scss new file mode 100755 index 0000000..0287bb9 --- /dev/null +++ b/src/styles/app.scss @@ -0,0 +1,301 @@ +/* +Template Name: Material Ad Astra +Author: UnEspace +Email: rampeur@gmail.com +File: scss +*/ +@use 'sass:color'; + +html { + --mat-expansion-header-collapsed-state-height: 48px; + --mat-expansion-header-expanded-state-height: 48px; + height: 100%; + position: relative; + min-height: 100%; + background: $white; + .page-wrapper{ + height:calc(100vh - 64px); + padding: 1.5rem; + } +} +body { + height: 100%; + margin: 0; + font-family: $bodyfont; + overflow-x: hidden; + font-weight: 300; +} + +*, +*:before, +*:after { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +* { + outline: none; +} + +a:hover, +a:focus, +a { + text-decoration: none; +} +a.link { + color: $headingtext; + text-decoration: none; + &:hover, + &:focus { + color: $primary; + } +} +a.warn { + color: $warn; +} +a.warn:hover { + color: color.adjust($warn, $alpha: -0.3); +} +a.accent { + color: $accent; +} +a.accent:hover { + color: color.adjust($accent, $alpha: -0.3); +} + +.no-shrink { + flex-shrink: 0; +} +.flex-spacer { + flex: 1 1 auto; +} + +.error-messages { + color: $error !important; + font-weight: 500; +} +.footer { + background-color: $sidebar-footer; + font-size: 0.88em; + padding: 5px 0; + position: absolute; + bottom: 0; + width: 100%; + a { + color: $sidebar-light; + } + .copyright { + color: $sidebar-light; + } +} +.img-responsive { + width: 100%; + height: auto; + display: inline-block; +} +.img-fluid { + max-width: 100%; + height: auto; +} +.shadow-none { + box-shadow: none !important; +} +.pointer { + cursor: pointer; +} +.font-monospace.fw-lighter, +.font-monospace .fw-lighter { + font-weight: 200 !important; +} + +.banner { + background-color: $white; + margin: -1.5rem -1.5rem 1.5rem -1.5rem; + .banner-content { + padding: 1.3rem 1.1rem 1.1rem 1.1rem; + } + .user-img { + width: $user-img-size; + height: $user-img-size; + border-radius: $user-img-size; + } + h4 { + font-weight: 500; + margin-bottom: 0.75rem; + } + p { + margin: 0 auto .5rem; + color: $muted; + max-width: 450px; + font-weight: 300; + } +} +.dark-theme, +.primary-theme { + dl.dl-horizontal dt { + color: $light; + } +} +.primary-theme { + app-full-layout { + /*--mat-sidenav-content-background-color: $sidenav-content;*/ + .mat-drawer-content { + background-color: color.scale($sidebar, $lightness: 4%); + } + .mat-expansion-panel { + background-color: color.scale($sidebar, $lightness: 14%); + } + .mat-mdc-card { + background-color: color.scale($sidebar, $lightness: 8%); + .mat-mdc-paginator { + background-color: color.scale($sidebar, $lightness: 8%); + } + } + .banner { + background-color: color.scale($sidebar, $lightness: 90%); + } + } +} +app-full-layout { + --mat-card-title-text-size: 22px; + --mat-card-subtitle-text-line-height: 24px; + --mat-card-subtitle-text-size: 16px; + .mat-mdc-form-field, + .mdc-text-field--filled .mdc-floating-label { + font-size: initial; + } + .mat-mdc-form-field-infix { + min-height: 40px; + } + .mdc-text-field--no-label:not(.mdc-text-field--outlined):not(.mdc-text-field--textarea) { + .mat-mdc-form-field-infix { + padding-top: 8px; + padding-bottom: 8px; + } + } + .mat-mdc-icon-button { + .mat-icon { + line-height: 0.87; + } + } + .mat-mdc-table { + background-color: initial; + } + [class^="text-bg-"], [class*=" text-bg-"]{ + .mat-mdc-card-subtitle { + color: inherit; + } + } +} +.mat-icon.mini { + --mat-menu-item-icon-size: 22px; + &.material-icons { + font-size: var(--mat-menu-item-icon-size); + } +} +.badge .mat-icon { + width: 0.76rem; + height: 0.76rem; + font-size: 0.76rem; +} + +/* Chrome, Safari, Edge, Opera */ +input::-webkit-outer-spin-button, +input::-webkit-inner-spin-button { + appearance: none; + -webkit-appearance: none; + margin: 0; +} +/* Firefox */ +input[type=number] { + appearance: textfield; + -moz-appearance: textfield; +} + +/**************** +* Definitions * +****************/ +dl.dl-horizontal { + margin-bottom: 0; + font-size: 14px; + margin-top: 0; + margin-bottom: 20px; + dt { + float: left; + width: 120px; + overflow: hidden; + clear: left; + font-weight: 500; + text-align: right; + text-overflow: ellipsis; + white-space: nowrap; + } + dt, + dd { + line-height: 1.42857143; + min-height: 1.42857143em; + } + dd { + margin-left: 140px; + /* color: $extra-light; */ + } + &.dl-large dt { + width: 160px; + } + &.dl-large dd { + margin-left: 180px; + } + &.dl-xlarge dt { + width: 200px; + } + &.dl-xlarge dd { + margin-left: 220px; + } +} + +/********************** +* Extra Text Colors * +**********************/ +.text-error { + color: $error !important; +} +.text-muted { + color: $muted !important; +} + +/**************************** +* Extra Background Colors * +****************************/ +.bg-crystal, +.bg-crystal .mdc-text-field--filled:not(.mdc-text-field--disabled) { + background-color: transparent !important; +} +.bg-dark-transparent { + background-color: $dark-transparent !important; +} + +/***************************** +* Icon Sizes * +*****************************/ +mat-icon { + &.icon-xxsmall { + font-size: 12px; + height: 12px; + width: 12px; + } + &.icon-xsmall { + font-size: 16px; + height: 16px; + width: 16px; + } + &.icon-small { + font-size: 18px; + height: 18px; + width: 18px; + } + &.icon-medium { + font-size: 20px; + height: 20px; + width: 20px; + } +} \ No newline at end of file diff --git a/src/styles/components/_index.scss b/src/styles/components/_index.scss new file mode 100644 index 0000000..3033c38 --- /dev/null +++ b/src/styles/components/_index.scss @@ -0,0 +1,9 @@ +//@use '../../app/shared/components/alert/alert-theme' as alert; +@use './button/variants' as button-variants; +@use './utils/variants' as utils-variants; + +@mixin theme($theme, $typography-config, $variants) { + //@include alert.theme($theme, $typography-config); + @include button-variants.color($theme, $variants); + @include utils-variants.color($theme, $variants); +} diff --git a/src/styles/components/button/_variants.scss b/src/styles/components/button/_variants.scss new file mode 100644 index 0000000..8066e21 --- /dev/null +++ b/src/styles/components/button/_variants.scss @@ -0,0 +1,77 @@ +@use 'sass:map'; +@use 'sass:meta'; +@use '@angular/material' as mat; + +$_ripple-opacity: 0.1; + +// Applies a focus style to an mat-button element for each of the supported palettes. +@mixin _focus-overlay-color($config-or-theme, $variants) { + $config: mat.m2-get-color-config($config-or-theme); + @each $variant, $variant-palette in $variants { + &.mat-#{"" + $variant} .mat-mdc-button-focus-overlay { + background-color: mat.m2-get-color-from-palette($variant-palette); + } + &.mat-#{"" + $variant} .mat-mdc-button-persistent-ripple::before { + background-color: mat.m2-get-color-from-palette($variant-palette); + } + } +} + +@mixin _ripple-background($palette, $hue, $opacity) { + $background-color: mat.m2-get-color-from-palette($palette, $hue, $opacity); + background-color: $background-color; + @if (meta.type-of($background-color) != color) { + opacity: $opacity; + } +} + +@mixin _ripple-color($theme, $hue, $opacity, $variants) { + @each $variant, $variant-palette in $variants { + &.mat-#{"" + $variant} .mat-ripple-element { + @include _ripple-background($variant-palette, $hue, $opacity); + } + } +} + +// Applies a property to an mat-button element for each of the supported palettes. +@mixin _theme-property($theme, $property, $hue, $variants) { + $background: map.get($theme, background); + $foreground: map.get($theme, foreground); + + @each $variant, $variant-palette in $variants { + &.mat-#{"" + $variant} { + #{$property}: mat.m2-get-color-from-palette($variant-palette, $hue); + &.mat-mdc-button-disabled { + $palette: if($property == 'color', $foreground, $background); + #{$property}: mat.m2-get-color-from-palette($palette, disabled-button); + } + } + } +} + +@mixin color($config-or-theme, $variants) { + $config: mat.m2-get-color-config($config-or-theme); + $foreground: map.get($config, foreground); + $background: map.get($config, background); + + .mat-icon:not(:disabled) { + @include _theme-property($config, 'color', text, $variants); + } + + .mdc-button:not(:disabled), + .mat-mdc-icon-button:not(:disabled), + .mat-mdc-stroked-button:not(:disabled) { + @include _theme-property($config, 'color', text, $variants); + @include _focus-overlay-color($config, $variants); + } + + .mat-mdc-flat-button:not(:disabled), + .mat-mdc-raised-button:not(:disabled), + .mat-mdc-unelevated-button:not(:disabled), + .mat-mdc-fab:not(:disabled), + .mat-mdc-mini-fab:not(:disabled) { + @include _theme-property($config, 'color', default-contrast, $variants); + @include _theme-property($config, 'background-color', default, $variants); + @include _ripple-color($config, default-contrast, $_ripple-opacity, $variants); + } +} diff --git a/src/styles/components/utils/_variants.scss b/src/styles/components/utils/_variants.scss new file mode 100644 index 0000000..a648e4a --- /dev/null +++ b/src/styles/components/utils/_variants.scss @@ -0,0 +1,19 @@ +@use 'sass:meta'; +@use '@angular/material' as mat; + +@mixin _progress-bar-color($config-or-theme, $variants) { + $config: mat.m2-get-color-config($config-or-theme); + @each $variant, $variant-palette in $variants { + &.mat-#{"" + $variant} { + #{--mdc-linear-progress-active-indicator-color}: mat.m2-get-color-from-palette($variant-palette); + #{--mdc-linear-progress-track-color}: mat.m2-get-color-from-palette($variant-palette, 500, 0.25); + } + } +} + +@mixin color($config-or-theme, $variants) { + $config: mat.m2-get-color-config($config-or-theme); + .mat-mdc-progress-bar { + @include _progress-bar-color($config, $variants); + } +} diff --git a/src/styles/fonts/icomoon.eot b/src/styles/fonts/icomoon.eot index b7b8e15..34516d3 100644 Binary files a/src/styles/fonts/icomoon.eot and b/src/styles/fonts/icomoon.eot differ diff --git a/src/styles/fonts/icomoon.svg b/src/styles/fonts/icomoon.svg index e76128b..0d2ae12 100644 --- a/src/styles/fonts/icomoon.svg +++ b/src/styles/fonts/icomoon.svg @@ -8,54 +8,60 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/styles/fonts/icomoon.ttf b/src/styles/fonts/icomoon.ttf index 0b39fe9..20ea669 100644 Binary files a/src/styles/fonts/icomoon.ttf and b/src/styles/fonts/icomoon.ttf differ diff --git a/src/styles/fonts/icomoon.woff b/src/styles/fonts/icomoon.woff index 74fa250..619940f 100644 Binary files a/src/styles/fonts/icomoon.woff and b/src/styles/fonts/icomoon.woff differ diff --git a/src/styles/responsive.scss b/src/styles/responsive.scss new file mode 100755 index 0000000..a89aa6e --- /dev/null +++ b/src/styles/responsive.scss @@ -0,0 +1,93 @@ +/* +Template Name: Material Ad Astra +Author: UnEspace +Email: rampeur@gmail.com +File: scss +*/ + +/*********************************** +* CFor Laptop & above all (1650px) * +***********************************/ + +@media (min-width: 1650px) { + .main-container.boxed { + max-width: 1920px; + margin: 0 auto; + } +} + +/********************************** +* For Laptop & above all (1370px) * +**********************************/ + +@media (max-width: 1600px) { + .main-container.boxed { + max-width: 1300px; + margin: 0 auto; + } +} + +/************************************* +* Small Desktop & above all (1024px) * +*************************************/ + +@media (min-width: 1024px) { + .card-group { + padding: 0 15px; + display: flex; + flex-flow: row wrap; + .mat-card { + margin: 15px 0px; + flex: 1 0 0%; + border-left: 1px solid $border; + &:first-child { + border: 0px; + } + } + } +} + +@media (max-width: 1023px) { + .card-group { + margin: 15px 0; + .mat-card { + margin: 0 15px; + border-top: 1px solid $border; + &:first-child { + border: 0px; + } + } + } +} + +/************************** +* Ipad & above all(768px) * +**************************/ + +@media (min-width: 768px) { + .navbar-header { + width: auto; + .navbar-brand { + padding-top: 0px; + } + } +} + +/****************************** +* Phone and below ipad(767px) * +******************************/ + +@media (max-width: 767px) { + .navbar-header { + width: 210px; + } + .mat-toolbar-single-row { + height: 64px !important; + } + .d-flex { + display: block; + } + .no-block { + display: flex; + } +} diff --git a/src/styles/styles.scss b/src/styles/styles.scss index d94f9c1..2d16db8 100644 --- a/src/styles/styles.scss +++ b/src/styles/styles.scss @@ -1,118 +1,199 @@ -$success: #7952b3; +/* +Template Name: Material Ad Astra +Author: UnEspace +Email: rampeur@gmail.com +File: scss +*/ +@use 'sass:color'; +@use 'sass:map'; +@use './components'; +@use '@angular/material' as mat; -@import "bootstrap/scss/bootstrap.scss"; +/* Bootstrap */ +// Functions first +@import "bootstrap/scss/functions"; -$dark-blue: #141d5e; -/*#171f50;*/ -$dark-grey: #222222; -$gold: #d7c067; -$orange: #ff8300; -$time-grey: #b7b2aa; -$time-grey-dark: #474747; -$dark-grey: #222222; +// Variable overrides second +@import 'variable'; +@import 'palettes'; -body { - margin: 0; -} -#__next { - display: flex !important; - height: 100% !important; -} +// Required Bootstrap imports +@import "bootstrap/scss/variables"; +//@import "bootstrap/scss/variables-dark"; +@import "bootstrap/scss/maps"; +@import "bootstrap/scss/mixins"; +@import "bootstrap/scss/utilities"; -.bg-darker { - background-color: $dark-grey !important; -} -.bg-dark-blue { - --bs-bg-opacity: 1; - --dark-blue: 20, 29, 94; - background-color: rgba(var(--dark-blue), var(--bs-bg-opacity)) !important; - color: var(--bs-gray-400) !important; - &.gold h5 { - color: $gold; - } - a { - color: var(--bs-gray-400) !important; - } -} +// Layout & components +@import "bootstrap/scss/root"; +@import "bootstrap/scss/reboot"; +@import "bootstrap/scss/type"; +@import "bootstrap/scss/containers"; +@import "bootstrap/scss/grid"; +//@import "bootstrap/scss/tables"; +@import "bootstrap/scss/transitions"; +@import "bootstrap/scss/pagination"; +@import "bootstrap/scss/badge"; +@import "bootstrap/scss/alert"; -.error-messages { - width: 100%; - margin-top: 0.25rem; - font-size: 0.875em; - color: var(--bs-form-invalid-color); -} +// Helpers +@import "bootstrap/scss/helpers"; -.clock { - height: 100px; - .divider { - width: 2px; - background-color: var(--bs-gray-400); - height: 60px; - top: 20px; - left: calc(50% - 1px); - } -} +// Utilities +@import "bootstrap/scss/utilities/api"; -.datelib { - color: $dark-blue; - border-bottom: 1px solid $dark-blue; - width: 328px; - opacity: 0.8; -} +@include mat.core(); -.block { - width: 24px; - color: var(--bs-gray-400); - transition: 0.4s; - &.active:before { - color: $dark-blue; - font-weight: 500; - opacity: 0.8; - } - &.second:before { - color: $orange; - } - &:not(:nth-child(n + 16)):nth-child(n + 11), - &:not(:nth-child(n + 46)):nth-child(n + 41) { - margin-right: 10px; - } - &:not(:nth-child(n + 31)):nth-child(n + 26) { - margin-right: 20px; - } - &:before { - content: attr(data-num); - position: relative; - display: block; - font-size: 16px; - width: 100%; - height: 100%; - line-height: 20px; - text-align: center; - } - &:nth-child(-n + 10):before { - content: "0" attr(data-num); - } -} +// Define the palettes for your theme using the Material Design palettes available in palette.scss +// (imported above). For each palette, you can optionally specify a default, lighter, and darker +// hue. Available color palettes: https://material.io/design/color/ -[data-bs-theme=dark] { - .clock { - .divider { - background-color: $time-grey; +//$adastra_app-primary: mat.m2-define-palette(mat.$light-green-palette); +//$adastra_app-accent: mat.m2-define-palette(mat.$blue-grey-palette, A200, A100, A400); +//$adastra_app-warn: mat.m2-define-palette(mat.$blue-palette); + +$adastra_app-primary: mat.m2-define-palette($md-custom-primary, 500); +$adastra_app-secondary: mat.m2-define-palette($md-custom-warn); +$adastra_app-accent: mat.m2-define-palette($md-custom-accent, A200, A100, A400); +//$adastra_app-warn: mat.m2-define-palette($md-custom-warn); +$adastra_app-warn: mat.m2-define-palette($md-custom-raspberry, 400); +$adastra_app-danger: mat.m2-define-palette($md-custom-red, 700); +$adastra_app-success: mat.m2-define-palette($md-custom-green); +$adastra_app-info: mat.m2-define-palette($md-custom-blue); +$adastra_app-warning: mat.m2-define-palette($md-custom-orange, 700); +$adastra_app-blue: mat.m2-define-palette($md-custom-blue, 700); +$adastra_app-red: mat.m2-define-palette($md-custom-red); +$adastra_app-green: mat.m2-define-palette($md-custom-green, 400); + +$adastra_app-turquoise: mat.m2-define-palette($md-custom-turquoise); +$adastra_app-cyan: mat.m2-define-palette($md-custom-cyan); +$adastra_app-navy: mat.m2-define-palette($md-custom-navy); +$adastra_app-purple: mat.m2-define-palette($md-custom-purple); +$adastra_app-raspberry: mat.m2-define-palette($md-custom-raspberry); +$adastra_app-orange: mat.m2-define-palette($md-custom-orange); +$adastra_app-yellow: mat.m2-define-palette($md-custom-yellow); +$adastra_app-teal: mat.m2-define-palette($md-custom-teal); +$adastra_app-magenta: mat.m2-define-palette($md-custom-magenta); +$adastra_app-pink: mat.m2-define-palette($md-custom-pink); +$adastra_app-megna: mat.m2-define-palette($md-custom-megna); +$adastra_app-purple-light: mat.m2-define-palette($md-custom-purple-light); +$adastra_app-navy-light: mat.m2-define-palette($md-custom-navy-light); +$adastra_app-grey: mat.m2-define-palette(mat.$m2-grey-palette, 400); +$adastra_app-muted: mat.m2-define-palette(mat.$m2-grey-palette, 300); + +$custom-typography: mat.m2-define-typography-config( + $font-family: 'Barlow, sans-serif', + $body-1: mat.m2-define-typography-level( + $font-family: 'Barlow, sans-serif', + $font-weight: 400, + $font-size: 14px, + $line-height: 1.42857143, + $letter-spacing: normal, + ), + $body-2: mat.m2-define-typography-level( + $font-family: 'Barlow, sans-serif', + $font-weight: 500, + $font-size: 14px, + $line-height: 22px, + $letter-spacing: normal, + ) +); + +// Create the theme object. A theme consists of configurations for individual +// theming systems such as "color" or "typography". +//$adastra_app-theme: mat.m2-define-dark-theme(( +$adastra_app-theme: mat.m2-define-light-theme(( + color: ( + primary: $adastra_app-primary, + accent: $adastra_app-accent, + warn: $adastra_app-warn, + ), + typography: $custom-typography, + density: 0 +)); + +$adastra_app-variants: ( + secondary: $adastra_app-secondary, + danger: $adastra_app-danger, + success: $adastra_app-success, + info: $adastra_app-info, + warning: $adastra_app-warning, + red: $adastra_app-red, + green: $adastra_app-green, + blue: $adastra_app-blue, + cyan: $adastra_app-cyan, + teal: $adastra_app-teal, + turquoise: $adastra_app-turquoise, + megna: $adastra_app-megna, + navy: $adastra_app-navy, + navy-light: $adastra_app-navy-light, + raspberry: $adastra_app-raspberry, + orange: $adastra_app-orange, + yellow: $adastra_app-yellow, + purple: $adastra_app-purple, + purple-light: $adastra_app-purple-light, + magenta: $adastra_app-magenta, + pink: $adastra_app-pink, + grey: $adastra_app-grey, + muted: $adastra_app-muted +); +/* +$config: mat.m2-get-color-config($adastra_app-theme); +$foreground: map.get($config, foreground); +$background: map.get($config, background); +*/ +$foreground: map.get($adastra_app-theme, foreground); +$background: map.get($adastra_app-theme, background); + +/* +@use './components'; +@include mat.core-theme($adastra_app-theme); +@include mat.button-theme($adastra_app-theme); +@include mat.badge-theme($adastra_app-theme); +@include mat.icon-theme($adastra_app-theme); +@include mat.icon-button-theme($adastra_app-theme); +@include mat.toolbar-theme($adastra_app-theme); +@include mat.card-theme($adastra_app-theme); +@include mat.table-theme($adastra_app-theme); +@include mat.sort-theme($adastra_app-theme); +@include mat.paginator-theme($adastra_app-theme); +@include mat.tabs-theme($adastra_app-theme); +@include mat.form-field-theme($adastra_app-theme); +@include mat.input-theme($adastra_app-theme); +@include mat.select-theme($adastra_app-theme); +@include mat.progress-spinner-theme($adastra_app-theme); +@include mat.dialog-theme($adastra_app-theme); +@include mat.menu-theme($adastra_app-theme); +@include mat.snack-bar-theme($adastra_app-theme); +@include components.theme($adastra_app-theme, $custom-typography, $adastra_app-variants); +*/ + +@include mat.all-component-themes($adastra_app-theme); +@include components.theme($adastra_app-theme, $custom-typography, $adastra_app-variants); + +//@import "chartist/dist/index"; + +@each $variant, $var-color in $grays { + .bg-gray-#{"" + $variant} { + --#{$prefix}-bg-opacity: 1; + background-color: RGBA(color.red($var-color), color.green($var-color), color.blue($var-color), var(--#{$prefix}bg-opacity, 1)) !important; + /* background-color: RGBA(color.channel($var-color, "red"), color.channel($var-color, "green"), color.channel($var-color, "blue"), var(--#{$prefix}bg-opacity, 1)) !important; */ } - } - .datelib { - color: $time-grey; - border-bottom: 1px solid $time-grey; - opacity: 0.5; - } - .block { - color: $time-grey-dark; - &.active:before { - color: $time-grey; - opacity: 1; +} + +@each $variant, $variant-palette in $adastra_app-variants { + .text-bg-#{"" + $variant} { + color: mat.m2-get-contrast-color-from-palette($variant-palette, 500) !important; } - &.second:before { - color: $gold; - } - } -} \ No newline at end of file +} + +@import 'spinner'; +@import 'icomoon'; +@import 'header'; +@import 'sidebar'; +@import 'tables'; +@import 'charts'; +@import 'responsive'; +@import 'app'; + +//@import "../styles/icons/material-design-iconic-font/css/materialdesignicons.min.css"; diff --git a/src/styles/tables.scss b/src/styles/tables.scss new file mode 100644 index 0000000..888b0b4 --- /dev/null +++ b/src/styles/tables.scss @@ -0,0 +1,409 @@ +/* +Template Name: Material Ad Astra +Author: UnEspace +Email: rampeur@gmail.com +File: scss +*/ + +/******************* +Table +*******************/ + +.table-responsive { + overflow: auto; + .mat-table { + min-width: 280px; + } + .mat-header-row { + .mat-header-cell { + white-space: nowrap; + } + } + .mat-cell { + white-space: nowrap; + } +} +table { + background-color:transparent; + &.table { + border-spacing: 0; + border-collapse: collapse; + margin-bottom:20px; + max-width:100%; + width:100%; + text-align: left; + td, th { + padding: 0; + } + th { + text-align:left + } + } + .mat-mdc-icon-button.mat-mdc-button-base { + --mdc-icon-button-state-layer-size: 38px; + width: var(--mdc-icon-button-state-layer-size); + height: var(--mdc-icon-button-state-layer-size); + padding: 7px; + .material-icons { + font-size: 22px; + } + .mat-icon { + height: 22px; + width: 22px; + } + } +} +caption { + padding-top:8px; + padding-bottom:8px; + color:#777; + text-align:left +} +.table>tbody>tr>td, +.table>tbody>tr>th, +.table>tfoot>tr>td, +.table>tfoot>tr>th, +.table>thead>tr>td, +.table>thead>tr>th { + padding:8px; + line-height:1.42857143; + vertical-align:top; + border-top:1px solid #ddd +} +.table>thead>tr>th { + vertical-align:bottom; + border-bottom:2px solid #ddd +} + +.table>caption+thead>tr:first-child>td, +.table>caption+thead>tr:first-child>th, +.table>colgroup+thead>tr:first-child>td, +.table>colgroup+thead>tr:first-child>th, +.table>thead:first-child>tr:first-child>td, +.table>thead:first-child>tr:first-child>th { + border-top:0 +} +.table>tbody+tbody { + border-top:2px solid #ddd +} +.table .table { + background-color:#fff +} +.table-condensed>tbody>tr>td, +.table-condensed>tbody>tr>th, +.table-condensed>tfoot>tr>td, +.table-condensed>tfoot>tr>th, +.table-condensed>thead>tr>td, +.table-condensed>thead>tr>th { + padding:5px +} +.table-bordered { + border:1px solid #ddd +} +.table-bordered>tbody>tr>td, +.table-bordered>tbody>tr>th, +.table-bordered>tfoot>tr>td, +.table-bordered>tfoot>tr>th, +.table-bordered>thead>tr>td, +.table-bordered>thead>tr>th { + border:1px solid #ddd +} +.table-bordered>thead>tr>td, +.table-bordered>thead>tr>th { + border-bottom-width:2px +} +.table-striped>tbody>tr:nth-of-type(odd) { + background-color:#f9f9f9 +} +.table-hover>tbody>tr:hover { + background-color:#f5f5f5 +} + +table col[class*=col-] { + position:static; + display:table-column; + float:none +} +table td[class*=col-], +table th[class*=col-] { + position:static; + display:table-cell; + float:none +} +.table>tbody>tr.active>td, +.table>tbody>tr.active>th, +.table>tbody>tr>td.active, +.table>tbody>tr>th.active, +.table>tfoot>tr.active>td, +.table>tfoot>tr.active>th, +.table>tfoot>tr>td.active, +.table>tfoot>tr>th.active, +.table>thead>tr.active>td, +.table>thead>tr.active>th, +.table>thead>tr>td.active, +.table>thead>tr>th.active { + background-color:#f5f5f5; +} +.table-hover>tbody>tr.active:hover>td, +.table-hover>tbody>tr.active:hover>th, +.table-hover>tbody>tr:hover>.active, +.table-hover>tbody>tr>td.active:hover, +.table-hover>tbody>tr>th.active:hover { + background-color:#e8e8e8; +} +.table>tbody>tr.success>td, +.table>tbody>tr.success>th, +.table>tbody>tr>td.success, +.table>tbody>tr>th.success, +.table>tfoot>tr.success>td, +.table>tfoot>tr.success>th, +.table>tfoot>tr>td.success, +.table>tfoot>tr>th.success, +.table>thead>tr.success>td, +.table>thead>tr.success>th, +.table>thead>tr>td.success, +.table>thead>tr>th.success { + background-color:#dff0d8; +} +.table-hover>tbody>tr.success:hover>td, +.table-hover>tbody>tr.success:hover>th, +.table-hover>tbody>tr:hover>.success, +.table-hover>tbody>tr>td.success:hover, +.table-hover>tbody>tr>th.success:hover { + background-color:#d0e9c6; +} +.table>tbody>tr.info>td, +.table>tbody>tr.info>th, +.table>tbody>tr>td.info, +.table>tbody>tr>th.info, +.table>tfoot>tr.info>td, +.table>tfoot>tr.info>th, +.table>tfoot>tr>td.info, +.table>tfoot>tr>th.info, +.table>thead>tr.info>td, +.table>thead>tr.info>th, +.table>thead>tr>td.info, +.table>thead>tr>th.info { + background-color:#d9edf7; +} +.table-hover>tbody>tr.info:hover>td, +.table-hover>tbody>tr.info:hover>th, +.table-hover>tbody>tr:hover>.info, +.table-hover>tbody>tr>td.info:hover, +.table-hover>tbody>tr>th.info:hover { + background-color:#c4e3f3; +} +.table>tbody>tr.warning>td, +.table>tbody>tr.warning>th, +.table>tbody>tr>td.warning, +.table>tbody>tr>th.warning, +.table>tfoot>tr.warning>td, +.table>tfoot>tr.warning>th, +.table>tfoot>tr>td.warning, +.table>tfoot>tr>th.warning, +.table>thead>tr.warning>td, +.table>thead>tr.warning>th, +.table>thead>tr>td.warning, +.table>thead>tr>th.warning { + background-color:#fcf8e3; +} +.table-hover>tbody>tr.warning:hover>td, +.table-hover>tbody>tr.warning:hover>th, +.table-hover>tbody>tr:hover>.warning, +.table-hover>tbody>tr>td.warning:hover, +.table-hover>tbody>tr>th.warning:hover { + background-color:#faf2cc; +} +.table>tbody>tr.danger>td, +.table>tbody>tr.danger>th, +.table>tbody>tr>td.danger, +.table>tbody>tr>th.danger, +.table>tfoot>tr.danger>td, +.table>tfoot>tr.danger>th, +.table>tfoot>tr>td.danger, +.table>tfoot>tr>th.danger, +.table>thead>tr.danger>td, +.table>thead>tr.danger>th, +.table>thead>tr>td.danger, +.table>thead>tr>th.danger { + background-color:#f2dede; +} +.table-hover>tbody>tr.danger:hover>td, +.table-hover>tbody>tr.danger:hover>th, +.table-hover>tbody>tr:hover>.danger, +.table-hover>tbody>tr>td.danger:hover, +.table-hover>tbody>tr>th.danger:hover { + background-color:#ebcccc; +} + +tr.mat-mdc-header-row.primary, +.table>thead>tr.primary { + background-color: rgba(167, 212, 196, 0.1); // #a5d492; +} +.table>tbody>tr.primary.active>td, +.table>tbody>tr.primary.active>th, +.table>tbody>tr.primary>td.active, +.table>tbody>tr.primary>th.active, +.table>tfoot>tr.primary.active>td, +.table>tfoot>tr.primary.active>th, +.table>tfoot>tr.primary>td.active, +.table>tfoot>tr.primary>th.active, +.table>thead>tr.primary.active>td, +.table>thead>tr.primary.active>th, +.table>thead>tr.primary>td.active, +.table>thead>tr.primary>th.active { + background-color: rgba(165, 212, 146, 0.2); +} +.table-hover>tbody>tr.primary.active:hover>td, +.table-hover>tbody>tr.primary.active:hover>th, +.table-hover>tbody>tr.primary:hover>.active, +.table-hover>tbody>tr.primary>td.active:hover, +.table-hover>tbody>tr.primary>th.active:hover { + background-color: rgba(165, 212, 146, 0.3); +} + +tr.mat-mdc-header-row.warn, +.table>thead>tr.warn { + background-color: rgba(151, 136, 199, 0.1); // #9788c7 +} +.table>tbody>tr.warn.active>td, +.table>tbody>tr.warn.active>th, +.table>tbody>tr.warn>td.active, +.table>tbody>tr.warn>th.active, +.table>tfoot>tr.warn.active>td, +.table>tfoot>tr.warn.active>th, +.table>tfoot>tr.warn>td.active, +.table>tfoot>tr.warn>th.active, +.table>thead>tr.warn.active>td, +.table>thead>tr.warn.active>th, +.table>thead>tr.warn>td.active, +.table>thead>tr.warn>th.active { + background-color: rgba(151, 136, 199, 0.2); +} +.table-hover>tbody>tr.warn.active:hover>td, +.table-hover>tbody>tr.warn.active:hover>th, +.table-hover>tbody>tr.warn:hover>.active, +.table-hover>tbody>tr.warn>td.active:hover, +.table-hover>tbody>tr.warn>th.active:hover { + background-color: rgba(151, 136, 199, 0.3); +} + +tr.mat-mdc-header-row.accent, +.table>thead>tr.accent { + background-color: rgba(205, 186, 152, 0.1); // #cdba98 +} +.table>tbody>tr.accent.active>td, +.table>tbody>tr.accent.active>th, +.table>tbody>tr.accent>td.active, +.table>tbody>tr.accent>th.active, +.table>tfoot>tr.accent.active>td, +.table>tfoot>tr.accent.active>th, +.table>tfoot>tr.accent>td.active, +.table>tfoot>tr.accent>th.active, +.table>thead>tr.accent.active>td, +.table>thead>tr.accent.active>th, +.table>thead>tr.accent>td.active, +.table>thead>tr.accent>th.active { + background-color: rgba(205, 186, 152, 0.2); +} +.table-hover>tbody>tr.accent.active:hover>td, +.table-hover>tbody>tr.accent.active:hover>th, +.table-hover>tbody>tr.accent:hover>.active, +.table-hover>tbody>tr.accent>td.active:hover, +.table-hover>tbody>tr.accent>th.active:hover { + background-color: rgba(205, 186, 152, 0.3); +} + +.table-responsive { + min-height:.01%; + overflow-x:auto +} +.table .mat-mdc-row { + height: auto; + color: inherit; +} +.table .mat-mdc-header-row { + height: auto; +} + +body.dark-theme { + .table.table-dark>thead>tr>th, + .table.table-dark>tbody>tr>th, + .table.table-dark>tfoot>tr>th { + background-color: rgba(0, 0, 0, 0.25); + font-weight: normal; + } + .table.table-dark>tbody>tr>td, + .table.table-dark>tbody>tr>th, + .table.table-dark>tfoot>tr>td, + .table.table-dark>tfoot>tr>th, + .table.table-dark>thead>tr>td, + .table.table-dark>thead>tr>th { + border-top:1px solid rgba(221, 221, 221, 0.3); + } + .table.table-dark>thead>tr>th { + border-bottom:2px solid rgba(221, 221, 221, 0.3); + padding-top: 0.7rem; + } + .table.table-dark>tfoot>tr>th { + border-top:2px solid rgba(221, 221, 221, 0.3); + } + .table.table-dark>tbody+tbody { + border-top:2px solid rgb(221, 221, 221, 0.3); + } + .table-striped.table-dark>tbody>tr:nth-of-type(odd) { + background-color:rgba(255, 255, 255, 0.03); + } + .table-striped.table-dark>tbody>tr:nth-of-type(even) { + background-color:rgba(255, 255, 255, 0.01); + } + .table-hover.table-dark>tbody>tr:hover { + background-color:rgba(0, 0, 0, 0.02); + } +} + +@media screen and (max-width:767px) { + .table-responsive { + width:100%; + margin-bottom:15px; + overflow-y:hidden; + -ms-overflow-style:-ms-autohiding-scrollbar; + border:1px solid #ddd + } + .table-responsive>.table { + margin-bottom:0 + } + .table-responsive>.table>tbody>tr>td, + .table-responsive>.table>tbody>tr>th, + .table-responsive>.table>tfoot>tr>td, + .table-responsive>.table>tfoot>tr>th, + .table-responsive>.table>thead>tr>td, + .table-responsive>.table>thead>tr>th { + white-space:nowrap + } + .table-responsive>.table-bordered { + border:0 + } + .table-responsive>.table-bordered>tbody>tr>td:first-child, + .table-responsive>.table-bordered>tbody>tr>th:first-child, + .table-responsive>.table-bordered>tfoot>tr>td:first-child, + .table-responsive>.table-bordered>tfoot>tr>th:first-child, + .table-responsive>.table-bordered>thead>tr>td:first-child, + .table-responsive>.table-bordered>thead>tr>th:first-child { + border-left:0 + } + .table-responsive>.table-bordered>tbody>tr>td:last-child, + .table-responsive>.table-bordered>tbody>tr>th:last-child, + .table-responsive>.table-bordered>tfoot>tr>td:last-child, + .table-responsive>.table-bordered>tfoot>tr>th:last-child, + .table-responsive>.table-bordered>thead>tr>td:last-child, + .table-responsive>.table-bordered>thead>tr>th:last-child { + border-right:0 + } + .table-responsive>.table-bordered>tbody>tr:last-child>td, + .table-responsive>.table-bordered>tbody>tr:last-child>th, + .table-responsive>.table-bordered>tfoot>tr:last-child>td, + .table-responsive>.table-bordered>tfoot>tr:last-child>th { + border-bottom:0 + } +} \ No newline at end of file diff --git a/src/styles/variable.scss b/src/styles/variable.scss new file mode 100755 index 0000000..bba8954 --- /dev/null +++ b/src/styles/variable.scss @@ -0,0 +1,269 @@ +/* +Template Name: Material Ad Astra +Author: UnEspace +Email: rampeur@gmail.com +File: scss +*/ + +@use '@angular/material' as mat; +@use 'palettes' as palettes; + +//@import 'palettes'; + +$bodyfont: 'Barlow', "Helvetica Neue", sans-serif; +$headingfont: 'Barlow', "Helvetica Neue", sans-serif; +$font-family-monospace: 'Inconsolata', SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace !default; +$font-size-base: 0.875rem; +$badge-font-size: .76rem; +$badge-font-weight: 600; + +$user-img-size: 54px; +$user-img-height: 158px; +$sidenav-width: 237px; +$sidenav-height: 35px; + +/* Theme Colors */ +$primary: mat.m2-get-color-from-palette(palettes.$md-custom-primary, 700); // #1c398e; +$accent: mat.m2-get-color-from-palette(palettes.$md-custom-accent, 700); // #d9caae; +$warn: mat.m2-get-color-from-palette(palettes.$md-custom-raspberry, 400); // #c0356f; +//$warn: mat.m2-get-color-from-palette(palettes.$md-custom-warn, 600); // #9788c7; +$secondary: mat.m2-get-color-from-palette(palettes.$md-custom-warn, 600); // #9788c7; +$headingtext: mat.m2-get-color-from-palette(palettes.$md-custom-primary, 500); // #2c4aa3; +$bodytext: mat.m2-get-color-from-palette(palettes.$md-custom-primary, 100); // #c0c7e3; +//$sidebar: mat.m2-get-color-from-palette(palettes.$md-custom-primary, 700); // #1c398e; +$sidebar: mat.m2-get-color-from-palette(palettes.$md-custom-primary, 900); // #4f64af; +$sidebar-light: #d9d9d9; +$sidebar-selected: mat.m2-get-color-from-palette(palettes.$md-custom-primary, 500); // #2c4aa3; +$sidebar-footer: mat.m2-get-color-from-palette(palettes.$md-custom-primary, 500); // #2c4aa3; +$sidebar-text: mat.m2-get-color-from-palette(palettes.$md-custom-primary, 500); // #2c4aa3 +$sidebar-icons: mat.m2-get-color-from-palette(palettes.$md-custom-primary, 500); // #2c4aa3 +$sidenav-content: #1c1c1c; +$armygreen: #4b5320; +$odbgreen: #485b54; +$error: #b95252; //#b85c5c; + +/* Bootstrap Colors */ +$danger: mat.m2-get-color-from-palette(palettes.$md-custom-red, 700); // #f15050 +$success: mat.m2-get-color-from-palette(palettes.$md-custom-green, 500); // #16d57c +$warning: mat.m2-get-color-from-palette(palettes.$md-custom-orange, 700); // #ffb035 +$info: mat.m2-get-color-from-palette(palettes.$md-custom-blue, 500); // #0dcaf0 +$inverse: mat.m2-get-color-from-palette(palettes.$md-custom-raspberry, 400); // #c0356f + +/* Dark Colors */ +$danger-dark: shade-color($danger, 30%) !default; // #e6294b +$success-dark: shade-color($success, 30%) !default; // #1eacbe +$warning-dark: shade-color($warning, 30%) !default; // #e9ab2e +$info-dark: shade-color($info, 30%) !default; // #028ee1 +$inverse-dark: shade-color($inverse, 30%) !default; // #232a37 +$primary-dark: #6352ce; +$dark-transparent: rgba(0, 0, 0, 0.05); + +/* Light Colors */ +$light-danger: tint-color($danger, 86%) !default; // #f9e7eb; +$light-success: tint-color($success, 86%) !default; // #e8fdf8; +$light-warning: tint-color($warning, 86%) !default; // #fff8ec; +$light-info: tint-color($info, 86%) !default; // #e3f3fd; +$light-inverse: tint-color($inverse, 86%) !default; // #f6f6f6; + + +// scss-docs-start gray-color-variables +$white: #fff !default; +$gray-100: #f8f9fa !default; +$gray-200: #e9ecef !default; +$gray-300: #dee2e6 !default; +$gray-400: #ced4da !default; +$gray-500: #adb5bd !default; +$gray-600: #6c757d !default; +$gray-700: #495057 !default; +$gray-800: #343a40 !default; +$gray-900: #212529 !default; +$black: #000 !default; +// scss-docs-end gray-color-variables + +$empty: $gray-600 !default; // #6c757d; +$muted: $gray-500 !default; // #adb5bd; +$dark: $gray-700 !default; // #495057; +$light: $gray-200 !default; // #e9ecef; +$extra-light: $gray-100 !default; // #f8f9fa; +$grey: $gray-500 !default; // #adb5bd; + +// fusv-disable +// scss-docs-start gray-colors-map +$grays: ( + "100": $gray-100, + "200": $gray-200, + "300": $gray-300, + "400": $gray-400, + "500": $gray-500, + "600": $gray-600, + "700": $gray-700, + "800": $gray-800, + "900": $gray-900 +) !default; +// scss-docs-end gray-colors-map +// fusv-enable + +// scss-docs-start color-variables +$blue-light: #20b6fc !default; // #20b6fc +$indigo: #6610f2 !default; // #6610f2 +$blue: mat.m2-get-color-from-palette(palettes.$md-custom-blue, 700) !default; // #1976d2 +$purple: mat.m2-get-color-from-palette(palettes.$md-custom-purple, 500) !default; // #7460ee +$purple-light: mat.m2-get-color-from-palette(palettes.$md-custom-purple-light, 500) !default; // #8a65e0 +$pink: mat.m2-get-color-from-palette(palettes.$md-custom-pink, 500) !default; // #ed5094 +$magenta: mat.m2-get-color-from-palette(palettes.$md-custom-magenta, 500) !default; // #fd18f3 +$raspberry: mat.m2-get-color-from-palette(palettes.$md-custom-raspberry, 500) !default; // #b51156 +$red: mat.m2-get-color-from-palette(palettes.$md-custom-red, 500) !default; // #f15050 +$orange: mat.m2-get-color-from-palette(palettes.$md-custom-orange, 500) !default; // #ff9900 +$yellow: mat.m2-get-color-from-palette(palettes.$md-custom-yellow, 500) !default; // #ffe205 +$megna: mat.m2-get-color-from-palette(palettes.$md-custom-megna, 500) !default; // #00897b +$green: mat.m2-get-color-from-palette(palettes.$md-custom-green, 400) !default; // #4cae4c +$teal: mat.m2-get-color-from-palette(palettes.$md-custom-teal, 500) !default; // #5dcc89 +$turquoise: mat.m2-get-color-from-palette(palettes.$md-custom-turquoise, 500) !default; // #02bfab +$cyan: mat.m2-get-color-from-palette(palettes.$md-custom-cyan, 500) !default; // #65dae0 +$navy: mat.m2-get-color-from-palette(palettes.$md-custom-navy, 500) !default; // #17466f +$navy-light: mat.m2-get-color-from-palette(palettes.$md-custom-navy-light, 500) !default; // #337ab7 +// scss-docs-end color-variables + +// scss-docs-start colors-map +$colors: ( + "blue": $blue, + "blue-light": $blue-light, + "indigo": $indigo, + "purple": $purple, + "purple-light": $purple-light, + "pink": $pink, + "magenta": $magenta, + "raspberry": $raspberry, + "red": $red, + "orange": $orange, + "yellow": $yellow, + "megna": $megna, + "green": $green, + "teal": $teal, + "turquoise": $turquoise, + "cyan": $cyan, + "navy": $navy, + "navy-light": $navy-light, + "black": $black, + "white": $white, + "gray": $gray-600, + "gray-dark": $gray-800, + "muted": $muted +) !default; +// scss-docs-end colors-map + +// scss-docs-start theme-colors-map +$theme-colors: ( + "primary": $primary, + "accent": $accent, + "warn": $warn, + "secondary": $secondary, + "muted": $muted, + "success": $success, + "info": $info, + "warning": $warning, + "danger": $danger, + "light": $light, + "dark": $dark, + "white": $white, + "red": $red, + "orange": $orange, + "yellow": $yellow, + "megna": $megna, + "green": $green, + "teal": $teal, + "turquoise": $turquoise, + "cyan": $cyan, + "blue": $blue, + "navy": $navy, + "navy-light": $navy-light, + "pink": $pink, + "magenta": $magenta, + "purple": $purple, + "purple-light": $purple-light, + "raspberry": $raspberry, + "grey": $grey +) !default; +// scss-docs-end theme-colors-map + +/* + +// scss-docs-start theme-text-variables +$primary-text-emphasis: shade-color($primary, 60%) !default; +$secondary-text-emphasis: shade-color($secondary, 60%) !default; +$success-text-emphasis: shade-color($success, 60%) !default; +$info-text-emphasis: shade-color($info, 60%) !default; +$warning-text-emphasis: shade-color($warning, 60%) !default; +$danger-text-emphasis: shade-color($danger, 60%) !default; +$light-text-emphasis: $gray-700 !default; +$dark-text-emphasis: $gray-700 !default; +// scss-docs-end theme-text-variables + +// scss-docs-start theme-bg-subtle-variables +$primary-bg-subtle: tint-color($primary, 80%) !default; +$secondary-bg-subtle: tint-color($secondary, 80%) !default; +$success-bg-subtle: tint-color($success, 80%) !default; +$info-bg-subtle: tint-color($info, 80%) !default; +$warning-bg-subtle: tint-color($warning, 80%) !default; +$danger-bg-subtle: tint-color($danger, 80%) !default; +$light-bg-subtle: mix($gray-100, $white) !default; +$dark-bg-subtle: $gray-400 !default; +// scss-docs-end theme-bg-subtle-variables + +// scss-docs-start theme-border-subtle-variables +$primary-border-subtle: tint-color($primary, 60%) !default; +$secondary-border-subtle: tint-color($secondary, 60%) !default; +$success-border-subtle: tint-color($success, 60%) !default; +$info-border-subtle: tint-color($info, 60%) !default; +$warning-border-subtle: tint-color($warning, 60%) !default; +$danger-border-subtle: tint-color($danger, 60%) !default; +$light-border-subtle: $gray-200 !default; +$dark-border-subtle: $gray-500 !default; +// scss-docs-end theme-border-subtle-variables + +*/ + +/*Extra Variable*/ +$rgt: right; +$lft: left; +$border: rgba(120, 130, 140, 0.13); +$table-border: #f3f1f1; +$card-brd: #d7dfe3; +$dark-text: #848a96; +$radius: 4px; +$form-brd: #d9d9d9; +$font-16: 16px; + +/* Chart */ +$chart-color-a: #35a2eb; +$chart-color-b: #ff6384; +$chart-color-c: #4bc0c0; +$chart-color-d: #ff9f40; +$chart-color-e: #9966ff; +$chart-color-f: #ffcd56; +$chart-color-g: #c9cbcf; +$chart-color-h: #5dcc89; +$chart-color-i: #b51156; +$chart-color-j: #ffe205; +$chart-color-k: #bf65e0; +$chart-color-l: #4cae4c; +$chart-color-m: #ed5094; +$chart-color-n: #337ab7; +$chart-color-o: #fd18f3; +$chart-color-p: #d61f1f; +$chart-color-q: #00897b; +$chart-color-r: #99abb4; +$chart-color-s: #cdba98; +$chart-color-t: #65e0b8; +$chart-color-u: #02bfab; +$chart-color-v: #65dae0; +$chart-color-w: #a1c7a1; +$chart-color-x: #d9caae; +$chart-color-y: #9788c7; +$chart-color-z: #d4ce70; + +$vector-color-white: #ffffff; +$vector-color-black: #000000; +$vector-color-navy: #021754; +$vector-color-grey: #b7b7b7; +$vector-color-gold: #ffc201; diff --git a/tsconfig.app.json b/tsconfig.app.json new file mode 100644 index 0000000..374cc9d --- /dev/null +++ b/tsconfig.app.json @@ -0,0 +1,14 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/app", + "types": [] + }, + "files": [ + "src/main.ts" + ], + "include": [ + "src/**/*.d.ts" + ] +} diff --git a/tsconfig.json b/tsconfig.json index 057906e..ee442f1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,41 +1,62 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ { + "compileOnSave": false, "compilerOptions": { - "target": "ES2017", - "lib": [ - "dom", - "dom.iterable", - "esnext" - ], - "allowJs": true, - "skipLibCheck": true, - "strict": true, - "forceConsistentCasingInFileNames": true, - "noEmit": true, - "esModuleInterop": true, - "module": "esnext", - "moduleResolution": "bundler", - "resolveJsonModule": true, - "isolatedModules": true, - "jsx": "preserve", - "incremental": true, + "baseUrl": "./", + "rootDir": "./", "paths": { - "@/*": [ - "./src/*" - ] + "@app/*": ["src/app/*"], + "@components/*": ["src/app/components/*"], + "@components": ["src/app/components"], + "@core/*": ["src/app/core/*"], + "@models": ["src/app/core/models"], + "@models/*": ["src/app/core/models/*"], + "@services": ["src/app/core/services"], + "@services/*": ["src/app/core/services/*"], + "@guards": ["src/app/core/guards"], + "@guards/*": ["src/app/core/guards/*"], + "@interceptors": ["src/app/core/interceptors"], + "@interceptors/*": ["src/app/core/interceptors/*"], + "@resolvers": ["src/app/core/resolvers"], + "@resolvers/*": ["src/app/core/resolvers/*"], + "@viewmodels": ["src/app/core/viewmodels"], + "@viewmodels/*": ["src/app/core/viewmodels/*"], + "@interfaces": ["src/app/core/interfaces"], + "@interfaces/*": ["src/app/core/interfaces/*"], + "@constants": ["src/app/core/constants"], + "@constants/*": ["src/app/core/constants/*"], + "@environments/*": ["src/environments/*"], + "@data/*": ["src/files-data/*"], + "@assets/*": ["src/assets/*"], + "@styles/*": ["src/styles/*"] }, - "plugins": [ - { - "name": "next" - } - ] + "outDir": "./dist/out-tsc", + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "sourceMap": true, + "declaration": false, + "experimentalDecorators": true, + "moduleResolution": "node", + "importHelpers": true, + "target": "ES2022", + "module": "ES2022", + "useDefineForClassFields": false, + "lib": [ + "ES2022", + "dom" + ], + "skipLibCheck": true, + "esModuleInterop": true, + "resolveJsonModule": true }, - "include": [ - "**/*.ts", - "**/*.tsx", - "next-env.d.ts", - ".next/types/**/*.ts" - ], - "exclude": [ - "node_modules" - ] + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } } diff --git a/tsconfig.spec.json b/tsconfig.spec.json new file mode 100644 index 0000000..be7e9da --- /dev/null +++ b/tsconfig.spec.json @@ -0,0 +1,14 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/spec", + "types": [ + "jasmine" + ] + }, + "include": [ + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +}