diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index 21742c08..00000000 --- a/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -conductorscripts/**/*.sh text eol=lf diff --git a/.gitignore b/.gitignore index 496ee2ca..d67f5419 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,5 @@ -.DS_Store \ No newline at end of file +.env +.DS_Store +node_modules +__MACOSX +dist \ No newline at end of file diff --git a/Makefile b/Makefile index 71c8bd46..40e2df76 100644 --- a/Makefile +++ b/Makefile @@ -1,20 +1,110 @@ -platform: - PROFILE=platform docker compose --profile platform up --attach conductor +help: + @echo "================ Prelude Makefile Commands ================" + @echo "" + @echo "Conductor Development Environments:" + @echo " phase1 - Start Phase 1 development environment" + @echo " phase2 - Start Phase 2 development environment" + @echo " phase3 - Start Phase 3 development environment" + @echo " stage-dev - Start Stage development environment" + @echo "" + @echo "Conductor Deployment:" + @echo " pre-check - Run pre-deployment checks" + @echo " deploy-stage - Deploy the stage application (with pre-checks)" + @echo "" + @echo "Conductor Data Loading and Management:" + @echo " clean-data - Remove all documents from Elasticsearch (preserves index structure)" + @echo "" + @echo "Conductor System Management:" + @echo " down - Gracefully shutdown all containers" + @echo " reset - DANGER: Remove all containers and volumes (DATA LOSS)" + @echo "" + @echo "Composer Configuration Generation:" + @echo " generate-phase-one-configs - Generate Phase One Configurations" + @echo " generate-phase-two-configs - Generate Phase Two Configurations" + @echo " generate-phase-three-configs - Generate Phase Three Configurations" + @echo "" + @echo "General Usage:" + @echo " make help - Show this help message" + @echo " make - Run a specific command" + @echo "" + @echo "===============================================================" -stageDev: - PROFILE=stageDev docker compose --profile stageDev up --attach conductor +# ================================================================================== # +# Conductor: # +# ================================================================================== # -arrangerDev: - PROFILE=arrangerDev docker compose --profile arrangerDev up --attach conductor +# Run pre-deployment checks +phase0: + @echo "Running Pre-deployment checks..." + chmod +x ./apps/conductor/scripts/deployments/phase0.sh + ./apps/conductor/scripts/deployments/phase0.sh -maestroDev: - PROFILE=maestroDev docker compose --profile maestroDev up --attach conductor +# Start Phase One development environment +phase1: + @echo "Starting Phase 1 development environment..." + PROFILE=phase1 docker compose -f ./docker-compose.yml --profile phase1 up --attach conductor -songDev: - PROFILE=songDev docker compose --profile songDev up --attach conductor +# Start Phase Two development environment +phase2: + @echo "Starting Phase 2 development environment..." + PROFILE=phase2 docker compose -f ./docker-compose.yml --profile phase2 up --attach conductor -scoreDev: - PROFILE=scoreDev docker compose --profile scoreDev up --attach conductor +# Start Phase Three development environment +phase3: + @echo "Starting Phase 3 development environment..." + PROFILE=phase3 docker compose -f ./docker-compose.yml --profile phase3 up --attach conductor +# Start Stage development environment +stage-dev: + @echo "Starting Stage development environment..." + PROFILE=stageDev docker compose -f ./docker-compose.yml --profile stageDev up --attach conductor + + +# Deploy the stage application (with pre-checks) +deploy-stage: pre-check + @echo "Deploying stage application..." + docker build -t stageimage:1.0 . + +# Gracefully shutdown all containers while preserving volumes down: - PROFILE=platform docker compose --profile platform down + @echo "Shutting down all running containers..." + PROFILE=default docker compose -f ./docker-compose.yml --profile default down + +# Shutdown all containers and remove all volumes (WARNING: Deletes all data) +reset: + @echo "\033[1;33mWarning:\033[0m This will remove all containers AND their volumes. Data will be lost." + @read -p "Are you sure you want to continue? [y/N] " confirm; \ + if [ "$$confirm" = "y" ] || [ "$$confirm" = "Y" ]; then \ + PROFILE=default docker compose -f ./docker-compose.yml --profile default down -v ; \ + else \ + echo "Operation cancelled"; \ + fi + +# Remove all documents from Elasticsearch (preserves index structure) +clean-data: + @echo "\033[1;33mWarning:\033[0m This will delete ALL data from the Elasticsearch index." + @read -p "Are you sure you want to continue? [y/N] " confirm; \ + if [ "$$confirm" = "y" ] || [ "$$confirm" = "Y" ]; then \ + PROFILE=clean docker compose -f ./docker-compose.yml --profile clean up --attach conductor; \ + else \ + echo "\033[1;36mOperation cancelled\033[0m"; \ + fi + +# ================================================================================== # +# Composer: # +# ================================================================================== # + +# Generate Phase One Configurations +generate-phase-one-configs: + @echo "Generating Phase One Configurations..." + PROFILE=generatePhaseOneConfigs docker compose -f ./docker-composer.yml --profile generatePhaseOneConfigs up --attach composer + +# Generate Phase Two Configurations +generate-phase-two-configs: + @echo "Generating Phase Two Configurations..." + PROFILE=generatePhaseTwoConfigs docker compose -f ./docker-composer.yml --profile generatePhaseTwoConfigs up --attach composer + +# Generate Phase Three Configurations +generate-phase-three-configs: + @echo "Generating Phase Three Configurations..." + PROFILE=generatePhaseThreeConfigs docker compose -f ./docker-composer.yml --profile generatePhaseThreeConfigs up --attach composer \ No newline at end of file diff --git a/README.md b/README.md index 8d828dc8..b1d3e8ff 100644 --- a/README.md +++ b/README.md @@ -1,69 +1,189 @@ -# Conductor +# Prelude - Version 1.0.0-beta -Conductor is a flexible Docker Compose setup that simplifies the process of spinning up Overture development and deployment configurations using Docker profiles and extensible scripting events. +Prelude is a toolkit designed for the planning and development stages of Overture data platform implementation. It helps teams incrementally build and validate platform requirements, enabling them to: -## Key Features +- Systematically verify requirements and user workflows +- Minimize technical overhead during planning and prototyping +- Create a comprehensive blueprint for production deployment -- **Profile-based Deployments**: Uses Docker profiles to manage different environment setups. -- **Conductor-driven Execution**: The Conductor service executes ordered scripts based on the `PROFILE` environment variable. +> [!IMPORTANT] +> Prelude is not intended for production environments. It serves as a preparatory tool to ensure successful production deployments. We are actively enhancing resources to support teams transitioning from Prelude to production. + +We welcome feedback and suggestions—please share them via [our ideas forum](https://github.com/overture-stack/docs/discussions/new?category=ideas). + +## Development Phases + +Prelude is structured into four incremental phases: + +![Development Phases](apps/stage/public/docs/images/DevelopmentPhases.png "Prelude Development Phases") + +| **Phase** | **Focus** | **Components** | +| --------------------------------------- | ----------------------------------- | --------------------------------- | +| **Phase 1:** Data Exploration & Theming | Data visualization in the portal | Elasticsearch, Arranger, Stage | +| **Phase 2:** Tabular Data Management | Backend data storage and validation | Lyric, Lectern, Postgres, MongoDB | +| **Phase 3:** File Management | File storage and metadata tracking | Song, Score, Object Storage | +| **_Phase 4:_** Identity & Access | Security and user management | Keycloak integration | + +**Phase 4** is not included in Prelude v1 and will be implemented in a future release. + +## Supplemental Tools + +### Composer + +**Composer** transforms your data into base Overture configurations, generating: + +- **Elasticsearch Mappings** – Defines the structure and indexing settings for your data +- **Arranger UI Configs** – Configures the user interface for data exploration and visualization +- **Lectern Dictionary Schema** – Creates data dictionaries and schemas for tabular data +- **Song Schema** – Generates schema configurations for file metadata + +These configurations provide a foundation for Overture components, ensuring consistent data representation and interoperability. + +### Conductor + +**Conductor** streamlines interactions with Overture APIs, offering: + +- **Elasticsearch Management** + + - Transform and load CSV data into Elasticsearch + +- **Metadata and Schema Handling** + + - Validate and submit schema dictionaries to Lectern + - Register Lectern dictionaries with Lyric + +- **Data Management** + + - Upload tabular data to Lyric + - Create Song studies + - Update Song with analysis schemas + - Upload and publish file data with Song and Score ## Getting Started -**1. Clone the repo's `main` branch** +### Prerequisites -``` -git clone -b concerto https://github.com/overture-stack/composer.git && cd composer +- **Docker Desktop 4.39.0+** with: + - 8-core CPU minimum + - 8 GB memory + - 2 GB swap + - 64 GB virtual disk +- **Node.js 18+ and npm 9+** + +### First Steps + +Start by running the pre-deployment check to ensure your environment is properly configured: + +```bash +make phase0 ``` -**2. Run one of the following commands to spin up different environments:** +This command will verify your system meets all requirements and provide guidance on any necessary adjustments. -| Environment | Unix/macOS | Windows | -|-------------|------------|---------| -| Overture Platform | `make platform` | `make.bat platform` | -| Stage Dev | `make stageDev` | `make.bat stageDev` | -| Arranger Dev | `make arrangerDev` | `make.bat arrangerDev` | -| Maestro Dev | `make maestroDev` | `make.bat maestroDev` | -| Song Dev | `make songDev` | `make.bat songDev` | -| Score Dev | `make scoreDev` | `make.bat scoreDev` | +### Deployment Options -Each command spins up complementary services for the specified development environment. +The portal can be deployed in phases, with each phase adding additional functionality: -## Repository Structure +```bash +# Deploy Phase 1: Data Exploration & Theming +make phase1 +# Deploy Phase 2: Tabular Data Management +make phase2 + +# Deploy Phase 3: File Management +make phase3 + +# Run Stage in development mode +make stage-dev + +# Reset all containers and volumes +make reset ``` -. -├── conductorScripts/ -│ ├── deployments -│ └── services -├── configurationFiles/ -│ ├── arrangerConfigs -│ ├── elasticsearchConfigs -│ └── keycloakConfigs -├── guideMaterials -├── persistentStorage/ -│ ├── data-keycloak-db -│ ├── data-minio -│ └── data-song-db -├── Makefile -└── make.bat -``` -- **`conductorScripts/`** Contains scripts for orchestrating the deployment process. - - `deployments/`: Scripts that execute service scripts sequentially based on the deployment configuration. These also include custom post-deployment logs with essential next steps for the deployment scenario. - - `services/`: Modular scripts for individual service setup tasks. Each file is named according to its purpose, with inline comments documenting the code. +### Accessing the Portal + +Once running, access the documentation portal at: [http://localhost:3000](http://localhost:3000) + +## Documentation Structure + +The documentation is organized into phases matching the Prelude development workflow: -- **`configurationFiles/`** Stores all required configuration files, including: - - `arrangerConfigs/`: Configuration files specific to Arranger. - - `elasticsearchConfigs/`: Configuration files for Elasticsearch, encompassing indexing mappings and documents for seeding data. - - `keycloakConfigs/`: Configuration files for Keycloak, including preconfigured realm files and Overture API key provider details. +- **Introduction**: Overview of the Prelude toolkit and its components +- **Phase One**: Data Exploration & Theming (Elasticsearch, Arranger, Stage) +- **Phase Two**: Tabular Data Management (Lyric, Lectern, Postgres, MongoDB) +- **Phase Three**: File Management (Song, Score, Object Storage) +- **Phase Four**: Identity & Access (Coming in future release) +- **Support**: How to get help and contribute -- **`guideMaterials/`** Supplementary folders and files for use with the [Overture guides](https://www.overture.bio/documentation/guides/). +## Development -- **`persistentStorage/`** Directory for storing persistent data during container startups and restarts. These folders come pre-loaded with mock data. - - `data-keycloak-db/`: Persistent local storage for the Keycloak database. - - `data-minio/`: Persistent local storage for MinIO object storage. - - `data-song-db/`: Persistent local storage for the Song database. +### Local Development Environment + +To modify the documentation portal itself: + +1. Clone the repository +2. Install dependencies: + ```bash + cd apps/stage + npm install + ``` +3. Run the development server: + ```bash + npm run dev + ``` + +### Updating Documentation Content + +Documentation content is stored as Markdown files in the `public/docs` directory. To add or update content: + +1. Files are prefixed with numbers (`00-`, `01-`, etc.) to control ordering +2. Each file should start with a top-level heading (`# Title`) +3. Place images in `public/docs/images/` +4. Use standard Markdown syntax for formatting + +## Project Structure + +The project follows a modular structure with two main applications: Conductor (for data management) and Stage (for the front-end portal). + +``` +├── apps/ +│ ├── composer/ # Config generation tool +│ │ └── src/ # Source code +│ │ ├── cli/ # CLI interface +│ │ ├── commands/ # Command implementations +│ │ ├── services/ # Core functions for config generation +│ │ └── utils/ # Utility functions +│ │ +│ ├── conductor/ # Data management tool +│ │ ├── src/ # Source code +│ │ │ ├── cli/ # CLI interface +│ │ │ ├── commands/ # Command implementations +│ │ │ ├── services/ # Core services (ES, Lectern, etc.) +│ │ │ └── utils/ # Utility functions +│ │ ├── configs/ # Configuration files +│ │ │ ├── arrangerConfigs/ # Arranger UI configurations +│ │ │ ├── elasticsearchConfigs/ # Elasticsearch mappings +│ │ │ ├── lecternDictionaries/ # Data dictionaries +│ │ │ └── songSchemas/ # Song schemas +│ │ └── scripts/ # Deployment and service scripts +│ │ ├── deployments/ # Phase deployment scripts +│ │ └── services/ # Service management scripts +│ │ +│ └── stage/ # Frontend portal +│ ├── components/ +│ │ ├── pages/ # Page-specific components +│ │ └── theme/ # Theming +│ ├── pages/ # Next.js pages +│ └── public/ # Static assets +│ └── docs/ # Markdown documentation files +│ └── images/ # Documentation images +│ +├── configs/ # Symlink to conductor configs +├── data/ # Data files +└── docs/ # Symlink to Stage docs +``` -- **`Makefile`** Contains [`make` commands](https://www.gnu.org/software/make/manual/make.html#Overview-of-make) for Unix-based systems (macOS, Linux) to streamline Docker operations. +## Support -- **`make.bat`** Windows equivalent of the Makefile, featuring batch commands tailored for Windows systems. +For assistance, reach out via the [community support channels](https://docs.overture.bio/community/support), for private inquiries email us at [contact@overture.bio](mailto:contact@overture.bio). diff --git a/apps/composer/package-lock.json b/apps/composer/package-lock.json new file mode 100644 index 00000000..b5215472 --- /dev/null +++ b/apps/composer/package-lock.json @@ -0,0 +1,389 @@ +{ + "name": "composer", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "composer", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "@elastic/elasticsearch": "^7.17.14", + "@types/chalk": "^0.4.31", + "@types/node": "^22.9.3", + "chalk": "^4.1.2", + "commander": "^12.1.0", + "csv-parse": "^5.6.0", + "ts-node": "^10.9.2", + "uuid": "^11.0.3" + }, + "bin": { + "composer": "dist/main.js" + }, + "devDependencies": { + "@types/uuid": "^10.0.0", + "typescript": "^5.7.2" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@elastic/elasticsearch": { + "version": "7.17.14", + "resolved": "https://registry.npmjs.org/@elastic/elasticsearch/-/elasticsearch-7.17.14.tgz", + "integrity": "sha512-6uQ1pVXutwz1Krwooo67W+3K8BwH1ASMh1WoHTpomUzw8EXecXN5lHIJ9EPqTHuv1WqR2LKkSJyagcq0HYUJpg==", + "license": "Apache-2.0", + "dependencies": { + "debug": "^4.3.1", + "hpagent": "^0.1.1", + "ms": "^2.1.3", + "secure-json-parse": "^2.4.0" + }, + "engines": { + "node": ">=12" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "license": "MIT" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "license": "MIT" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "license": "MIT" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "license": "MIT" + }, + "node_modules/@types/chalk": { + "version": "0.4.31", + "resolved": "https://registry.npmjs.org/@types/chalk/-/chalk-0.4.31.tgz", + "integrity": "sha512-nF0fisEPYMIyfrFgabFimsz9Lnuu9MwkNrrlATm2E4E46afKDyeelT+8bXfw1VSc7sLBxMxRgT7PxTC2JcqN4Q==", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "22.9.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.3.tgz", + "integrity": "sha512-F3u1fs/fce3FFk+DAxbxc78DF8x0cY09RRL8GnXLmkJ1jvx3TtPdWoTT5/NiYfI5ASqXBmfqJi9dZ3gxMx4lzw==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.8" + } + }, + "node_modules/@types/uuid": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "license": "MIT" + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "license": "MIT" + }, + "node_modules/csv-parse": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-5.6.0.tgz", + "integrity": "sha512-l3nz3euub2QMg5ouu5U09Ew9Wf6/wQ8I++ch1loQ0ljmzhmfZYrH9fflS22i/PQEvsPvxCwxgz5q7UB8K1JO4Q==", + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/hpagent": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/hpagent/-/hpagent-0.1.2.tgz", + "integrity": "sha512-ePqFXHtSQWAFXYmj+JtOTHr84iNrII4/QRlAAPPE+zqnKy4xJo7Ie1Y4kC7AdB+LxLxSTTzBMASsEcy0q8YyvQ==", + "license": "MIT" + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "license": "ISC" + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/secure-json-parse": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz", + "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==", + "license": "BSD-3-Clause" + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "license": "MIT", + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/typescript": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", + "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "license": "MIT" + }, + "node_modules/uuid": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.0.3.tgz", + "integrity": "sha512-d0z310fCWv5dJwnX1Y/MncBAqGMKEzlBb1AOf7z9K8ALnd0utBX/msg/fA0+sbyN1ihbMsLhrBlnl1ak7Wa0rg==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/esm/bin/uuid" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "license": "MIT" + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "license": "MIT", + "engines": { + "node": ">=6" + } + } + } +} diff --git a/apps/composer/package.json b/apps/composer/package.json new file mode 100644 index 00000000..5a2a4136 --- /dev/null +++ b/apps/composer/package.json @@ -0,0 +1,37 @@ +{ + "name": "composer", + "version": "1.0.0", + "main": "index.js", + "scripts": { + "start": "ts-node src/main.ts", + "build": "tsc", + "test": "node --test --require ts-node/register src/__tests__/*.test.ts", + "test:watch": "node --test --watch --require ts-node/register src/__tests__/*.test.ts", + "test:coverage": "node --test --experimental-test-coverage --require ts-node/register src/__tests__/*.test.ts", + "test:song": "node --test --require ts-node/register --test-name-pattern=\"SongCommand\" src/__tests__/*.test.ts", + "test:lectern": "node --test --require ts-node/register --test-name-pattern=\"LecternCommand\" src/__tests__/*.test.ts", + "test:mapping": "node --test --require ts-node/register --test-name-pattern=\"MappingCommand\" src/__tests__/*.test.ts", + "test:arranger": "node --test --require ts-node/register --test-name-pattern=\"ArrangerCommand\" src/__tests__/*.test.ts" + }, + "bin": { + "composer": "./dist/main.js" + }, + "keywords": [], + "author": "", + "license": "ISC", + "description": "", + "dependencies": { + "@elastic/elasticsearch": "^7.17.14", + "@types/chalk": "^0.4.31", + "@types/node": "^22.9.3", + "chalk": "^4.1.2", + "commander": "^12.1.0", + "csv-parse": "^5.6.0", + "ts-node": "^10.9.2", + "uuid": "^11.0.3" + }, + "devDependencies": { + "@types/uuid": "^10.0.0", + "typescript": "^5.7.2" + } +} diff --git a/apps/composer/readme.md b/apps/composer/readme.md new file mode 100644 index 00000000..4dbbff27 --- /dev/null +++ b/apps/composer/readme.md @@ -0,0 +1,80 @@ +## Repository Structure + +``` +conductor/apps/composer/ +│ +├── src/ # Source code directory +│ ├── cli/ # Command-line interface components +│ │ ├── environment.ts +│ │ ├── index.ts +│ │ ├── options.ts +│ │ ├── profiles.ts +│ │ └── validation.ts +│ │ +│ ├── commands/ # Application commands +│ │ ├── Commandfactory.ts +│ │ ├── arrangerCommand.ts +│ │ ├── baseCommand.ts +│ │ ├── dictionaryCommand.ts +│ │ ├── mappingCommands.ts +│ │ └── songCommand.ts +│ │ +│ ├── services/ # Business logic services +│ │ ├── generateArrangerConfigs.ts +│ │ ├── generateEsMappingFromCSV.ts +│ │ ├── generateEsMappingFromJSON.ts +│ │ ├── generateLecternDictionary.ts +│ │ └── generateSongSchema.ts +│ │ +│ ├── types/ # TypeScript type definitions +│ │ ├── arranger.ts +│ │ ├── cli.ts +│ │ ├── constants.ts +│ │ ├── elasticsearch.ts +│ │ ├── index.ts +│ │ ├── lectern.ts +│ │ ├── song.ts +│ │ └── validations.ts +│ │ +│ ├── utils/ # Utility functions +│ │ ├── csvParser.ts +│ │ └── errors.ts +│ │ +│ └── validations/ # Validation utilities +│ ├── csvValidator.ts +│ ├── enviromentValidator.ts +│ ├── fileValidator.ts +│ └── index.ts +│ +├── tests/ # Test directory +│ ├── **fixtures**/ # Test fixture data +│ │ ├── mapping.json +│ │ ├── metadata.json +│ │ ├── output +│ │ └── sample.csv +│ │ +│ └── **tests**/ # Test cases +│ ├── commands +│ └── setup.ts +│ +├── dist/ # Compiled output directory +├── node_modules/ # Dependency packages +├── README.md +├── package.json +├── package-lock.json +└── tsconfig.json +``` + +### Key Components + +- **CLI**: Handles command-line interface logic and validation +- **Commands**: Defines various application commands like arranger, dictionary, and mapping +- **Services**: Provides core logic for generating configurations and mappings +- **Types**: Contains TypeScript type definitions +- **Utils**: Global Utility functions, including CSV parsing +- **Validations**: Validation logic for CSV, environment, and file operations + +### Test Structure + +- \***\*fixtures\*\***: Contains sample data and test resources +- \***\*tests\*\***: Includes test cases and setup configurations diff --git a/apps/composer/src/cli/environment.ts b/apps/composer/src/cli/environment.ts new file mode 100644 index 00000000..65b8ee2e --- /dev/null +++ b/apps/composer/src/cli/environment.ts @@ -0,0 +1,121 @@ +import { EnvConfig } from "../types"; +import { ComposerError, ErrorCodes } from "../utils/errors"; +import { Logger } from "../utils/logger"; +import { + CONFIG_PATHS, + BASE_CONFIG_DIR, + getDefaultOutputPathForProfile, +} from "../utils/paths"; + +/** + * Maps config key to environment variable name + */ +const ENV_VAR_MAP: Record = { + // Input files + inputFiles: "FILES", + + // Output paths + outputPath: "OUTPUT_PATH", + + // Lectern Dictionary options + dictionaryName: "DICTIONARY_NAME", + dictionaryDescription: "DICTIONARY_DESC", + dictionaryVersion: "DICTIONARY_VERSION", + + // Song Schema options + schemaName: "SCHEMA_NAME", + fileTypes: "FILE_TYPES", + + // Elasticsearch options + esIndex: "ES_INDEX", + esShards: "ES_SHARDS", + esReplicas: "ES_REPLICAS", + esIgnoredFields: "ES_IGNORED_FIELDS", + esSkipMetadata: "ES_SKIP_METADATA", // Added environment variable for skip metadata option + + // CSV options + csvDelimiter: "CSV_DELIMITER", + + // Arranger options + arrangerDocType: "ARRANGER_DOC_TYPE", + + // Legacy variables + dataFile: "TABULAR_DATA_FILE", + indexName: "TABULAR_INDEX_NAME", + fileMetadataSample: "FILE_METADATA_SAMPLE", + tabularSample: "TABULAR_SAMPLE", + songSchema: "GENERATE_SONG_SCHEMA", + lecternDictionary: "LECTERN_DICTIONARY", + esConfigDir: "ES_CONFIG_DIR", + arrangerConfigDir: "ARRANGER_CONFIG_DIR", +}; + +/** + * Loads and validates environment configuration with defaults + */ +export function loadEnvironmentConfig(): EnvConfig { + try { + Logger.debug("Loading environment configuration"); + + const config: EnvConfig = { + // New variables aligned with Docker Compose + inputFiles: process.env.FILES?.split(",").map((f) => f.trim()), + outputPath: process.env.OUTPUT_PATH || BASE_CONFIG_DIR, + + // Lectern Dictionary options + dictionaryName: process.env.DICTIONARY_NAME || "lectern_dictionary", + dictionaryDescription: + process.env.DICTIONARY_DESC || "Generated dictionary from CSV files", + dictionaryVersion: process.env.DICTIONARY_VERSION || "1.0.0", + + // Song Schema options + schemaName: process.env.SCHEMA_NAME || "song_schema", + fileTypes: process.env.FILE_TYPES?.split(/\s+/), + + // Elasticsearch options + esIndex: process.env.ES_INDEX || "data", + esShards: parseInt(process.env.ES_SHARDS || "1", 10), + esReplicas: parseInt(process.env.ES_REPLICAS || "1", 10), + esIgnoredFields: process.env.ES_IGNORED_FIELDS?.split(/\s+/), + // Parse boolean environment variable + esSkipMetadata: process.env.ES_SKIP_METADATA?.toLowerCase() === "true", + + // CSV options + csvDelimiter: process.env.CSV_DELIMITER || ",", + + // Arranger options + arrangerDocType: process.env.ARRANGER_DOC_TYPE || "file", + + // Maintain backward compatibility with old variables + dataFile: process.env.TABULAR_DATA_FILE, + indexName: process.env.TABULAR_INDEX_NAME, + fileMetadataSample: + process.env.FILE_METADATA_SAMPLE || CONFIG_PATHS.samples.fileMetadata, + tabularSample: process.env.TABULAR_SAMPLE || CONFIG_PATHS.samples.tabular, + songSchema: process.env.GENERATE_SONG_SCHEMA || CONFIG_PATHS.song.dir, + lecternDictionary: + process.env.LECTERN_DICTIONARY || CONFIG_PATHS.lectern.dir, + esConfigDir: process.env.ES_CONFIG_DIR || CONFIG_PATHS.elasticsearch.dir, + arrangerConfigDir: + process.env.ARRANGER_CONFIG_DIR || CONFIG_PATHS.arranger.dir, + }; + + // Log overridden defaults + Object.entries(config).forEach(([key, value]) => { + const envVar = ENV_VAR_MAP[key as keyof EnvConfig]; + if (process.env[envVar]) { + Logger.debug(`Using custom ${key}: ${value}`); + } + }); + + Logger.debugObject("Environment configuration", config); + return config; + } catch (error) { + if (error instanceof ComposerError) throw error; + throw new ComposerError( + "Failed to load environment configuration", + ErrorCodes.ENV_ERROR, + error + ); + } +} diff --git a/apps/composer/src/cli/index.ts b/apps/composer/src/cli/index.ts new file mode 100644 index 00000000..b3170342 --- /dev/null +++ b/apps/composer/src/cli/index.ts @@ -0,0 +1,166 @@ +import { Command } from "commander"; +import { Profile, CLIOutput } from "../types"; +import { ComposerError, ErrorCodes } from "../utils/errors"; +import { validateEnvironment } from "../validations"; +import { loadEnvironmentConfig } from "./environment"; +import { getDefaultOutputPath } from "./profiles"; +import { validateCliOptions } from "./validation"; +import { configureCommandOptions } from "./options"; +import { Logger } from "../utils/logger"; +import * as fs from "fs"; +import * as path from "path"; + +/** + * Extract file types from a JSON file containing file metadata + * Used to automatically determine file types for Song schema generation + * + * @param filePath Path to the JSON file + * @returns Array of file types found in the file + */ +function extractFileTypesFromJson(filePath: string): string[] { + try { + const fileContent = fs.readFileSync(filePath, "utf-8"); + const data = JSON.parse(fileContent); + + // Check if the JSON has a files array with fileType properties + if (data && data.files && Array.isArray(data.files)) { + // Extract unique file types + const fileTypes = new Set(); + data.files.forEach((file: any) => { + if (file.fileType) { + fileTypes.add(file.fileType); + } + }); + + return Array.from(fileTypes); + } + + return []; + } catch (error) { + Logger.debug(`Error extracting file types from JSON: ${error}`); + return []; + } +} + +export async function setupCLI(): Promise { + const program = new Command(); + + try { + // Load environment and parse options + const envConfig = loadEnvironmentConfig(); + configureCommandOptions(program); + program.parse(); + const options = program.opts(); + + // Process profile + const profile = options.profile as Profile; + const outputPath = + options.output || getDefaultOutputPath(profile, envConfig); + + // Log consolidated configuration + Logger.debugObject("CLI Configuration", { + command: { + profile, + input: options.files, + output: outputPath, + }, + directories: { + elasticsearch: envConfig.esConfigDir, + arranger: envConfig.arrangerConfigDir, + lectern: envConfig.lecternDictionary, + song: envConfig.songSchema, + }, + }); + + // Validate options and environment + await validateEnvironment({ + profile, + outputPath, + }); + + // Build CLI output + const cliOutput: CLIOutput = { + config: { + elasticsearch: { + index: + options.indexPattern || + options.index || + envConfig.indexName || + "data", + shards: parseInt(options.shards, 10) || envConfig.esShards || 1, + replicas: parseInt(options.replicas, 10) || envConfig.esReplicas || 0, + ignoredFields: options.ignoreFields || envConfig.esIgnoredFields, + skipMetadata: + options.skipMetadata || envConfig.esSkipMetadata || false, // Added skipMetadata option + }, + delimiter: options.delimiter || envConfig.csvDelimiter || ",", + }, + profile, + filePaths: options.files, + outputPath, + force: options.force || false, + envConfig, + arrangerConfigDir: + options.arrangerConfigDir || envConfig.arrangerConfigDir, + }; + + // Add profile-specific config + if (profile === "generateLecternDictionary") { + cliOutput.dictionaryConfig = { + name: options.name, + description: options.description, + version: options.version, + }; + } else if (profile === "generateSongSchema") { + // For Song schema, try to extract file types from the input file if not specified + let fileTypes = options.fileTypes; + + // If file types not specified and there's exactly one JSON file, try to extract them + if ( + (!fileTypes || fileTypes.length === 0) && + options.files && + options.files.length === 1 + ) { + const filePath = options.files[0]; + if (path.extname(filePath).toLowerCase() === ".json") { + Logger.debug("Attempting to extract file types from JSON file"); + const extractedTypes = extractFileTypesFromJson(filePath); + if (extractedTypes.length > 0) { + Logger.debug( + `Found file types in JSON: ${extractedTypes.join(", ")}` + ); + fileTypes = extractedTypes; + } + } + } + + // Provide reasonable defaults for Song schema configuration + cliOutput.songConfig = { + name: + options.name || + path.basename(options.files[0], path.extname(options.files[0])), + fileTypes: fileTypes || [], + }; + + Logger.debug( + `Song schema config: ${JSON.stringify(cliOutput.songConfig)}` + ); + } else if (profile === "generateArrangerConfigs") { + cliOutput.arrangerConfig = { + documentType: + (options.arrangerDocType as "file" | "analysis") || "file", + }; + } + + return cliOutput; + } catch (error) { + if (error instanceof ComposerError) { + throw error; + } + throw new ComposerError( + "Error setting up CLI", + ErrorCodes.ENV_ERROR, + error + ); + } +} diff --git a/apps/composer/src/cli/options.ts b/apps/composer/src/cli/options.ts new file mode 100644 index 00000000..0bdc5fd4 --- /dev/null +++ b/apps/composer/src/cli/options.ts @@ -0,0 +1,143 @@ +import { Command, Option } from "commander"; +import { Profile, Profiles, CLIOutput } from "../types"; +import { ComposerError, ErrorCodes } from "../utils/errors"; +import { PROFILE_DESCRIPTIONS } from "./profiles"; +import { Logger } from "../utils/logger"; + +/** + * Configures and returns the CLI command with all available options + */ +export function configureCommandOptions(program: Command): Command { + Logger.debug("Configuring command options"); + + return program + .name("composer") + .description( + "Generate Dictionary, Song Schema, or Elasticsearch configurations" + ) + .option("--debug", "Enable debug logging") + .addOption( + new Option("-p, --profile ", "Execution profile") + .choices(Object.keys(Profiles)) + .default("default") + .argParser((value) => { + Logger.debug`Parsing profile value: ${value}`; + if (!Object.values(Profiles).includes(value as Profile)) { + Logger.debug`Invalid profile detected: ${value}`; + throw new ComposerError( + `Invalid profile: ${value}. Valid profiles are:\n${Array.from( + PROFILE_DESCRIPTIONS.entries() + ) + .map(([profile, desc]) => ` ${profile}: ${desc}`) + .join("\n")}`, + ErrorCodes.INVALID_ARGS + ); + } + Logger.debug`Profile validated: ${value}`; + return value as Profile; + }) + ) + .requiredOption( + "-f, --files ", + "Input file paths (CSV or JSON, space separated)" + ) + .option("-i, --index ", "Elasticsearch index name", "data") + .option("--shards ", "Number of Elasticsearch shards", "1") + .option("--replicas ", "Number of Elasticsearch replicas", "1") + .option( + "-o, --output ", + "Output file path for generated schemas or mapping" + ) + .option( + "--arranger-doc-type ", + "Arranger document type (file or analysis)", + "file" + ) + .option("-n, --name ", "Dictionary/Schema name") + .option( + "-d, --description ", + "Dictionary description", + "Generated dictionary from CSV files" + ) + .option("-v, --version ", "Dictionary version", "1.0.0") + .option("--file-types ", "Allowed file types for Song schema") + .option("--delimiter ", "CSV delimiter", ",") + .option( + "--ignore-fields ", + "Field names to exclude from Elasticsearch mapping" + ) + .option( + "--skip-metadata", + "Skip adding submission metadata to Elasticsearch mapping" + ) + .option("--force", "Force overwrite of existing files without prompting") + .helpOption("-h, --help", "Display help for command") + .addHelpText("after", () => { + Logger.showReferenceCommands(); + return ""; // Return empty string since we handle the formatting in showReferenceCommands + }) + .hook("preAction", (thisCommand) => { + const opts = thisCommand.opts(); + if (opts.debug) { + Logger.enableDebug(); + Logger.debug`Full command options: ${JSON.stringify(opts, null, 2)}`; + } + }); +} + +/** + * Parse command line arguments and convert them to CLIOutput format + */ +export function parseCommandLineArgs(opts: any): CLIOutput { + Logger.debug("Parsing command line arguments"); + + const output: CLIOutput = { + profile: opts.profile || "default", + debug: opts.debug || false, + filePaths: opts.files || [], + outputPath: opts.output, + force: opts.force || false, + config: { + elasticsearch: { + index: opts.index || "data", + shards: parseInt(opts.shards || "1", 10), + replicas: parseInt(opts.replicas || "1", 10), + ignoredFields: opts.ignoreFields || [], + skipMetadata: opts.skipMetadata || false, // Add skip metadata option + }, + delimiter: opts.delimiter || ",", + }, + envConfig: { + fileMetadataSample: opts.fileMetadataSample || "", + tabularSample: opts.tabularSample || "", + songSchema: opts.songSchema || "", + lecternDictionary: opts.lecternDictionary || "", + esConfigDir: opts.esConfigDir || "", + arrangerConfigDir: opts.arrangerConfigDir || "", + }, + arrangerConfig: opts.arrangerDocType + ? { + documentType: opts.arrangerDocType, + } + : undefined, + delimiter: opts.delimiter, + dictionaryConfig: { + name: opts.name || "lectern_dictionary", + description: opts.description || "Generated dictionary from CSV files", + version: opts.version || "1.0.0", + }, + songConfig: + opts.name || opts.fileTypes + ? { + name: opts.name || `song_schema`, + fileTypes: opts.fileTypes, + } + : undefined, + }; + + if (opts.debug) { + Logger.debug`Parsed CLI output: ${JSON.stringify(output, null, 2)}`; + } + + return output; +} diff --git a/apps/composer/src/cli/profiles.ts b/apps/composer/src/cli/profiles.ts new file mode 100644 index 00000000..f1aa94f4 --- /dev/null +++ b/apps/composer/src/cli/profiles.ts @@ -0,0 +1,59 @@ +import { Profile, EnvConfig, Profiles } from "../types"; +import { ComposerError, ErrorCodes } from "../utils/errors"; +import { Logger } from "../utils/logger"; +import { getDefaultOutputPathForProfile } from "../utils/paths"; + +export const PROFILE_DESCRIPTIONS = new Map([ + [Profiles.GENERATE_SONG_SCHEMA, "Generate SONG schema from JSON metadata"], + [ + Profiles.GENERATE_LECTERN_DICTIONARY, + "Generate Lectern dictionary from CSV files", + ], + [ + Profiles.GENERATE_ELASTICSEARCH_MAPPING, + "Generate Elasticsearch mapping from CSV or JSON", + ], + [ + Profiles.GENERATE_ARRANGER_CONFIGS, + "Generate Arranger configs from Elasticsearch mapping", + ], + [Profiles.GENERATE_CONFIGS, "Generate all configurations"], + [Profiles.DEFAULT, "Default profile"], +]); + +// Get all valid profiles +const VALID_PROFILES = Object.values(Profiles); + +export function validateProfile(profile: Profile): Profile { + Logger.debug`Validating profile: ${profile}`; + + if (!VALID_PROFILES.includes(profile)) { + throw new ComposerError( + `Invalid profile: ${profile}. Valid profiles are: ${VALID_PROFILES.join( + ", " + )}`, + ErrorCodes.INVALID_ARGS + ); + } + + Logger.debug`Profile validated: ${profile}`; + return profile; +} + +export function getDefaultOutputPath( + profile: Profile, + envConfig: EnvConfig +): string | undefined { + Logger.debug`Getting default output path for profile: ${profile}`; + + // Get the standard output path + let defaultPath = getDefaultOutputPathForProfile(profile); + + // Use environment output path if available + if (envConfig.outputPath) { + defaultPath = envConfig.outputPath; + } + + Logger.debug`Using default output path: ${defaultPath}`; + return defaultPath; +} diff --git a/apps/composer/src/cli/validation.ts b/apps/composer/src/cli/validation.ts new file mode 100644 index 00000000..f793eb93 --- /dev/null +++ b/apps/composer/src/cli/validation.ts @@ -0,0 +1,62 @@ +import { Profile, Profiles } from "../types"; +import { ComposerError, ErrorCodes } from "../utils/errors"; + +interface CLIOptions { + name?: string; + shards?: number; + replicas?: number; + arrangerDocType?: string; + [key: string]: any; +} + +export function validateCliOptions( + options: CLIOptions, + profile: Profile +): void { + try { + switch (profile) { + case Profiles.GENERATE_LECTERN_DICTIONARY: + // Removed name requirement, as it will be auto-generated if not provided + break; + + case Profiles.GENERATE_ELASTICSEARCH_MAPPING: + if (options.shards && (isNaN(options.shards) || options.shards < 1)) { + throw new ComposerError( + "Number of shards must be a positive integer", + ErrorCodes.INVALID_ARGS + ); + } + if ( + options.replicas && + (isNaN(options.replicas) || options.replicas < 0) + ) { + throw new ComposerError( + "Number of replicas must be a non-negative integer", + ErrorCodes.INVALID_ARGS + ); + } + break; + + case Profiles.GENERATE_ARRANGER_CONFIGS: + if ( + options.arrangerDocType && + !["file", "analysis"].includes(options.arrangerDocType) + ) { + throw new ComposerError( + 'Arranger document type must be either "file" or "analysis"', + ErrorCodes.INVALID_ARGS + ); + } + break; + } + } catch (error) { + if (error instanceof ComposerError) throw error; + throw new ComposerError( + "Invalid CLI options", + ErrorCodes.INVALID_ARGS, + error + ); + } +} + +export type { CLIOptions }; diff --git a/apps/composer/src/commands/Commandfactory.ts b/apps/composer/src/commands/Commandfactory.ts new file mode 100644 index 00000000..d7d0af98 --- /dev/null +++ b/apps/composer/src/commands/Commandfactory.ts @@ -0,0 +1,67 @@ +import type { Profile } from "../types"; +import { Profiles } from "../types"; +import { Command } from "./baseCommand"; +import { ComposerError, ErrorCodes, handleError } from "../utils/errors"; +import { Logger } from "../utils/logger"; + +// Import individual commands +import { SongCommand } from "./songCommand"; +import { DictionaryCommand } from "./lecternCommand"; +import { MappingCommand } from "./mappingCommands"; +import { ArrangerCommand } from "./arrangerCommand"; + +type CommandConstructor = new () => Command; + +type CommandMap = { + [K in Profile]: CommandConstructor; +}; + +// Map of profile names to user-friendly display names +const PROFILE_DISPLAY_NAMES: Record = { + [Profiles.GENERATE_SONG_SCHEMA]: "Song Schema Generator", + [Profiles.GENERATE_LECTERN_DICTIONARY]: "Lectern Dictionary Generator", + [Profiles.GENERATE_ELASTICSEARCH_MAPPING]: "Elasticsearch Mapping Generator", + [Profiles.GENERATE_ARRANGER_CONFIGS]: "Arranger Configs Generator", +}; + +const PROFILE_TO_COMMAND: Partial = { + [Profiles.GENERATE_SONG_SCHEMA]: SongCommand, + [Profiles.GENERATE_LECTERN_DICTIONARY]: DictionaryCommand, + [Profiles.GENERATE_ELASTICSEARCH_MAPPING]: MappingCommand, + [Profiles.GENERATE_ARRANGER_CONFIGS]: ArrangerCommand, +} as const; + +export class CommandFactory { + static createCommand(profile: Profile): Command { + Logger.debug`Creating command for profile: ${profile}`; + const CommandClass = PROFILE_TO_COMMAND[profile]; + + if (!CommandClass) { + const error = new ComposerError( + `Unsupported profile: ${profile}`, + ErrorCodes.INVALID_ARGS + ); + + handleError(error, () => { + // Use the new section method for better organization + Logger.section("Available Profiles"); + + // List all available profiles with descriptions + Object.entries(PROFILE_TO_COMMAND).forEach(([profileName]) => { + const displayName = PROFILE_DISPLAY_NAMES[profileName] || profileName; + Logger.commandInfo(profileName, displayName); + }); + + // Show reference commands with improved formatting + Logger.header(`Example Commands`); + Logger.showReferenceCommands(); + }); + } + + const command = new CommandClass(); + const displayName = PROFILE_DISPLAY_NAMES[profile] || profile; + + Logger.debug`Created ${displayName} command instance`; + return command; + } +} diff --git a/apps/composer/src/commands/arrangerCommand.ts b/apps/composer/src/commands/arrangerCommand.ts new file mode 100644 index 00000000..67571602 --- /dev/null +++ b/apps/composer/src/commands/arrangerCommand.ts @@ -0,0 +1,192 @@ +import * as path from "path"; +import * as fs from "fs"; +import { Command } from "./baseCommand"; +import { CLIOutput } from "../types"; +import { ComposerError, ErrorCodes } from "../utils/errors"; +import { generateArrangerConfigs } from "../services/generateArrangerConfigs"; +import { Logger } from "../utils/logger"; +import { CONFIG_PATHS } from "../utils/paths"; + +/** + * Command implementation for generating Arranger configurations + * Takes an Elasticsearch mapping file as input and generates the required + * configuration files for setting up Arranger + */ +export class ArrangerCommand extends Command { + // Define arranger-specific defaults + protected readonly defaultOutputFileName = "configs"; + + constructor() { + super("Arranger", CONFIG_PATHS.arranger.dir); + // Override the default filename from the base class + this.defaultOutputFileName = "configs"; + } + + /** + * Override isUsingDefaultPath to handle arranger-specific defaults + */ + protected isUsingDefaultPath(cliOutput: CLIOutput): boolean { + return ( + cliOutput.outputPath === CONFIG_PATHS.arranger.configs || + cliOutput.outputPath === + path.join(CONFIG_PATHS.arranger.dir, "configs") || + super.isUsingDefaultPath(cliOutput) + ); + } + + /** + * Validates the command input parameters + * @param cliOutput The CLI output containing command parameters + * @throws {ComposerError} If validation fails + */ + protected async validate(cliOutput: CLIOutput): Promise { + Logger.debug("Starting ArrangerCommand validation"); + await super.validate(cliOutput); + + if (!cliOutput.outputPath) { + Logger.debug("Output path validation failed"); + throw new ComposerError( + "Output path is required", + ErrorCodes.INVALID_ARGS + ); + } + + // Ensure only one mapping file is provided + if (cliOutput.filePaths.length !== 1) { + Logger.debug( + `Invalid number of mapping files: ${cliOutput.filePaths.length}` + ); + throw new ComposerError( + "You must provide exactly one mapping file", + ErrorCodes.INVALID_ARGS + ); + } + + const validDocumentTypes = ["file", "analysis"]; + const documentType = cliOutput.arrangerConfig?.documentType; + Logger.debug`Validating document type: ${documentType}`; + + if (!documentType || !validDocumentTypes.includes(documentType)) { + Logger.debug`Invalid document type: ${documentType}`; + throw new ComposerError( + `Invalid document type. Must be one of: ${validDocumentTypes.join( + ", " + )}`, + ErrorCodes.INVALID_ARGS + ); + } + + // Warn if using default document type ("file") + if (documentType === "file") { + Logger.defaultValueInfo( + `Using default Arranger document type: "file"`, + "Use --arranger-doc-type to specify a different document type (file or analysis)." + ); + } + + const filePath = cliOutput.filePaths[0]; + const fileExtension = path.extname(filePath).toLowerCase(); + Logger.debug`Validating file extension: ${fileExtension}`; + + if (fileExtension !== ".json") { + Logger.debug("File extension validation failed - not JSON"); + throw new ComposerError( + "Arranger configs require a JSON mapping file", + ErrorCodes.INVALID_FILE + ); + } + + if (!fs.existsSync(filePath)) { + Logger.debug`File not found at path: ${filePath}`; + throw new ComposerError( + `File not found: ${filePath}`, + ErrorCodes.INVALID_FILE + ); + } + + Logger.debug("ArrangerCommand validation completed successfully"); + } + + /** + * Executes the command to generate Arranger configurations + * @param cliOutput The CLI output containing command parameters + * @returns The generated configurations + * @throws {ComposerError} If generation fails + */ + protected async execute(cliOutput: CLIOutput): Promise { + Logger.debug("Starting ArrangerCommand execution"); + let outputPath = cliOutput.outputPath!; + + // Normalize output path for arranger config files + if (fs.existsSync(outputPath) && fs.statSync(outputPath).isDirectory()) { + outputPath = path.join(outputPath, this.defaultOutputFileName); + Logger.debug( + `Output is a directory, will create ${this.defaultOutputFileName} inside it` + ); + } + + const filePath = cliOutput.filePaths[0]; + + try { + Logger.info("Reading mapping file"); + Logger.debug`Reading file from path: ${filePath}`; + const mappingContent = fs.readFileSync(filePath, "utf-8"); + + let mapping; + try { + Logger.debug("Parsing JSON mapping content"); + mapping = JSON.parse(mappingContent); + } catch (error) { + Logger.debug`JSON parsing failed: ${error}`; + throw new ComposerError( + "Invalid JSON mapping file", + ErrorCodes.INVALID_FILE + ); + } + + // Ensure output directory exists + const outputDir = path.dirname(outputPath); + this.createDirectoryIfNotExists(outputDir); + + Logger.debug("Generating Arranger configurations"); + const configs = generateArrangerConfigs( + mapping, + cliOutput.config.elasticsearch?.index + ); + + // Write each configuration to a separate file + const baseFilePath = path.join(outputDir, "base.json"); + const extendedFilePath = path.join(outputDir, "extended.json"); + const tableFilePath = path.join(outputDir, "table.json"); + const facetsFilePath = path.join(outputDir, "facets.json"); + + fs.writeFileSync(baseFilePath, JSON.stringify(configs.base, null, 2)); + fs.writeFileSync( + extendedFilePath, + JSON.stringify(configs.extended, null, 2) + ); + fs.writeFileSync(tableFilePath, JSON.stringify(configs.table, null, 2)); + fs.writeFileSync(facetsFilePath, JSON.stringify(configs.facets, null, 2)); + + Logger.debug("Configuration generation completed"); + Logger.success`Configuration files saved to:`; + Logger.generic(` - ${baseFilePath}`); + Logger.generic(` - ${extendedFilePath}`); + Logger.generic(` - ${tableFilePath}`); + Logger.generic(` - ${facetsFilePath}`); + + return configs; + } catch (error) { + Logger.debug`Error during execution: ${error}`; + if (error instanceof ComposerError) { + Logger.error(error.message); + throw error; + } + throw new ComposerError( + "Failed to generate Arranger configurations", + ErrorCodes.GENERATION_FAILED, + error + ); + } + } +} diff --git a/apps/composer/src/commands/baseCommand.ts b/apps/composer/src/commands/baseCommand.ts new file mode 100644 index 00000000..7118c1df --- /dev/null +++ b/apps/composer/src/commands/baseCommand.ts @@ -0,0 +1,258 @@ +import { CLIOutput } from "../types"; +import { ComposerError, ErrorCodes, handleError } from "../utils/errors"; +import { Logger } from "../utils/logger"; +import * as fs from "fs"; +import * as path from "path"; +import { validateFile, validateDelimiter } from "../validations/fileValidator"; +import * as readline from "readline"; +import { expandDirectoryPaths } from "../utils/fileUtils"; + +/** + * Abstract base class for all CLI commands. + * Provides common functionality for command execution, validation, and file handling. + */ +export abstract class Command { + /** Default directory where output files will be stored if not specified by user */ + protected defaultOutputPath: string; + + /** Default filename for output files */ + protected defaultOutputFileName: string = "output.json"; + + /** + * Creates a new Command instance. + * + * @param name - Name of the command for logging and identification + * @param defaultOutputPath - Optional custom default output directory + */ + constructor(protected name: string, defaultOutputPath?: string) { + this.defaultOutputPath = defaultOutputPath || "configs"; + } + + /** + * Main method to run the command with the provided CLI arguments. + * Handles validation, output path resolution, and error handling. + * + * @param cliOutput - The parsed command line arguments + * @returns A promise that resolves when command execution is complete + */ + async run(cliOutput: CLIOutput): Promise { + const startTime = Date.now(); + + try { + // Enable debug logging if requested + if (cliOutput.debug) { + Logger.enableDebug(); + Logger.debug`Running ${this.name} command with debug enabled`; + } + + // Validate input arguments + await this.validate(cliOutput); + + Logger.debug`Output path before check: ${cliOutput.outputPath}`; + + let usingDefaultPath = false; + + // If no output path specified, use the default + if (!cliOutput.outputPath?.trim()) { + Logger.debug("No output directory specified."); + usingDefaultPath = true; + cliOutput.outputPath = path.join(this.defaultOutputPath); + } + + const isDefaultPath = this.isUsingDefaultPath(cliOutput); + + // Inform user about output path + if (isDefaultPath || usingDefaultPath) { + Logger.defaultValueInfo( + `Using default output path: ${cliOutput.outputPath}`, + "Use -o or --output to specify a different location" + ); + } else { + Logger.info`Output directory set to: ${cliOutput.outputPath}`; + } + + // Check for existing files and confirm overwrite if needed + // Skip confirmation if force flag is set + if (cliOutput.outputPath && cliOutput.force !== true) { + const shouldContinue = await this.checkForExistingFiles( + cliOutput.outputPath + ); + if (!shouldContinue) { + Logger.info("Operation cancelled by user."); + return; + } + } else if (cliOutput.force === true) { + Logger.debug("Force flag enabled, skipping overwrite confirmation"); + } + + Logger.header(`Generating ${this.name} Configurations`); + + // Execute the specific command implementation + await this.execute(cliOutput); + } catch (error) { + handleError(error); + } + } + + /** + * Abstract method that must be implemented by derived classes. + * Contains the specific logic for each command. + * + * @param cliOutput - The parsed command line arguments + * @returns A promise that resolves when execution is complete + */ + protected abstract execute(cliOutput: CLIOutput): Promise; + + /** + * Checks if the current output path is the default one. + * + * @param cliOutput - The parsed command line arguments + * @returns true if using the default output path, false otherwise + */ + protected isUsingDefaultPath(cliOutput: CLIOutput): boolean { + return ( + cliOutput.outputPath === this.defaultOutputPath || + cliOutput.outputPath === + path.join(this.defaultOutputPath, this.defaultOutputFileName) + ); + } + + /** + * Validates command line arguments. + * Ensures that input files exist and validates any specified delimiter. + * + * @param cliOutput - The parsed command line arguments + * @throws ComposerError if validation fails + */ + protected async validate(cliOutput: CLIOutput): Promise { + if (!cliOutput.filePaths?.length) { + throw new ComposerError( + "No input files provided", + ErrorCodes.INVALID_ARGS + ); + } + + // Expand directory paths to file paths + const originalPaths = [...cliOutput.filePaths]; + const expandedPaths = expandDirectoryPaths(cliOutput.filePaths); + + if (expandedPaths.length === 0) { + throw new ComposerError( + "No valid input files found", + ErrorCodes.INVALID_ARGS + ); + } + + // If we found more files than were originally specified, log this info + if (expandedPaths.length > originalPaths.length) { + Logger.info(`Found ${expandedPaths.length} files from specified paths`); + } + + // Replace the original file paths with expanded ones + cliOutput.filePaths = expandedPaths; + Logger.debug(`Expanded file paths: ${cliOutput.filePaths.join(", ")}`); + + // Validate each input file + for (const filePath of cliOutput.filePaths) { + await validateFile(filePath); + } + + // Validate delimiter if provided + if (cliOutput.delimiter) { + validateDelimiter(cliOutput.delimiter); + } + } + + /** + * Creates a directory if it doesn't already exist. + * + * @param dirPath - Path to the directory to create + */ + protected createDirectoryIfNotExists(dirPath: string): void { + if (!fs.existsSync(dirPath)) { + fs.mkdirSync(dirPath, { recursive: true }); + Logger.info`Created directory: ${dirPath}`; + } + } + + /** + * Checks if files in the output directory would be overwritten. + * Prompts the user for confirmation if files would be overwritten. + * + * @param outputPath - Path where output files will be written + * @returns A promise that resolves to true if execution should continue, false otherwise + */ + protected async checkForExistingFiles(outputPath: string): Promise { + let directoryPath = outputPath; + let outputFileName: string | undefined; + + // Determine if outputPath is a file or directory + if (path.extname(outputPath)) { + Logger.debug`Output path appears to be a file: ${outputPath}`; + directoryPath = path.dirname(outputPath); + outputFileName = path.basename(outputPath); + Logger.debug( + `Using directory: ${directoryPath}, fileName: ${outputFileName}` + ); + } else { + // If outputPath is a directory, use the default filename + outputFileName = this.defaultOutputFileName; + Logger.debug( + `Output path is a directory, using default filename: ${outputFileName}` + ); + } + + // Create the output directory if it doesn't exist + this.createDirectoryIfNotExists(directoryPath); + + // Get existing entries in the directory + const existingEntries = fs.existsSync(directoryPath) + ? fs.readdirSync(directoryPath) + : []; + + // Check for exact file match only + const filesToOverwrite = existingEntries.filter((entry) => { + const fullPath = path.join(directoryPath, entry); + + // Only check if this exact file exists and is a file (not a directory) + return entry === outputFileName && fs.statSync(fullPath).isFile(); + }); + + // If no files would be overwritten, continue without prompting + if (filesToOverwrite.length === 0) { + return true; + } + + // Display list of files that would be overwritten + Logger.fileList( + "The following file(s) in the output directory will be overwritten", + filesToOverwrite + ); + + // Create readline interface for user input + const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, + }); + + // Prompt user for confirmation + return new Promise((resolve) => { + rl.question( + Logger.input("Do you wish to continue? [y/n]: "), + (answer) => { + rl.close(); + resolve(answer.toLowerCase() === "y"); + } + ); + }); + } + + /** + * Logs information about a generated file. + * + * @param filePath - Path to the generated file + */ + protected logGeneratedFile(filePath: string): void { + Logger.info`Generated file: ${filePath}`; + } +} diff --git a/apps/composer/src/commands/lecternCommand.ts b/apps/composer/src/commands/lecternCommand.ts new file mode 100644 index 00000000..545c9b20 --- /dev/null +++ b/apps/composer/src/commands/lecternCommand.ts @@ -0,0 +1,272 @@ +// Updated lecternCommand.ts +import * as path from "path"; +import * as fs from "fs"; +import { Command } from "./baseCommand"; +import { CLIOutput } from "../types"; +import { ComposerError, ErrorCodes } from "../utils/errors"; +import { + generateDictionary, + generateSchema, +} from "../services/generateLecternDictionary"; +import { parseCSVLine } from "../utils/csvParser"; +import { validateCSVHeaders, validateEnvironment } from "../validations"; +import { Profiles } from "../types"; +import { Logger } from "../utils/logger"; +import { CONFIG_PATHS } from "../utils/paths"; + +export class DictionaryCommand extends Command { + // Define dictionary-specific defaults + protected readonly defaultOutputFileName = "dictionary.json"; + + constructor() { + super("Lectern Dictionary", CONFIG_PATHS?.lectern?.dir); + // Override the default filename from the base class + this.defaultOutputFileName = "dictionary.json"; + } + + /** + * Override isUsingDefaultPath to handle dictionary-specific defaults + */ + protected isUsingDefaultPath(cliOutput: CLIOutput): boolean { + return ( + cliOutput.outputPath === CONFIG_PATHS?.lectern?.dictionary || + cliOutput.outputPath === + path.join(CONFIG_PATHS?.lectern?.dir || "", "dictionary.json") || + super.isUsingDefaultPath(cliOutput) + ); + } + + protected async validate(cliOutput: CLIOutput): Promise { + await super.validate(cliOutput); + + if (!cliOutput.outputPath) { + throw new ComposerError( + "Output path is required", + ErrorCodes.INVALID_ARGS + ); + } + + // Validate dictionary config + if (!cliOutput.dictionaryConfig) { + throw new ComposerError( + "Dictionary configuration is required", + ErrorCodes.INVALID_ARGS + ); + } + + const config = cliOutput.dictionaryConfig; + + if (!config.name) { + // Set a default value first + config.name = "lectern_dictionary"; + + Logger.defaultValueInfo( + `No dictionary name supplied, defaulting to: ${config.name}`, + "--name " + ); + } + + // Similar fixes for description and version if needed + if (config.description === "Generated dictionary from CSV files") { + Logger.defaultValueInfo( + "No dictionary description supplied, using default description", + "--description " + ); + } + + if (config.version === "1.0.0") { + Logger.defaultValueInfo( + "No dictionary version supplied, using default version: 1.0.0", + "--version " + ); + } + + // Get only CSV files from the paths (already expanded in base class) + const csvFiles = cliOutput.filePaths.filter( + (filePath) => path.extname(filePath).toLowerCase() === ".csv" + ); + + // Check if we've got valid CSV files + if (csvFiles.length === 0) { + throw new ComposerError( + "Lectern dictionary generation requires CSV input files", + ErrorCodes.INVALID_FILE + ); + } + + // If we filtered out some non-CSV files, log which ones were skipped + if (csvFiles.length < cliOutput.filePaths.length) { + const skippedFiles = cliOutput.filePaths.filter( + (filePath) => path.extname(filePath).toLowerCase() !== ".csv" + ); + + Logger.warn(`Skipping ${skippedFiles.length} non-CSV files`); + skippedFiles.forEach((file) => { + Logger.generic(` - ${file}`); + }); + } + + // Update filePaths to only include CSV files + cliOutput.filePaths = csvFiles; + Logger.info(`Processing ${csvFiles.length} CSV files`); + + // Validate CSV headers for each file + const validFiles: string[] = []; + const invalidFiles: string[] = []; + + for (const filePath of cliOutput.filePaths) { + try { + const csvHeadersValid = await validateCSVHeaders( + filePath, + cliOutput.config.delimiter + ); + if (csvHeadersValid) { + validFiles.push(filePath); + } else { + invalidFiles.push(filePath); + } + } catch (error) { + Logger.warn(`Error validating CSV headers in ${filePath}: ${error}`); + invalidFiles.push(filePath); + } + } + + // If some files are invalid, warn and continue with valid ones + if (invalidFiles.length > 0) { + Logger.warn(`Skipping ${invalidFiles.length} files with invalid headers`); + invalidFiles.forEach((file) => { + Logger.generic(` - ${path.basename(file)}`); + }); + + // Update filePaths to only include valid files + cliOutput.filePaths = validFiles; + } + + // Ensure we still have files to process + if (cliOutput.filePaths.length === 0) { + throw new ComposerError( + "No valid CSV files found with proper headers", + ErrorCodes.VALIDATION_FAILED + ); + } + + Logger.info( + `Found ${cliOutput.filePaths.length} valid CSV files to process` + ); + } + + protected async execute(cliOutput: CLIOutput): Promise { + const { dictionaryConfig } = cliOutput; + const delimiter = cliOutput.config.delimiter; + + // Get output path, similar to MappingCommand + let outputPath = cliOutput.outputPath!; + + // Normalize output path for dictionary files specifically + if (fs.existsSync(outputPath) && fs.statSync(outputPath).isDirectory()) { + outputPath = path.join(outputPath, this.defaultOutputFileName); + Logger.debug( + `Output is a directory, will create ${this.defaultOutputFileName} inside it` + ); + } else if (!outputPath.endsWith(".json")) { + outputPath += ".json"; + Logger.info`Adding .json extension to output path`; + } + + try { + // Validate environment + await validateEnvironment({ + profile: Profiles.GENERATE_LECTERN_DICTIONARY, + outputPath: outputPath, + }); + + const dictionary = generateDictionary( + dictionaryConfig!.name, + dictionaryConfig!.description, + dictionaryConfig!.version + ); + + let processedFiles = 0; + let skippedFiles = 0; + + for (const filePath of cliOutput.filePaths) { + try { + const fileContent = fs.readFileSync(filePath, "utf-8"); + const [headerLine, sampleLine] = fileContent.split("\n"); + + if (!headerLine) { + Logger.warn( + `CSV file ${path.basename( + filePath + )} is empty or has no headers. Skipping.` + ); + skippedFiles++; + continue; + } + + const headers = parseCSVLine(headerLine, delimiter, true)[0]; + if (!headers) { + Logger.warn( + `Failed to parse CSV headers in ${path.basename( + filePath + )}. Skipping.` + ); + skippedFiles++; + continue; + } + + // Process sample data + const sampleData: Record = {}; + if (sampleLine) { + const sampleValues = parseCSVLine(sampleLine, delimiter, false)[0]; + if (sampleValues) { + headers.forEach((header: string, index: number) => { + sampleData[header] = sampleValues[index] || ""; + }); + } + } + + // Pass the full file path to generateSchema to extract the schema name + const schema = generateSchema(filePath, headers, sampleData); + dictionary.schemas.push(schema); + Logger.debug`Generated schema for ${schema.name}`; + processedFiles++; + } catch (error) { + Logger.warn`Skipping ${path.basename( + filePath + )} due to error: ${error}`; + skippedFiles++; + continue; + } + } + + // Log summary of processing + Logger.info(`Successfully processed ${processedFiles} CSV files`); + if (skippedFiles > 0) { + Logger.warn(`Skipped ${skippedFiles} files due to errors`); + } + + // Ensure output directory exists + const outputDir = path.dirname(outputPath); + if (!fs.existsSync(outputDir)) { + fs.mkdirSync(outputDir, { recursive: true }); + Logger.debug`Created output directory: ${outputDir}`; + } + + // Write dictionary to file + fs.writeFileSync(outputPath, JSON.stringify(dictionary, null, 2)); + Logger.success`Dictionary saved to ${outputPath}`; + + return dictionary; + } catch (error) { + if (error instanceof ComposerError) { + throw error; + } + throw new ComposerError( + "Error generating Lectern dictionary", + ErrorCodes.GENERATION_FAILED, + error + ); + } + } +} diff --git a/apps/composer/src/commands/mappingCommands.ts b/apps/composer/src/commands/mappingCommands.ts new file mode 100644 index 00000000..7edea015 --- /dev/null +++ b/apps/composer/src/commands/mappingCommands.ts @@ -0,0 +1,382 @@ +import * as path from "path"; +import * as fs from "fs"; +import { Command } from "./baseCommand"; +import { CLIOutput } from "../types"; +import { ComposerError, ErrorCodes } from "../utils/errors"; +import { generateMappingFromCSV } from "../services/generateEsMappingFromCSV"; +import { + generateMappingFromJson, + // Renamed to avoid conflict + MappingOptions as JsonMappingOptions, +} from "../services/generateEsMappingFromJSON"; +import { validateCSVHeaders } from "../validations"; +import { parseCSVLine } from "../utils/csvParser"; +import { Logger } from "../utils/logger"; +import { CONFIG_PATHS } from "../utils/paths"; +import { ElasticsearchMapping } from "../types/elasticsearch"; +import { ElasticsearchField } from "../types/elasticsearch"; + +// Local interface for mapping options +interface MappingOptions { + index_pattern?: string; + number_of_shards?: number; + number_of_replicas?: number; + ignoredFields?: string[]; + skipMetadata?: boolean; +} + +export class MappingCommand extends Command { + // Define mapping-specific defaults + protected readonly defaultOutputFileName = "mapping.json"; + + constructor() { + super("Elasticsearch Mapping", CONFIG_PATHS.elasticsearch.dir); + // Override the default filename from the base class + this.defaultOutputFileName = "mapping.json"; + } + + /** + * Recursively count fields in an Elasticsearch mapping + */ + private countFields(properties: Record): number { + let count = 0; + + const recurseCount = (props: Record) => { + for (const [, field] of Object.entries(props)) { + count++; + + // Recursively count nested object or nested type properties + if (field.properties) { + recurseCount(field.properties); + } + } + }; + + recurseCount(properties); + return count; + } + + /** + * Analyze field types in an Elasticsearch mapping + */ + private analyzeFieldTypes(properties: Record): { + topLevelFields: number; + nestedFields: number; + typeDistribution: Record; + } { + let topLevelFields = 0; + let nestedFields = 0; + const typeDistribution: Record = {}; + + const analyzeRecursive = ( + props: Record, + isTopLevel: boolean = true + ) => { + for (const [, field] of Object.entries(props)) { + // Count top-level vs nested fields + if (isTopLevel) topLevelFields++; + else nestedFields++; + + // Track field types + const type = field.type; + typeDistribution[type] = (typeDistribution[type] || 0) + 1; + + // Recursively analyze nested properties + if (field.properties) { + analyzeRecursive(field.properties, false); + } + } + }; + + analyzeRecursive(properties); + + return { + topLevelFields, + nestedFields, + typeDistribution, + }; + } + + /** + * Override isUsingDefaultPath to handle mapping-specific defaults + */ + protected isUsingDefaultPath(cliOutput: CLIOutput): boolean { + return ( + cliOutput.outputPath === CONFIG_PATHS.elasticsearch.mapping || + cliOutput.outputPath === + path.join(CONFIG_PATHS.elasticsearch.dir, "mapping.json") || + super.isUsingDefaultPath(cliOutput) + ); + } + + protected async validate(cliOutput: CLIOutput): Promise { + await super.validate(cliOutput); + + // Validate file extensions + const validExtensions = [".csv", ".json"]; + const invalidFiles = cliOutput.filePaths.filter( + (filePath) => + !validExtensions.includes(path.extname(filePath).toLowerCase()) + ); + + if (invalidFiles.length > 0) { + throw new ComposerError( + "Invalid file types detected. Only .csv and .json files are supported", + ErrorCodes.INVALID_FILE, + { invalidFiles } + ); + } + + // Ensure all files are the same type + const extensions = new Set( + cliOutput.filePaths.map((filePath) => + path.extname(filePath).toLowerCase() + ) + ); + if (extensions.size > 1) { + throw new ComposerError( + "For now all input files must be of the same type (either all CSV or all JSON)", + ErrorCodes.INVALID_FILE, + Logger.warn( + "Merging JSON and CSV data into a single mapping will part of a future release" + ) + ); + } + + // Validate index pattern + if (cliOutput.config.elasticsearch?.index) { + if (!/^[a-z0-9][a-z0-9_-]*$/.test(cliOutput.config.elasticsearch.index)) { + throw new ComposerError( + "Invalid index pattern. Must start with a letter or number and contain only lowercase letters, numbers, hyphens, and underscores", + ErrorCodes.INVALID_ARGS + ); + } + } + } + + protected async execute(cliOutput: CLIOutput): Promise { + // Start execution timing + const startTime = Date.now(); + + let outputPath = cliOutput.outputPath!; + + // Normalize output path for mapping files specifically + if (fs.existsSync(outputPath) && fs.statSync(outputPath).isDirectory()) { + outputPath = path.join(outputPath, this.defaultOutputFileName); + Logger.debug( + `Output is a directory, will create ${this.defaultOutputFileName} inside it` + ); + } else if (!outputPath.endsWith(".json")) { + outputPath += ".json"; + Logger.info`Adding .json extension to output path`; + } + + try { + const mappingOptions: MappingOptions = { + index_pattern: cliOutput.config.elasticsearch?.index || "default", + number_of_shards: cliOutput.config.elasticsearch?.shards || 1, + number_of_replicas: cliOutput.config.elasticsearch?.replicas || 0, + ignoredFields: cliOutput.config.elasticsearch?.ignoredFields || [], + skipMetadata: cliOutput.config.elasticsearch?.skipMetadata || false, + }; + + Logger.debugObject("Mapping options", mappingOptions); + + // Generate mapping based on file type + const fileExtension = path.extname(cliOutput.filePaths[0]).toLowerCase(); + const isCSV = fileExtension === ".csv"; + + const finalMapping = isCSV + ? await this.handleCSVMapping( + cliOutput.filePaths, + cliOutput.config.delimiter, + mappingOptions + ) + : await this.handleJSONMapping(cliOutput.filePaths, mappingOptions); + + // Ensure output directory exists + const outputDir = path.dirname(outputPath); + this.createDirectoryIfNotExists(outputDir); + + // Write mapping to file + fs.writeFileSync(outputPath, JSON.stringify(finalMapping, null, 2)); + + // Show summary + this.logMappingSummary(finalMapping, outputPath, mappingOptions); + + // Track total execution time + const executionTime = Date.now() - startTime; + Logger.timing("Execution completed in", executionTime); + + return finalMapping; + } catch (error) { + if (error instanceof ComposerError) { + throw error; + } + throw new ComposerError( + "Error generating Elasticsearch mapping", + ErrorCodes.GENERATION_FAILED, + error + ); + } + } + + private async handleCSVMapping( + filePaths: string[], + delimiter: string, + options: MappingOptions + ) { + const allHeaders: Set = new Set(); + const sampleData: Record = {}; + + // Track per-file processing + let processedFileCount = 0; + + for (const filePath of filePaths) { + const fileStartTime = Date.now(); + Logger.info`Processing CSV file: ${path.basename(filePath)}`; + + // Validate CSV structure + const csvHeadersValid = await validateCSVHeaders(filePath, delimiter); + if (!csvHeadersValid) { + throw new ComposerError( + `CSV file ${filePath} has invalid headers`, + ErrorCodes.VALIDATION_FAILED + ); + } + + // Parse file content + const fileContent = fs.readFileSync(filePath, "utf-8"); + const [headerLine, sampleLine] = fileContent.split("\n"); + + if (!headerLine || !sampleLine) { + throw new ComposerError( + `CSV file ${filePath} must contain at least a header row and one data row`, + ErrorCodes.INVALID_FILE + ); + } + + // Extract headers and sample data + const headers = parseCSVLine(headerLine, delimiter, true)[0]; + const sampleValues = parseCSVLine(sampleLine, delimiter, false)[0]; + + if (!headers || !sampleValues) { + throw new ComposerError( + `Failed to parse CSV headers or sample data in ${filePath}`, + ErrorCodes.INVALID_FILE + ); + } + + // Merge headers and sample data + const originalHeaderCount = allHeaders.size; + headers.forEach((header: string, index: number) => { + allHeaders.add(header); + if (!sampleData[header]) { + sampleData[header] = sampleValues[index]?.toString() || ""; + } + }); + + const newHeaders = allHeaders.size - originalHeaderCount; + processedFileCount++; + + Logger.debug( + `Found ${headers.length} fields in ${path.basename( + filePath + )} (${newHeaders} new fields)` + ); + + // Show timing for large files + const fileEndTime = Date.now(); + if (fileEndTime - fileStartTime > 500) { + // Only show timing if processing took over 500ms + Logger.timing( + `Processed file ${processedFileCount}/${filePaths.length}`, + fileEndTime - fileStartTime + ); + } + } + + Logger.debug`Total unique fields found: ${allHeaders.size}`; + return generateMappingFromCSV( + Array.from(allHeaders), + sampleData, + options.index_pattern || "default", + { skipMetadata: options.skipMetadata } + ); + } + + private async handleJSONMapping( + filePaths: string[], + options: MappingOptions + ) { + const filePath = filePaths[0]; + Logger.info`Processing JSON file: ${path.basename(filePath)}`; + + // Convert from local MappingOptions to JsonMappingOptions + const jsonOptions: JsonMappingOptions = { + ignoredFields: options.ignoredFields, + skipMetadata: options.skipMetadata, // Pass the skipMetadata option + }; + + return generateMappingFromJson( + filePath, + options.index_pattern || "default", + jsonOptions + ); + } + private logMappingSummary( + mapping: ElasticsearchMapping, + outputPath: string, + options: MappingOptions + ): void { + try { + // Index pattern info + Logger.info(`Index Pattern created: ${mapping.index_patterns[0]}`); + + // Aliases info + const aliasNames = Object.keys(mapping.aliases); + if (aliasNames.length > 0) { + Logger.info(`Alias(es) used: ${aliasNames.join(", ")}`); + } else { + Logger.info("No aliases defined"); + } + + // Fields info with count + const fieldCount = this.countFields(mapping.mappings.properties); + + // Breakdown of field types + const fieldBreakdown = this.analyzeFieldTypes( + mapping.mappings.properties + ); + + // Log detailed field information + Logger.info( + `Field Analysis: ${fieldCount} total fields\n` + + ` • Top-level fields: ${fieldBreakdown.topLevelFields}\n` + + ` • Nested array fields: ${fieldBreakdown.nestedFields}\n` + + ` • Field types: ${Object.entries(fieldBreakdown.typeDistribution) + .map(([type, count]) => `${count} ${type}`) + .join(", ")}` + ); + + // Metadata skipping info + if (options.skipMetadata) { + Logger.info("Submission metadata excluded from mapping"); + } + + // Shards and replicas + Logger.info(`Shards: ${mapping.settings.number_of_shards}`); + Logger.info(`Replicas: ${mapping.settings.number_of_replicas}`); + + // Ensure success logging + Logger.success("Elasticsearch mapping generated successfully"); + + // Use generic logging for file path to avoid template literal issues + Logger.generic(`Mapping template saved to: ${outputPath}`); + } catch (error) { + // Fallback logging in case of any unexpected errors + Logger.error("Error in logging mapping summary"); + Logger.debug(`${error}`); + } + } +} diff --git a/apps/composer/src/commands/songCommand.ts b/apps/composer/src/commands/songCommand.ts new file mode 100644 index 00000000..db4dc23f --- /dev/null +++ b/apps/composer/src/commands/songCommand.ts @@ -0,0 +1,193 @@ +import * as path from "path"; +import * as fs from "fs"; +import { Command } from "./baseCommand"; +import { CLIOutput } from "../types"; +import { ComposerError, ErrorCodes } from "../utils/errors"; +import { + generateSongSchema, + validateSongSchema, +} from "../services/generateSongSchema"; +import { validateFile, validateEnvironment } from "../validations"; +import { Profiles } from "../types"; +import { Logger } from "../utils/logger"; +import { CONFIG_PATHS } from "../utils/paths"; + +export class SongCommand extends Command { + constructor() { + super("Song Schema", CONFIG_PATHS.song.dir); + } + + private sanitizeSchemaName(name: string): string { + const sanitized = name + .replace(/\s+/g, "_") // Replace spaces with underscores + .replace(/[^\w-]/g, "") // Remove non-word chars (except hyphens) + .replace(/^[^a-zA-Z]+/, "") // Remove leading non-letters + .replace(/^$/, "schema"); // Use 'schema' if empty after sanitization + + if (sanitized !== name) { + Logger.warn`Schema name "${name}" will be sanitized to "${sanitized}"`; + } + + return sanitized; + } + + /** + * Override isUsingDefaultPath to handle Song schema-specific defaults + */ + protected isUsingDefaultPath(cliOutput: CLIOutput): boolean { + return ( + cliOutput.outputPath === CONFIG_PATHS.song.schema || + cliOutput.outputPath === + path.join(CONFIG_PATHS.song.dir, "songSchema.json") || + super.isUsingDefaultPath(cliOutput) + ); + } + + protected async validate(cliOutput: CLIOutput): Promise { + Logger.debug("Starting SongCommand validation"); + await super.validate(cliOutput); + + // Ensure only one JSON file is provided + if (cliOutput.filePaths.length !== 1) { + Logger.debug( + `Invalid number of JSON files: ${cliOutput.filePaths.length}` + ); + throw new ComposerError( + "You must provide exactly one JSON file", + ErrorCodes.INVALID_ARGS + ); + } + + if (!cliOutput.outputPath) { + Logger.debug("Output path validation failed"); + throw new ComposerError( + "Output path is required", + ErrorCodes.INVALID_ARGS + ); + } + + // Validate and sanitize schema name if provided + if (cliOutput.songConfig?.name) { + this.sanitizeSchemaName(cliOutput.songConfig.name); + } + + // Validate file type and accessibility + const filePath = cliOutput.filePaths[0]; + const fileExtension = path.extname(filePath).toLowerCase(); + Logger.debug`Validating file extension: ${fileExtension}`; + + if (fileExtension !== ".json") { + Logger.debug("File extension validation failed - not JSON"); + throw new ComposerError( + "Song schema generation requires a JSON input file", + ErrorCodes.INVALID_FILE + ); + } + + const fileValid = await validateFile(filePath); + if (!fileValid) { + Logger.debug`File not found or invalid: ${filePath}`; + throw new ComposerError( + `Invalid file ${filePath}`, + ErrorCodes.INVALID_FILE + ); + } + + Logger.debug("SongCommand validation completed successfully"); + } + + protected async execute(cliOutput: CLIOutput): Promise { + Logger.debug("Starting SongCommand execution"); + const outputPath = cliOutput.outputPath!; + const filePath = cliOutput.filePaths[0]; + + try { + Logger.info`Reading JSON input: ${path.basename(filePath)}`; + const fileContent = fs.readFileSync(filePath, "utf-8"); + let sampleData: Record; + + try { + sampleData = JSON.parse(fileContent); + } catch (error) { + Logger.debug`JSON parsing failed: ${error}`; + throw new ComposerError( + "Invalid JSON file", + ErrorCodes.INVALID_FILE, + error + ); + } + + // Validate JSON structure - only require experiment object + if (!sampleData || !sampleData.experiment) { + Logger.debug("Invalid JSON structure - missing experiment object"); + throw new ComposerError( + "JSON must contain an experiment object", + ErrorCodes.VALIDATION_FAILED + ); + } + + // Determine schema name + const schemaName = cliOutput.songConfig?.name + ? this.sanitizeSchemaName(cliOutput.songConfig.name) + : this.sanitizeSchemaName( + path.basename(filePath, path.extname(filePath)) + ); + + Logger.debug`Using schema name: ${schemaName}`; + + // Configure schema options with both fileTypes and externalValidations + const songOptions = { + fileTypes: cliOutput.songConfig?.fileTypes || [], + externalValidations: [], + }; + + if (songOptions.fileTypes.length > 0) { + Logger.debug( + `Configured file types: ${songOptions.fileTypes.join(", ")}` + ); + } + + // Generate and validate schema + Logger.info("Generating schema"); + const songSchema = generateSongSchema( + sampleData, + schemaName, + songOptions + ); + + Logger.debug("Validating generated schema"); + if (!validateSongSchema(songSchema)) { + Logger.debug("Generated schema validation failed"); + throw new ComposerError( + "Generated schema validation failed", + ErrorCodes.VALIDATION_FAILED + ); + } + + // Ensure output directory exists + await validateEnvironment({ + profile: Profiles.GENERATE_SONG_SCHEMA, + outputPath: outputPath, + }); + + // Write schema to file + fs.writeFileSync(outputPath, JSON.stringify(songSchema, null, 2)); + + Logger.success`Schema template saved to ${outputPath}`; + Logger.warn( + "Remember to update your schema with any specific validation requirements, including fileTypes and externalValidations options." + ); + } catch (error) { + Logger.debug`Error during execution: ${error}`; + if (error instanceof ComposerError) { + Logger.error(error.message); + throw error; + } + throw new ComposerError( + "Error generating SONG schema", + ErrorCodes.GENERATION_FAILED, + error + ); + } + } +} diff --git a/apps/composer/src/main.ts b/apps/composer/src/main.ts new file mode 100644 index 00000000..57730fa5 --- /dev/null +++ b/apps/composer/src/main.ts @@ -0,0 +1,76 @@ +#!/usr/bin/env node + +/** + * Conductor Main Entry Point + * + * This is the main entry point for the Conductor CLI application. + * It orchestrates the high-level application flow by: + * 1. Setting up the CLI environment and parsing arguments + * 2. Creating the appropriate command based on the provided profile + * 3. Executing the command + * 4. Handling any errors that occur during execution + * + * The application follows a layered architecture: + * - main.ts (this file): Application entry point and orchestration + * - cli.ts: Command-line argument parsing and environment setup + * - commandFactory.ts: Command instance creation based on profile + * - baseCommand.ts: Common command functionality and execution framework + * - Individual command implementations: Specific business logic + * + * Error handling is centralized through the handleError utility, + * which ensures consistent error reporting across the application. + * + * Usage: + * $ conductor [options] + * + * Example: + * $ conductor upload --file data.csv --index my-index + */ + +import { setupCLI } from "./cli"; +import { CommandFactory } from "./commands/Commandfactory"; +import { handleError } from "./utils/errors"; +import { Logger } from "./utils/logger"; +import chalk from "chalk"; + +/** + * Main application function that orchestrates the entire execution flow. + * + * This async function: + * 1. Sets up the CLI and obtains parsed arguments + * 2. Creates an appropriate command instance via the CommandFactory + * 3. Executes the command with the parsed arguments + * 4. Delegates error handling to the central error handler + * + * The function is designed to clearly separate concerns: + * - CLI setup and argument parsing + * - Command selection and creation + * - Command execution + * - Error handling + */ +async function main() { + try { + // Initialize logger first thing + const cliOutput = await setupCLI(); + + Logger.header(`Conductor: Data Processing Utilities`); + console.log(chalk.grey.italic` Version: 1.0.0`); + console.log(chalk.grey.italic` Profile: ${cliOutput.profile}`); + Logger.generic(" "); + Logger.initialize(); + Logger.debug`Starting CLI setup`; + + Logger.debug`Creating command instance`; + const command = CommandFactory.createCommand(cliOutput.profile); + + Logger.debug`Running command`; + await command.run(cliOutput); + } catch (error) { + // Let the handleError function handle this error + handleError(error); + // This line will never be reached due to process.exit in handleError + } +} + +// Execute the main function and catch any unhandled errors +main().catch(handleError); diff --git a/apps/composer/src/services/generateArrangerConfigs.ts b/apps/composer/src/services/generateArrangerConfigs.ts new file mode 100644 index 00000000..54c175c1 --- /dev/null +++ b/apps/composer/src/services/generateArrangerConfigs.ts @@ -0,0 +1,426 @@ +import { Logger } from "../utils/logger"; +import type { + ArrangerBaseConfig, + ExtendedField, + ArrangerExtendedConfig, + TableColumn, + ArrangerTableConfig, + FacetAggregation, + ArrangerFacetsConfig, +} from "../types"; +import type { ElasticsearchMapping, ElasticsearchField } from "../types"; + +// ---- Field Name Formatting Utilities ---- + +/** + * Joins path segments with dots to create standard field names + * Example: ['data', 'user', 'name'] → 'data.user.name' + */ +function formatFieldName(path: string[]): string { + return path.join("."); +} + +/** + * Joins path segments with double underscores for facet field names + * Example: ['data', 'user', 'name'] → 'data__user__name' + */ +function formatFacetFieldName(path: string[]): string { + return path.join("__"); +} + +/** + * Formats field names for display by capitalizing words and replacing separators + * Removes container prefix (like 'data') for cleaner display + * Example: 'data.user.first_name' → 'User First Name' + */ +function formatDisplayName(fieldName: string): string { + // Split by dots and remove the container field if present + const parts = fieldName.split(/[._]/); + if (parts.length > 1 && isContainerField(parts[0])) { + parts.shift(); // Remove the container field + } + + return parts + .map((word) => word.charAt(0).toUpperCase() + word.slice(1)) + .join(" "); +} + +// ---- Path and Query Generation ---- + +/** + * Generates a proper JSON path for a nested field in Elasticsearch + * Correctly formats paths for nested arrays with hits.edges[*].node structure + * + * @param fieldPath Array of path segments to the field + * @param fieldTypeMap Map of field paths to their Elasticsearch types + * @returns Properly formatted jsonPath string + */ +function generateJsonPath( + fieldPath: string[], + fieldTypeMap: Map +): string | undefined { + if (fieldPath.length <= 1) { + return undefined; + } + + // Start with root + let path = "$"; + let currentPathSegments: string[] = []; + + // Build the path segment by segment with appropriate nesting structure + for (let i = 0; i < fieldPath.length; i++) { + const segment = fieldPath[i]; + currentPathSegments.push(segment); + + // Add the current segment to the path + path += `.${segment}`; + + // Check if this segment is a nested type and not the last segment + if (i < fieldPath.length - 1) { + const currentPath = currentPathSegments.join("."); + const fieldType = fieldTypeMap.get(currentPath); + + // Add the hits.edges[*].node structure for nested types + if (fieldType === "nested") { + path += ".hits.edges[*].node"; + } + } + } + + return path; +} + +/** + * Generates a GraphQL query string for a nested field + * Creates a properly nested query structure following Arranger's requirements + * + * @param fieldPath Array of path segments to the field + * @param fieldTypeMap Map of field paths to their Elasticsearch types + * @returns GraphQL query string + */ +function generateGraphQLQuery( + fieldPath: string[], + fieldTypeMap: Map +): string | undefined { + if (fieldPath.length <= 1) { + return undefined; + } + + // Build the query from bottom up + let query = fieldPath[fieldPath.length - 1]; + let currentPathSegments: string[] = [...fieldPath]; + + // Remove the last element as we've already added it + currentPathSegments.pop(); + + // Work backwards through the path to create the nested structure + while (currentPathSegments.length > 0) { + // Get the last segment in our current path + const segment = currentPathSegments.pop(); + + // Build the path string to check if this is a nested field + const checkPath = fieldPath + .slice(0, currentPathSegments.length + 1) + .join("."); + const fieldType = fieldTypeMap.get(checkPath); + + // For fields that are marked as 'nested' type in Elasticsearch + if (fieldType === "nested") { + query = `${segment} { hits { edges { node { ${query} } } } }`; + } else { + // Standard object nesting + query = `${segment} { ${query} }`; + } + } + + return query; +} + +// ---- Field Processing ---- + +/** + * Processes Elasticsearch mapping fields to generate Arranger configurations + * Handles nested fields recursively and generates extended fields, table columns, and facet aggregations + * + * @param properties The Elasticsearch mapping properties to process + * @param parentPath Optional array of parent path segments + * @param fieldTypeMap Map of field paths to their Elasticsearch types + * @returns Object containing extended fields, table columns, and facet aggregations + */ +function processFields( + properties: Record, + parentPath: string[] = [], + fieldTypeMap: Map = new Map() +): { + extendedFields: ExtendedField[]; + tableColumns: TableColumn[]; + facetAggregations: FacetAggregation[]; +} { + Logger.debug`Processing fields with parent path: ${parentPath.join(".")}`; + + const extendedFields: ExtendedField[] = []; + const tableColumns: TableColumn[] = []; + const facetAggregations: FacetAggregation[] = []; + + // Process each field in the Elasticsearch mapping + for (const [fieldName, field] of Object.entries(properties)) { + // Skip fields with problematic characters that would cause GraphQL errors + if (fieldName.includes(".") || fieldName.includes("-")) { + Logger.debug`Skipping field with problematic name: ${fieldName}`; + continue; + } + + const currentPath = [...parentPath, fieldName]; + const formattedFieldName = formatFieldName(currentPath); + + // Track if this is a submission_metadata field + const isSubmissionMetadata = + fieldName === "submission_metadata" || + currentPath.includes("submission_metadata"); + + if (isSubmissionMetadata) { + Logger.debug`Processing submission_metadata field (will be hidden by default): ${fieldName}`; + } + + // Store this field's type in the map for reference when building queries + fieldTypeMap.set(formattedFieldName, field.type); + + // Add to extended fields with display name and isArray flag for nested arrays + const extendedField: ExtendedField = { + displayName: formatDisplayName(formattedFieldName), + fieldName: formattedFieldName, + }; + + // Add isArray property for nested type fields + if (field.type === "nested") { + extendedField.isArray = true; + } + + extendedFields.push(extendedField); + Logger.debug`Added extended field: ${formattedFieldName}`; + + // Handle nested and object types + if (field.type === "nested" || field.type === "object") { + Logger.debug`Processing nested/object field: ${formattedFieldName}`; + + // Skip adding nested/object fields to table columns + // We only want primitive fields in the table + Logger.debug`Skipping table column for nested/object field: ${formattedFieldName}`; + + // Recursively process nested properties if they exist + if (field.properties) { + const nestedResults = processFields( + field.properties, + currentPath, + fieldTypeMap + ); + + // Add the results from nested processing + extendedFields.push(...nestedResults.extendedFields); + tableColumns.push(...nestedResults.tableColumns); + facetAggregations.push(...nestedResults.facetAggregations); + } + } + // Process regular (non-object) fields + else { + // Add to table columns - primitive fields are sortable + const tableColumn: TableColumn = { + canChangeShow: true, + fieldName: formattedFieldName, + // Show if it's shallow enough in the tree and not submission_metadata + show: + isShallowField(currentPath, parentPath[0]) && !isSubmissionMetadata, + sortable: true, + }; + + // Add special display type for size fields + if (fieldName === "size" || fieldName.endsWith("_size")) { + tableColumn.displayType = "bytes"; + } + + // Add jsonPath and query for nested fields (2+ segments) + if (currentPath.length > 1) { + const jsonPath = generateJsonPath(currentPath, fieldTypeMap); + const query = generateGraphQLQuery(currentPath, fieldTypeMap); + + if (jsonPath && query) { + tableColumn.jsonPath = jsonPath; + tableColumn.query = query; + } + } + + tableColumns.push(tableColumn); + Logger.debug`Added table column: ${formattedFieldName}`; + + // Add to facet aggregations for searchable field types + if (isSearchableField(field)) { + const facetAggregation = { + active: !isSubmissionMetadata, // Not active if it's submission_metadata + fieldName: formatFacetFieldName(currentPath), + show: !isSubmissionMetadata, // Not shown if it's submission_metadata + }; + facetAggregations.push(facetAggregation); + Logger.debug`Added facet: ${formatFacetFieldName( + currentPath + )} (active: ${!isSubmissionMetadata})`; + } + } + } + + return { extendedFields, tableColumns, facetAggregations }; +} + +/** + * Determines if a field should be displayed by default based on its path depth + */ +function isShallowField(path: string[], containerField?: string): boolean { + // Fields directly at the root level are shown + if (path.length <= 2) { + return true; + } + + // Fields at the 3rd level are shown if under a container like 'data' + if (path.length === 3 && isContainerField(containerField)) { + return true; + } + + // All other fields are hidden by default + return false; +} + +/** + * Determines if a field is a container object (like 'data') + */ +function isContainerField(fieldName?: string): boolean { + if (!fieldName) return false; + + // Only consider "data" as a container field + return fieldName.toLowerCase() === "data"; +} + +/** + * Determines if a field is searchable (can be used in facets) + */ +function isSearchableField(field: ElasticsearchField): boolean { + return ["keyword", "text", "integer", "float", "date", "boolean"].includes( + field.type + ); +} + +/** + * Main function to generate Arranger configurations from Elasticsearch mapping + * Creates four configuration files: + * - base.json: Basic index configuration + * - extended.json: Field display names and metadata + * - table.json: Table column configuration + * - facets.json: Search facet configuration + */ +export function generateArrangerConfigs( + mapping: ElasticsearchMapping, + indexName: string = "data", + documentType: "file" | "analysis" = "file" +): { + base: ArrangerBaseConfig; + extended: ArrangerExtendedConfig; + table: ArrangerTableConfig; + facets: ArrangerFacetsConfig; +} { + Logger.info`Generating Arranger configs for index: ${indexName}`; + Logger.info`Document type: ${documentType}`; + + try { + // Extract the mapping properties, preserving the structure + let mappingProperties = mapping.mappings.properties; + let basePath: string[] = []; + + // Create a map to store field types for reference during query generation + const fieldTypeMap = new Map(); + + // Store the initial mapping structure for better debugging + Logger.debug("Analyzing initial mapping structure"); + + // Find all field types from the Elasticsearch mapping and store them + function recursivelyTrackFieldTypes( + properties: Record, + path: string[] = [] + ): void { + for (const [fieldName, field] of Object.entries(properties)) { + const currentPath = [...path, fieldName]; + const formattedPath = currentPath.join("."); + + // Store this field's type + fieldTypeMap.set(formattedPath, field.type); + Logger.debug(`Field: ${formattedPath}, Type: ${field.type}`); + + // Recursively process nested properties + if (field.properties) { + recursivelyTrackFieldTypes(field.properties, currentPath); + } + } + } + + // Track field types for the entire mapping + recursivelyTrackFieldTypes(mappingProperties); + + // Detect if we have a top-level container field like 'data' + // and set up the base path accordingly + for (const [topFieldName, topField] of Object.entries(mappingProperties)) { + if (topField.type === "object" && topField.properties) { + Logger.info`Found top-level object field '${topFieldName}', will use as base path`; + basePath = [topFieldName]; + break; + } + } + + // Process fields with or without a base path + Logger.info`Using base path: ${ + basePath.length ? basePath.join(".") : "(none)" + }`; + + // Extract fields to process - if we have a base path, use properties from that field + const fieldsToProcess = + basePath.length > 0 + ? (mappingProperties[basePath[0]] as ElasticsearchField).properties || + {} + : mappingProperties; + + // Process the fields, passing along the field type map + const { extendedFields, tableColumns, facetAggregations } = processFields( + fieldsToProcess, + basePath, + fieldTypeMap + ); + + Logger.info`Generated ${extendedFields.length} extended fields`; + Logger.info`Generated ${tableColumns.length} table columns`; + Logger.info`Generated ${facetAggregations.length} facet aggregations`; + + // Create configurations + const configs = { + base: { + documentType, + index: indexName, + }, + extended: { + extended: extendedFields, + }, + table: { + table: { + columns: tableColumns, + }, + }, + facets: { + facets: { + aggregations: facetAggregations, + }, + }, + }; + + Logger.debug("Configuration generated successfully"); + return configs; + } catch (error) { + Logger.error("Error generating Arranger configurations"); + Logger.error(`${error}`); + throw error; + } +} diff --git a/apps/composer/src/services/generateEsMappingFromCSV.ts b/apps/composer/src/services/generateEsMappingFromCSV.ts new file mode 100644 index 00000000..11c87e85 --- /dev/null +++ b/apps/composer/src/services/generateEsMappingFromCSV.ts @@ -0,0 +1,361 @@ +import { Logger } from "../utils/logger"; +import type { ElasticsearchMapping, ElasticsearchField } from "../types"; +import { ComposerError, ErrorCodes } from "../utils/errors"; + +// ---- Type Inference Configuration ---- + +/** + * Rules for inferring Elasticsearch field types from CSV data + * Controls how different field types are detected and handled + */ +interface TypeInferenceRules { + maxTextLength: number; // Length at which strings become 'text' instead of 'keyword' + datePatterns: string[]; // Field names that suggest date content + excludePatterns: string[]; // Field names to treat carefully (e.g., sensitive data) + booleanValues: string[]; // Valid values for boolean fields +} + +/** + * Configuration options for mapping generation + */ +export interface CSVMappingOptions { + skipMetadata?: boolean; // Whether to skip adding submission metadata + customRules?: Partial; // Custom type inference rules +} + +/** + * Default rules for type inference + */ +const defaultRules: TypeInferenceRules = { + maxTextLength: 256, + datePatterns: ["date", "time", "timestamp", "created", "updated", "modified"], + excludePatterns: ["password", "secret", "key", "token"], + booleanValues: ["true", "false", "yes", "no", "0", "1"], +}; + +/** + * Validates if a string could be a valid date + */ +function isValidDate(dateString: string): boolean { + const date = new Date(dateString); + return date instanceof Date && !isNaN(date.getTime()); +} + +/** + * Infers Elasticsearch field types from CSV headers and sample data + * Handles different data types based on content and naming patterns + * + * Type Inference Rules: + * - null/undefined/empty → keyword with null_value + * - numbers → integer or float + * - booleans → boolean (based on common boolean values) + * - strings → date, text, or keyword based on content and field name + * + * @example + * inferFieldType("user_id", "123") → { type: "integer" } + * inferFieldType("description", "very long text...") → { type: "text" } + * inferFieldType("is_active", "true") → { type: "boolean" } + */ +export function inferFieldType( + headerName: string, + sampleValue: string, + rules: TypeInferenceRules = defaultRules +): ElasticsearchField { + try { + Logger.debug`Inferring type for field: ${headerName}`; + + // Handle empty values + if (!sampleValue || sampleValue.trim() === "") { + Logger.debug( + "Empty value detected, defaulting to keyword with null value" + ); + return { type: "keyword" as const, null_value: "No Data" }; + } + + // Handle sensitive data patterns + if ( + rules.excludePatterns.some((pattern) => + headerName.toLowerCase().includes(pattern) + ) + ) { + Logger.debug("Field matches exclude pattern, setting as keyword"); + return { type: "keyword" as const }; + } + + // Check for numeric fields + if (!isNaN(Number(sampleValue))) { + if (Number.isInteger(Number(sampleValue))) { + Logger.debug("Detected integer type"); + return { type: "integer" as const }; + } + Logger.debug("Detected float type"); + return { type: "float" as const }; + } + + // Check for boolean fields + const lowerValue = sampleValue.toLowerCase(); + if (rules.booleanValues.includes(lowerValue)) { + Logger.debug("Detected boolean type"); + return { type: "boolean" as const }; + } + + // Check for dates based on header name + if ( + rules.datePatterns.some((pattern) => + headerName.toLowerCase().includes(pattern) + ) + ) { + // If the sample value is a valid date, use date type + if (isValidDate(sampleValue)) { + Logger.debug("Detected date type"); + return { type: "date" as const }; + } + } + + // Check string length for keyword vs text + if (sampleValue.length > rules.maxTextLength) { + Logger.debug("Detected text type (long string)"); + return { type: "text" as const }; + } + + // Default to keyword for shorter strings + Logger.debug("Detected keyword type"); + return { type: "keyword" as const }; + } catch (error) { + Logger.error("Error inferring field type"); + Logger.debugObject("Error details", { headerName, sampleValue, error }); + throw new ComposerError( + "Error inferring field type", + ErrorCodes.GENERATION_FAILED, + { headerName, sampleValue, error } + ); + } +} + +/** + * Generates Elasticsearch mapping from CSV headers and sample data + * Adds standard metadata fields and configuration + * + * @example + * // For CSV with headers: "name", "age", "email" + * generateMappingFromCSV(["name", "age", "email"], { name: "John", age: "30", email: "john@example.com" }) → { + * mappings: { + * properties: { + * data: { + * properties: { + * name: { type: "keyword" }, + * age: { type: "integer" }, + * email: { type: "keyword" }, + * submission_metadata: { ... } + * } + * } + * } + * } + * // ... other configuration + * } + */ +export function generateMappingFromCSV( + csvHeaders: string[], + sampleData: Record, + indexName: string = "data", + options: CSVMappingOptions = {} +): ElasticsearchMapping { + try { + Logger.debug("generateEsMappingFromCSV running"); + Logger.debug`Processing ${csvHeaders.length} CSV columns`; + + // Extract options + const skipMetadata = options.skipMetadata || false; + const customRules = options.customRules || {}; + + // Merge custom rules with defaults + const rules: TypeInferenceRules = { + ...defaultRules, + ...customRules, + }; + + // Log metadata skipping + if (skipMetadata) { + Logger.info`Submission metadata fields will be excluded from mapping`; + } + + // Check if using default index name + if (indexName === "default" || indexName === "data") { + Logger.defaultValueWarning( + "No index name supplied, defaulting to: data", + "--index " + ); + indexName = "data"; + } else { + Logger.info`Using index name: ${indexName}`; + } + + // Generate field mappings + Logger.info`Analyzing ${csvHeaders.length} fields for type inference`; + + const typeInferenceStart = Date.now(); + const properties: Record = {}; + + // Track field type counts for summary + let numericFieldCount = 0; + let dateFieldCount = 0; + let booleanFieldCount = 0; + let textFieldCount = 0; + let keywordFieldCount = 0; + let complexFieldCount = 0; + + csvHeaders.forEach((header) => { + const fieldType = inferFieldType(header, sampleData[header], rules); + properties[header] = fieldType; + + // Count field types for summary + switch (fieldType.type) { + case "integer": + case "float": + numericFieldCount++; + break; + case "date": + dateFieldCount++; + break; + case "boolean": + booleanFieldCount++; + break; + case "text": + textFieldCount++; + break; + case "keyword": + keywordFieldCount++; + break; + case "object": + case "nested": + complexFieldCount++; + break; + } + }); + + const typeInferenceTime = Date.now() - typeInferenceStart; + if (typeInferenceTime > 500) { + Logger.timing("Type inference", typeInferenceTime); + } + + Logger.debug`Field analysis complete`; + + // Log field type distribution if debug enabled + if (numericFieldCount > 0) { + Logger.debug`Numeric fields: ${numericFieldCount}`; + } + if (dateFieldCount > 0) { + Logger.debug`Date fields: ${dateFieldCount}`; + } + if (booleanFieldCount > 0) { + Logger.debug`Boolean fields: ${booleanFieldCount}`; + } + if (textFieldCount > 0) { + Logger.debug`Text fields: ${textFieldCount}`; + } + if (keywordFieldCount > 0) { + Logger.debug`Keyword fields: ${keywordFieldCount}`; + } + if (complexFieldCount > 0) { + Logger.debug`Complex fields: ${complexFieldCount}`; + } + + // Create data properties with or without submission metadata + const dataProperties = skipMetadata + ? { ...properties } + : { + ...properties, + submission_metadata: { + type: "object" as const, + properties: { + submitter_id: { type: "keyword" as const, null_value: "No Data" }, + processing_started: { type: "date" as const }, + processed_at: { type: "date" as const }, + source_file: { type: "keyword" as const, null_value: "No Data" }, + record_number: { type: "integer" as const }, + hostname: { type: "keyword" as const, null_value: "No Data" }, + username: { type: "keyword" as const, null_value: "No Data" }, + }, + }, + }; + + // Create complete mapping with dynamic index name + const mapping: ElasticsearchMapping = { + index_patterns: [`${indexName}-*`], + aliases: { + [`${indexName}_centric`]: {}, + }, + mappings: { + properties: { + data: { + type: "object" as const, + properties: dataProperties, + }, + }, + }, + settings: { + number_of_shards: 1, + number_of_replicas: 0, + }, + }; + + Logger.debug("Mapping configuration generated successfully"); + Logger.debugObject("Generated Mapping", mapping); + return mapping; + } catch (error) { + Logger.error("Error generating mapping from CSV"); + Logger.debugObject("Error details", { csvHeaders, error }); + throw new ComposerError( + "Error generating mapping from CSV", + ErrorCodes.GENERATION_FAILED, + { csvHeaders, error } + ); + } +} + +/** + * Merges two Elasticsearch mappings + * Combines properties while preserving other configuration + */ +export function mergeMappings( + target: ElasticsearchMapping, + source: ElasticsearchMapping +): ElasticsearchMapping { + try { + Logger.info("Combining multiple mapping configurations"); + + const targetFieldCount = Object.keys(target.mappings.properties).length; + const sourceFieldCount = Object.keys(source.mappings.properties).length; + + Logger.info`Target mapping has ${targetFieldCount} top-level properties`; + Logger.info`Source mapping has ${sourceFieldCount} top-level properties`; + + const mergedProperties = { + ...target.mappings.properties, + ...source.mappings.properties, + }; + + const mergedMapping = { + ...target, + mappings: { + properties: mergedProperties, + }, + }; + + const resultFieldCount = Object.keys(mergedProperties).length; + Logger.success( + `Mappings merged successfully (${resultFieldCount} total properties)` + ); + + Logger.debugObject("Merged Mapping", mergedMapping); + return mergedMapping; + } catch (error) { + Logger.error("Error merging mappings"); + Logger.debugObject("Error details", error); + throw new ComposerError( + "Error merging mappings", + ErrorCodes.GENERATION_FAILED, + error + ); + } +} diff --git a/apps/composer/src/services/generateEsMappingFromJSON.ts b/apps/composer/src/services/generateEsMappingFromJSON.ts new file mode 100644 index 00000000..2a7fb3e0 --- /dev/null +++ b/apps/composer/src/services/generateEsMappingFromJSON.ts @@ -0,0 +1,431 @@ +import fs from "fs"; +import path from "path"; +import { Logger } from "../utils/logger"; +import type { ElasticsearchMapping, ElasticsearchField } from "../types"; +import { ComposerError, ErrorCodes } from "../utils/errors"; + +// ---- Type Inference Configuration ---- + +/** + * Rules for inferring Elasticsearch field types from JSON data + * Controls how different field types are detected and handled + */ +interface TypeInferenceRules { + maxTextLength: number; // Length at which strings become 'text' instead of 'keyword' + datePatterns: string[]; // Field names that suggest date content + excludePatterns: string[]; // Field names to treat carefully (e.g., sensitive data) +} + +/** + * Configuration options for mapping generation + */ +export interface MappingOptions { + ignoredFields?: string[]; // Field names to exclude from mapping + skipMetadata?: boolean; // Whether to skip adding submission metadata + customRules?: Partial; // Custom type inference rules +} + +/** + * Default rules for type inference + */ +const defaultRules: TypeInferenceRules = { + maxTextLength: 256, + datePatterns: ["date", "time", "timestamp", "created", "updated", "modified"], + excludePatterns: ["password", "secret", "key", "token"], +}; + +/** + * Validates if a string represents a valid date + */ +function isValidDate(dateString: string): boolean { + const date = new Date(dateString); + return date instanceof Date && !isNaN(date.getTime()); +} + +/** + * Infers Elasticsearch field types from JSON data + * Handles nested objects, arrays, and multiple data types + * + * Type Inference Rules: + * - null/undefined → keyword with null_value + * - objects → nested object with recursive type inference + * - arrays → nested type with inferred element type + * - numbers → integer or float + * - booleans → boolean + * - strings → date, text, or keyword based on content + * + * @example + * inferFieldType("user_id", 123) → { type: "integer" } + * inferFieldType("description", "very long text...") → { type: "text" } + * inferFieldType("tags", ["red", "blue"]) → { type: "nested", properties: { value: { type: "keyword" } } } + */ +export function inferFieldType( + keyName: string, + sampleValue: any, + rules: TypeInferenceRules = defaultRules +): ElasticsearchField { + try { + Logger.debug`Inferring type for field: ${keyName}`; + + // Handle null/undefined + if (sampleValue === null || sampleValue === undefined) { + Logger.debug("Null/undefined value detected, defaulting to keyword"); + return { type: "keyword" as const, null_value: "No Data" }; + } + + // Handle sensitive data patterns + if ( + rules.excludePatterns.some((pattern) => + keyName.toLowerCase().includes(pattern) + ) + ) { + Logger.debug("Field matches exclude pattern, setting as keyword"); + return { type: "keyword" as const }; + } + + // Handle nested objects + if (typeof sampleValue === "object" && !Array.isArray(sampleValue)) { + Logger.debug`Processing nested object for ${keyName}`; + const properties: Record = {}; + for (const [key, value] of Object.entries(sampleValue)) { + properties[key] = inferFieldType(key, value, rules); + } + return { type: "object" as const, properties }; + } + + // Handle arrays + if (Array.isArray(sampleValue)) { + Logger.debug`Processing array for ${keyName}`; + + if (sampleValue.length === 0) { + return { type: "keyword" as const }; + } + + // Check if array contains objects + if ( + typeof sampleValue[0] === "object" && + sampleValue[0] !== null && + !Array.isArray(sampleValue[0]) + ) { + // For arrays of objects, directly infer properties from the first element + // This eliminates the "value" wrapper + const properties: Record = {}; + + for (const [key, value] of Object.entries(sampleValue[0])) { + properties[key] = inferFieldType(key, value, rules); + } + + return { + type: "nested" as const, + properties: properties, + }; + } else { + // For arrays of primitives, use a simpler approach + const elementType = inferFieldType( + `${keyName}_element`, + sampleValue[0], + rules + ); + + return { + type: "nested" as const, + properties: { value: elementType }, + }; + } + } + + // Handle numbers + if (typeof sampleValue === "number") { + if (Number.isInteger(sampleValue)) { + Logger.debug("Detected integer type"); + return { type: "integer" as const }; + } + Logger.debug("Detected float type"); + return { type: "float" as const }; + } + + // Handle booleans + if (typeof sampleValue === "boolean") { + Logger.debug("Detected boolean type"); + return { type: "boolean" as const }; + } + + // Handle strings + if (typeof sampleValue === "string") { + // Check for dates + if ( + rules.datePatterns.some((pattern) => + keyName.toLowerCase().includes(pattern) + ) + ) { + if (isValidDate(sampleValue)) { + Logger.debug("Detected date type"); + return { type: "date" as const }; + } + } + + // Handle long strings + if (sampleValue.length > rules.maxTextLength) { + Logger.debug("Detected text type (long string)"); + return { type: "text" as const }; + } + + Logger.debug("Detected keyword type"); + return { type: "keyword" as const }; + } + + // Default fallback + Logger.debug("Using default keyword type for unknown value type"); + return { type: "keyword" as const }; + } catch (error) { + Logger.error("Error inferring field type"); + Logger.debugObject("Error details", { keyName, sampleValue, error }); + throw new ComposerError( + "Error inferring field type", + ErrorCodes.GENERATION_FAILED, + { keyName, sampleValue, error } + ); + } +} + +/** + * Generates Elasticsearch mapping from a JSON file + * Supports both single objects and arrays of objects + * Adds standard metadata fields and configuration + * Allows configurable field exclusion and metadata skipping + * + * @example + * // For a JSON file containing: { "name": "John", "age": 30 } + * generateMappingFromJson("data.json", "users", { ignoredFields: ["createdAt"], skipMetadata: true }) → { + * mappings: { + * properties: { + * data: { + * properties: { + * name: { type: "keyword" }, + * age: { type: "integer" } + * // submission_metadata is NOT included when skipMetadata is true + * } + * } + * } + * } + * // ... other configuration + * } + */ +export function generateMappingFromJson( + jsonFilePath: string, + indexName: string, + options: MappingOptions = {} +): ElasticsearchMapping { + try { + Logger.debug("generateEsMappingFromJSON running"); + Logger.debug( + `Processing file: ${path.basename( + jsonFilePath + )} within generateEsMappingFromJSON function` + ); + + // Extract options with defaults + const ignoredFields = options.ignoredFields || []; + const skipMetadata = options.skipMetadata || false; + const customRules = options.customRules || {}; + + // Merge custom rules with defaults + const rules: TypeInferenceRules = { + ...defaultRules, + ...customRules, + }; + + // Log ignored fields if any are specified + if (ignoredFields.length > 0) { + Logger.info`Fields that will be excluded from mapping: ${ignoredFields.join( + ", " + )}`; + } + + // Log metadata skipping + if (skipMetadata) { + Logger.info`Submission metadata fields will be excluded from mapping`; + } + + // Check if using default index name + if (indexName === "default" || indexName === "data") { + Logger.defaultValueWarning( + "No index name supplied, defaulting to: data", + "--index " + ); + indexName = "data"; + } else { + Logger.info`Using index name: ${indexName}`; + } + + // Read and parse JSON + const startTime = Date.now(); + + const jsonData = JSON.parse(fs.readFileSync(jsonFilePath, "utf8")); + const parseTime = Date.now() - startTime; + + if (parseTime > 500) { + Logger.timing("JSON parsing", parseTime); + } + + if (typeof jsonData !== "object" || jsonData === null) { + throw new ComposerError( + "Invalid JSON: Expected a non-null object", + ErrorCodes.INVALID_FILE + ); + } + + // Prepare properties for mapping + let mappingProperties: Record; + + // Determine if the top-level contains a 'data' key + const hasDataKey = jsonData.hasOwnProperty("data"); + const sampleData = hasDataKey ? jsonData.data : jsonData; + + // Process the sample data, preserving the 'data' key if present + const processDataStructure = ( + data: Record + ): Record => { + const dataProperties: Record = {}; + + // Process each field in the data + Object.entries(data).forEach(([key, value]) => { + // Skip ignored fields + if (ignoredFields.includes(key)) { + Logger.debug`Ignoring field: ${key}`; + return; + } + + // Recursively process nested arrays or objects + if (Array.isArray(value) && value.length > 0) { + const firstElement = value[0]; + if (typeof firstElement === "object" && firstElement !== null) { + dataProperties[key] = { + type: "nested", + properties: processDataStructure(firstElement), + }; + } else { + // Simple array of primitives + dataProperties[key] = inferFieldType(key, value[0], rules); + } + } else if (typeof value === "object" && value !== null) { + dataProperties[key] = { + type: "object", + properties: processDataStructure(value), + }; + } else { + // Simple field + dataProperties[key] = inferFieldType(key, value, rules); + } + }); + + return dataProperties; + }; + + // Process the data structure + if (hasDataKey) { + mappingProperties = { + data: { + type: "object", + properties: processDataStructure(sampleData), + }, + }; + } else { + // If no 'data' key, use the entire object directly + mappingProperties = processDataStructure(sampleData); + } + + // Create complete mapping with dynamic index name + const mapping: ElasticsearchMapping = { + index_patterns: [`${indexName}-*`], + aliases: { + [`${indexName}_centric`]: {}, + }, + mappings: { + properties: mappingProperties, + }, + settings: { + number_of_shards: 1, + number_of_replicas: 0, + }, + }; + + Logger.debug("Mapping configuration generated successfully"); + Logger.debugObject("Generated Mapping", mapping); + return mapping; + } catch (error) { + // Type-safe error handling + const errorMessage = error instanceof Error ? error.message : String(error); + + const errorStack = + error instanceof Error ? error.stack : "No stack trace available"; + + Logger.error("Error generating mapping from JSON"); + Logger.debugObject("Error details", { + filePath: jsonFilePath, + errorMessage, + stack: errorStack, + }); + + if (error instanceof ComposerError) { + throw error; + } + throw new ComposerError( + `Error generating mapping from JSON: ${errorMessage}`, + ErrorCodes.GENERATION_FAILED, + { + filePath: jsonFilePath, + errorMessage, + stack: errorStack, + } + ); + } +} + +/** + * Merges two Elasticsearch mappings + * Combines properties while preserving other configuration + */ +export function mergeMappings( + target: ElasticsearchMapping, + source: ElasticsearchMapping +): ElasticsearchMapping { + try { + Logger.section("Merging Mappings"); + Logger.info("Combining multiple mapping configurations"); + + const targetFieldCount = Object.keys(target.mappings.properties).length; + const sourceFieldCount = Object.keys(source.mappings.properties).length; + + Logger.info`Target mapping has ${targetFieldCount} top-level properties`; + Logger.info`Source mapping has ${sourceFieldCount} top-level properties`; + + const mergedProperties = { + ...target.mappings.properties, + ...source.mappings.properties, + }; + + const mergedMapping = { + ...target, + mappings: { + properties: mergedProperties, + }, + }; + + const resultFieldCount = Object.keys(mergedProperties).length; + Logger.success( + `Mappings merged successfully (${resultFieldCount} total properties)` + ); + + Logger.debugObject("Merged Mapping", mergedMapping); + return mergedMapping; + } catch (error) { + Logger.error("Error merging mappings"); + Logger.debugObject("Error details", error); + throw new ComposerError( + "Error merging mappings", + ErrorCodes.GENERATION_FAILED, + error + ); + } +} diff --git a/apps/composer/src/services/generateLecternDictionary.ts b/apps/composer/src/services/generateLecternDictionary.ts new file mode 100644 index 00000000..5b5db334 --- /dev/null +++ b/apps/composer/src/services/generateLecternDictionary.ts @@ -0,0 +1,199 @@ +import { Logger } from "../utils/logger"; +import * as path from "path"; +import type { + LecternDictionary, + LecternSchema, + LecternField, + ValueType, + MetaData, +} from "../types"; + +// ---- Value Type Inference ---- + +/** + * Infers the Lectern value type from a field's sample data + * + * Rules: + * - Empty values → string + * - Boolean-like values → boolean (true/false, yes/no, 1/0) + * - Numeric values → integer or number + * - Default → string + * + * @example + * inferValueType("age", "25") → "integer" + * inferValueType("is_active", "true") → "boolean" + * inferValueType("score", "85.5") → "number" + * inferValueType("name", "John") → "string" + */ +export function inferValueType( + headerName: string, + sampleValue: string +): ValueType { + Logger.debug`Inferring type for field: ${headerName}`; + + // Handle empty values + if (!sampleValue || sampleValue.trim() === "") { + Logger.debug("Empty sample value detected, defaulting to string type"); + return "string"; + } + + // Check for boolean values + const lowerValue = sampleValue.toLowerCase(); + const booleanValues = ["true", "false", "yes", "no", "0", "1"]; + if (booleanValues.includes(lowerValue)) { + Logger.debug("Detected boolean type"); + return "boolean"; + } + + // Check for numeric values + if (!isNaN(Number(sampleValue))) { + if (Number.isInteger(Number(sampleValue))) { + Logger.debug("Detected integer type"); + return "integer"; + } + Logger.debug("Detected number type"); + return "number"; + } + + // Default to string type + Logger.debug("Detected string type"); + return "string"; +} + +// ---- Dictionary Generation ---- + +/** + * Creates a base Lectern dictionary structure + * Initializes an empty dictionary with metadata + * + * @example + * generateDictionary( + * "My Dictionary", + * "Sample data dictionary", + * "1.0.0" + * ) → { + * name: "My Dictionary", + * description: "Sample data dictionary", + * version: "1.0.0", + * schemas: [], + * meta: {} + * } + */ +export function generateDictionary( + dictionaryName: string, + description: string, + version: string +): LecternDictionary { + Logger.info("Generating Lectern dictionary"); + Logger.info`Dictionary Name: ${dictionaryName}`; + Logger.info`Description: ${description}`; + Logger.info`Version: ${version}`; + + const dictionary = { + name: dictionaryName, + description: description, + version: version, + meta: {}, + schemas: [], + }; + + Logger.debug`${dictionaryName} dictionary generated`; + + Logger.debugObject("Dictionary Details", dictionary); + return dictionary; +} + +// ---- Schema Generation ---- + +/** + * Generates a Lectern schema from CSV headers and sample data + * Creates field definitions with inferred types and metadata + * Uses the input file name as the schema name + * + * Process: + * 1. Maps each CSV header to a field definition + * 2. Infers value types from sample data + * 3. Adds metadata and descriptions + * 4. Assembles complete schema + * + * @example + * generateSchema( + * "patient_data.csv", + * ["name", "age", "is_active"], + * { name: "John", age: "30", is_active: "true" } + * ) → { + * name: "patient_data", + * description: "Schema generated from patient_data.csv", + * fields: [ + * { name: "name", valueType: "string", ... }, + * { name: "age", valueType: "integer", ... }, + * { name: "is_active", valueType: "boolean", ... } + * ], + * meta: { createdAt: "...", filename: "patient_data.csv" } + * } + */ +export function generateSchema( + inputFilePath: string, + csvHeaders: string[], + sampleData: Record +): LecternSchema { + // Generate schema name from file name + const schemaName = path + .basename(inputFilePath, path.extname(inputFilePath)) + .toLowerCase() + .replace(/[^a-z0-9]/g, "_"); + + Logger.info`Generating schema: ${schemaName} from file: ${inputFilePath}`; + Logger.debugObject("CSV Headers", csvHeaders); + + // Generate field definitions + const fields: LecternField[] = csvHeaders.map((header) => { + const sampleValue = sampleData[header] || ""; + const valueType = inferValueType(header, sampleValue); + + // Create field definition with metadata + const field: LecternField = { + name: header, + description: `Field containing ${header} data`, + valueType: valueType, + meta: { + displayName: header, + }, + }; + + Logger.debug`Created field definition for: ${header}`; + Logger.debugObject(`Field Details for ${header}`, field); + return field; + }); + + // Create schema with metadata + const schema: LecternSchema = { + name: schemaName, + description: `Schema generated from ${path.basename(inputFilePath)}`, + fields: fields, + meta: { + createdAt: new Date().toISOString(), + sourceFile: path.basename(inputFilePath), + }, + }; + + Logger.info`${schemaName} schema added to dictionary`; + Logger.debugObject("Schema Details", schema); + return schema; +} + +/* Usage Examples: +// Create a dictionary +const dictionary = generateDictionary("Patient Data", "Medical records schema", "1.0.0"); + +// Generate schema from CSV data +const filePath = "patient_data.csv"; +const headers = ["name", "age", "is_active"]; +const sampleData = { + name: "John Doe", + age: "30", + is_active: "true" +}; +const schema = generateSchema(filePath, headers, sampleData); +dictionary.schemas.push(schema); +*/ diff --git a/apps/composer/src/services/generateSongSchema.ts b/apps/composer/src/services/generateSongSchema.ts new file mode 100644 index 00000000..a1fa0686 --- /dev/null +++ b/apps/composer/src/services/generateSongSchema.ts @@ -0,0 +1,321 @@ +import { Logger } from "../utils/logger"; +import type { SongSchema, SongField, SongOptions } from "../types"; + +// ---- Type Inference ---- + +/** + * Infers SONG field type from property value + * + * Rules: + * - Numbers → integer or number + * - Booleans → boolean + * - Default → string + * + * @example + * inferSongType("age", 25) → "integer" + * inferSongType("score", 85.5) → "number" + * inferSongType("active", true) → "boolean" + * inferSongType("name", "sample") → "string" + */ +export function inferSongType( + propertyName: string, + value: any +): string | string[] { + Logger.debug`Inferring type for field: ${propertyName}`; + + // Handle numeric values + if (!isNaN(Number(value))) { + if (Number.isInteger(Number(value))) { + Logger.debug("Detected integer type"); + return "integer"; + } + Logger.debug("Detected number type"); + return "number"; + } + + // Handle boolean values + if (typeof value === "boolean" || value === "true" || value === "false") { + Logger.debug("Detected boolean type"); + return "boolean"; + } + + // Default to string + Logger.debug("Defaulting to string type"); + return "string"; +} + +// ---- Field Generation ---- + +/** + * Generates a SONG field definition based on value analysis + * Handles arrays, objects, and primitive types + * + * @example + * // Primitive + * generateSongField("name", "John") → { type: "string" } + * + * // Array + * generateSongField("tags", ["red", "blue"]) → { + * type: "array", + * items: { type: "string" } + * } + * + * // Object + * generateSongField("address", { city: "NY" }) → { + * type: "object", + * properties: { city: { type: "string" } }, + * required: ["city"] + * } + */ +export function generateSongField(propertyName: string, value: any): SongField { + // Handle arrays + if (Array.isArray(value)) { + Logger.debug`Generating field for array: ${propertyName}`; + const itemType = + value.length > 0 + ? generateSongField("arrayItem", value[0]) + : { type: "string" }; + + return { + type: "array", + items: itemType, + }; + } + + // Handle objects + if (typeof value === "object" && value !== null) { + Logger.debug`Generating field for object: ${propertyName}`; + const { fields, fieldNames } = generateSongFields(value); + + return { + propertyNames: { + enum: fieldNames, + }, + required: fieldNames, + type: "object", + properties: fields, + }; + } + + // Handle primitive types + Logger.debug`Generating field for primitive: ${propertyName}`; + return { + type: inferSongType(propertyName, value), + }; +} + +/** + * Generates field definitions for all properties in an object + * Preserves field order and tracks required fields + */ +export function generateSongFields(data: Record): { + fields: Record; + fieldNames: string[]; +} { + Logger.debug("Generating field definitions"); + + const fields: Record = {}; + const fieldNames: string[] = []; + + for (const propertyName of Object.keys(data)) { + try { + const value = data[propertyName]; + fields[propertyName] = generateSongField(propertyName, value); + fieldNames.push(propertyName); + Logger.debug`Generated field definition for: ${propertyName}`; + } catch (error) { + Logger.warn`Error generating field definition for ${propertyName}: ${error}`; + // Provide a minimal field definition instead of failing + fields[propertyName] = { type: "object" }; + fieldNames.push(propertyName); + } + } + + return { fields, fieldNames }; +} + +// ---- Schema Generation ---- + +/** + * Generates a complete SONG schema from sample data + * Focuses on required experiment section and optional workflow section + * + * @example + * generateSongSchema( + * { + * workflow: { name: "analysis" }, + * experiment: { id: "exp1" } + * }, + * "my_schema", + * { fileTypes: ["bam", "vcf"] } + * ) → { + * name: "my_schema", + * options: { fileTypes: ["bam", "vcf"] }, + * schema: { + * type: "object", + * required: ["experiment"], + * properties: { ... } + * } + * } + */ +export function generateSongSchema( + sampleData: Record, + schemaName: string, + options?: SongOptions +): SongSchema { + Logger.debug("Generating SONG schema"); + Logger.debug`Schema name: ${schemaName}`; + + // Extract fields from sample data, focusing on experiment (required) and workflow (optional) + const schemaFields: Record = {}; + const requiredFields: string[] = ["experiment"]; + + // Add experiment section (required) + if (sampleData.experiment) { + try { + schemaFields.experiment = generateSongField( + "experiment", + sampleData.experiment + ); + Logger.debug("Added experiment field to schema"); + } catch (error) { + Logger.warn`Error generating experiment field: ${error}`; + // Provide a minimal placeholder since experiment is required + schemaFields.experiment = { type: "object" }; + } + } else { + // If no experiment data provided, add an empty object placeholder + Logger.warn( + "No experiment data provided in sample, adding empty placeholder" + ); + schemaFields.experiment = { type: "object" }; + } + + // Add workflow section (optional) + if (sampleData.workflow) { + try { + schemaFields.workflow = generateSongField( + "workflow", + sampleData.workflow + ); + Logger.debug("Added workflow field to schema"); + // Add workflow to required fields if present in the sample + requiredFields.push("workflow"); + } catch (error) { + Logger.warn`Error generating workflow field: ${error}`; + // Add a basic field definition + schemaFields.workflow = { type: "object" }; + } + } + + // Define schema options + const schemaOptions: SongOptions = { + fileTypes: options?.fileTypes || [], + externalValidations: options?.externalValidations || [], + }; + + // Construct the full schema + const schema: SongSchema = { + name: schemaName, + options: schemaOptions, + schema: { + type: "object", + required: requiredFields, + properties: schemaFields, + }, + }; + + Logger.debug("Song schema generated successfully"); + Logger.debugObject("Generated Schema", schema); + return schema; +} + +// ---- Schema Validation ---- + +/** + * Validates a generated SONG schema + * Checks: + * - Schema name is valid + * - Schema has an experiment section + * - Required fields are defined + * - Properties are present + * + * @example + * validateSongSchema({ + * name: "my_schema", + * schema: { + * type: "object", + * required: ["experiment"], + * properties: { experiment: { type: "object" } } + * } + * }) → true/false + */ +export function validateSongSchema(schema: SongSchema): boolean { + try { + Logger.debug("Validating SONG schema"); + + // Validate schema name + if (!schema.name) { + throw new Error("Schema must have a name"); + } + if (schema.name.includes(" ")) { + throw new Error("Schema name cannot contain spaces"); + } + + // Validate schema structure + if (!schema.schema || schema.schema.type !== "object") { + throw new Error("Schema must be an object type"); + } + if (!Array.isArray(schema.schema.required)) { + throw new Error("Schema must have a required array"); + } + if ( + !schema.schema.properties || + Object.keys(schema.schema.properties).length === 0 + ) { + throw new Error("Schema must have at least one property"); + } + + // Validate experiment section is present and required + const properties = schema.schema.properties; + if (!properties.experiment) { + throw new Error("Schema must have an experiment section"); + } + if (!schema.schema.required.includes("experiment")) { + throw new Error("The experiment field must be required"); + } + + Logger.debug("Schema validation passed"); + return true; + } catch (error: unknown) { + const errorMessage = + error instanceof Error ? error.message : "Unknown error occurred"; + + Logger.debug`Schema validation failed: ${errorMessage}`; + return false; + } +} + +/* Usage Examples: +// Generate schema from sample data +const sampleData = { + workflow: { + name: "DNA-Seq Analysis", + version: "1.0" + }, + experiment: { + id: "EXP-001", + type: "sequencing", + platform: "illumina" + } +}; + +const schema = generateSongSchema( + sampleData, + "dna_seq_schema", + { fileTypes: ["fastq", "bam"] } +); + +// Validate the generated schema +const isValid = validateSongSchema(schema); +*/ diff --git a/apps/composer/src/types/arranger.ts b/apps/composer/src/types/arranger.ts new file mode 100644 index 00000000..7ecb5a4c --- /dev/null +++ b/apps/composer/src/types/arranger.ts @@ -0,0 +1,49 @@ +export interface ArrangerConfig { + documentType: "file" | "analysis"; + extendedFields?: string[]; + tableColumns?: string[]; + facetFields?: string[]; +} + +export interface ArrangerBaseConfig { + documentType: "file" | "analysis"; + index: string; +} + +export interface ExtendedField { + displayName: string; + fieldName: string; + isArray?: boolean; +} + +export interface ArrangerExtendedConfig { + extended: ExtendedField[]; +} + +export interface TableColumn { + canChangeShow: boolean; + fieldName: string; + show: boolean; + sortable: boolean; + jsonPath?: string; + query?: string; + displayType?: string; +} + +export interface ArrangerTableConfig { + table: { + columns: TableColumn[]; + }; +} + +export interface FacetAggregation { + active: boolean; + fieldName: string; + show: boolean; +} + +export interface ArrangerFacetsConfig { + facets: { + aggregations: FacetAggregation[]; + }; +} diff --git a/apps/composer/src/types/cli.ts b/apps/composer/src/types/cli.ts new file mode 100644 index 00000000..edebcc8f --- /dev/null +++ b/apps/composer/src/types/cli.ts @@ -0,0 +1,78 @@ +import { Profiles } from "./constants"; +import { ArrangerConfig } from "./arranger"; + +export type Profile = (typeof Profiles)[keyof typeof Profiles]; + +export interface Config { + elasticsearch: { + index: string; + shards: number; + replicas: number; + ignoredFields?: string[]; // Fields to exclude from mapping + skipMetadata?: boolean; // Option to skip submission metadata + }; + delimiter: string; +} + +export interface CLIOutput { + profile: Profile; + debug?: boolean; + filePaths: string[]; + force?: boolean; + config: Config; + outputPath?: string; + outputPathProvided?: boolean; + arrangerConfigDir?: string; + envConfig: EnvConfig; + delimiter?: string; + dictionaryConfig?: { + name: string; + description: string; + version: string; + }; + songConfig?: { + name?: string; + fileTypes?: string[]; + }; + arrangerConfig?: ArrangerConfig; +} + +export interface EnvConfig { + // Input files + inputFiles?: string[]; + + // Output paths + outputPath?: string; + + // Lectern Dictionary options + dictionaryName?: string; + dictionaryDescription?: string; + dictionaryVersion?: string; + + // Song Schema options + schemaName?: string; + fileTypes?: string[]; + + // Elasticsearch options + esIndex?: string; + esShards?: number; + esReplicas?: number; + esIgnoredFields?: string[]; + esSkipMetadata?: boolean; // Environment variable for skip metadata option + + // CSV options + csvDelimiter?: string; + + // Arranger options + arrangerDocType?: string; + + // Legacy variables + dataFile?: string; + indexName?: string; + fileMetadataSample?: string; + tabularSample?: string; + songSchema?: string; + lecternDictionary?: string; + esConfigDir?: string; + arrangerConfigDir?: string; +} diff --git a/apps/composer/src/types/constants.ts b/apps/composer/src/types/constants.ts new file mode 100644 index 00000000..a7e68fda --- /dev/null +++ b/apps/composer/src/types/constants.ts @@ -0,0 +1,8 @@ +export const Profiles = { + GENERATE_SONG_SCHEMA: "generateSongSchema", + GENERATE_LECTERN_DICTIONARY: "generateLecternDictionary", + GENERATE_ELASTICSEARCH_MAPPING: "generateElasticsearchMapping", + GENERATE_ARRANGER_CONFIGS: "generateArrangerConfigs", + GENERATE_CONFIGS: "generateConfigs", + DEFAULT: "default", +} as const; diff --git a/apps/composer/src/types/elasticsearch.ts b/apps/composer/src/types/elasticsearch.ts new file mode 100644 index 00000000..a34a1ca7 --- /dev/null +++ b/apps/composer/src/types/elasticsearch.ts @@ -0,0 +1,29 @@ +export interface ElasticsearchField { + type: + | "keyword" + | "integer" + | "float" + | "date" + | "object" + | "boolean" + | "nested" + | "text"; + null_value?: string; + properties?: Record; +} + +export interface ElasticsearchMapping { + index_patterns: string[]; + aliases: Record; + mappings: { + properties: Record; + }; + settings: { + number_of_shards: number; + number_of_replicas: number; + }; +} + +export interface ElasticsearchError extends Error { + name: string; +} diff --git a/apps/composer/src/types/index.ts b/apps/composer/src/types/index.ts new file mode 100644 index 00000000..7db55ccf --- /dev/null +++ b/apps/composer/src/types/index.ts @@ -0,0 +1,7 @@ +export * from "./constants"; +export * from "./cli"; +export * from "./elasticsearch"; +export * from "./arranger"; +export * from "./song"; +export * from "./lectern"; +export * from "./validations"; diff --git a/apps/composer/src/types/lectern.ts b/apps/composer/src/types/lectern.ts new file mode 100644 index 00000000..83c7a5c4 --- /dev/null +++ b/apps/composer/src/types/lectern.ts @@ -0,0 +1,91 @@ +export type ValueType = "string" | "integer" | "number" | "boolean"; +export type MatchCase = "all" | "any" | "none"; +export type CompareRelation = + | "equal" + | "notEqual" + | "contains" + | "containedIn" + | "greaterThan" + | "greaterThanOrEqual" + | "lesserThan" + | "lesserThanOrEqual"; + +export interface RangeRule { + min?: number; + max?: number; + exclusiveMin?: number; + exclusiveMax?: number; +} + +export interface FieldRestrictions { + required?: boolean; + regex?: string; + codeList?: any[]; + range?: RangeRule; + compare?: ComparedFieldsRule; + count?: number | RangeRule; + empty?: boolean; +} + +export interface ComparedFieldsRule { + fields: string | string[]; + relation: CompareRelation; + case?: MatchCase; +} + +export interface MetaData { + [key: string]: string | number | boolean | string[] | number[] | MetaData; +} + +export interface ConditionalRestriction { + if: { + conditions: Array<{ + fields: string[]; + match: { + value?: any; + codeList?: any[]; + regex?: string; + range?: RangeRule; + count?: number | RangeRule; + exists?: boolean; + }; + arrayFieldCase?: MatchCase; + case?: MatchCase; + }>; + case?: MatchCase; + }; + then: FieldRestrictions | FieldRestrictions[]; + else?: FieldRestrictions | FieldRestrictions[]; +} + +export interface LecternField { + name: string; + description?: string; + valueType: ValueType; + meta?: MetaData; + isArray?: boolean; + delimiter?: string; + restrictions?: + | FieldRestrictions + | ConditionalRestriction + | Array; + unique?: boolean; +} + +export interface LecternSchema { + name: string; + description?: string; + meta?: MetaData; + fields: LecternField[]; +} + +export interface LecternDictionary { + name: string; + version: string; + description?: string; + meta?: MetaData; + schemas: LecternSchema[]; + references?: { + [key: string]: any; + }; +} diff --git a/apps/composer/src/types/song.ts b/apps/composer/src/types/song.ts new file mode 100644 index 00000000..10f800bf --- /dev/null +++ b/apps/composer/src/types/song.ts @@ -0,0 +1,32 @@ +export interface SongOptions { + fileTypes?: string[]; + externalValidations?: Array<{ + url?: string; + jsonPath?: string; + }>; +} + +export interface SongSchema { + name: string; + options?: SongOptions; + schema: { + type: string; + required: string[]; + properties: Record; + }; +} + +export interface SongField { + type: string | string[]; + description?: string; + pattern?: string; + enum?: string[]; + items?: SongField; + properties?: Record; + required?: string[]; + propertyNames?: { + enum: string[]; + }; + minItems?: number; + maxItems?: number; +} diff --git a/apps/composer/src/types/validations.ts b/apps/composer/src/types/validations.ts new file mode 100644 index 00000000..faae6643 --- /dev/null +++ b/apps/composer/src/types/validations.ts @@ -0,0 +1,21 @@ +import { Profile } from "./cli"; + +/** + * Configuration interface for path validation operations. + * Defines the structure for various directory and file paths needed by different profiles. + */ +export interface PathValidationConfig { + profile: Profile; // The operation profile being used + outputPath?: string; // Path where generated files will be saved +} + +/** + * Configuration options for CSV parsing operations. + * These settings control how the parser handles various CSV formatting scenarios. + */ +export interface CSVParseOptions { + delimiter: string; // Character used to separate values + trim: boolean; // Remove whitespace from values + skipEmptyLines: boolean; // Ignore empty lines in the CSV + relax_column_count: boolean; // Allow rows with different column counts +} diff --git a/apps/composer/src/utils/csvParser.ts b/apps/composer/src/utils/csvParser.ts new file mode 100644 index 00000000..b088c2c1 --- /dev/null +++ b/apps/composer/src/utils/csvParser.ts @@ -0,0 +1,125 @@ +import * as fs from "fs"; +import { parse as csvParse } from "csv-parse/sync"; +import { ComposerError, ErrorCodes } from "./errors"; +import { CSVParseOptions } from "../types/validations"; +import { Logger } from "./logger"; + +export function parseCSVLine( + line: string, + delimiter: string, + isHeaderRow: boolean = false +): string[][] { + try { + Logger.debug`Parsing CSV line${isHeaderRow ? " (headers)" : ""}`; + + const parseOptions: CSVParseOptions = { + delimiter, + trim: true, + skipEmptyLines: true, + relax_column_count: true, + }; + + Logger.debugObject("Parse options", parseOptions); + + const result = csvParse(line, parseOptions); + + if (isHeaderRow) { + const headers = result[0] ? [result[0]] : []; + if (headers.length > 0) { + Logger.debug`Found ${headers[0].length} columns`; + } + return headers; + } + + return result; + } catch (error) { + throw new ComposerError( + "Error parsing CSV line", + ErrorCodes.PARSING_ERROR, + { line, error } + ); + } +} + +export function readCSVHeadersAndSample( + filePath: string, + delimiter: string +): { headers: string[]; sampleData: Record } { + try { + Logger.debug`Reading CSV file: ${filePath}`; + Logger.debug`Using delimiter: "${delimiter}"`; + + const fileContent = fs.readFileSync(filePath, "utf-8"); + const [headerLine, sampleLine] = fileContent.split("\n"); + + if (!headerLine) { + throw new ComposerError( + "CSV file is empty or has no headers", + ErrorCodes.INVALID_FILE + ); + } + + const headers = parseCSVLine(headerLine, delimiter, true)[0]; + if (!headers) { + throw new ComposerError( + "Failed to parse CSV headers", + ErrorCodes.PARSING_ERROR + ); + } + + Logger.debug`Found headers: ${headers.join(", ")}`; + + const sampleData: Record = {}; + if (sampleLine) { + const sampleValues = parseCSVLine(sampleLine, delimiter, false)[0]; + if (sampleValues) { + headers.forEach((header: string, index: number) => { + sampleData[header] = sampleValues[index] || ""; + Logger.debug( + `Column "${header}": ${inferValueType(sampleValues[index] || "")}` + ); + }); + } + } + + return { headers, sampleData }; + } catch (error) { + if (error instanceof ComposerError) { + throw error; + } + throw new ComposerError( + "Error reading CSV headers and sample", + ErrorCodes.FILE_ERROR, + error + ); + } +} + +export function inferValueType( + value: string +): "string" | "number" | "boolean" | "date" { + const lowerValue = value.toLowerCase().trim(); + + // Check for boolean values + if (["true", "false", "yes", "no", "1", "0"].includes(lowerValue)) { + return "boolean"; + } + + // Check for numeric values + if (!isNaN(Number(value)) && value.toString().trim() !== "") { + return "number"; + } + + // Check for valid date values + if (isValidDate(value)) { + return "date"; + } + + // Default to string type + return "string"; +} + +function isValidDate(dateString: string): boolean { + const date = new Date(dateString); + return date instanceof Date && !isNaN(date.getTime()); +} diff --git a/apps/composer/src/utils/errors.ts b/apps/composer/src/utils/errors.ts new file mode 100644 index 00000000..41ddaa6b --- /dev/null +++ b/apps/composer/src/utils/errors.ts @@ -0,0 +1,78 @@ +import { Logger } from "./logger"; +export class ComposerError extends Error { + constructor(message: string, public code: string, public details?: any) { + super(message); + this.name = "ComposerError"; + } + + toString(): string { + return `${this.message}${ + this.details ? `\nDetails: ${JSON.stringify(this.details, null, 2)}` : "" + }`; + } +} + +export const ErrorCodes = { + INVALID_ARGS: "[INVALID_ARGS]", + FILE_NOT_FOUND: "[FILE_NOT_FOUND]", + INVALID_FILE: "[INVALID_FILE]", + VALIDATION_FAILED: "[VALIDATION_FAILED]", + ENV_ERROR: "[ENV_ERROR]", + GENERATION_FAILED: "[GENERATION_FAILED]", + PARSING_ERROR: "[PARSING_ERROR]", + FILE_ERROR: "[FILE_ERROR]", + FILE_WRITE_ERROR: "[FILE_WRITE_ERROR]", +} as const; + +export type ErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes]; + +function formatErrorDetails(details: any): string { + if (typeof details === "string") { + return details; + } + if (details instanceof Error) { + return details.message; + } + try { + return JSON.stringify(details, null, 2); + } catch { + return String(details); + } +} + +// errors.ts +export function handleError( + error: unknown, + showAvailableProfiles?: () => void +): never { + if (error instanceof ComposerError) { + Logger.error`${error.code}: ${error.message}`; + + // Call the callback function if provided + if (showAvailableProfiles) { + showAvailableProfiles(); + } + + if (error.details) { + const formattedDetails = formatErrorDetails(error.details); + Logger.debug("Details:"); + Logger.debug(formattedDetails); + } + + // Log stack trace in debug mode + Logger.debug("Stack trace:"); + Logger.debug(error.stack || "No stack trace available"); + } else { + Logger.error("Unexpected error occurred"); + + if (error instanceof Error) { + Logger.error(error.message); + Logger.debug("Stack trace:"); + Logger.debug(error.stack || "No stack trace available"); + } else { + Logger.error(String(error)); + } + } + + process.exit(1); +} diff --git a/apps/composer/src/utils/fileUtils.ts b/apps/composer/src/utils/fileUtils.ts new file mode 100644 index 00000000..dd7a57dd --- /dev/null +++ b/apps/composer/src/utils/fileUtils.ts @@ -0,0 +1,115 @@ +import * as fs from "fs"; +import * as path from "path"; +import { Logger } from "./logger"; +import { ComposerError, ErrorCodes } from "./errors"; + +/** + * Expands directory paths to individual file paths, filtering by extension if specified + * @param paths Array of file or directory paths + * @param extensions Optional array of extensions to filter by (e.g., ['.csv', '.json']) + * @returns Array of expanded file paths + */ +export function expandDirectoryPaths( + paths: string[], + extensions?: string[] +): string[] { + if (!paths || paths.length === 0) { + return []; + } + + let expandedPaths: string[] = []; + + paths.forEach((inputPath) => { + try { + const stats = fs.statSync(inputPath); + + if (stats.isDirectory()) { + Logger.debug(`Processing directory: ${inputPath}`); + + // Read all files in the directory + const filesInDir = fs + .readdirSync(inputPath) + .map((file) => path.join(inputPath, file)) + .filter((file) => { + try { + const fileStat = fs.statSync(file); + + // Skip if not a file + if (!fileStat.isFile()) { + return false; + } + + // Filter by extension if specified + if (extensions && extensions.length > 0) { + const ext = path.extname(file).toLowerCase(); + return extensions.includes(ext); + } + + return true; + } catch (error) { + Logger.debug(`Error accessing file ${file}: ${error}`); + return false; + } + }); + + if (filesInDir.length === 0) { + if (extensions && extensions.length > 0) { + Logger.warn( + `No files with extensions ${extensions.join( + ", " + )} found in directory: ${inputPath}` + ); + } else { + Logger.warn(`Directory is empty: ${inputPath}`); + } + } else { + Logger.debug( + `Found ${filesInDir.length} files in directory ${inputPath}` + ); + expandedPaths = [...expandedPaths, ...filesInDir]; + } + } else { + // It's a file, check extension if needed + if (extensions && extensions.length > 0) { + const ext = path.extname(inputPath).toLowerCase(); + if (extensions.includes(ext)) { + expandedPaths.push(inputPath); + } else { + Logger.debug( + `Skipping file with unsupported extension: ${inputPath}` + ); + } + } else { + expandedPaths.push(inputPath); + } + } + } catch (error) { + Logger.debug(`Error accessing path ${inputPath}: ${error}`); + throw new ComposerError( + `Cannot access path: ${inputPath}`, + ErrorCodes.FILE_NOT_FOUND, + error + ); + } + }); + + return expandedPaths; +} + +/** + * Gets all CSV files from the provided paths (directories or files) + * @param paths Array of file or directory paths + * @returns Array of CSV file paths + */ +export function getCSVFiles(paths: string[]): string[] { + return expandDirectoryPaths(paths, [".csv"]); +} + +/** + * Gets all JSON files from the provided paths (directories or files) + * @param paths Array of file or directory paths + * @returns Array of JSON file paths + */ +export function getJSONFiles(paths: string[]): string[] { + return expandDirectoryPaths(paths, [".json"]); +} diff --git a/apps/composer/src/utils/index.ts b/apps/composer/src/utils/index.ts new file mode 100644 index 00000000..d99e7a71 --- /dev/null +++ b/apps/composer/src/utils/index.ts @@ -0,0 +1,4 @@ +export * from "./errors"; +export * from "./logger"; +export * from "./paths"; +export * from "./fileUtils"; diff --git a/apps/composer/src/utils/logger.ts b/apps/composer/src/utils/logger.ts new file mode 100644 index 00000000..e444d56f --- /dev/null +++ b/apps/composer/src/utils/logger.ts @@ -0,0 +1,419 @@ +import chalk from "chalk"; + +export enum LogLevel { + DEBUG = 0, + INFO = 1, + SUCCESS = 2, + WARN = 3, + ERROR = 4, + HELP = 5, + GENERIC = 6, + SECTION = 7, + INPUT = 8, +} + +interface LoggerConfig { + level: LogLevel; + debug: boolean; +} + +export class Logger { + private static config: LoggerConfig = { + level: LogLevel.INFO, + debug: false, + }; + + private static formatMessage(message: string, level: LogLevel): string { + const icons = { + [LogLevel.DEBUG]: "🔍", + [LogLevel.INFO]: "▸", + [LogLevel.SUCCESS]: "✓", + [LogLevel.WARN]: "⚠", + [LogLevel.ERROR]: "✗", + [LogLevel.HELP]: "💡", + [LogLevel.GENERIC]: "", + [LogLevel.SECTION]: "", + [LogLevel.INPUT]: "❔", + }; + + const colors: Record string> = { + [LogLevel.DEBUG]: chalk.bold.gray, + [LogLevel.INFO]: chalk.bold.cyan, + [LogLevel.SUCCESS]: chalk.bold.green, + [LogLevel.WARN]: chalk.bold.yellow, + [LogLevel.ERROR]: chalk.bold.red, + [LogLevel.HELP]: chalk.bold.yellow, + [LogLevel.GENERIC]: chalk.white, + [LogLevel.SECTION]: chalk.bold.blue, + [LogLevel.INPUT]: chalk.bold.yellow, + }; + + const levelLabels = { + [LogLevel.DEBUG]: "Debug", + [LogLevel.INFO]: "Info", + [LogLevel.SUCCESS]: "Success", + [LogLevel.WARN]: "Warn", + [LogLevel.ERROR]: "Error", + [LogLevel.HELP]: "Help", + [LogLevel.GENERIC]: "", + [LogLevel.SECTION]: "", + [LogLevel.INPUT]: "User Input", + }; + + const needsNewLine = [ + LogLevel.ERROR, + LogLevel.INPUT, + LogLevel.WARN, + LogLevel.SUCCESS, + ].includes(level); + + const prefix = needsNewLine ? "\n" : ""; + + if (level === LogLevel.GENERIC) { + return colors[level](message); + } + + if (level === LogLevel.SECTION) { + return `${prefix}${colors[level](`${icons[level]} ${message}`)}`; + } + + return `${prefix}${colors[level]( + `${icons[level]} ${levelLabels[level]} ` + )}${message}`; + } + + static setLevel(level: LogLevel): void { + this.config.level = level; + } + + static enableDebug(): void { + this.config.debug = true; + this.config.level = LogLevel.DEBUG; + console.log(chalk.gray("🔍 **Debug mode enabled**")); + } + + /** + * Tagged template helper that automatically bolds interpolated values. + */ + static formatVariables( + strings: TemplateStringsArray, + ...values: any[] + ): string { + return strings.reduce((result, string, i) => { + const value = + i < values.length ? chalk.bold.whiteBright(String(values[i])) : ""; + return result + string + value; + }, ""); + } + + /** + * Core log function that accepts either a tagged template literal or a plain string. + */ + private static log( + level: LogLevel, + strings: TemplateStringsArray | string, + ...values: any[] + ): void { + if (this.config.level > level && level !== LogLevel.DEBUG) return; + if (!this.config.debug && level === LogLevel.DEBUG) return; + + const message = + typeof strings === "string" + ? strings + : this.formatVariables(strings, ...values); + + const formattedMessage = this.formatMessage(message, level); + + if (level === LogLevel.WARN) { + console.warn(formattedMessage); + } else if (level === LogLevel.ERROR) { + console.error(formattedMessage); + } else { + console.log(formattedMessage); + } + } + + static debug(strings: TemplateStringsArray | string, ...values: any[]): void { + this.log(LogLevel.DEBUG, strings, ...values); + } + + static info(strings: TemplateStringsArray | string, ...values: any[]): void { + this.log(LogLevel.INFO, strings, ...values); + } + + static success( + strings: TemplateStringsArray | string, + ...values: any[] + ): void { + this.log(LogLevel.SUCCESS, strings, ...values); + } + + static warn(strings: TemplateStringsArray | string, ...values: any[]): void { + this.log(LogLevel.WARN, strings, ...values); + } + + static error(strings: TemplateStringsArray | string, ...values: any[]): void { + this.log(LogLevel.ERROR, strings, ...values); + } + + static help(strings: TemplateStringsArray | string, ...values: any[]): void { + this.log(LogLevel.HELP, strings, ...values); + } + + static generic(message: string): void { + console.log(this.formatMessage(message, LogLevel.GENERIC)); + } + + static input(message: string): string { + return this.formatMessage(message, LogLevel.INPUT); + } + + static section(text: string): void { + console.log(this.formatMessage(text, LogLevel.SECTION)); + } + + static header(text: string): void { + const separator = "═".repeat(text.length + 6); + console.log(`\n${chalk.bold.magenta(separator)}`); + console.log(`${chalk.bold.magenta(" " + text + " ")}`); + console.log(`${chalk.bold.magenta(separator)}\n`); + } + + static commandInfo(command: string, description: string): void { + console.log`${chalk.bold.blue(command)}: ${description}`; + } + + static defaultValueInfo(message: string, overrideCommand: string): void { + if (this.config.level <= LogLevel.INFO) { + console.log(this.formatMessage(message, LogLevel.INFO)); + console.log(chalk.gray` Override with: ${overrideCommand}\n`); + } + } + + static defaultValueWarning(message: string, overrideCommand: string): void { + if (this.config.level <= LogLevel.WARN) { + console.warn(this.formatMessage(message, LogLevel.WARN)); + console.log(chalk.gray` Override with: ${overrideCommand}\n`); + } + } + + static debugObject(label: string, obj: any): void { + if (this.config.debug) { + console.log(chalk.gray`🔍 ${label}:`); + Object.entries(obj).forEach(([key, value]) => { + console.log(chalk.gray` ${key}:`, value || "Not set"); + }); + } + } + + static initialize(): void { + if (process.env.DEBUG === "true") { + this.enableDebug(); + } + } + + static timing(label: string, timeMs: number): void { + const formattedTime = + timeMs < 1000 + ? `${timeMs.toFixed(1)}ms` + : `${(timeMs / 1000).toFixed(2)}s`; + + console.log(chalk.gray`⏱ ${label}: ${formattedTime}`); + } + + static fileList(title: string, files: string[]): void { + if (files.length === 0) return; + Logger.warn`${title}:\n`; + files.forEach((file) => { + console.log(chalk.gray` - ${file}`); + }); + } + static errorfileList(title: string, files: string[]): void { + if (files.length === 0) return; + Logger.error`${title}:\n`; + files.forEach((file) => { + console.log(chalk.gray` - ${file}`); + }); + } + static showReferenceCommands(): void { + this.header("Command Examples"); + + // Dictionary Generation + this.generic(chalk.bold.magenta("Generate Lectern Dictionary:")); + this.generic( + chalk.white( + "composer -p generateLecternDictionary -f clinical.csv demographics.csv" + ) + ); + this.generic(chalk.gray("Options:")); + this.generic( + chalk.gray("-p, --profile Execution profile (default: default)") + ); + this.generic( + chalk.gray( + "-f, --files Input file paths (CSV or JSON, space separated) (required)" + ) + ); + this.generic( + chalk.gray( + "-o, --output Output file path for generated dictionary" + ) + ); + this.generic( + chalk.gray( + "-n, --name Dictionary name (default: lectern_dictionary)" + ) + ); + this.generic( + chalk.gray( + "-d, --description Dictionary description (default: Generated dictionary from CSV files)" + ) + ); + this.generic( + chalk.gray("-v, --version Dictionary version (default: 1.0.0)") + ); + this.generic( + chalk.gray("--delimiter CSV delimiter (default: ,)") + ); + this.generic(""); + this.generic( + chalk.gray( + "Example: composer -p generateLecternDictionary -f clinical.csv demographics.csv -o dictionary.json -n 'Clinical Dictionary' -v '2.0.0'" + ) + ); + this.generic(""); + + // Song Schema Generation + this.generic(chalk.bold.magenta("Generate Song Schema:")); + this.generic( + chalk.white("composer -p generateSongSchema -f schema-template.json") + ); + this.generic(chalk.gray("Options:")); + this.generic( + chalk.gray("-p, --profile Execution profile (default: default)") + ); + this.generic( + chalk.gray( + "-f, --files Input file paths (CSV or JSON, space separated) (required)" + ) + ); + this.generic( + chalk.gray( + "-o, --output Output file path for generated schema" + ) + ); + this.generic( + chalk.gray("-n, --name Schema name (default: song_schema)") + ); + this.generic( + chalk.gray("--file-types Allowed file types for Song schema") + ); + this.generic(""); + this.generic( + chalk.gray( + "Example: composer -p generateSongSchema -f data-model.json -o song-schema.json -n 'Analysis Schema' --file-types bam vcf fastq" + ) + ); + this.generic(""); + + // Elasticsearch Mapping Generation + this.generic(chalk.bold.magenta("Generate Elasticsearch Mapping:")); + this.generic( + chalk.white("composer -p generateElasticearchMapping -f data.csv") + ); + this.generic(chalk.gray("Options:")); + this.generic( + chalk.gray("-p, --profile Execution profile (default: default)") + ); + this.generic( + chalk.gray( + "-f, --files Input file paths (CSV or JSON, space separated) (required)" + ) + ); + this.generic( + chalk.gray( + "-o, --output Output file path for generated mapping" + ) + ); + this.generic( + chalk.gray( + "-i, --index Elasticsearch index name (default: data)" + ) + ); + this.generic( + chalk.gray( + "--shards Number of Elasticsearch shards (default: 1)" + ) + ); + this.generic( + chalk.gray( + "--replicas Number of Elasticsearch replicas (default: 1)" + ) + ); + this.generic( + chalk.gray("--delimiter CSV delimiter (default: ,)") + ); + this.generic( + chalk.gray( + "--ignore-fields Field names to exclude from mapping" + ) + ); + this.generic( + chalk.gray( + "--skip-metadata Skip adding submission metadata to mapping" + ) + ); + this.generic(""); + this.generic( + chalk.gray( + "Example: composer -p generateElasticsearchMapping -f data.csv metadata.csv -i my_index --shards 3 --replicas 2 -o es-mapping.json" + ) + ); + this.generic( + chalk.gray( + "Example with ignored fields: composer -p generateElasticsearchMapping -f donor_data.json --ignore-fields entityName organization isValid id" + ) + ); + this.generic( + chalk.gray( + "Example without metadata: composer -p generateElasticsearchMapping -f donor_data.json --skip-metadata" + ) + ); + this.generic(""); + + // Arranger Configuration Generation + this.generic(chalk.bold.magenta("Generate Arranger Configs:")); + this.generic( + chalk.white("composer -p generateArrangerConfigs -f metadata.csv") + ); + this.generic(chalk.gray("Options:")); + this.generic( + chalk.gray("-p, --profile Execution profile (default: default)") + ); + this.generic( + chalk.gray("-f, --files Input file mapping (JSON) (required)") + ); + this.generic( + chalk.gray( + "-o, --output Output file path for generated configs" + ) + ); + this.generic( + chalk.gray( + "--arranger-doc-type Arranger document type (file or analysis) (default: file)" + ) + ); + this.generic( + chalk.gray( + "-i, --index Elasticsearch index name (default: data)" + ) + ); + this.generic(""); + this.generic( + chalk.gray( + "Example: composer -p generateArrangerConfigs -f mapping.json -o arranger-config/ --arranger-doc-type analysis -i clinical_data" + ) + ); + this.generic(""); + } +} diff --git a/apps/composer/src/utils/paths.ts b/apps/composer/src/utils/paths.ts new file mode 100644 index 00000000..b03c1534 --- /dev/null +++ b/apps/composer/src/utils/paths.ts @@ -0,0 +1,103 @@ +import * as path from "path"; +import { Profile, Profiles } from "../types"; + +/** + * Base directory for all configuration files + */ +export const BASE_CONFIG_DIR = "generatedConfigs"; + +/** + * Config type definitions for type safety + */ +type ConfigType = "song" | "lectern" | "elasticsearch" | "arranger"; + +/** + * Configuration paths organized by type + */ +export const CONFIG_PATHS = { + song: { + dir: path.join(BASE_CONFIG_DIR, "songSchema"), + schema: path.join(BASE_CONFIG_DIR, "songSchema", "songSchema.json"), + }, + lectern: { + dir: path.join(BASE_CONFIG_DIR, "lecternDictionaries"), + dictionary: path.join( + BASE_CONFIG_DIR, + "lecternDictionaries", + "dictionary.json" + ), + }, + elasticsearch: { + dir: path.join(BASE_CONFIG_DIR, "elasticsearchConfigs"), + mapping: path.join(BASE_CONFIG_DIR, "elasticsearchConfigs", "mapping.json"), + }, + arranger: { + dir: path.join(BASE_CONFIG_DIR, "arrangerConfigs"), + configs: path.join(BASE_CONFIG_DIR, "arrangerConfigs", "configs"), + }, + samples: { + fileMetadata: "data/sampleData/fileMetadata.json", + tabular: "data/tabularData.csv", + }, +} as const; + +/** + * Gets directory path for the specified config type + */ +export function getConfigDir(configType: ConfigType): string { + return CONFIG_PATHS[configType].dir; +} + +/** + * Gets file path within a config directory + */ +export function getConfigFilePath( + configType: ConfigType, + filename: string +): string { + return path.join(getConfigDir(configType), filename); +} + +/** + * Maps profile to its corresponding config type + */ +export function getConfigTypeForProfile(profile: Profile): ConfigType | null { + switch (profile) { + case Profiles.GENERATE_SONG_SCHEMA: + return "song"; + case Profiles.GENERATE_LECTERN_DICTIONARY: + return "lectern"; + case Profiles.GENERATE_ELASTICSEARCH_MAPPING: + return "elasticsearch"; + case Profiles.GENERATE_ARRANGER_CONFIGS: + return "arranger"; + default: + return null; + } +} + +/** + * Gets default output path for a specific profile + */ +export function getDefaultOutputPathForProfile( + profile: Profile +): string | undefined { + const configType = getConfigTypeForProfile(profile); + + if (!configType) { + return undefined; + } + + switch (configType) { + case "song": + return CONFIG_PATHS.song.schema; + case "lectern": + return CONFIG_PATHS.lectern.dictionary; + case "elasticsearch": + return CONFIG_PATHS.elasticsearch.mapping; + case "arranger": + return CONFIG_PATHS.arranger.configs; + default: + return undefined; + } +} diff --git a/apps/composer/src/validations/csvValidator.ts b/apps/composer/src/validations/csvValidator.ts new file mode 100644 index 00000000..00668a5c --- /dev/null +++ b/apps/composer/src/validations/csvValidator.ts @@ -0,0 +1,211 @@ +import * as fs from "fs"; +import { ComposerError, ErrorCodes } from "../utils/errors"; +import { parseCSVLine } from "../utils/csvParser"; +import { Logger } from "../utils/logger"; + +/** + * Validates the header structure of a CSV file. + * Reads the first line of the file and validates the headers. + * + * @param filePath - Path to the CSV file + * @param delimiter - Character used to separate values in the CSV + * @returns Promise resolving to true if headers are valid + * @throws ComposerError if headers are invalid or file can't be read + */ +export async function validateCSVHeaders( + filePath: string, + delimiter: string +): Promise { + try { + Logger.debug`Validating CSV headers for file: ${filePath}`; + Logger.debug`Using delimiter: '${delimiter}'`; + + const fileContent = fs.readFileSync(filePath, "utf-8"); + const [headerLine] = fileContent.split("\n"); + + if (!headerLine) { + Logger.debug("CSV file is empty or has no headers"); + throw new ComposerError( + "CSV file is empty or has no headers", + ErrorCodes.INVALID_FILE + ); + } + + const headers = parseCSVLine(headerLine, delimiter, true)[0]; + if (!headers) { + Logger.debug("Failed to parse CSV headers"); + throw new ComposerError( + "Failed to parse CSV headers", + ErrorCodes.INVALID_FILE + ); + } + + Logger.debug`Parsed headers: ${headers.join(", ")}`; + return validateCSVStructure(headers); + } catch (error) { + Logger.debug("Error during CSV header validation"); + Logger.debugObject("Error details", error); + + if (error instanceof ComposerError) { + throw error; + } + throw new ComposerError( + "Error validating CSV headers", + ErrorCodes.VALIDATION_FAILED, + error + ); + } +} + +/** + * Validates CSV headers against naming conventions and rules. + * Checks: + * - Special character restrictions + * - Maximum length limits + * - Reserved word restrictions + * - GraphQL naming conventions + * - Duplicate prevention + * + * @param headers - Array of header strings to validate + * @returns Promise resolving to true if all headers are valid + * @throws ComposerError with details if validation fails + */ +export async function validateCSVStructure( + headers: string[] +): Promise { + try { + Logger.debug("Starting CSV structure validation"); + + // Clean and filter headers + const cleanedHeaders = headers + .map((header) => header.trim()) + .filter((header) => header !== ""); + + // Validate basic header presence + if (cleanedHeaders.length === 0) { + Logger.debug("No valid headers found in CSV file"); + throw new ComposerError( + "No valid headers found in CSV file", + ErrorCodes.VALIDATION_FAILED + ); + } + + if (cleanedHeaders.length !== headers.length) { + Logger.debug("Empty or whitespace-only headers detected"); + throw new ComposerError( + "Empty or whitespace-only headers detected", + ErrorCodes.VALIDATION_FAILED + ); + } + + // Define validation rules + const invalidChars = [ + ":", + ">", + "<", + ".", + " ", + ",", + "/", + "\\", + "?", + "#", + "[", + "]", + "{", + "}", + '"', + "*", + "|", + "+", + "@", + "&", + "(", + ")", + "!", + "^", + ]; + const maxLength = 255; + const reservedWords = [ + "_type", + "_id", + "_source", + "_all", + "_parent", + "_field_names", + "_routing", + "_index", + "_size", + "_timestamp", + "_ttl", + "_meta", + "_doc", + "__typename", + "__schema", + "__type", + ]; + const graphqlNamePattern = /^[A-Za-z_][A-Za-z0-9_]*$/; + + // Validate headers against all rules + const invalidHeaders = cleanedHeaders.filter((header: string) => { + const hasInvalidChars = invalidChars.some((char) => + header.includes(char) + ); + const isTooLong = Buffer.from(header).length > maxLength; + const isReserved = reservedWords.includes(header.toLowerCase()); + const isValidGraphQLName = graphqlNamePattern.test(header); + return hasInvalidChars || isTooLong || isReserved || !isValidGraphQLName; + }); + + if (invalidHeaders.length > 0) { + Logger.debug("Invalid headers detected"); + Logger.fileList("The following header(s) are invalid", invalidHeaders); + throw new ComposerError( + "Invalid header names detected", + ErrorCodes.VALIDATION_FAILED, + { invalidHeaders } + ); + } + + // Check for duplicate headers + const headerCounts: Record = cleanedHeaders.reduce( + (acc: Record, header: string) => { + acc[header] = (acc[header] || 0) + 1; + return acc; + }, + {} + ); + + const duplicates = Object.entries(headerCounts) + .filter(([_, count]) => count > 1) + .map(([header, _]) => header); + + if (duplicates.length > 0) { + Logger.debug("Duplicate headers found"); + Logger.debugObject("Duplicate headers", { + duplicates, + counts: headerCounts, + }); + throw new ComposerError( + "Duplicate headers found in CSV file", + ErrorCodes.VALIDATION_FAILED, + { duplicates, counts: headerCounts } + ); + } + + Logger.debug("CSV header structure is valid"); + return true; + } catch (error) { + Logger.debug("Error during CSV structure validation"); + Logger.debugObject("Error details", error); + + if (error instanceof ComposerError) { + throw error; + } + throw new ComposerError( + "Error validating CSV structure", + ErrorCodes.VALIDATION_FAILED, + error + ); + } +} diff --git a/apps/composer/src/validations/enviromentValidator.ts b/apps/composer/src/validations/enviromentValidator.ts new file mode 100644 index 00000000..92d316ca --- /dev/null +++ b/apps/composer/src/validations/enviromentValidator.ts @@ -0,0 +1,92 @@ +import * as fs from "fs"; +import * as path from "path"; +import { ComposerError, ErrorCodes } from "../utils/errors"; +import { PathValidationConfig } from "../types/validations"; +import { Logger } from "../utils/logger"; + +// Keep track of validation state to prevent duplicate validations +let environmentValidated = false; + +/** + * Determines which directories are required based on the selected profile. + */ +function getRequiredDirectories(config: PathValidationConfig): string[] { + const { profile, outputPath } = config; + const directories: string[] = []; + + if (outputPath) { + const outputDir = path.dirname(outputPath); + if (outputDir !== ".") { + directories.push(outputDir); + } + } + + return [...new Set(directories)].map((dir) => path.normalize(dir)); +} + +/** + * Validates the environment configuration and creates any missing directories. + */ +export async function validateEnvironment( + config: PathValidationConfig +): Promise { + // Skip if already validated + if (environmentValidated) { + Logger.debug("Environment already validated, skipping check"); + return true; + } + + Logger.debugObject("Environment configuration", config); + + // Get and create required directories + const directories = getRequiredDirectories(config); + for (const dir of directories) { + if (dir && !fs.existsSync(dir)) { + try { + fs.mkdirSync(dir, { recursive: true }); + Logger.info`Created directory: ${dir}`; + } catch (error) { + throw new ComposerError( + `Failed to create directory ${dir}`, + ErrorCodes.ENV_ERROR, + error + ); + } + } + } + + environmentValidated = true; + return true; +} + +/** + * Validates that all required npm dependencies are installed. + */ +export async function validateDependencies( + composerPath: string +): Promise { + Logger.debug("Setting up configuration generator"); + Logger.debug("Checking Composer dependencies"); + + try { + const nodeModulesPath = path.join(composerPath, "node_modules"); + if (!fs.existsSync(nodeModulesPath)) { + throw new ComposerError( + "node_modules not found. Consider running 'npm install'", + ErrorCodes.ENV_ERROR + ); + } + + Logger.debug("Dependencies validation complete"); + return true; + } catch (error) { + if (error instanceof ComposerError) { + throw error; + } + throw new ComposerError( + "Error validating dependencies", + ErrorCodes.ENV_ERROR, + error + ); + } +} diff --git a/apps/composer/src/validations/fileValidator.ts b/apps/composer/src/validations/fileValidator.ts new file mode 100644 index 00000000..30d78f4c --- /dev/null +++ b/apps/composer/src/validations/fileValidator.ts @@ -0,0 +1,98 @@ +import * as fs from "fs"; +import * as path from "path"; +import { ComposerError, ErrorCodes } from "../utils/errors"; +import { Logger } from "../utils/logger"; + +/** + * Performs comprehensive validation of a file: + * - Checks if file exists + * - Verifies parent directory exists + * - Confirms file is readable + * - Ensures file is not empty + * + * @param filePath - Path to the file to validate + * @returns Promise resolving to true if file is valid + * @throws ComposerError for any validation failures + */ +export async function validateFile(filePath: string): Promise { + try { + Logger.debug`Validating file: ${filePath}`; + + // Verify file existence + if (!fs.existsSync(filePath)) { + Logger.debug`File does not exist: ${filePath}`; + throw new ComposerError( + `File '${filePath}' does not exist`, + ErrorCodes.FILE_NOT_FOUND + ); + } + + // Verify parent directory existence + const dirPath = path.dirname(filePath); + if (!fs.existsSync(dirPath)) { + Logger.error`Directory does not exist: ${dirPath}`; + throw new ComposerError( + `Directory does not exist: ${dirPath}`, + ErrorCodes.FILE_NOT_FOUND + ); + } + + // Check file permissions + try { + fs.accessSync(filePath, fs.constants.R_OK); + } catch (error) { + Logger.error`File is not readable: ${filePath}`; + throw new ComposerError( + `File '${filePath}' is not readable`, + ErrorCodes.INVALID_FILE, + error + ); + } + + // Verify file has content + const stats = fs.statSync(filePath); + if (stats.size === 0) { + Logger.error`File is empty: ${filePath}`; + throw new ComposerError( + `File '${filePath}' is empty`, + ErrorCodes.INVALID_FILE + ); + } + Logger.debug`File '${filePath}' is valid and readable`; + return true; + } catch (error) { + Logger.debug("Error during file validation"); + Logger.debugObject("Error details", error); + + if (error instanceof ComposerError) { + throw error; + } + throw new ComposerError( + "Error validating file", + ErrorCodes.INVALID_FILE, + error + ); + } +} + +/** + * Validates that the CSV delimiter is a single character. + * + * @param delimiter - Character to be used as CSV delimiter + * @returns true if delimiter is valid + * @throws ComposerError if delimiter is invalid + */ +export function validateDelimiter(delimiter: string): boolean { + Logger.info`Validating delimiter: '${delimiter}'`; + + if (!delimiter || delimiter.length !== 1) { + Logger.debug("Invalid delimiter: must be a single character"); + throw new ComposerError( + "Delimiter must be a single character", + ErrorCodes.INVALID_ARGS + ); + } + + Logger.debug("Delimiter validation successful"); + return true; +} diff --git a/apps/composer/src/validations/index.ts b/apps/composer/src/validations/index.ts new file mode 100644 index 00000000..ef654b2f --- /dev/null +++ b/apps/composer/src/validations/index.ts @@ -0,0 +1,25 @@ +/** + * Central export point for all validation utilities. + * This module provides a comprehensive set of validation tools for: + * - Environment configuration + * - File system operations + * - CSV structure and content + * - Path validation + * + * Import specific validators from here to ensure consistent usage + * across the application. + */ + +export { + validateEnvironment, + validateDependencies, +} from "./enviromentValidator"; + +export { validateFile, validateDelimiter } from "./fileValidator"; + +export { validateCSVHeaders, validateCSVStructure } from "./csvValidator"; + +export type { + PathValidationConfig, + CSVParseOptions, +} from "../types/validations"; diff --git a/apps/composer/tsconfig.json b/apps/composer/tsconfig.json new file mode 100644 index 00000000..a91b7d29 --- /dev/null +++ b/apps/composer/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "target": "es2018", + "module": "commonjs", + "lib": ["es2018"], + "outDir": "./dist", + "rootDir": "./src", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] +} \ No newline at end of file diff --git a/apps/conductor/.gitattributes b/apps/conductor/.gitattributes new file mode 100644 index 00000000..fc5193b2 --- /dev/null +++ b/apps/conductor/.gitattributes @@ -0,0 +1 @@ +scripts/**/*.sh text eol=lf \ No newline at end of file diff --git a/apps/conductor/configs/arrangerConfigs/datatable1/base.json b/apps/conductor/configs/arrangerConfigs/datatable1/base.json new file mode 100644 index 00000000..06cf2504 --- /dev/null +++ b/apps/conductor/configs/arrangerConfigs/datatable1/base.json @@ -0,0 +1,4 @@ +{ + "documentType": "file", + "index": "datatable1_centric" +} diff --git a/apps/conductor/configs/arrangerConfigs/datatable1/extended.json b/apps/conductor/configs/arrangerConfigs/datatable1/extended.json new file mode 100644 index 00000000..f96ab43c --- /dev/null +++ b/apps/conductor/configs/arrangerConfigs/datatable1/extended.json @@ -0,0 +1,132 @@ +{ + "extended": [ + { + "displayName": "Gender", + "fieldName": "data.gender" + }, + { + "displayName": "Donor Id", + "fieldName": "data.donor_id" + }, + { + "displayName": "Vital Status", + "fieldName": "data.vital_status" + }, + { + "displayName": "Diagnosis", + "fieldName": "data.diagnosis", + "isArray": true + }, + { + "displayName": "Diagnosis Stage", + "fieldName": "data.diagnosis.stage" + }, + { + "displayName": "Diagnosis Donor Id", + "fieldName": "data.diagnosis.donor_id" + }, + { + "displayName": "Diagnosis Cancer Type", + "fieldName": "data.diagnosis.cancer_type" + }, + { + "displayName": "Diagnosis Diagnosis Id", + "fieldName": "data.diagnosis.diagnosis_id" + }, + { + "displayName": "Diagnosis Primary Site", + "fieldName": "data.diagnosis.primary_site" + }, + { + "displayName": "Diagnosis Staging System", + "fieldName": "data.diagnosis.staging_system" + }, + { + "displayName": "Diagnosis Age At Diagnosis", + "fieldName": "data.diagnosis.age_at_diagnosis" + }, + { + "displayName": "Diagnosis Followup", + "fieldName": "data.diagnosis.followup", + "isArray": true + }, + { + "displayName": "Diagnosis Followup Followup Id", + "fieldName": "data.diagnosis.followup.followup_id" + }, + { + "displayName": "Diagnosis Followup Diagnosis Id", + "fieldName": "data.diagnosis.followup.diagnosis_id" + }, + { + "displayName": "Diagnosis Followup Disease Status", + "fieldName": "data.diagnosis.followup.disease_status" + }, + { + "displayName": "Diagnosis Followup Followup Interval", + "fieldName": "data.diagnosis.followup.followup_interval" + }, + { + "displayName": "Diagnosis Specimen", + "fieldName": "data.diagnosis.specimen", + "isArray": true + }, + { + "displayName": "Diagnosis Specimen Sample Id", + "fieldName": "data.diagnosis.specimen.sample_id" + }, + { + "displayName": "Diagnosis Specimen Sample Type", + "fieldName": "data.diagnosis.specimen.sample_type" + }, + { + "displayName": "Diagnosis Specimen Specimen Id", + "fieldName": "data.diagnosis.specimen.specimen_id" + }, + { + "displayName": "Diagnosis Specimen Diagnosis Id", + "fieldName": "data.diagnosis.specimen.diagnosis_id" + }, + { + "displayName": "Diagnosis Specimen Specimen Type", + "fieldName": "data.diagnosis.specimen.specimen_type" + }, + { + "displayName": "Diagnosis Specimen Tissue Source", + "fieldName": "data.diagnosis.specimen.tissue_source" + }, + { + "displayName": "Diagnosis Treatment", + "fieldName": "data.diagnosis.treatment", + "isArray": true + }, + { + "displayName": "Diagnosis Treatment Drug Name", + "fieldName": "data.diagnosis.treatment.drug_name" + }, + { + "displayName": "Diagnosis Treatment Diagnosis Id", + "fieldName": "data.diagnosis.treatment.diagnosis_id" + }, + { + "displayName": "Diagnosis Treatment Treatment Id", + "fieldName": "data.diagnosis.treatment.treatment_id" + }, + { + "displayName": "Diagnosis Treatment Treatment Type", + "fieldName": "data.diagnosis.treatment.treatment_type" + }, + { + "displayName": "Diagnosis Treatment Treatment Start", + "fieldName": "data.diagnosis.treatment.treatment_start" + }, + { + "displayName": "Diagnosis Treatment Treatment Duration", + "fieldName": "data.diagnosis.treatment.treatment_duration" + }, + { + "displayName": "Diagnosis Treatment Treatment Response", + "fieldName": "data.diagnosis.treatment.treatment_response" + } + ] +} \ No newline at end of file diff --git a/apps/conductor/configs/arrangerConfigs/datatable1/facets.json b/apps/conductor/configs/arrangerConfigs/datatable1/facets.json new file mode 100644 index 00000000..e20db06d --- /dev/null +++ b/apps/conductor/configs/arrangerConfigs/datatable1/facets.json @@ -0,0 +1,141 @@ +{ + "facets": { + "aggregations": [ + { + "active": true, + "fieldName": "data__gender", + "show": true + }, + { + "active": true, + "fieldName": "data__donor_id", + "show": true + }, + { + "active": true, + "fieldName": "data__vital_status", + "show": true + }, + { + "active": true, + "fieldName": "data__diagnosis__stage", + "show": true + }, + { + "active": true, + "fieldName": "data__diagnosis__donor_id", + "show": true + }, + { + "active": true, + "fieldName": "data__diagnosis__cancer_type", + "show": true + }, + { + "active": true, + "fieldName": "data__diagnosis__diagnosis_id", + "show": true + }, + { + "active": true, + "fieldName": "data__diagnosis__primary_site", + "show": true + }, + { + "active": true, + "fieldName": "data__diagnosis__staging_system", + "show": true + }, + { + "active": true, + "fieldName": "data__diagnosis__age_at_diagnosis", + "show": true + }, + { + "active": true, + "fieldName": "data__diagnosis__followup__followup_id", + "show": true + }, + { + "active": true, + "fieldName": "data__diagnosis__followup__diagnosis_id", + "show": true + }, + { + "active": true, + "fieldName": "data__diagnosis__followup__disease_status", + "show": true + }, + { + "active": true, + "fieldName": "data__diagnosis__followup__followup_interval", + "show": true + }, + { + "active": true, + "fieldName": "data__diagnosis__specimen__sample_id", + "show": true + }, + { + "active": true, + "fieldName": "data__diagnosis__specimen__sample_type", + "show": true + }, + { + "active": true, + "fieldName": "data__diagnosis__specimen__specimen_id", + "show": true + }, + { + "active": true, + "fieldName": "data__diagnosis__specimen__diagnosis_id", + "show": true + }, + { + "active": true, + "fieldName": "data__diagnosis__specimen__specimen_type", + "show": true + }, + { + "active": true, + "fieldName": "data__diagnosis__specimen__tissue_source", + "show": true + }, + { + "active": true, + "fieldName": "data__diagnosis__treatment__drug_name", + "show": true + }, + { + "active": true, + "fieldName": "data__diagnosis__treatment__diagnosis_id", + "show": true + }, + { + "active": true, + "fieldName": "data__diagnosis__treatment__treatment_id", + "show": true + }, + { + "active": true, + "fieldName": "data__diagnosis__treatment__treatment_type", + "show": true + }, + { + "active": true, + "fieldName": "data__diagnosis__treatment__treatment_start", + "show": true + }, + { + "active": true, + "fieldName": "data__diagnosis__treatment__treatment_duration", + "show": true + }, + { + "active": true, + "fieldName": "data__diagnosis__treatment__treatment_response", + "show": true + } + ] + } +} \ No newline at end of file diff --git a/apps/conductor/configs/arrangerConfigs/datatable1/table.json b/apps/conductor/configs/arrangerConfigs/datatable1/table.json new file mode 100644 index 00000000..f654dd0a --- /dev/null +++ b/apps/conductor/configs/arrangerConfigs/datatable1/table.json @@ -0,0 +1,222 @@ +{ + "table": { + "columns": [ + { + "canChangeShow": true, + "fieldName": "data.gender", + "show": true, + "sortable": true, + "jsonPath": "$.data.gender", + "query": "data { gender }" + }, + { + "canChangeShow": true, + "fieldName": "data.donor_id", + "show": true, + "sortable": true, + "jsonPath": "$.data.donor_id", + "query": "data { donor_id }" + }, + { + "canChangeShow": true, + "fieldName": "data.vital_status", + "show": true, + "sortable": true, + "jsonPath": "$.data.vital_status", + "query": "data { vital_status }" + }, + { + "canChangeShow": true, + "fieldName": "data.diagnosis.stage", + "show": true, + "sortable": true, + "jsonPath": "$.data.diagnosis.hits.edges[*].node.stage", + "query": "data { diagnosis { hits { edges { node { stage } } } } }" + }, + { + "canChangeShow": true, + "fieldName": "data.diagnosis.donor_id", + "show": true, + "sortable": true, + "jsonPath": "$.data.diagnosis.hits.edges[*].node.donor_id", + "query": "data { diagnosis { hits { edges { node { donor_id } } } } }" + }, + { + "canChangeShow": true, + "fieldName": "data.diagnosis.cancer_type", + "show": true, + "sortable": true, + "jsonPath": "$.data.diagnosis.hits.edges[*].node.cancer_type", + "query": "data { diagnosis { hits { edges { node { cancer_type } } } } }" + }, + { + "canChangeShow": true, + "fieldName": "data.diagnosis.diagnosis_id", + "show": true, + "sortable": true, + "jsonPath": "$.data.diagnosis.hits.edges[*].node.diagnosis_id", + "query": "data { diagnosis { hits { edges { node { diagnosis_id } } } } }" + }, + { + "canChangeShow": true, + "fieldName": "data.diagnosis.primary_site", + "show": true, + "sortable": true, + "jsonPath": "$.data.diagnosis.hits.edges[*].node.primary_site", + "query": "data { diagnosis { hits { edges { node { primary_site } } } } }" + }, + { + "canChangeShow": true, + "fieldName": "data.diagnosis.staging_system", + "show": true, + "sortable": true, + "jsonPath": "$.data.diagnosis.hits.edges[*].node.staging_system", + "query": "data { diagnosis { hits { edges { node { staging_system } } } } }" + }, + { + "canChangeShow": true, + "fieldName": "data.diagnosis.age_at_diagnosis", + "show": true, + "sortable": true, + "jsonPath": "$.data.diagnosis.hits.edges[*].node.age_at_diagnosis", + "query": "data { diagnosis { hits { edges { node { age_at_diagnosis } } } } }" + }, + { + "canChangeShow": true, + "fieldName": "data.diagnosis.followup.followup_id", + "show": false, + "sortable": true, + "jsonPath": "$.data.diagnosis.hits.edges[*].node.followup.hits.edges[*].node.followup_id", + "query": "data { diagnosis { hits { edges { node { followup { hits { edges { node { followup_id } } } } } } } } }" + }, + { + "canChangeShow": true, + "fieldName": "data.diagnosis.followup.diagnosis_id", + "show": false, + "sortable": true, + "jsonPath": "$.data.diagnosis.hits.edges[*].node.followup.hits.edges[*].node.diagnosis_id", + "query": "data { diagnosis { hits { edges { node { followup { hits { edges { node { diagnosis_id } } } } } } } } }" + }, + { + "canChangeShow": true, + "fieldName": "data.diagnosis.followup.disease_status", + "show": false, + "sortable": true, + "jsonPath": "$.data.diagnosis.hits.edges[*].node.followup.hits.edges[*].node.disease_status", + "query": "data { diagnosis { hits { edges { node { followup { hits { edges { node { disease_status } } } } } } } } }" + }, + { + "canChangeShow": true, + "fieldName": "data.diagnosis.followup.followup_interval", + "show": false, + "sortable": true, + "jsonPath": "$.data.diagnosis.hits.edges[*].node.followup.hits.edges[*].node.followup_interval", + "query": "data { diagnosis { hits { edges { node { followup { hits { edges { node { followup_interval } } } } } } } } }" + }, + { + "canChangeShow": true, + "fieldName": "data.diagnosis.specimen.sample_id", + "show": false, + "sortable": true, + "jsonPath": "$.data.diagnosis.hits.edges[*].node.specimen.hits.edges[*].node.sample_id", + "query": "data { diagnosis { hits { edges { node { specimen { hits { edges { node { sample_id } } } } } } } } }" + }, + { + "canChangeShow": true, + "fieldName": "data.diagnosis.specimen.sample_type", + "show": false, + "sortable": true, + "jsonPath": "$.data.diagnosis.hits.edges[*].node.specimen.hits.edges[*].node.sample_type", + "query": "data { diagnosis { hits { edges { node { specimen { hits { edges { node { sample_type } } } } } } } } }" + }, + { + "canChangeShow": true, + "fieldName": "data.diagnosis.specimen.specimen_id", + "show": false, + "sortable": true, + "jsonPath": "$.data.diagnosis.hits.edges[*].node.specimen.hits.edges[*].node.specimen_id", + "query": "data { diagnosis { hits { edges { node { specimen { hits { edges { node { specimen_id } } } } } } } } }" + }, + { + "canChangeShow": true, + "fieldName": "data.diagnosis.specimen.diagnosis_id", + "show": false, + "sortable": true, + "jsonPath": "$.data.diagnosis.hits.edges[*].node.specimen.hits.edges[*].node.diagnosis_id", + "query": "data { diagnosis { hits { edges { node { specimen { hits { edges { node { diagnosis_id } } } } } } } } }" + }, + { + "canChangeShow": true, + "fieldName": "data.diagnosis.specimen.specimen_type", + "show": false, + "sortable": true, + "jsonPath": "$.data.diagnosis.hits.edges[*].node.specimen.hits.edges[*].node.specimen_type", + "query": "data { diagnosis { hits { edges { node { specimen { hits { edges { node { specimen_type } } } } } } } } }" + }, + { + "canChangeShow": true, + "fieldName": "data.diagnosis.specimen.tissue_source", + "show": false, + "sortable": true, + "jsonPath": "$.data.diagnosis.hits.edges[*].node.specimen.hits.edges[*].node.tissue_source", + "query": "data { diagnosis { hits { edges { node { specimen { hits { edges { node { tissue_source } } } } } } } } }" + }, + { + "canChangeShow": true, + "fieldName": "data.diagnosis.treatment.drug_name", + "show": false, + "sortable": true, + "jsonPath": "$.data.diagnosis.hits.edges[*].node.treatment.hits.edges[*].node.drug_name", + "query": "data { diagnosis { hits { edges { node { treatment { hits { edges { node { drug_name } } } } } } } } }" + }, + { + "canChangeShow": true, + "fieldName": "data.diagnosis.treatment.diagnosis_id", + "show": false, + "sortable": true, + "jsonPath": "$.data.diagnosis.hits.edges[*].node.treatment.hits.edges[*].node.diagnosis_id", + "query": "data { diagnosis { hits { edges { node { treatment { hits { edges { node { diagnosis_id } } } } } } } } }" + }, + { + "canChangeShow": true, + "fieldName": "data.diagnosis.treatment.treatment_id", + "show": false, + "sortable": true, + "jsonPath": "$.data.diagnosis.hits.edges[*].node.treatment.hits.edges[*].node.treatment_id", + "query": "data { diagnosis { hits { edges { node { treatment { hits { edges { node { treatment_id } } } } } } } } }" + }, + { + "canChangeShow": true, + "fieldName": "data.diagnosis.treatment.treatment_type", + "show": false, + "sortable": true, + "jsonPath": "$.data.diagnosis.hits.edges[*].node.treatment.hits.edges[*].node.treatment_type", + "query": "data { diagnosis { hits { edges { node { treatment { hits { edges { node { treatment_type } } } } } } } } }" + }, + { + "canChangeShow": true, + "fieldName": "data.diagnosis.treatment.treatment_start", + "show": false, + "sortable": true, + "jsonPath": "$.data.diagnosis.hits.edges[*].node.treatment.hits.edges[*].node.treatment_start", + "query": "data { diagnosis { hits { edges { node { treatment { hits { edges { node { treatment_start } } } } } } } } }" + }, + { + "canChangeShow": true, + "fieldName": "data.diagnosis.treatment.treatment_duration", + "show": false, + "sortable": true, + "jsonPath": "$.data.diagnosis.hits.edges[*].node.treatment.hits.edges[*].node.treatment_duration", + "query": "data { diagnosis { hits { edges { node { treatment { hits { edges { node { treatment_duration } } } } } } } } }" + }, + { + "canChangeShow": true, + "fieldName": "data.diagnosis.treatment.treatment_response", + "show": false, + "sortable": true, + "jsonPath": "$.data.diagnosis.hits.edges[*].node.treatment.hits.edges[*].node.treatment_response", + "query": "data { diagnosis { hits { edges { node { treatment { hits { edges { node { treatment_response } } } } } } } } }" + } + ] + } +} \ No newline at end of file diff --git a/apps/conductor/configs/elasticsearchConfigs/datatable1-mapping.json b/apps/conductor/configs/elasticsearchConfigs/datatable1-mapping.json new file mode 100644 index 00000000..6c9ac6f5 --- /dev/null +++ b/apps/conductor/configs/elasticsearchConfigs/datatable1-mapping.json @@ -0,0 +1,120 @@ +{ + "index_patterns": ["datatable1-*"], + "aliases": { + "datatable1_centric": {} + }, + "mappings": { + "properties": { + "data": { + "type": "object", + "properties": { + "gender": { + "type": "keyword" + }, + "donor_id": { + "type": "keyword" + }, + "vital_status": { + "type": "keyword" + }, + "diagnosis": { + "type": "nested", + "properties": { + "stage": { + "type": "keyword" + }, + "donor_id": { + "type": "keyword" + }, + "cancer_type": { + "type": "keyword" + }, + "diagnosis_id": { + "type": "keyword" + }, + "primary_site": { + "type": "keyword" + }, + "staging_system": { + "type": "keyword" + }, + "age_at_diagnosis": { + "type": "integer" + }, + "followup": { + "type": "nested", + "properties": { + "followup_id": { + "type": "keyword" + }, + "diagnosis_id": { + "type": "keyword" + }, + "disease_status": { + "type": "keyword" + }, + "followup_interval": { + "type": "integer" + } + } + }, + "specimen": { + "type": "nested", + "properties": { + "sample_id": { + "type": "keyword" + }, + "sample_type": { + "type": "keyword" + }, + "specimen_id": { + "type": "keyword" + }, + "diagnosis_id": { + "type": "keyword" + }, + "specimen_type": { + "type": "keyword" + }, + "tissue_source": { + "type": "keyword" + } + } + }, + "treatment": { + "type": "nested", + "properties": { + "drug_name": { + "type": "keyword" + }, + "diagnosis_id": { + "type": "keyword" + }, + "treatment_id": { + "type": "keyword" + }, + "treatment_type": { + "type": "keyword" + }, + "treatment_start": { + "type": "integer" + }, + "treatment_duration": { + "type": "integer" + }, + "treatment_response": { + "type": "keyword" + } + } + } + } + } + } + } + } + }, + "settings": { + "number_of_shards": 1, + "number_of_replicas": 0 + } +} diff --git a/apps/conductor/configs/elasticsearchConfigs/mapping.json b/apps/conductor/configs/elasticsearchConfigs/mapping.json new file mode 100644 index 00000000..30a1e1be --- /dev/null +++ b/apps/conductor/configs/elasticsearchConfigs/mapping.json @@ -0,0 +1,120 @@ +{ + "index_patterns": ["data-*"], + "aliases": { + "data_centric": {} + }, + "mappings": { + "properties": { + "data": { + "type": "object", + "properties": { + "gender": { + "type": "keyword" + }, + "donor_id": { + "type": "keyword" + }, + "vital_status": { + "type": "keyword" + }, + "diagnosis": { + "type": "nested", + "properties": { + "stage": { + "type": "keyword" + }, + "donor_id": { + "type": "keyword" + }, + "cancer_type": { + "type": "keyword" + }, + "diagnosis_id": { + "type": "keyword" + }, + "primary_site": { + "type": "keyword" + }, + "staging_system": { + "type": "keyword" + }, + "age_at_diagnosis": { + "type": "integer" + }, + "followup": { + "type": "nested", + "properties": { + "followup_id": { + "type": "keyword" + }, + "diagnosis_id": { + "type": "keyword" + }, + "disease_status": { + "type": "keyword" + }, + "followup_interval": { + "type": "integer" + } + } + }, + "specimen": { + "type": "nested", + "properties": { + "sample_id": { + "type": "keyword" + }, + "sample_type": { + "type": "keyword" + }, + "specimen_id": { + "type": "keyword" + }, + "diagnosis_id": { + "type": "keyword" + }, + "specimen_type": { + "type": "keyword" + }, + "tissue_source": { + "type": "keyword" + } + } + }, + "treatment": { + "type": "nested", + "properties": { + "drug_name": { + "type": "keyword" + }, + "diagnosis_id": { + "type": "keyword" + }, + "treatment_id": { + "type": "keyword" + }, + "treatment_type": { + "type": "keyword" + }, + "treatment_start": { + "type": "integer" + }, + "treatment_duration": { + "type": "integer" + }, + "treatment_response": { + "type": "keyword" + } + } + } + } + } + } + } + } + }, + "settings": { + "number_of_shards": 1, + "number_of_replicas": 0 + } +} diff --git a/apps/conductor/configs/lecternDictionaries/dictionary.json b/apps/conductor/configs/lecternDictionaries/dictionary.json new file mode 100644 index 00000000..21862143 --- /dev/null +++ b/apps/conductor/configs/lecternDictionaries/dictionary.json @@ -0,0 +1,214 @@ +{ + "name": "example-dictionary", + "description": "Generated dictionary from CSV files", + "version": "1.0", + "meta": {}, + "schemas": [ + { + "name": "donor", + "description": "Schema generated from donor.csv", + "foreignKey": [ + { + "schema": "diagnosis", + "mappings": [{ "local": "{{Local ID}}", "foreign": "{{Foreign ID}}" }] + } + ], + "fields": [ + { + "name": "donor_id", + "description": "Field containing donor_id data", + "valueType": "string", + "meta": { + "displayName": "donor_id" + } + }, + { + "name": "gender", + "description": "Field containing gender data", + "valueType": "string", + "meta": { + "displayName": "gender" + } + }, + { + "name": "vital_status", + "description": "Field containing vital_status data", + "valueType": "string", + "meta": { + "displayName": "vital_status" + } + } + ], + "meta": { + "createdAt": "2025-03-20T16:11:06.493Z", + "sourceFile": "donor.csv" + } + }, + { + "name": "diagnosis", + "description": "Schema generated from diagnosis.csv", + "fields": [ + { + "name": "diagnosis_id", + "description": "Field containing diagnosis_id data", + "valueType": "string", + "meta": { + "displayName": "diagnosis_id" + } + }, + { + "name": "donor_id", + "description": "Field containing donor_id data", + "valueType": "string", + "meta": { + "displayName": "donor_id" + } + }, + { + "name": "primary_site", + "description": "Field containing primary_site data", + "valueType": "string", + "meta": { + "displayName": "primary_site" + } + }, + { + "name": "age_at_diagnosis", + "description": "Field containing age_at_diagnosis data", + "valueType": "integer", + "meta": { + "displayName": "age_at_diagnosis" + } + }, + { + "name": "cancer_type", + "description": "Field containing cancer_type data", + "valueType": "string", + "meta": { + "displayName": "cancer_type" + } + }, + { + "name": "staging_system", + "description": "Field containing staging_system data", + "valueType": "string", + "meta": { + "displayName": "staging_system" + } + }, + { + "name": "stage", + "description": "Field containing stage data", + "valueType": "string", + "meta": { + "displayName": "stage" + } + } + ], + "meta": { + "createdAt": "2025-03-20T16:11:06.491Z", + "sourceFile": "diagnosis.csv" + } + }, + { + "name": "followup", + "description": "Schema generated from followup.csv", + "fields": [ + { + "name": "treatment_id", + "description": "Field containing treatment_id data", + "valueType": "string", + "meta": { + "displayName": "treatment_id" + } + }, + { + "name": "followup_id", + "description": "Field containing followup_id data", + "valueType": "string", + "meta": { + "displayName": "followup_id" + } + }, + { + "name": "followup_interval", + "description": "Field containing followup_interval data", + "valueType": "integer", + "meta": { + "displayName": "followup_interval" + } + }, + { + "name": "disease_status", + "description": "Field containing disease_status data", + "valueType": "string", + "meta": { + "displayName": "disease_status" + } + } + ], + "meta": { + "createdAt": "2025-03-20T16:11:06.494Z", + "sourceFile": "followup.csv" + } + }, + { + "name": "treatment", + "description": "Schema generated from treatment.csv", + "fields": [ + { + "name": "donor_id", + "description": "Field containing donor_id data", + "valueType": "string", + "meta": { + "displayName": "donor_id" + } + }, + { + "name": "treatment_id", + "description": "Field containing treatment_id data", + "valueType": "string", + "meta": { + "displayName": "treatment_id" + } + }, + { + "name": "treatment_type", + "description": "Field containing treatment_type data", + "valueType": "string", + "meta": { + "displayName": "treatment_type" + } + }, + { + "name": "treatment_start", + "description": "Field containing treatment_start data", + "valueType": "integer", + "meta": { + "displayName": "treatment_start" + } + }, + { + "name": "treatment_duration", + "description": "Field containing treatment_duration data", + "valueType": "integer", + "meta": { + "displayName": "treatment_duration" + } + }, + { + "name": "treatment_response", + "description": "Field containing treatment_response data", + "valueType": "string", + "meta": { + "displayName": "treatment_response" + } + } + ], + "meta": { + "createdAt": "2025-03-20T16:11:06.495Z", + "sourceFile": "treatment.csv" + } + } + ] +} diff --git a/apps/conductor/configs/songSchemas/song-schema.json b/apps/conductor/configs/songSchemas/song-schema.json new file mode 100644 index 00000000..421f3a22 --- /dev/null +++ b/apps/conductor/configs/songSchemas/song-schema.json @@ -0,0 +1,57 @@ +{ + "name": "MyNewSchema", + "version": "1", + "options": { + "fileTypes": ["VCF", "TBI"] + }, + "schema": { + "type": "object", + "required": ["workflow", "experiment"], + "properties": { + "workflow": { + "type": "object", + "required": [ + "workflowName", + "workflowShortName", + "workflowVersion", + "inputs", + "runId", + "sessionId" + ], + "properties": { + "workflowName": { "type": "string" }, + "workflowShortName": { "type": "string" }, + "workflowVersion": { "type": "string" }, + "inputs": { + "type": "array", + "items": { + "type": "object", + "required": ["analysisType", "analysisId"], + "properties": { + "analysisType": { "type": "string" }, + "analysisId": { "type": "string" } + } + } + }, + "runId": { "type": "string" }, + "sessionId": { "type": "string" } + } + }, + "experiment": { + "type": "object", + "required": [ + "platform", + "experimentalStrategy", + "sequencingCenter", + "sequencingDate" + ], + "properties": { + "platform": { "type": "string" }, + "experimentalStrategy": { "type": "string" }, + "sequencingCenter": { "type": "string" }, + "sequencingDate": { "type": "string" } + } + } + } + } +} diff --git a/apps/conductor/docs/csvUpload.md b/apps/conductor/docs/csvUpload.md new file mode 100644 index 00000000..b3ad032e --- /dev/null +++ b/apps/conductor/docs/csvUpload.md @@ -0,0 +1,267 @@ +# CSV Upload to Elasticsearch + +## Overview + +The CSV Upload feature provides a command-line interface for processing and uploading CSV data to Elasticsearch. It handles parsing, validation, transformation, and bulk indexing of CSV files with error handling and progress reporting. + +## Key Features + +- Parse and validate CSV files with customizable delimiters +- Upload data to Elasticsearch with configurable batch sizes +- Automatic field-type detection and mapping +- Detailed progress reporting and error logging +- Concurrent file processing for improved performance +- Configurable retry mechanism for resilient uploads + +## Command-Line Usage + +```bash +conductor upload --files [ ...] [options] +``` + +### Required Parameters + +- `--files, -f`: One or more CSV files to process and upload + +### Optional Parameters + +- `--delimiter, -d`: CSV field delimiter (default: ",") +- `--batch-size, -b`: Number of records to send in each batch (default: 1000) +- `--index, -i`: Elasticsearch index name (default: from config) +- `--url, -u`: Elasticsearch URL (default: from config or localhost:9200) +- `--username`: Elasticsearch username (default: elastic) +- `--password`: Elasticsearch password (default: myelasticpassword) +- `--force`: Skip confirmation prompts (default: false) +- `--output, -o`: Output directory for results +- `--debug`: Enable debug logging + +## Architecture + +The CSV Upload feature follows a modular architecture with clear separation of concerns: + +### Command Layer + +The `UploadCommand` class extends the abstract `Command` base class and orchestrates the upload process. It: + +1. Validates input files and settings +2. Sets up the Elasticsearch client +3. Processes each file through the CSV processor +4. Aggregates results and handles errors +5. Reports success or failure + +### Service Layer + +The feature uses specialized service modules: + +- `services/elasticsearch/`: Provides functions for Elasticsearch operations +- `services/csvProcessor/`: Handles CSV parsing and transformation +- `validations/`: Contains validation functions for various inputs + +### File Processing Flow + +1. **Validation Phase**: Files and settings are validated +2. **Connection Phase**: Elasticsearch connection is established and validated +3. **Processing Phase**: Each file is processed in sequence +4. **Reporting Phase**: Results are aggregated and reported + +## Code Walkthrough + +### Command Structure + +```typescript +export class UploadCommand extends Command { + constructor() { + super("upload"); + this.defaultOutputFileName = "upload-results.json"; + } + + protected async execute(cliOutput: CLIOutput): Promise { + // Command implementation + } +} +``` + +### File Processing Loop + +The command processes each file individually: + +```typescript +for (const filePath of filePaths) { + Logger.debug(`Processing File: ${filePath}`); + + try { + await this.processFile(filePath, config); + Logger.debug(`Successfully processed ${filePath}`); + successCount++; + } catch (error) { + failureCount++; + // Error handling logic + } +} +``` + +### CSV Header Validation + +The command performs basic validation of CSV headers: + +```typescript +private async validateCSVHeaders(filePath: string, delimiter: string): Promise { + const fileContent = fs.readFileSync(filePath, "utf-8"); + const [headerLine] = fileContent.split("\n"); + + if (!headerLine) { + throw new ConductorError("CSV file is empty or has no headers", ErrorCodes.INVALID_FILE); + } + + const parseResult = parseCSVLine(headerLine, delimiter, true); + // Additional validation logic +} +``` + +### CSV Processing Service + +The actual CSV processing is handled by a dedicated service: + +```typescript +// In services/csvProcessor/index.ts +export async function processCSVFile( + filePath: string, + config: Config, + client: Client +): Promise { + // Initialize processor + const processor = new CSVProcessor(config, client); + + // Process the file + return await processor.processFile(filePath); +} +``` + +### Batch Processing + +Records are processed in batches for efficient uploading: + +```typescript +// In services/csvProcessor/processor.ts +private async processBatch(batch: Record[]): Promise { + if (batch.length === 0) return; + + this.currentBatch++; + const batchNumber = this.currentBatch; + + try { + await sendBatchToElasticsearch( + this.client, + batch, + this.config.elasticsearch.index, + (failureCount) => this.handleFailures(failureCount, batchNumber) + ); + + this.processedRecords += batch.length; + this.updateProgress(); + } catch (error) { + // Error handling + } +} +``` + +### Elasticsearch Bulk Operations + +The upload leverages Elasticsearch's bulk API for efficient indexing: + +```typescript +// In services/elasticsearch/bulk.ts +export async function sendBulkWriteRequest( + client: Client, + records: object[], + indexName: string, + onFailure: (count: number) => void, + options: BulkOptions = {} +): Promise { + // Retry logic and bulk request implementation + const body = records.flatMap((doc) => [ + { index: { _index: indexName } }, + doc, + ]); + + const { body: result } = await client.bulk({ + body, + refresh: true, + }); + + // Process results and handle errors +} +``` + +## Error Handling + +The upload feature implements multi-level error handling: + +1. **Command-Level Errors**: General validation and processing errors +2. **File-Level Errors**: Issues with specific files +3. **Batch-Level Errors**: Problems with specific batches of records +4. **Record-Level Errors**: Individual record validation or indexing failures + +All errors are logged and properly aggregated in the final result. + +## Performance Considerations + +The upload process is optimized for performance: + +1. **Batch Processing**: Records are sent in configurable batches +2. **Streaming Parser**: CSV files are streamed rather than loaded entirely into memory +3. **Retry Mechanism**: Failed batches are retried with exponential backoff +4. **Progress Reporting**: Real-time progress is reported for large files + +## Data Transformation + +The processor can transform CSV data before indexing: + +1. **Type Detection**: Automatically detects field types +2. **Date Parsing**: Converts date strings to proper date objects +3. **Nested Fields**: Supports dot notation for nested objects +4. **Numeric Conversion**: Converts numeric strings to actual numbers + +## Extending the Feature + +To extend this feature: + +1. **Add New Validations**: Create additional validators in the `validations/` directory +2. **Enhance Transformations**: Modify the `transformRecord` function in the CSV processor +3. **Add CLI Options**: Update `configureCommandOptions` in `cli/options.ts` +4. **Support New File Formats**: Create new processor implementations for different formats + +## Best Practices + +When working with this code: + +1. **Stream Large Files**: Avoid loading entire files into memory +2. **Validate Early**: Perform validation before processing +3. **Handle Partial Failures**: Allow some records to fail without aborting the entire batch +4. **Use Appropriate Batch Sizes**: Adjust batch size based on record complexity +5. **Monitor Memory Usage**: Watch for memory leaks when processing large files + +## Testing + +For testing the feature: + +```bash +# Upload a single file +conductor upload -f ./data/sample.csv + +# Upload multiple files with custom settings +conductor upload -f ./data/file1.csv ./data/file2.csv -d ";" -b 500 -i my-index + +# Debug mode with custom credentials +conductor upload -f ./data/sample.csv --debug --username admin --password secret +``` + +## Troubleshooting + +Common issues and solutions: + +1. **CSV Parsing Errors**: Check delimiter settings and file encoding +2. **Elasticsearch Connection Issues**: Verify URL and credentials +3. **Mapping Errors**: Ensure index mapping is compatible with CSV data types +4. **Memory Limitations**: Reduce batch size for large records +5. **Performance Issues**: Increase batch size for simple records diff --git a/apps/conductor/docs/indexManagement.md b/apps/conductor/docs/indexManagement.md new file mode 100644 index 00000000..b1686ba3 --- /dev/null +++ b/apps/conductor/docs/indexManagement.md @@ -0,0 +1,248 @@ +# Elasticsearch Index Management + +## Overview + +The Index Management feature provides a command-line interface for creating and managing Elasticsearch indices and templates. It allows users to define index mapping templates and create indices that conform to these templates, making it easy to maintain consistent data structures across your Elasticsearch cluster. + +## Key Features + +- Create and manage Elasticsearch index templates +- Automatically generate indices that match template patterns +- Smart handling of aliases defined in templates +- Support for command-line options and configuration files +- Comprehensive error handling and logging + +## Command-Line Usage + +```bash +conductor indexManagement --template-file [options] +``` + +### Required Parameters + +- `--template-file, -t`: Path to the JSON template file + +### Optional Parameters + +- `--template-name, -n`: Custom name for the template (default: auto-generated) +- `--index-name, -i`: Custom name for the index (default: derived from template pattern) +- `--alias, -a`: Custom alias for the index (default: from template or indexed-name-alias) +- `--url, -u`: Elasticsearch URL (default: from config or localhost:9200) +- `--username`: Elasticsearch username (default: elastic) +- `--password`: Elasticsearch password (default: myelasticpassword) +- `--force`: Skip confirmation prompts (default: false) +- `--output, -o`: Output directory for results +- `--debug`: Enable debug logging + +## Template File Format + +The template file should be a valid Elasticsearch index template in JSON format. Here's an example: + +```json +{ + "index_patterns": ["tabular-*"], + "aliases": { + "tabular-index_centric": {} + }, + "mappings": { + "properties": { + "field1": { "type": "keyword" }, + "field2": { "type": "integer" } + } + }, + "settings": { + "number_of_shards": 1, + "number_of_replicas": 0 + } +} +``` + +Key components: + +- `index_patterns`: Patterns that indices must match for the template to apply +- `aliases`: Default aliases for the indices +- `mappings`: Field definitions and data types +- `settings`: Index configuration settings + +## Architecture + +The Index Management feature follows a modular architecture with clear separation of concerns: + +### Command Layer + +The `IndexManagementCommand` class extends the abstract `Command` base class and provides the entry point for the feature. It: + +1. Parses command-line arguments +2. Loads and analyzes the template file +3. Orchestrates the creation of templates and indices +4. Reports success or failure to the CLI + +### Service Layer + +The feature uses specialized service modules in the `services/elasticsearch/` directory: + +- `client.ts`: Handles client creation and connection management +- `templates.ts`: Provides functions for template operations +- `indices.ts`: Manages index operations + +Each service module contains focused, pure functions that handle specific aspects of Elasticsearch interaction. + +### Helper Functions + +A key component is the `extractTemplateInfo` function that analyzes a template to: + +- Extract index patterns and convert them to valid index names +- Find aliases defined in the template +- Extract settings like number of shards and replicas + +This allows the command to make intelligent decisions about defaults. + +## Code Walkthrough + +### Command Execution Flow + +1. **Template Loading**: The command loads and parses the template file + + ```typescript + const rawContent = fs.readFileSync(templateFile, "utf-8"); + templateContent = JSON.parse(rawContent); + ``` + +2. **Template Analysis**: The template is analyzed to extract useful information + + ```typescript + const templateInfo = extractTemplateInfo(templateContent); + ``` + +3. **Name Resolution**: Index and alias names are determined using a priority system + + ```typescript + const indexName = + options.indexName || + config.elasticsearch?.index || + templateInfo.defaultIndexName || + `index-${Date.now()}`; + ``` + +4. **Connection**: An Elasticsearch client is created and connection is validated + + ```typescript + const client = createClientFromConfig(config); + await validateConnection(client); + ``` + +5. **Template Creation**: The template is created if it doesn't exist + + ```typescript + const isTemplateExists = await templateExists(client, templateName); + if (!isTemplateExists) { + await createTemplate(client, templateName, templateContent); + } + ``` + +6. **Index Creation**: An index is created with the appropriate alias + ```typescript + const isIndexExists = await indexExists(client, indexName); + if (!isIndexExists) { + await createIndex(client, indexName, indexSettings); + } + ``` + +### Template Analysis + +The `extractTemplateInfo` function analyzes a template to extract useful information: + +```typescript +export function extractTemplateInfo( + templateBody: Record +): TemplateInfo { + const info: TemplateInfo = {}; + + // Extract default index name from index patterns + if ( + templateBody.index_patterns && + Array.isArray(templateBody.index_patterns) + ) { + const pattern = templateBody.index_patterns[0]; + info.defaultIndexName = pattern.replace(/\*$/, Date.now()); + } + + // Extract default alias from aliases + if (templateBody.aliases && typeof templateBody.aliases === "object") { + const aliasNames = Object.keys(templateBody.aliases); + if (aliasNames.length > 0) { + info.defaultAliasName = aliasNames[0]; + } + } + + // Extract settings + if (templateBody.settings) { + if (templateBody.settings.number_of_shards) { + info.numberOfShards = parseInt( + templateBody.settings.number_of_shards, + 10 + ); + } + + if (templateBody.settings.number_of_replicas) { + info.numberOfReplicas = parseInt( + templateBody.settings.number_of_replicas, + 10 + ); + } + } + + return info; +} +``` + +## Error Handling + +The feature implements comprehensive error handling: + +1. **Template File Errors**: Checks if the file exists and contains valid JSON +2. **Connection Errors**: Provides specific guidance for connection issues +3. **Template Creation Errors**: Detailed error messages for template operations +4. **Index Creation Errors**: Clear reporting of index creation failures + +All errors are wrapped in a `ConductorError` with appropriate error codes for consistent handling. + +## Extending the Feature + +To extend this feature: + +1. **Add New Template Operations**: Add functions to `templates.ts` +2. **Support New Index Operations**: Add functions to `indices.ts` +3. **Add CLI Options**: Update `configureCommandOptions` in `cli/options.ts` +4. **Add New Template Analysis**: Enhance the `extractTemplateInfo` function + +## Best Practices + +When working with this code: + +1. **Maintain Separation of Concerns**: Keep service functions pure and focused +2. **Prioritize Error Handling**: Always provide meaningful error messages +3. **Use TypeScript Interfaces**: Define clear interfaces for inputs and outputs +4. **Log Extensively**: Use consistent logging for better observability +5. **Follow Command Pattern**: Extend the base Command class for new commands + +## Testing + +For testing the feature: + +```bash +# Create a template and index +conductor indexManagement --template-file ./templates/my-mapping.json + +# Create with custom names +conductor indexManagement --template-file ./templates/my-mapping.json --template-name my-template --index-name my-index --alias my-alias +``` + +## Troubleshooting + +Common issues and solutions: + +1. **Authentication Failures**: Ensure username and password are correct +2. **Template Parsing Errors**: Validate JSON syntax in the template file +3. **Index Name Conflicts**: Check if indices with similar names already exist +4. **Pattern Matching Issues**: Ensure index names match the patterns in templates diff --git a/apps/conductor/docs/lecternUpload.md b/apps/conductor/docs/lecternUpload.md new file mode 100644 index 00000000..1ae7c7ca --- /dev/null +++ b/apps/conductor/docs/lecternUpload.md @@ -0,0 +1,201 @@ +# Lectern Schema Upload + +## Overview + +The Lectern Schema Upload feature provides a command-line interface for uploading data dictionary schemas to a Lectern server. It simplifies the process of managing and versioning data schemas across different environments, ensuring consistent data definitions. + +## Key Features + +- Upload JSON schemas to Lectern server +- Robust health check mechanism +- Multiple retry attempts for server connection +- Validate schema files before upload +- Comprehensive error handling +- Support for different Lectern server configurations +- Flexible authentication options + +## Health Check Mechanism + +The upload process includes a sophisticated health check: + +- **Connection Attempts**: 10 retry attempts +- **Retry Delay**: 20 seconds between attempts +- **Timeout**: 10 seconds per attempt +- **Status Verification**: + - Checks multiple status indicators + - Supports various server response formats + - Provides detailed connection failure information + +## URL Handling + +Intelligent URL normalization ensures compatibility: + +- Strips trailing slashes +- Handles different endpoint variations +- Automatically appends `/dictionaries` if needed +- Supports multiple URL formats + +## Command-Line Usage + +```bash +conductor lecternUpload --schema-file [options] +``` + +### Required Parameters + +- `--schema-file, -s`: Path to the JSON schema file to upload (required) + +### Optional Parameters + +- `--lectern-url, -u`: Lectern server URL (default: http://localhost:3031) +- `--auth-token, -t`: Authentication token for the Lectern server +- `--output, -o`: Output directory for response logs +- `--force`: Force overwrite of existing files +- `--debug`: Enable detailed debug logging + +## Schema File Format + +The schema file should be a valid JSON file that defines the data dictionary structure. Here's an example: + +```json +{ + "name": "My Data Dictionary", + "version": "1.0.0", + "description": "Comprehensive data dictionary for project", + "fields": [ + { + "name": "patient_id", + "type": "string", + "description": "Unique identifier for patient" + }, + { + "name": "age", + "type": "integer", + "description": "Patient's age in years" + } + ] +} +``` + +## Error Handling Capabilities + +Comprehensive error handling includes: + +- **Schema Validation**: + - JSON parsing errors + - Schema structure validation +- **Connection Errors**: + - Server unreachable + - Authentication failures + - Timeout handling +- **Upload Errors**: + - Duplicate schema detection + - Format validation + - Detailed error reporting + +### Error Scenario Examples + +``` +✗ Error Lectern Schema Upload Failed + Type: BadRequest + Possible reasons: + - Schema might already exist + - Invalid schema format + - Duplicate upload attempt +``` + +## Architecture + +### Command Layer + +The `LecternUploadCommand` class handles the schema upload process: + +1. Validates the schema file +2. Checks Lectern server health +3. Uploads the schema +4. Provides detailed logging and error reporting + +### Service Layer + +The `LecternService` manages interactions with the Lectern server: + +- Normalizes server URLs +- Handles authentication +- Manages schema upload requests + +## Configuration Options + +### Environment Variables + +- `LECTERN_URL`: Default Lectern server URL +- `LECTERN_AUTH_TOKEN`: Default authentication token +- `LECTERN_SCHEMA`: Default schema file path + +## Example Usage + +### Basic Upload + +```bash +# Upload a schema to the default local Lectern server +conductor lecternUpload -s ./data/dictionary.json +``` + +### Custom Configuration + +```bash +# Upload to a specific Lectern server with authentication +conductor lecternUpload \ + -s ./data/advanced-dictionary.json \ + -u https://lectern.example.com \ + -t my-secret-token \ + -o ./lectern-logs +``` + +## Troubleshooting + +Common issues and solutions: + +1. **Connection Failures**: + + - Verify Lectern server URL + - Check server availability + - Ensure network connectivity + +2. **Authentication Errors**: + + - Verify authentication token + - Check server authentication requirements + +3. **Schema Validation Errors**: + - Validate JSON syntax + - Ensure schema meets Lectern's requirements + - Check for missing or incorrect fields + +## Extending the Feature + +To extend this feature: + +1. Add new validation logic in the upload command +2. Enhance error handling +3. Add support for more complex authentication methods +4. Implement additional pre-upload schema transformations + +## Best Practices + +- Always validate schema files before upload +- Use environment variables for sensitive information +- Implement logging for traceability +- Handle potential network and server errors gracefully + +## Testing + +```bash +# Basic schema upload +conductor lecternUpload -s schema.json + +# Upload with debug logging +conductor lecternUpload -s schema.json --debug + +# Specify custom Lectern server +conductor lecternUpload -s schema.json -u https://custom-lectern.org +``` diff --git a/apps/conductor/docs/lryicUpload.md b/apps/conductor/docs/lryicUpload.md new file mode 100644 index 00000000..5bd77f75 --- /dev/null +++ b/apps/conductor/docs/lryicUpload.md @@ -0,0 +1,201 @@ +# Lyric Data Loading + +## Overview + +The Lyric Data Loading feature provides a command-line interface for submitting, validating, and committing data files to a Lyric service. It automates the entire data loading workflow by identifying valid files based on schema information from Lectern, handling the multi-step submission process, and providing robust error handling and retry mechanisms. + +## Key Features + +- Automatic schema-based file validation and renaming +- Complete data loading workflow (submit, validate, commit) +- Integration with Lectern for schema information +- Multiple retry attempts for validation status checks +- Comprehensive error handling and diagnostics +- Command-line and programmatic interfaces +- Flexible configuration through environment variables or command options + +## Workflow Process + +The data loading process includes several automated steps: + +1. **Schema Discovery**: Automatically fetches dictionary and schema information from Lectern +2. **File Validation**: Finds and validates CSV files matching the schema name +3. **File Renaming**: Automatically renames files to match schema conventions if needed +4. **Data Submission**: Submits validated files to Lyric +5. **Validation Monitoring**: Polls the submission status until validation completes +6. **Commit Process**: Commits valid submissions to finalize the data loading + +## Command-Line Usage + +```bash +conductor lyricData [options] +``` + +### Required Parameters + +- `--lyric-url, -u`: Lyric service URL (required or via LYRIC_URL environment variable) +- `--lectern-url, -l`: Lectern service URL (required or via LECTERN_URL environment variable) +- `--data-directory, -d`: Directory containing CSV data files (required or via LYRIC_DATA environment variable) + +### Optional Parameters + +- `--category-id, -c`: Category ID (default: "1") +- `--organization, -g`: Organization name (default: "OICR") +- `--max-retries, -m`: Maximum number of retry attempts (default: 10) +- `--retry-delay, -r`: Delay between retry attempts in milliseconds (default: 20000) +- `--output, -o`: Output directory for response logs +- `--force`: Force overwrite of existing files +- `--debug`: Enable detailed debug logging + +## Environment Variables + +All command parameters can be configured through environment variables: + +- `LYRIC_URL`: Lyric service URL +- `LECTERN_URL`: Lectern service URL +- `LYRIC_DATA`: Directory containing CSV data files +- `CATEGORY_ID`: Category ID +- `ORGANIZATION`: Organization name +- `MAX_RETRIES`: Maximum number of retry attempts +- `RETRY_DELAY`: Delay between retry attempts in milliseconds + +## File Naming Requirements + +The Lyric data loading process requires CSV files to match the schema name from Lectern. The system will: + +1. Use exact matches (e.g., `patient.csv` for schema name "patient") +2. Auto-rename files that start with the schema name (e.g., `patient_v1.csv` → `patient.csv`) +3. Skip files that don't match the schema naming pattern + +## Error Handling Capabilities + +Comprehensive error handling includes: + +- **Schema Discovery Errors**: + - Lectern connection failures + - Missing or invalid dictionary or schema information +- **File Validation Errors**: + - Missing data directory + - No matching CSV files + - Filename format issues +- **Submission Errors**: + - Network connection problems + - Service unavailability + - Authentication failures +- **Validation Errors**: + - Invalid data in CSV files + - Schema validation failures + - Timeout during validation wait + +### Error Scenario Examples + +``` +✗ Error: Data Loading Failed + Validation failed. Please check your data files for errors. + Submission ID: 12345 + Status: INVALID + + You can check the submission details at: http://localhost:3030/submission/12345 +``` + +## Architecture + +### Command Layer + +The `LyricUploadCommand` class handles the data loading process: + +1. Validates the required parameters and environment +2. Sets up the Lyric data service +3. Coordinates the complete data loading workflow +4. Provides detailed error information and suggestions + +### Service Layer + +The `LyricDataService` manages all interactions with the Lyric and Lectern services: + +- Fetches dictionary and schema information from Lectern +- Finds and validates files matching the schema name +- Submits data to Lyric +- Monitors validation status +- Commits validated submissions + +## Example Usage + +### Basic Data Loading + +```bash +# Load data using environment variables +export LYRIC_URL=http://localhost:3030 +export LECTERN_URL=http://localhost:3031 +export LYRIC_DATA=/path/to/data +conductor lyricData +``` + +### Custom Configuration + +```bash +# Load data with custom parameters +conductor lyricData \ + --lyric-url https://lyric.example.com \ + --lectern-url https://lectern.example.com \ + --data-directory ./data \ + --category-id 2 \ + --organization "My Organization" \ + --max-retries 15 \ + --retry-delay 30000 \ + --output ./logs +``` + +## Troubleshooting + +Common issues and solutions: + +1. **No Valid Files Found**: + + - Ensure CSV files match the schema name from Lectern + - Check file extensions (must be .csv) + - Verify file permissions and readability + +2. **Validation Failures**: + + - Check CSV content against schema requirements + - Examine validation error messages + - Review submission details in the Lyric UI + +3. **Connection Issues**: + + - Verify Lyric and Lectern service URLs + - Check network connectivity + - Ensure services are running and accessible + +4. **Timeout During Validation**: + - Increase the `--max-retries` value + - Adjust the `--retry-delay` parameter + - Check if the validation process is stuck in Lyric + +## Best Practices + +- Ensure CSV files follow the schema naming convention +- Validate CSV data before submission +- Use environment variables for consistent configuration +- Monitor the validation process in the Lyric UI +- Review logs for detailed information on each step +- Run with `--debug` for maximum visibility into the process + +## Testing + +```bash +# Basic data loading +conductor lyricData -u http://localhost:3030 -l http://localhost:3031 -d ./data + +# With debug output for troubleshooting +conductor lyricData -u http://localhost:3030 -l http://localhost:3031 -d ./data --debug + +# Custom organization and category +conductor lyricData -u http://localhost:3030 -l http://localhost:3031 -d ./data -c 2 -g "Research Team" +``` + +## Related Commands + +- `lyricRegister`: Register a Lectern dictionary with Lyric +- `lecternUpload`: Upload a schema to Lectern diff --git a/apps/conductor/docs/maestroIndex.md b/apps/conductor/docs/maestroIndex.md new file mode 100644 index 00000000..6e38f115 --- /dev/null +++ b/apps/conductor/docs/maestroIndex.md @@ -0,0 +1,84 @@ +# Repository Indexing Command + +## Overview + +The Repository Indexing command allows you to trigger indexing operations on a repository with varying levels of specificity. This command sends a POST request to the indexing service, enabling you to index a specific repository, optionally filtered by organization and ID. + +## Key Features + +- Simple repository-wide indexing operations +- Organization-specific indexing +- Precise indexing targeting specific document IDs +- Comprehensive error handling and detailed reporting +- Environment variable support for CI/CD integration + +## Command-Line Usage + +```bash +conductor indexRepository --repository-code [options] +``` + +### Required Parameters + +- `--repository-code `: Code of the repository to index (required) + +### Optional Parameters + +- `--index-url `: Indexing service URL (default: http://localhost:11235) +- `--organization `: Filter indexing to a specific organization +- `--id `: Index only a specific document ID (requires organization parameter) +- `--output, -o`: Output directory for response logs +- `--force`: Skip confirmation prompts +- `--debug`: Enable detailed debug logging + +## Environment Variables + +All command parameters can also be configured through environment variables: + +- `INDEX_URL`: Indexing service URL +- `REPOSITORY_CODE`: Repository code to index +- `ORGANIZATION`: Organization name filter +- `ID`: Specific ID to index + +## Example Usage + +### Basic Indexing + +Index an entire repository: + +```bash +conductor indexRepository --repository-code lyric.overture +``` + +### Organization-Specific Indexing + +Index all documents from a specific organization: + +```bash +conductor indexRepository --repository-code lyric.overture --organization OICR +``` + +### Specific Document Indexing + +Index a single document by ID: + +```bash +conductor indexRepository --repository-code lyric.overture --organization OICR --id DO123456 +``` + +### Custom Index URL + +Use a custom indexing service URL: + +```bash +conductor indexRepository --repository-code lyric.overture --index-url http://index-service:8080 +``` + +## Troubleshooting + +Common issues and solutions: + +1. **Connection Refused**: Ensure the indexing service is running at the specified URL +2. **Repository Not Found**: Verify that the repository code is correct +3. **Authentication Error**: Check if you have the necessary permissions +4. **Timeout**: The indexing service might be under heavy load or the operation is complex diff --git a/apps/conductor/docs/registerLyric.md b/apps/conductor/docs/registerLyric.md new file mode 100644 index 00000000..79311399 --- /dev/null +++ b/apps/conductor/docs/registerLyric.md @@ -0,0 +1,218 @@ +# Lyric Dictionary Registration + +## Overview + +The Lyric Dictionary Registration feature provides a command-line interface for registering data dictionaries with a Lyric service. It streamlines the process of dictionary management across different environments, ensuring consistent data definitions and schema availability. + +## Key Features + +- Register data dictionaries with Lyric service +- Automatic health check verification +- Multiple retry attempts for improved reliability +- Comprehensive error handling +- Support for various environment configurations +- Command-line and programmatic interfaces +- Flexible configuration through environment variables or command options + +## Health Check Mechanism + +The registration process includes an automated health check: + +- **Connection Attempts**: 3 retry attempts +- **Retry Delay**: 5 seconds between attempts +- **Timeout**: 10 seconds per attempt +- **Status Verification**: + - Validates Lyric service availability + - Checks health endpoint status + - Provides detailed connection diagnostics + +## URL Handling + +Intelligent URL normalization ensures compatibility: + +- Removes trailing slashes +- Automatically determines the correct registration endpoint +- Supports multiple URL formats and configurations +- Maintains path integrity + +## Command-Line Usage + +```bash +conductor lyricRegister [options] +``` + +### Required Parameters + +- `--lyric-url, -u`: Lyric service URL (required or via LYRIC_URL environment variable) + +### Optional Parameters + +- `--category-name, -c`: Category name (default: "clinical") +- `--dictionary-name, -d`: Dictionary name (default: "clinical_data_dictionary") +- `--dictionary-version, -v`: Dictionary version (default: "1.0") +- `--default-centric-entity, -e`: Default centric entity (default: "clinical_data") +- `--output, -o`: Output directory for response logs +- `--force`: Force overwrite of existing files +- `--debug`: Enable detailed debug logging + +## Environment Variables + +All command parameters can be configured through environment variables: + +- `LYRIC_URL`: Lyric service URL +- `CATEGORY_NAME`: Category name +- `DICTIONARY_NAME`: Dictionary name +- `DICTIONARY_VERSION`: Dictionary version +- `DEFAULT_CENTRIC_ENTITY`: Default centric entity + +## Error Handling Capabilities + +Comprehensive error handling includes: + +- **Configuration Validation**: + - Required parameter checking + - URL format validation +- **Connection Errors**: + - Service unreachable + - Network issues + - Timeout handling +- **Registration Errors**: + - Duplicate dictionary detection + - Parameter validation + - Detailed error reporting +- **Dictionary Already Exists**: + - Clearly indicates when a dictionary with the same parameters already exists + - Shows the specific parameters that caused the conflict + - Provides suggestions for resolution +- **Parameter Validation Errors**: + - Detailed information about which parameter failed validation + - Shows the validation rule that was violated + - Suggests corrective actions +- **Connection Issues**: + - Comprehensive details about connection failures + - Information about network and endpoint status + - Troubleshooting suggestions specific to the error type + +### Error Scenario Examples + +``` +✗ Error: Lyric Dictionary Registration Failed + Type: Connection Error + Message: Failed to connect to Lyric service + Details: Unable to establish connection with Lyric service +``` + +## Architecture + +### Command Layer + +The `LyricRegistrationCommand` class handles the dictionary registration process: + +1. Validates the required parameters +2. Checks Lyric service health +3. Registers the dictionary with retry support +4. Provides detailed logging and error reporting + +### Service Layer + +The `LyricService` manages interactions with the Lyric service: + +- Normalizes service URLs +- Handles parameter validation +- Manages dictionary registration requests +- Performs health checks + +## Example Usage + +### Basic Registration + +```bash +# Register a dictionary with the default configuration +conductor lyricRegister --lyric-url http://localhost:3030 +``` + +### Custom Configuration + +```bash +# Register with custom dictionary parameters +conductor lyricRegister \ + --lyric-url https://lyric.example.com \ + --category-name genomics \ + --dictionary-name gene_dictionary \ + --dictionary-version 2.1 \ + --default-centric-entity gene_data \ + --output ./lyric-logs +``` + +### Using Environment Variables + +```bash +# Set environment variables +export LYRIC_URL=http://localhost:3030 +export CATEGORY_NAME=clinical +export DICTIONARY_NAME=patient_dictionary +export DICTIONARY_VERSION=1.5 +export DEFAULT_CENTRIC_ENTITY=patient_data + +# Register using environment configuration +conductor lyricRegister +``` + +## Standalone Script + +A standalone bash script is also provided for direct usage: + +```bash +# Use the standalone script +./lyric-register.sh +``` + +## Troubleshooting + +Common issues and solutions: + +1. **Connection Failures**: + + - Verify Lyric service URL + - Check service availability + - Ensure network connectivity + +2. **Registration Errors**: + + - Verify parameter values + - Check for duplicate dictionary entries + - Ensure Lyric service is properly configured + +3. **Environment Issues**: + - Validate environment variable settings + - Check for conflicting command-line options + - Verify service compatibility + +## Extending the Feature + +To extend this feature: + +1. Add new validation logic in the registration command +2. Enhance error handling with more detailed diagnostics +3. Implement additional Lyric service operations +4. Add support for bulk registrations + +## Best Practices + +- Use environment variables for consistent configurations +- Implement logging for traceability +- Handle potential network and service errors gracefully +- Verify service health before attempting registration + +## Testing + +```bash +# Basic dictionary registration +conductor lyricRegister -u http://localhost:3030 + +# Registration with debug logging +conductor lyricRegister -u http://localhost:3030 --debug + +# Specify custom dictionary parameters +conductor lyricRegister -u http://localhost:3030 -c genomics -d gene_dictionary -v 2.0 +``` diff --git a/apps/conductor/docs/scoreManifestUpload.md b/apps/conductor/docs/scoreManifestUpload.md new file mode 100644 index 00000000..7f28f67e --- /dev/null +++ b/apps/conductor/docs/scoreManifestUpload.md @@ -0,0 +1,149 @@ +# Score Manifest Upload + +## Overview + +The Score Manifest Upload feature provides a streamlined command-line interface for generating file manifests from SONG analyses and uploading data files to Score object storage. This command simplifies the data submission process by leveraging the native Score client for file uploads. + +## Key Features + +- Generate manifests from SONG analysis IDs +- Utilize native Score client for file uploads +- Simple and straightforward workflow +- Automatic manifest generation +- Flexible configuration options +- Support for environment variable configuration + +## Workflow Integration + +The Score Manifest Upload command is a key step in the Overture data submission workflow: + +1. **Metadata Submission**: Submit analysis metadata to SONG +2. **File Upload**: Generate manifest and upload files with Score +3. **Publication**: Publish the analysis to make it available + +## Command-Line Usage + +```bash +conductor scoreManifestUpload --analysis-id [options] +``` + +### Required Parameters + +- `--analysis-id, -a`: Analysis ID obtained from SONG submission (required) + +### Optional Parameters + +- `--data-dir, -d`: Directory containing the data files (default: "./data") +- `--output-dir, -o`: Directory for manifest file output (default: "./output") +- `--manifest-file, -m`: Custom path for manifest file (default: "/manifest.txt") +- `--song-url, -u`: SONG server URL (default: http://localhost:8080) +- `--score-url, -s`: Score server URL (default: http://localhost:8087) +- `--auth-token, -t`: Authentication token for Score client + +## Manifest Generation + +The command automatically generates a manifest file with the following format: + +``` +object_id file_path md5 size access +analysis-id-filename.vcf.gz /full/path/to/filename.vcf.gz 94b790078d8e98ad08ffc42389e2fa68 17246 open +``` + +Key characteristics: + +- Object ID is generated based on analysis ID and filename +- MD5 checksum is computed for each file +- Default access level is "open" + +## Prerequisites + +- Score client must be installed and accessible in the system PATH +- Requires valid authentication token +- Requires an existing analysis ID from SONG + +## Example Usages + +### Basic Upload + +```bash +# Upload files for a specific analysis ID +conductor scoreManifestUpload --analysis-id 4d9ed1c5-1053-4377-9ed1-c51053f3771f +``` + +### Advanced Configuration + +```bash +# Custom directories and authentication +conductor scoreManifestUpload \ + --analysis-id 4d9ed1c5-1053-4377-9ed1-c51053f3771f \ + --data-dir /path/to/sequencing/data \ + --output-dir /path/to/manifests \ + --auth-token your-score-access-token +``` + +## Environment Variables + +The command supports the following environment variables: + +- `ANALYSIS_ID`: Default analysis ID +- `DATA_DIR`: Default data directory +- `OUTPUT_DIR`: Default output directory +- `MANIFEST_FILE`: Custom manifest file path +- `SONG_URL`: SONG server URL +- `SCORE_URL`: Score server URL +- `AUTH_TOKEN`: Authentication token for Score client + +## Troubleshooting + +Common issues and solutions: + +1. **Manifest Generation Failures**: + + - Verify analysis ID exists + - Ensure data directory contains files + - Check file permissions + +2. **Upload Failures**: + - Verify Score client is installed + - Check authentication token + - Ensure network connectivity + - Verify Score client configuration + +## Best Practices + +- Organize data files clearly +- Use consistent naming conventions +- Validate files before upload +- Use environment variables for consistent configuration + +## Complete Workflow Example + +```bash +# Step 1: Submit metadata to Song +conductor songSubmitAnalysis --analysis-file SP059902.vcf.json + +# Step 2: Upload files to Score +conductor scoreManifestUpload --analysis-id + +# Step 3: Publish the analysis +conductor songPublishAnalysis --analysis-id +``` + +## Testing and Validation + +```bash +# Basic upload +conductor scoreManifestUpload -a your-analysis-id + +# Debug mode for detailed logging +conductor scoreManifestUpload -a your-analysis-id --debug + +# Specify custom data directory +conductor scoreManifestUpload -a your-analysis-id -d /custom/data/path +``` + +## Limitations + +- Relies on external Score client +- Uses a simple MD5 computation method +- Requires manual configuration of Score client profile diff --git a/apps/conductor/docs/songCreateStudy.md b/apps/conductor/docs/songCreateStudy.md new file mode 100644 index 00000000..fc94027e --- /dev/null +++ b/apps/conductor/docs/songCreateStudy.md @@ -0,0 +1,219 @@ +# SONG Create Study + +## Overview + +The SONG Create Study feature provides a streamlined command-line interface for creating and registering studies in a SONG metadata server. This functionality enables users to initialize study environments for genomic data submissions, a necessary prerequisite for uploading analyses and data to SONG-enabled genomic data management systems. + +## Key Features + +- Create new studies in SONG metadata service +- Intelligent health verification before operations +- Automatic retry mechanism with configurable attempts +- Conflict detection for existing studies +- Robust error handling and reporting +- Flexible authentication support +- Environment variable integration +- Detailed operation feedback + +## Health Check Mechanism + +Each create operation includes comprehensive health verification: + +- **Connection Status**: Verifies SONG service availability +- **Endpoint Health**: Checks `/isAlive` endpoint for service readiness +- **Timeout Control**: 10 second timeout for health verification +- **Response Validation**: Ensures proper service response codes +- **Connection Troubleshooting**: Provides actionable feedback for connection issues + +## Command-Line Usage + +```bash +conductor songCreateStudy [options] +``` + +### Required Parameters + +- `--song-url, -u`: SONG server URL (required, or set via SONG_URL environment variable) + +### Optional Parameters + +- `--study-id, -i`: Study ID (default: "demo") +- `--study-name, -n`: Study name (default: "string") +- `--organization, -g`: Organization name (default: "string") +- `--description, -d`: Study description (default: "string") +- `--auth-token, -t`: Authentication token (default: "123") +- `--output, -o`: Output directory for response logs +- `--force`: Force creation even if study already exists +- `--debug`: Enable detailed debug logging + +## Success Response + +Upon successful study creation, you'll receive confirmation with the study details: + +``` +✓ Success Study created successfully + + - Study ID: my-study-123 + - Study Name: My Genomic Study + - Organization: Research Organization + +▸ Info SONG Study Creation command completed successfully in 0.65s +``` + +## Error Handling Capabilities + +Comprehensive error detection and reporting includes: + +- **Validation Errors**: + - Required parameter verification + - Format validation +- **Communication Errors**: + - Connection failures + - Authentication issues + - Timeout handling + - HTTP status code validation +- **Server-side Issues**: + - API rejection handling + - Study conflict detection + - Detailed error response parsing + +### Error Response Examples + +``` +✗ Error [CONNECTION_ERROR]: Unable to establish connection with SONG service +✗ Error [INVALID_ARGS]: SONG URL not specified. Use --song-url or set SONG_URL environment variable. +``` + +## Study Already Exists + +When attempting to create a study that already exists: + +1. **Without `--force` flag**: Command will detect the existing study and report success with an "EXISTING" status +2. **With `--force` flag**: Command will proceed with creation attempt (useful for updating study info) + +``` +⚠ Warn Study ID my-study-123 already exists +``` + +## Architecture + +### Command Layer + +The `SongCreateStudyCommand` class orchestrates the study creation process: + +1. Parameter validation +2. SONG service health verification +3. Existing study detection +4. Study payload transmission +5. Response handling and reporting + +### Service Integration + +The command integrates directly with the SONG API: + +- Manages authentication headers +- Implements retry logic for resilience +- Handles existing study detection +- Provides structured response handling + +## Configuration Options + +### Environment Variables + +- `SONG_URL`: Default SONG service URL +- `STUDY_ID`: Default study ID +- `STUDY_NAME`: Default study name +- `ORGANIZATION`: Default organization name +- `DESCRIPTION`: Default study description +- `AUTH_TOKEN`: Default authentication token + +## Example Usage + +### Basic Creation + +```bash +# Create a study with default parameters +conductor songCreateStudy --song-url http://localhost:8080 +``` + +### Detailed Configuration + +```bash +# Create a fully specified study +conductor songCreateStudy \ + --song-url https://song.genomics-platform.org \ + --study-id genomics-project-2023 \ + --study-name "Comprehensive Genomic Analysis 2023" \ + --organization "Center for Genomic Research" \ + --description "Multi-center study of genetic markers in cancer patients" \ + --auth-token bearer_eyJhbGc... +``` + +### Force Creation + +```bash +# Update an existing study by forcing creation +conductor songCreateStudy \ + --song-url http://localhost:8080 \ + --study-id existing-study \ + --study-name "Updated Study Name" \ + --force +``` + +## Troubleshooting + +Common issues and solutions: + +1. **Connection Issues**: + + - Verify SONG service URL is correct and accessible + - Check network connectivity and firewall settings + - Ensure service is running and healthy + +2. **Authentication Problems**: + + - Verify authentication token format and validity + - Check token permissions and expiration + - Ensure proper authorization for study creation + +3. **Study Creation Rejection**: + - Check if study already exists (use `--force` to update) + - Verify study ID format meets SONG requirements + - Check for proper formatting of study name and organization + - Review server logs for detailed rejection reasons + +## Study Payload Structure + +The command constructs a study payload with the following structure: + +```json +{ + "studyId": "your-study-id", + "name": "Your Study Name", + "description": "Study description text", + "organization": "Your Organization", + "info": {} +} +``` + +The `info` field can be used for additional metadata but is sent as an empty object by default. + +## Best Practices + +- Use meaningful study IDs that reflect the project purpose +- Provide detailed and accurate study descriptions +- Use environment variables for consistent configuration +- Create studies before attempting to upload schemas or analyses +- Document study creation in project documentation +- Use the same authentication token for related operations + +## Integration with SONG Workflow + +The typical SONG metadata workflow follows these steps: + +1. **Create Study** (using songCreateStudy) +2. **Upload Schema** (using songUploadSchema) +3. Upload analyses and data files +4. Query and manage metadata + +Creating a study is the essential first step in this workflow. diff --git a/apps/conductor/docs/songPublishAnalysis.md b/apps/conductor/docs/songPublishAnalysis.md new file mode 100644 index 00000000..8b5d8bc3 --- /dev/null +++ b/apps/conductor/docs/songPublishAnalysis.md @@ -0,0 +1,258 @@ +# SONG Publish Analysis + +## Overview + +The SONG Publish Analysis feature provides a streamlined command-line interface for publishing genomic analysis data within the Overture ecosystem. This critical final step in the data submission workflow makes analyses visible to downstream services like Maestro for indexing and discovery, enabling researchers to access the data through front-end portals. + +## Key Features + +- Publish analyses to make them discoverable +- Intelligent Docker client detection +- Dual implementation strategy (Docker or direct API) +- Multiple retry mechanisms for reliability +- Comprehensive error detection and reporting +- Support for ignoring undefined MD5 checksums +- Clear success and failure feedback +- Integration with both Song client and REST API endpoints + +## Workflow Integration + +The SONG Publish Analysis command represents the final step in the Overture data submission workflow: + +1. **Metadata Submission**: Analysis metadata is submitted to SONG (`songSubmitAnalysis`) +2. **File Upload**: Data files are uploaded to Score (For now using the score client) +3. **Publication**: This command publishes the analysis making it available (`songPublishAnalysis`) + +## Publication Process + +When publishing an analysis, the command: + +1. Validates that the analysis ID exists +2. Verifies that all files referenced in the analysis have been uploaded to Score +3. Changes the analysis state from UNPUBLISHED to PUBLISHED +4. Makes the analysis available for indexing by Maestro +5. Enables discovery through front-end portal interfaces + +## Command-Line Usage + +```bash +conductor songPublishAnalysis --analysis-id [options] +``` + +### Required Parameters + +- `--analysis-id, -a`: Analysis ID to publish (required) + +### Optional Parameters + +- `--study-id, -i`: Study ID (default: "demo") +- `--song-url, -u`: SONG server URL (default: http://localhost:8080) +- `--auth-token, -t`: Authentication token (default: "123") +- `--ignore-undefined-md5`: Ignore files with undefined MD5 checksums +- `--debug`: Enable detailed debug logging + +## Docker Integration + +The command intelligently detects and utilizes the Song Docker container if available: + +```bash +# Check if Docker and Song client container are running +docker ps | grep "song-client" + +# Execute command using container if available +conductor songPublishAnalysis --analysis-id 4d9ed1c5-1053-4377-9ed1-c51053f3771f +``` + +## Success Response + +Upon successful publication, you'll receive confirmation with the analysis details: + +``` +✓ Analysis published successfully + + - Analysis ID: 4d9ed1c5-1053-4377-9ed1-c51053f3771f + - Study ID: demo + +▸ Info SONG Analysis Publication command completed successfully in 0.82s +``` + +## Error Handling Capabilities + +Comprehensive error detection and reporting includes: + +- **Input Validation**: + - Missing analysis ID + - Invalid analysis ID format + - Study ID validation +- **Publication Errors**: + + - Analysis not found + - Files not uploaded to Score + - Permission/authorization issues + - MD5 checksum issues + - Network connection failures + +- **State Transition Errors**: + - Invalid state transitions + - Already published analyses + - Suppressed analyses + +### Error Response Examples + +``` +✗ Error [INVALID_ARGS]: Analysis ID not specified. Use --analysis-id or set ANALYSIS_ID environment variable. +✗ Error [CONNECTION_ERROR]: Failed to publish analysis: Analysis not found: 4d9ed1c5-xxxx-xxxx-xxxx-xxxxxxxxxxxx +✗ Error [CONNECTION_ERROR]: Publishing failed with status 401: Unauthorized +✗ Error [CONNECTION_ERROR]: Failed to publish analysis: Files not found in Score storage +``` + +## Architecture + +### Command Layer + +The `SongPublishAnalysisCommand` class orchestrates the publication process: + +1. Analysis ID and parameter validation +2. Docker/environment detection for integration approach +3. Publication request through Song client or direct REST API +4. Response processing and error handling + +### Integration Approaches + +The command supports two integration approaches: + +1. **Docker Client Execution**: Utilizing existing Song client container +2. **Direct API Integration**: Making REST API calls when containers aren't available + +## Configuration Options + +### Environment Variables + +- `ANALYSIS_ID`: Default analysis ID +- `STUDY_ID`: Default study ID +- `SONG_URL`: Default SONG service URL +- `AUTH_TOKEN`: Default authentication token +- `IGNORE_UNDEFINED_MD5`: Default setting for ignoring undefined MD5 checksums + +## Example Usage + +### Basic Publication + +```bash +# Publish an analysis +conductor songPublishAnalysis --analysis-id 4d9ed1c5-1053-4377-9ed1-c51053f3771f +``` + +### Advanced Configuration + +```bash +# Publish with custom study and ignore MD5 issues +conductor songPublishAnalysis \ + --analysis-id 4d9ed1c5-1053-4377-9ed1-c51053f3771f \ + --study-id my-cancer-study \ + --song-url https://song.genomics-platform.org \ + --auth-token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... \ + --ignore-undefined-md5 +``` + +## Troubleshooting + +Common issues and solutions: + +1. **Publication Failures**: + + - Verify analysis ID exists and belongs to the correct study + - Ensure all files have been properly uploaded to Score + - Check MD5 checksums are defined (or use --ignore-undefined-md5) + - Verify proper authorization token and permissions + +2. **Authentication Issues**: + + - Check token format and validity + - Ensure token has proper permissions + - Verify token hasn't expired + +3. **Integration Problems**: + - Check Song service availability + - Verify network connectivity + - Ensure Docker container is configured correctly if using + +## Complete Workflow Example + +```bash +# Step 1: Submit metadata to Song +conductor songSubmitAnalysis --analysis-file SP059902.vcf.json +# Response: analysisId: 4d9ed1c5-1053-4377-9ed1-c51053f3771f + +# Step 2: Generate manifest and upload files +docker exec song-client sh -c "sing manifest -a {AnalysisId} -f /output/manifest.txt -d /output/" +docker exec score-client sh -c "score-client upload --manifest /output/manifest.txt" + +# Step 3: Publish the analysis +conductor songPublishAnalysis --analysis-id 4d9ed1c5-1053-4377-9ed1-c51053f3771f +``` + +## Analysis State Management + +The SONG Publish Analysis command transitions an analysis through specific states: + +1. **UNPUBLISHED**: Initial state after submission +2. **PUBLISHED**: State after successful publication +3. **SUPPRESSED**: Special state for analyses no longer needed + +Only analyses in the UNPUBLISHED state can be published. To unpublish an analysis that has been published, you would need to use the SONG API's unpublish endpoint. + +## Best Practices + +- Always upload all required files before publishing +- Use consistent study IDs across related commands +- Implement comprehensive logging for audit trails +- Follow a complete workflow from submission to publishing +- Consider using environment variables for consistent configuration + +## Testing + +```bash +# Basic publication +conductor songPublishAnalysis -a 4d9ed1c5-1053-4377-9ed1-c51053f3771f + +# Debug mode for detailed logging +conductor songPublishAnalysis -a 4d9ed1c5-1053-4377-9ed1-c51053f3771f --debug + +# Custom study ID +conductor songPublishAnalysis -a 4d9ed1c5-1053-4377-9ed1-c51053f3771f -i genomics-study-a +``` + +## Technical Details + +### API Endpoints + +When using the direct REST API approach, the command makes a PUT request to: + +``` +PUT /studies/{studyId}/analysis/publish/{id} +``` + +Optional query parameters: + +- `ignoreUndefinedMd5=true` - When the --ignore-undefined-md5 flag is used + +### Response Format + +The expected response format from a successful publication: + +```json +{ + "message": "AnalysisId 4d9ed1c5-1053-4377-9ed1-c51053f3771f successfully published" +} +``` + +### Publication Prerequisites + +For an analysis to be successfully published: + +1. The analysis must exist in SONG +2. All files referenced in the analysis must be uploaded to Score +3. The user must have publication permissions +4. The analysis must be in the UNPUBLISHED state +5. File checksums must match (unless ignoring undefined MD5) diff --git a/apps/conductor/docs/songUploadSchema.md b/apps/conductor/docs/songUploadSchema.md new file mode 100644 index 00000000..d2677613 --- /dev/null +++ b/apps/conductor/docs/songUploadSchema.md @@ -0,0 +1,239 @@ +# SONG Schema Upload + +## Overview + +The SONG Schema Upload feature provides a streamlined command-line interface for uploading analysis schemas to a SONG metadata server. This functionality facilitates standardized genomic data management by ensuring consistent schema definitions across environments, critical for bioinformatics and genomic data processing pipelines. + +## Key Features + +- Upload JSON schemas to SONG metadata service +- Intelligent endpoint management +- Proactive health verification +- Automatic retry mechanism +- Schema validation before transmission +- Robust error handling and reporting +- Flexible authentication support +- Detailed success and error feedback + +## Health Check Mechanism + +Each upload operation includes a comprehensive health verification: + +- **Connection Status**: Verifies SONG service availability +- **Endpoint Health**: Checks `/isAlive` endpoint for service status +- **Timeout Control**: 10 second timeout for health verification +- **Response Validation**: Ensures proper service response codes +- **Connection Troubleshooting**: Provides actionable feedback for connection issues + +## URL Intelligence + +Sophisticated URL handling ensures proper endpoint targeting: + +- Automatically normalizes URLs to standardized format +- Ensures `/schemas` endpoint is correctly specified +- Handles various URL formats gracefully +- Removes redundant path elements +- Supports both path and query parameter specifications + +## Command-Line Usage + +```bash +conductor songUploadSchema --schema-file [options] +``` + +### Required Parameters + +- `--schema-file, -s`: Path to the JSON schema file to upload (required) + +### Optional Parameters + +- `--song-url, -u`: SONG server URL (default: http://localhost:8080) +- `--auth-token, -t`: Authentication token (default: "123") +- `--output, -o`: Output directory for upload response logs +- `--force`: Force overwrite of existing output files +- `--debug`: Enable detailed debug logging + +## Schema File Format + +The schema file should be a valid JSON document following the SONG schema structure. Here's an example: + +```json +{ + "name": "genomic_variant_analysis", + "schema": { + "type": "object", + "required": ["sample_id", "analysis_type"], + "properties": { + "sample_id": { + "type": "string", + "description": "Unique identifier for the sample" + }, + "analysis_type": { + "type": "string", + "enum": ["somatic", "germline"], + "description": "Type of genomic analysis performed" + }, + "experimental_strategy": { + "type": "string", + "description": "Experimental strategy used" + } + } + }, + "options": { + "fileTypes": ["bam", "cram", "vcf"], + "externalValidations": [ + { + "url": "http://example.com/{study}/sample/{value}", + "jsonPath": "sample_id" + } + ] + } +} +``` + +## Success Response + +Upon successful schema upload, you'll receive confirmation with the schema details: + +``` +✓ Success Schema uploaded successfully + + - Schema Name: genomic_variant_analysis + - Schema Version: 1.0 + +▸ Info SONG Schema Upload command completed successfully in 0.78s +``` + +## Error Handling Capabilities + +Comprehensive error detection and reporting includes: + +- **Schema Validation**: + - JSON syntax verification + - Format compliance validation + - Structure integrity checks + - Required field verification (`name` and `schema`) +- **Communication Errors**: + - Connection failures + - Authentication issues + - Timeout handling + - HTTP status code validation +- **Server-side Issues**: + - API rejection handling + - Schema conflict detection + - Detailed error response parsing + +### Error Response Examples + +``` +✗ Error [CONNECTION_ERROR]: SONG schema upload error: Invalid schema format +✗ Error [CONNECTION_ERROR]: Unable to establish connection with SONG service +✗ Error [INVALID_FILE]: Schema file contains invalid JSON: Unexpected token at line 12 +✗ Error [INVALID_FILE]: Invalid schema: Missing required field 'name' +``` + +## Architecture + +### Command Layer + +The `SongUploadSchemaCommand` class orchestrates the schema upload process: + +1. Schema file validation and parsing +2. SONG service health verification +3. Schema transmission and response handling +4. Comprehensive logging and error management + +### Service Integration + +The command integrates directly with the SONG API: + +- Normalizes endpoint URLs +- Manages authentication headers +- Implements retry logic for resilience +- Provides structured response handling + +## Configuration Options + +### Environment Variables + +- `SONG_URL`: Default SONG service URL +- `SONG_SCHEMA`: Default schema file location +- `SONG_AUTH_TOKEN`: Default authentication token + +## Example Usage + +### Basic Upload + +```bash +# Upload a schema to a local SONG service +conductor songUploadSchema -s ./schemas/variant-analysis.json +``` + +### Advanced Configuration + +```bash +# Upload to a remote SONG service with authentication +conductor songUploadSchema \ + -s ./schemas/sequencing-experiment.json \ + -u https://song.genomics-platform.org \ + -t bearer_eyJhbGc... \ + -o ./upload-logs \ + --debug +``` + +## Troubleshooting + +Common issues and solutions: + +1. **Connection Issues**: + + - Verify SONG service URL is correct and accessible + - Check network connectivity and firewall settings + - Ensure service is running and healthy + +2. **Authentication Problems**: + + - Verify authentication token format and validity + - Check token permissions and expiration + - Ensure proper authorization for schema uploads + +3. **Schema Rejection**: + - Validate JSON syntax with a linter + - Check for required fields (`name` and `schema`) + - Verify compliance with SONG schema requirements: + - Ensure `schema` is a valid JSON Schema object + - Check that `options.fileTypes` is an array of strings if present + - Verify that `options.externalValidations` has valid URLs and jsonPaths if present + - Look for potential conflicts with existing schemas + +## Schema Structure Requirements + +For a schema to be valid, it must include: + +1. A `name` field (string) +2. A `schema` field (object) that follows JSON Schema structure +3. Optional `options` object that may include: + - `fileTypes`: Array of allowed file extensions + - `externalValidations`: Array of validation objects with `url` and `jsonPath` properties + +## Best Practices + +- Validate schemas locally before upload +- Use environment variables for consistent configuration +- Implement comprehensive logging for audit trails +- Store schemas in version control +- Follow schema versioning conventions +- Document schema changes thoroughly + +## Testing + +```bash +# Basic schema upload +conductor songUploadSchema -s analysis-schema.json + +# Debug mode for detailed logging +conductor songUploadSchema -s analysis-schema.json --debug + +# Specify custom SONG server +conductor songUploadSchema -s analysis-schema.json -u https://song-api.genomics.org +``` diff --git a/apps/conductor/docs/submitSongAnalysis.md b/apps/conductor/docs/submitSongAnalysis.md new file mode 100644 index 00000000..2842f1b9 --- /dev/null +++ b/apps/conductor/docs/submitSongAnalysis.md @@ -0,0 +1,254 @@ +# SONG Analysis Submission + +## Overview + +The SONG Analysis Submission feature provides a robust command-line interface for submitting genomic analysis metadata to a SONG server. This functionality is essential in genomic data workflows, allowing users to register analysis metadata before uploading the corresponding data files, maintaining data provenance and supporting reproducible science. + +## Key Features + +- Submit analysis metadata to SONG metadata service +- Support for complex, nested analysis JSON structures +- Intelligent health verification before operations +- Automatic retry mechanism with configurable attempts +- Duplicate detection with optional override +- Robust error handling and reporting +- Flexible authentication support +- Environment variable integration +- Detailed operation feedback with analysis ID extraction + +## Health Check Mechanism + +Each submission includes comprehensive health verification: + +- **Connection Status**: Verifies SONG service availability +- **Endpoint Health**: Checks `/isAlive` endpoint for service readiness +- **Timeout Control**: 20 second timeout for health verification +- **Response Validation**: Ensures proper service response codes +- **Connection Troubleshooting**: Provides actionable feedback for connection issues + +## Command-Line Usage + +```bash +conductor songSubmitAnalysis --analysis-file [options] +``` + +### Required Parameters + +- `--analysis-file, -a`: Path to the analysis JSON file to submit (required) +- `--song-url, -u`: SONG server URL (required, or set via SONG_URL environment variable) + +### Optional Parameters + +- `--study-id, -i`: Study ID (default: "demo") +- `--allow-duplicates`: Allow duplicate analysis submissions (default: false) +- `--auth-token, -t`: Authentication token (default: "123") +- `--output, -o`: Output directory for response logs +- `--force`: Force studyId from command line instead of from file +- `--debug`: Enable detailed debug logging + +## Analysis File Structure + +The analysis file should contain a valid SONG analysis JSON document. Example: + +```json +{ + "studyId": "demo", + "analysisType": { + "name": "sampleSchema" + }, + "files": [ + { + "dataType": "Raw SV Calls", + "fileName": "sample.vcf.gz", + "fileSize": 17246, + "fileMd5sum": "94b790078d8e98ad08ffc42389e2fa68", + "fileAccess": "open", + "fileType": "VCF", + "info": { + "dataCategory": "Simple Nucleotide Variation" + } + } + ], + "workflow": { + "workflowName": "Variant Calling", + "workflowVersion": "1.0.0", + "runId": "run123", + "sessionId": "session456" + }, + "experiment": { + "platform": "Illumina", + "experimentalStrategy": "WGS", + "sequencingCenter": "Sequencing Center" + } +} +``` + +## Success Response + +Upon successful analysis submission, you'll receive confirmation with the analysis details: + +``` +✓ Success Analysis submitted successfully + + - Analysis ID: 84f02a6c-e477-4078-9b70-2f398d16e8c4 + - Study ID: demo + - Analysis Type: sampleSchema + +▸ Info SONG Analysis Submission command completed successfully in 0.85s +``` + +## Error Handling Capabilities + +Comprehensive error detection and reporting includes: + +- **Validation Errors**: + - Required parameter verification + - JSON syntax validation + - Analysis structure validation + - Required fields verification +- **Communication Errors**: + - Connection failures + - Authentication issues + - Timeout handling + - HTTP status code validation +- **Server-side Issues**: + - API rejection handling + - Duplicate analysis detection + - Study not found handling + - Detailed error response parsing + +### Error Response Examples + +``` +✗ Error [CONNECTION_ERROR]: Unable to establish connection with SONG service +✗ Error [INVALID_ARGS]: Analysis file not specified. Use --analysis-file or set ANALYSIS_FILE environment variable. +✗ Error [INVALID_FILE]: Analysis file contains invalid JSON: Unexpected token at line 12 +``` + +## Duplicate Analysis Handling + +When attempting to submit an analysis that already exists: + +1. **Without `--allow-duplicates` flag**: Command will detect the existing analysis and report an error +2. **With `--allow-duplicates` flag**: Command will proceed with submission attempt + +``` +⚠ Warn Submission already exists, but --allow-duplicates was specified +``` + +## Study ID Handling + +The command supports two ways to specify the study ID: + +1. **From analysis file**: By default, the command uses the `studyId` field in the analysis file +2. **From command line**: Using the `--study-id` parameter (override with `--force` flag) + +If the study ID in the file differs from the command line, a warning is displayed: + +``` +⚠ Warn StudyId in file (study123) differs from provided studyId (demo) +``` + +## Architecture + +### Command Layer + +The `SongSubmitAnalysisCommand` class orchestrates the analysis submission process: + +1. Parameter validation +2. SONG service health verification +3. Analysis file validation and parsing +4. Analysis submission to SONG server +5. Response handling and analysis ID extraction + +### Service Integration + +The command integrates directly with the SONG API: + +- Normalizes endpoint URLs +- Manages authentication headers +- Implements retry logic for resilience +- Handles duplicate detection +- Extracts analysis ID from response + +## Configuration Options + +### Environment Variables + +- `SONG_URL`: Default SONG service URL +- `ANALYSIS_FILE`: Default analysis file path +- `STUDY_ID`: Default study ID +- `AUTH_TOKEN`: Default authentication token +- `ALLOW_DUPLICATES`: Whether to allow duplicate submissions (true/false) + +## Example Usage + +### Basic Submission + +```bash +# Submit an analysis with minimal configuration +conductor songSubmitAnalysis -a ./analysis.json -u http://localhost:8080 +``` + +### Complex Configuration + +```bash +# Submit with detailed configuration +conductor songSubmitAnalysis \ + --analysis-file ./analysis.json \ + --song-url https://song.genomics-platform.org \ + --study-id my-project-2023 \ + --auth-token "bearer_eyJhbGc..." \ + --allow-duplicates \ + --force \ + --debug +``` + +## Troubleshooting + +Common issues and solutions: + +1. **Connection Issues**: + + - Verify SONG service URL is correct and accessible + - Check network connectivity and firewall settings + - Ensure service is running and healthy + +2. **Authentication Problems**: + + - Verify authentication token format and validity + - Check token permissions and expiration + - Ensure proper authorization for analysis submission + +3. **Submission Rejection**: + - Check if analysis already exists (use `--allow-duplicates` if needed) + - Verify study exists (create with `songCreateStudy` command) + - Check analysis format against the expected schema + - Validate all required fields are present + +## Integration with SONG Workflow + +The typical SONG metadata workflow follows these steps: + +1. Create Study (using `songCreateStudy`) +2. Upload Schema (using `songUploadSchema`) if needed +3. **Submit Analysis** (using `songSubmitAnalysis`) +4. Upload files referenced in the analysis +5. Publish analysis to make it publicly available + +Submitting analysis is a crucial step in this workflow, enabling proper tracking of genomic data files. + +## Best Practices + +- Validate analysis JSON locally before submission +- Ensure study is created before submitting analysis +- Include accurate file sizes and MD5sums in analysis +- Use meaningful, consistent nomenclature +- Set up environment variables for consistent configuration +- Store analysis JSON files in version control +- Automate submissions in data processing pipelines +- Use `--debug` for troubleshooting + +## Notes on File Upload + +The SONG Analysis Submission command registers the metadata for your analysis, but does not upload the actual data files. After successfully submitting your analysis metadata and receiving an analysis ID, you'll need to use a separate file upload command to transfer the genomic data files to storage. diff --git a/apps/conductor/package-lock.json b/apps/conductor/package-lock.json new file mode 100644 index 00000000..26dec66b --- /dev/null +++ b/apps/conductor/package-lock.json @@ -0,0 +1,688 @@ +{ + "name": "conductor", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "conductor", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "@elastic/elasticsearch": "^7.17.14", + "@types/axios": "^0.9.36", + "axios": "^1.8.1", + "chalk": "^4.1.2", + "commander": "^12.1.0", + "csv-parse": "^5.6.0", + "ts-node": "^10.9.2", + "uuid": "^11.0.3" + }, + "bin": { + "conductor": "dist/main.js" + }, + "devDependencies": { + "@types/chalk": "^0.4.31", + "@types/commander": "^2.12.5", + "@types/node": "^22.9.3", + "@types/uuid": "^10.0.0", + "typescript": "^5.7.2" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@elastic/elasticsearch": { + "version": "7.17.14", + "resolved": "https://registry.npmjs.org/@elastic/elasticsearch/-/elasticsearch-7.17.14.tgz", + "integrity": "sha512-6uQ1pVXutwz1Krwooo67W+3K8BwH1ASMh1WoHTpomUzw8EXecXN5lHIJ9EPqTHuv1WqR2LKkSJyagcq0HYUJpg==", + "license": "Apache-2.0", + "dependencies": { + "debug": "^4.3.1", + "hpagent": "^0.1.1", + "ms": "^2.1.3", + "secure-json-parse": "^2.4.0" + }, + "engines": { + "node": ">=12" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "license": "MIT" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "license": "MIT" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "license": "MIT" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "license": "MIT" + }, + "node_modules/@types/axios": { + "version": "0.9.36", + "resolved": "https://registry.npmjs.org/@types/axios/-/axios-0.9.36.tgz", + "integrity": "sha512-NLOpedx9o+rxo/X5ChbdiX6mS1atE4WHmEEIcR9NLenRVa5HoVjAvjafwU3FPTqnZEstpoqCaW7fagqSoTDNeg==", + "license": "MIT" + }, + "node_modules/@types/chalk": { + "version": "0.4.31", + "resolved": "https://registry.npmjs.org/@types/chalk/-/chalk-0.4.31.tgz", + "integrity": "sha512-nF0fisEPYMIyfrFgabFimsz9Lnuu9MwkNrrlATm2E4E46afKDyeelT+8bXfw1VSc7sLBxMxRgT7PxTC2JcqN4Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/commander": { + "version": "2.12.5", + "resolved": "https://registry.npmjs.org/@types/commander/-/commander-2.12.5.tgz", + "integrity": "sha512-YXGZ/rz+s57VbzcvEV9fUoXeJlBt5HaKu5iUheiIWNsJs23bz6AnRuRiZBRVBLYyPnixNvVnuzM5pSaxr8Yp/g==", + "deprecated": "This is a stub types definition. commander provides its own type definitions, so you do not need this installed.", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "*" + } + }, + "node_modules/@types/node": { + "version": "22.13.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.4.tgz", + "integrity": "sha512-ywP2X0DYtX3y08eFVx5fNIw7/uIv8hYUKgXoK8oayJlLnKcRfEYCxWMVE1XagUdVtCJlZT1AU4LXEABW+L1Peg==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "node_modules/@types/uuid": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "license": "MIT" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/axios": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.1.tgz", + "integrity": "sha512-NN+fvwH/kV01dYUQ3PTOZns4LWtWhOFCAhQ/pHb88WQ1hNe5V/dvFwc4VJcDL11LT9xSX0QtsR8sWUuyOuOq7g==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "license": "MIT" + }, + "node_modules/csv-parse": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-5.6.0.tgz", + "integrity": "sha512-l3nz3euub2QMg5ouu5U09Ew9Wf6/wQ8I++ch1loQ0ljmzhmfZYrH9fflS22i/PQEvsPvxCwxgz5q7UB8K1JO4Q==", + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz", + "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hpagent": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/hpagent/-/hpagent-0.1.2.tgz", + "integrity": "sha512-ePqFXHtSQWAFXYmj+JtOTHr84iNrII4/QRlAAPPE+zqnKy4xJo7Ie1Y4kC7AdB+LxLxSTTzBMASsEcy0q8YyvQ==", + "license": "MIT" + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "license": "ISC" + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, + "node_modules/secure-json-parse": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz", + "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==", + "license": "BSD-3-Clause" + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "license": "MIT", + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/typescript": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", + "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "license": "MIT" + }, + "node_modules/uuid": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.0.5.tgz", + "integrity": "sha512-508e6IcKLrhxKdBbcA2b4KQZlLVp2+J5UwQ6F7Drckkc5N9ZJwFa4TgWtsww9UG8fGHbm6gbV19TdM5pQ4GaIA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/esm/bin/uuid" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "license": "MIT" + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "license": "MIT", + "engines": { + "node": ">=6" + } + } + } +} diff --git a/apps/conductor/package.json b/apps/conductor/package.json new file mode 100644 index 00000000..5e326247 --- /dev/null +++ b/apps/conductor/package.json @@ -0,0 +1,36 @@ +{ + "name": "conductor", + "version": "1.0.0", + "main": "index.js", + "scripts": { + "start": "ts-node src/main.ts", + "build": "tsc", + "test": "node --test src/__tests__/*.test.js", + "test:watch": "node --test --watch src/__tests__/*.test.js", + "test:coverage": "node --test --experimental-test-coverage src/__tests__/*.test.js" + }, + "bin": { + "conductor": "./dist/main.js" + }, + "keywords": [], + "author": "", + "license": "ISC", + "description": "", + "dependencies": { + "@elastic/elasticsearch": "^7.17.14", + "@types/axios": "^0.9.36", + "axios": "^1.8.1", + "chalk": "^4.1.2", + "commander": "^12.1.0", + "csv-parse": "^5.6.0", + "ts-node": "^10.9.2", + "uuid": "^11.0.3" + }, + "devDependencies": { + "@types/chalk": "^0.4.31", + "@types/commander": "^2.12.5", + "@types/node": "^22.9.3", + "@types/uuid": "^10.0.0", + "typescript": "^5.7.2" + } +} diff --git a/apps/conductor/readme.md b/apps/conductor/readme.md new file mode 100644 index 00000000..dadd12aa --- /dev/null +++ b/apps/conductor/readme.md @@ -0,0 +1,161 @@ +# Complete Conductor CLI Testing Commands + +## Basic File Format Tests + +1. **Valid CSV:** + + ```bash + conductor -f ./data/valid.csv + ``` + +2. **Malformed CSV:** + + ```bash + conductor -f ./data/malformed.csv + ``` + +3. **Semicolon Delimiter Without Flag:** + + ```bash + conductor -f ./data/semicolon.csv + ``` + +4. **Semicolon Delimiter With Flag:** + + ```bash + conductor -f ./data/semicolon.csv --delimiter ";" + ``` + +5. **Empty File:** + + ```bash + conductor -f ./data/empty.csv + ``` + +6. **Headers Only:** + + ```bash + conductor -f ./data/headers_only.csv + ``` + +7. **Invalid Headers:** + + ```bash + conductor -f ./data/invalid_headers.csv + ``` + +8. **Large Dataset:** + ```bash + conductor -f ./data/large.csv + ``` + +## Configuration Options + +9. **Custom Index:** + + ```bash + conductor -f ./data/valid.csv -i custom-index + ``` + +10. **Output Logs:** + + ```bash + conductor -f ./data/valid.csv -o ./logs/test-output.log + ``` + +11. **Custom Elasticsearch URL:** + + ```bash + conductor -f ./data/valid.csv --url http://localhost:9200 + ``` + +12. **With Authentication:** + + ```bash + conductor -f ./data/valid.csv -u elastic -p password + ``` + +13. **Full Connection Settings:** + + ```bash + conductor -f ./data/valid.csv --url http://localhost:9200 -u elastic -p password -i test-index + ``` + +14. **Custom Batch Size:** + + ```bash + conductor -f ./data/valid.csv -b 500 + ``` + +15. **Debug Mode:** + ```bash + conductor -f ./data/valid.csv --debug + ``` + +## Error Cases + +16. **Multiple Files (Valid):** + + ```bash + conductor -f ./data/valid.csv ./data/headers_only.csv + ``` + +17. **Multiple Files (Mixed Valid/Invalid):** + + ```bash + conductor -f ./data/valid.csv ./data/invalid.txt + ``` + +18. **Missing Required Arguments:** + + ```bash + conductor + ``` + +19. **Invalid File Extensions:** + + ```bash + conductor -f ./data/valid.csv.txt + ``` + +20. **File Not Found:** + + ```bash + conductor -f ./data/nonexistent.csv + ``` + +21. **Invalid Connection:** + + ```bash + conductor -f ./data/valid.csv --url http://wronghost:9200 + ``` + +22. **Authentication Error:** + + ```bash + conductor -f ./data/valid.csv -u wronguser -p wrongpass + ``` + +23. **Invalid Index Name:** + + ```bash + conductor -f ./data/valid.csv -i "invalid%index" + ``` + +24. **Invalid Batch Size:** + + ```bash + conductor -f ./data/valid.csv -b -1 + ``` + +25. **Invalid Batch Size (Non-Numeric):** + ```bash + conductor -f ./data/valid.csv -b xyz + ``` + +## Help Command + +26. **Help Command:** + ```bash + conductor --help + ``` diff --git a/apps/conductor/scripts/deployments/phase0.sh b/apps/conductor/scripts/deployments/phase0.sh new file mode 100755 index 00000000..11ecd5f4 --- /dev/null +++ b/apps/conductor/scripts/deployments/phase0.sh @@ -0,0 +1,159 @@ +#!/bin/sh +# Comprehensive Pre-Deployment Checks for Conductor Application + +# Minimum Requirements +DOCKER_ENGINE_MIN_VERSION="20.0.0" # Docker engine version requirement +NODE_MIN_VERSION="20.18.1" +DOCKER_MIN_CPU_CORES=8 +DOCKER_MIN_MEMORY_GB=8 +DOCKER_MIN_DISK_GB=64 + +# Function to compare version numbers +version_check() { + local required="$1" + local actual="$2" + + # Remove any leading 'v' or 'V' + actual=$(echo "$actual" | sed -e 's/^[vV]//') + required=$(echo "$required" | sed -e 's/^[vV]//') + + # Use sort to compare versions + result=$(printf '%s\n%s\n' "$required" "$actual" | sort -V | tail -n1) + + [ "$result" = "$actual" ] +} + +# Function to safely compare numeric values +safe_compare() { + local op="$1" + local a="$2" + local b="$3" + + # Handle empty or non-numeric values + if [ -z "$a" ] || [ -z "$b" ] || \ + { ! echo "$a" | grep -q '^[0-9.]*$'; } || \ + { ! echo "$b" | grep -q '^[0-9.]*$'; }; then + return 1 + fi + + case "$op" in + -lt) [ "$(echo "$a < $b" | bc)" -eq 1 ] ;; + -le) [ "$(echo "$a <= $b" | bc)" -eq 1 ] ;; + -gt) [ "$(echo "$a > $b" | bc)" -eq 1 ] ;; + -ge) [ "$(echo "$a >= $b" | bc)" -eq 1 ] ;; + *) return 1 ;; + esac +} + +# Print Minimum Requirements +print_requirements() { + printf "\n\033[1;33mMinimum System Requirements:\033[0m\n" + printf "\n\033[1;33m1. Docker:\033[0m\n" + printf " - Engine Version: %s or higher\n" "$DOCKER_ENGINE_MIN_VERSION" + printf " - CPU: %s cores\n" "$DOCKER_MIN_CPU_CORES" + printf " - Memory: %s GB\n" "$DOCKER_MIN_MEMORY_GB" + printf " - Virtual Disk: %s GB\n" "$DOCKER_MIN_DISK_GB" + printf "\n\033[1;33m2. Node.js:\033[0m\n" + printf " - Version: %s or higher\n" "$NODE_MIN_VERSION" + printf "\n" +} + +# Main Deployment Check Script +main() { + printf "\n\033[1;36m╔═════════════════════════════════╗\033[0m +\033[1;36m║ Running Pre-deployment checks ║\033[0m +\033[1;36m╚═════════════════════════════════╝\033[0m\n" + + # Check Docker + printf "\n\033[1;35m[1/3]\033[0m Checking Docker...\n" + + # Check Docker CLI installation + if ! command -v docker >/dev/null 2>&1; then + printf "\n\033[1;31mError:\033[0m Docker is not installed\033[0m\n" + print_requirements + exit 1 + fi + + ENGINE_VERSION=$(docker --version | awk '{print $3}' | sed 's/,//') + + # Check Docker Engine version + if ! version_check "$DOCKER_ENGINE_MIN_VERSION" "$ENGINE_VERSION"; then + printf "\n\033[1;31mError:\033[0m Docker Engine version %s does not meet minimum requirement of %s\033[0m\n" "$ENGINE_VERSION" "$DOCKER_ENGINE_MIN_VERSION" + print_requirements + exit 1 + fi + printf "\033[1;36mInfo:\033[0m Docker Engine version %s detected\033[0m\n" "$ENGINE_VERSION" + + # Check Docker is running + if ! docker info >/dev/null 2>&1; then + printf "\n\033[1;31mError:\033[0m Docker daemon is not running\033[0m\n" + exit 1 + fi + printf "\033[1;36mInfo:\033[0m Docker daemon is running\033[0m\n" + + # Check Docker Resources + printf "\n\033[1;35m[2/3]\033[0m Checking Docker Resources\n" + DOCKER_INFO=$(docker info 2>/dev/null) + + # CPU Cores Check + CPU_CORES=$(sysctl -n hw.ncpu 2>/dev/null || nproc 2>/dev/null || echo "0") + if ! safe_compare -lt "$CPU_CORES" "$DOCKER_MIN_CPU_CORES"; then + printf "\033[1;36mInfo:\033[0m Docker CPU allocation meets minimum requirements (%s cores)\033[0m\n" "$CPU_CORES" + else + printf "\033[1;33m⚠ Docker CPU cores (%s) are less than recommended (%s)\033[0m\n" "$CPU_CORES" "$DOCKER_MIN_CPU_CORES" + fi + + # Memory Check + TOTAL_MEMORY=$(docker info 2>/dev/null | grep "Total Memory" | awk '{print $3 $4}') + MEMORY_GB=$(echo "$TOTAL_MEMORY" | sed 's/GiB//') + if ! safe_compare -lt "$MEMORY_GB" "$DOCKER_MIN_MEMORY_GB"; then + printf "\033[1;36mInfo:\033[0m Docker memory allocation meets minimum requirements (%s GB)\033[0m\n" "$MEMORY_GB" + else + printf "\033[1;33m⚠ Docker memory (%s GB) is less than recommended (%s GB)\033[0m\n" "$MEMORY_GB" "$DOCKER_MIN_MEMORY_GB" + fi + + # Disk Space Check + # Use `diskutil` on macOS for disk space info + DOCKER_DISK_SPACE=$(diskutil info / 2>/dev/null | grep "Total Space" | awk '{print $3 $4}' | sed 's/[()]//g') + DISK_GB=$(echo "$DOCKER_DISK_SPACE" | sed 's/GB//') + + if ! safe_compare -lt "$DISK_GB" "$DOCKER_MIN_DISK_GB"; then + printf "\033[1;36mInfo:\033[0m Docker virtual disk space meets minimum requirements (%s GB)\033[0m\n" "$DISK_GB" + else + printf "\033[1;33m⚠ Docker virtual disk space (%s GB) is less than recommended (%s GB)\033[0m\n" "$DISK_GB" "$DOCKER_MIN_DISK_GB" + fi + + # Node.js Check + printf "\n\033[1;35m[3/3]\033[0m Checking Node.js\n" + if ! command -v node >/dev/null 2>&1; then + printf "\n\033[1;31mError:\033[0m Node.js is not installed\033[0m\n" + print_requirements + exit 1 + fi + + NODE_VERSION=$(node --version | cut -d 'v' -f2) + if ! version_check "$NODE_MIN_VERSION" "$NODE_VERSION"; then + printf "\n\033[1;31mError:\033[0m Node.js version %s does not meet minimum requirement of %s\033[0m\n" "$NODE_VERSION" "$NODE_MIN_VERSION" + print_requirements + exit 1 + fi + printf "\033[1;36mInfo:\033[0m Node.js version %s meets requirements\033[0m\n" "$NODE_VERSION" + + # Final Success + printf "\n\033[1;32mSuccess:\033[0m All requirements met\n" + printf "\n\033[1;33mSystem Resources:\033[0m\n" + printf "Docker Engine: \033[0;32m%s\033[0m\n" "$ENGINE_VERSION" + printf "CPU Cores: \033[0;32m%s\033[0m\n" "$CPU_CORES" + printf "Total Memory: \033[0;32m%s\033[0m\n" "$TOTAL_MEMORY" + printf "Disk Space: \033[0;32m%s GB\033[0m\n" "$DISK_GB" + printf "Node.js: \033[0;32m%s\033[0m\n" "$NODE_VERSION" + printf "\nTo setup stage move into its directory\n" + printf "\033[1;33mcd apps/stage\033[0m\n" + printf "\nAnd then run:\n" + printf "\033[1;33mdocker build -t stageimage:1.0 .\033[0m\n" + printf "\nOnce built you should be able to successfully run:\n" + printf "\033[1;33mmake phase1\033[0m\n" +} + +# Run the main function +main \ No newline at end of file diff --git a/apps/conductor/scripts/deployments/phase1.sh b/apps/conductor/scripts/deployments/phase1.sh new file mode 100755 index 00000000..d75f2e17 --- /dev/null +++ b/apps/conductor/scripts/deployments/phase1.sh @@ -0,0 +1,74 @@ +#!/bin/sh + +# Set the base directory for scripts +SCRIPT_DIR="/conductor/scripts/services" + +# Debug function for logging +debug() { + if [ "$DEBUG" = "true" ]; then + echo "[DEBUG] $1" + fi +} + +# rs = "Run Script" a simple function to apply permissions and run scripts +rs() { + if [ -f "$1" ]; then + debug "Found script at: $1" + debug "Current permissions: $(ls -l "$1")" + if chmod +x "$1"; then + debug "Successfully set execute permissions" + debug "New permissions: $(ls -l "$1")" + debug "Attempting to execute with sh explicitly..." + sh "$1" + else + echo "Failed to set execute permissions for $1" + return 1 + fi + else + echo "Script not found at: $1" + return 1 + fi +} + +# Cleanup any existing healthcheck file +echo -e "Cleaning up any existing health check files" +rs "$SCRIPT_DIR/utils/healthcheck_cleanup.sh" + +# Welcome +echo -e "\n\033[1;36m╔══════════════════════════════════════════════════════════╗\033[0m" +echo -e "\033[1;36m║ Spinning up the Prelude Phase One Development Portal ║\033[0m" +echo -e "\033[1;36m╚══════════════════════════════════════════════════════════╝\033[0m\n" + +# Elasticsearch Check +echo -e "\033[1;35m[1/5]\033[0m Checking Elasticsearch (this may take a few minutes)" +rs "${SCRIPT_DIR}/elasticsearch/elasticsearch_check.sh" + +# Elasticsearch Setup +echo -e "\n\033[1;35m[2/5]\033[0m Setting up Elasticsearch Indices" +rs "$SCRIPT_DIR/elasticsearch/setup_indices.sh" + +# Update Conductor to Healthy Status +echo -e "\n\033[1;35m[3/5]\033[0m Updating Conductor health status" +echo "healthy" > conductor/volumes/health/conductor_health +echo -e "\033[1;36mConductor:\033[0m Updating Container Status. Health check file created" + +# Check Stage +echo -e "\n\033[1;35m[4/5]\033[0m Checking Stage" +rs "$SCRIPT_DIR/stage/stage_check.sh" + +# Check Arranger +echo -e "\n\033[1;35m[5/5]\033[0m Checking Arranger Instances" +rs "$SCRIPT_DIR/arranger/arranger_check.sh" + +# Remove Health Check File +rs "${SCRIPT_DIR}/utils/healthcheck_cleanup.sh" + +# Success and Next Steps +echo -e "\n\033[1;36m╔═══════════════════════════════════════════════════════════════╗\033[0m" +echo -e "\033[1;36m║ Prelude Phase One Development Portal running on localhost ║\033[0m" +echo -e "\033[1;36m╚═══════════════════════════════════════════════════════════════╝\033[0m\n" +echo -e "\033[1m🌐 Development Portal should now be available at:\033[0m" +echo -e " \033[1;32mhttp://localhost:3000\033[0m" +echo -e " \033[0;90m(unless configured to use a different port)\033[0m\n" +echo -e "\033[1m📚 The PhaseOne usage guide can be found at:\033[0m" +echo -e " \033[1;32mhttp://localhost:3000/documentation/phaseone\033[0m\n" diff --git a/apps/conductor/scripts/deployments/phase2.sh b/apps/conductor/scripts/deployments/phase2.sh new file mode 100755 index 00000000..5c60b9bf --- /dev/null +++ b/apps/conductor/scripts/deployments/phase2.sh @@ -0,0 +1,86 @@ +#!/bin/sh + +# Set the base directory for scripts +SCRIPT_DIR="/conductor/scripts/services" + +# Debug function for logging +debug() { + if [ "$DEBUG" = "true" ]; then + echo "[DEBUG] $1" + fi +} + +# rs = "Run Script" a simple function to apply permissions and run scripts +rs() { + if [ -f "$1" ]; then + debug "Found script at: $1" + debug "Current permissions: $(ls -l "$1")" + if chmod +x "$1"; then + debug "Successfully set execute permissions" + debug "New permissions: $(ls -l "$1")" + debug "Attempting to execute with sh explicitly..." + sh "$1" + else + echo "Failed to set execute permissions for $1" + return 1 + fi + else + echo "Script not found at: $1" + return 1 + fi +} + +# Cleanup any existing healthcheck file +echo -e "Cleaning up any existing health check files" +rs "${SCRIPT_DIR}/utils/healthcheck_cleanup.sh" + +# Welcome +echo -e "\n\033[1;36m╔══════════════════════════════════════════════════════════╗\033[0m" +echo -e "\033[1;36m║ Spinning up the Prelude Phase Two Development Portal ║\033[0m" +echo -e "\033[1;36m╚══════════════════════════════════════════════════════════╝\033[0m\n" + +# Lectern Setup +echo -e "\033[1;35m[1/8]\033[0m Checking on Lectern" +rs "${SCRIPT_DIR}/lectern/lectern_check.sh" + +# Lyric Setup +echo -e "\n\033[1;35m[2/8]\033[0m Checking on Lyric" +rs "${SCRIPT_DIR}/lyric/lyric_check.sh" + +# Elasticsearch Check +echo -e "\n\033[1;35m[3/8]\033[0m Checking Elasticsearch (this may take a few minutes)" +rs "${SCRIPT_DIR}/elasticsearch/elasticsearch_check.sh" + +# Elasticsearch Setup +echo -e "\n\033[1;35m[4/8]\033[0m Setting up Elasticsearch Indices" +rs "$SCRIPT_DIR/elasticsearch/setup_indices.sh" + +# Update Conductor to Healthy Status +echo -e "\n\033[1;35m[5/8]\033[0m Updating Conductor health status" +echo "healthy" > conductor/volumes/health/conductor_health +echo -e "\033[1;36mConductor:\033[0m Updating Container Status. Health check file created" + +# Check Stage +echo -e "\n\033[1;35m[6/8]\033[0m Checking Stage" +rs "${SCRIPT_DIR}/stage/stage_check.sh" + +# Check Arranger +echo -e "\n\033[1;35m[7/8]\033[0m Checking Arranger" +rs "${SCRIPT_DIR}/arranger/arranger_check.sh" + +# Check Maestro +echo -e "\n\033[1;35m[8/8]\033[0m Checking Maestro" +rs "${SCRIPT_DIR}/maestro/maestro_check.sh" + +# Remove Health Check File +rs "${SCRIPT_DIR}/utils/healthcheck_cleanup.sh" + +# Success and Next Steps +echo -e "\n\033[1;36m╔═════════════════════════════════════════════════════════════════╗\033[0m" +echo -e "\033[1;36m║ Prelude Phase Two Development Portal running on localhost ║\033[0m" +echo -e "\033[1;36m╚═════════════════════════════════════════════════════════════════╝\033[0m\n" +echo -e "\033[1m🌐 Development Portal should now be available at:\033[0m" +echo -e " \033[1;32mhttp://localhost:3000\033[0m" +echo -e " \033[0;90m(unless configured to use a different port)\033[0m\n" +echo -e "\033[1m📚 The PhaseTwo usage guide can be found at:\033[0m" +echo -e " \033[1;32mhttp://localhost:3000/documentation/phasetwo\033[0m\n" diff --git a/apps/conductor/scripts/deployments/phase3.sh b/apps/conductor/scripts/deployments/phase3.sh new file mode 100755 index 00000000..38e24307 --- /dev/null +++ b/apps/conductor/scripts/deployments/phase3.sh @@ -0,0 +1,99 @@ +#!/bin/sh + +# Set the base directory for scripts +SCRIPT_DIR="/conductor/scripts/services" + + +# Debug function for logging +debug() { + if [ "$DEBUG" = "true" ]; then + echo "[DEBUG] $1" + fi +} + +# rs = "Run Script" a simple function to apply permissions and run scripts +rs() { + if [ -f "$1" ]; then + debug "Found script at: $1" + debug "Current permissions: $(ls -l "$1")" + if chmod +x "$1"; then + debug "Successfully set execute permissions" + debug "New permissions: $(ls -l "$1")" + debug "Attempting to execute with sh explicitly..." + sh "$1" + else + echo "Failed to set execute permissions for $1" + return 1 + fi + else + echo "Script not found at: $1" + return 1 + fi +} +# Cleanup any existing healthcheck file +echo -e "Cleaning up any existing health check files" +rs "${SCRIPT_DIR}/utils/healthcheck_cleanup.sh" + +# Welcome +echo -e "\n\033[1;36m╔════════════════════════════════════════════════════════════╗\033[0m" +echo -e "\033[1;36m║ Spinning up the Prelude Phase Three Development Portal ║\033[0m" +echo -e "\033[1;36m╚════════════════════════════════════════════════════════════╝\033[0m\n" + +# Lectern Setup +echo -e "\033[1;35m[1/11]\033[0m Checking on Lectern" +rs "${SCRIPT_DIR}/lectern/lectern_check.sh" + +# Lyric Setup +echo -e "\n\033[1;35m[2/11]\033[0m Checking on Lyric" +rs "${SCRIPT_DIR}/lyric/lyric_check.sh" + +# Minio Check +echo -e "\n\033[1;35m[3/11]\033[0m Checking Minio Object Storage" +rs "${SCRIPT_DIR}/score/object_storage_check.sh" + +# Score Setup +echo -e "\n\033[1;35m[4/11]\033[0m Checking on Score (this may take a few minutes)" +rs "${SCRIPT_DIR}/score/score_check.sh" + +# Song Setup +echo -e "\n\033[1;35m[5/11]\033[0m Checkng on Song" +rs "${SCRIPT_DIR}/song/song_check.sh" + +# Elasticsearch Check +echo -e "\n\033[1;35m[6/11]\033[0m Checking Elasticsearch (this may take a few minutes)" +rs "${SCRIPT_DIR}/elasticsearch/elasticsearch_check.sh" + +# Elasticsearch Setup +echo -e "\n\033[1;35m[7/11]\033[0m Setting up Elasticsearch Indices" +rs "$SCRIPT_DIR/elasticsearch/setup_indices.sh" + +# Update Conductor to Healthy Status +echo -e "\n\033[1;35m[8/11]\033[0m Updating Conductor health status" +echo "healthy" > conductor/volumes/health/conductor_health +echo -e "\033[1;36mConductor:\033[0m Updating Container Status. Health check file created" + +# Check Stage +echo -e "\n\033[1;35m[9/11]\033[0m Checking Stage" +rs "${SCRIPT_DIR}/stage/stage_check.sh" + +# Check Arranger +echo -e "\n\033[1;35m[10/11]\033[0m Checking Arranger" +rs "${SCRIPT_DIR}/arranger/arranger_check.sh" + +# Check Maestro +echo -e "\n\033[1;35m[11/11]\033[0m Checking Maestro" +rs "${SCRIPT_DIR}/maestro/maestro_check.sh" + +# Remove Health Check File +rs "${SCRIPT_DIR}/utils/healthcheck_cleanup.sh" + +# Success and Next Steps +echo -e "\n\033[1;36m╔═════════════════════════════════════════════════════════════════╗\033[0m" +echo -e "\033[1;36m║ Prelude Phase Three Development Portal running on localhost ║\033[0m" +echo -e "\033[1;36m╚═════════════════════════════════════════════════════════════════╝\033[0m\n" +echo -e "\033[1m🌐 Development Portal should now be available at:\033[0m" +echo -e " \033[1;32mhttp://localhost:3000\033[0m" +echo -e " \033[0;90m(unless configured to use a different port)\033[0m\n" +echo -e "\033[1m📚 The PhaseThree usage guide can be found at:\033[0m" +echo -e " \033[1;32mhttp://localhost:3000/documentation/phasethree\033[0m\n" + diff --git a/apps/conductor/scripts/deployments/stageDev.sh b/apps/conductor/scripts/deployments/stageDev.sh new file mode 100755 index 00000000..45259c6c --- /dev/null +++ b/apps/conductor/scripts/deployments/stageDev.sh @@ -0,0 +1,84 @@ +#!/bin/sh + +# Set the base directory for scripts +SCRIPT_DIR="/conductor/scripts/services" + +# Debug function for logging +debug() { + if [ "$DEBUG" = "true" ]; then + echo "[DEBUG] $1" + fi +} + +# rs = "Run Script" a simple function to apply permissions and run scripts +rs() { + if [ -f "$1" ]; then + debug "Found script at: $1" + debug "Current permissions: $(ls -l "$1")" + if chmod +x "$1"; then + debug "Successfully set execute permissions" + debug "New permissions: $(ls -l "$1")" + debug "Attempting to execute with sh explicitly..." + sh "$1" + else + echo "Failed to set execute permissions for $1" + return 1 + fi + else + echo "Script not found at: $1" + return 1 + fi +} + +# Cleanup any existing healthcheck file +echo -e "Cleaning up any existing health check files" +rs "$SCRIPT_DIR/utils/healthcheck_cleanup.sh" + +# Welcome +echo -e "\n\033[1;36m╔════════════════════════════════════════════╗\033[0m" +echo -e "\033[1;36m║ Spinning up the StageDev Environment ║\033[0m" +echo -e "\033[1;36m╚════════════════════════════════════════════╝\033[0m\n" + +# Elasticsearch Check +echo -e "\033[1;35m[1/5]\033[0m Checking Elasticsearch (this may take a few minutes)" +rs "${SCRIPT_DIR}/elasticsearch/elasticsearch_check.sh" + +# Elasticsearch Setup +echo -e "\n\033[1;35m[2/5]\033[0m Setting up Elasticsearch Indices" +rs "$SCRIPT_DIR/elasticsearch/setup_indices.sh" + +# Update Conductor to Healthy Status +echo -e "\n\033[1;35m[3/5]\033[0m Updating Conductor health status" +echo "healthy" > conductor/volumes/health/conductor_health +echo -e "\033[1;36mConductor:\033[0m Updating Container Status. Health check file created" + +# Check Arranger +echo -e "\n\033[1;35m[5/5]\033[0m Checking Arranger Instances" +rs "$SCRIPT_DIR/arranger/arranger_check.sh" + +# Remove Health Check File +rs "${SCRIPT_DIR}/utils/healthcheck_cleanup.sh" + +# Success and Next Steps +echo -e "\n\033[1;36m╔═══════════════════════════════════════╗\033[0m" +echo -e "\033[1;36m║ Stage Dev Service Setup Complete ║\033[0m" +echo -e "\033[1;36m╚═══════════════════════════════════════╝\033[0m\n" + +echo -e "\033[1m1️⃣ To run Stage locally, navigate to the directory:\033[0m" +echo -e " \033[1;32mcd apps/stage\033[0m\n" + +echo -e "\033[1m2️⃣ Copy the example environment file:\033[0m" +echo -e " \033[1;32mcp .env.stageDev .env\033[0m\n" + +echo -e "\033[1m3️⃣ Install the dependencies:\033[0m" +echo -e " \033[1;32mnpm ci\033[0m" + +echo -e " \033[1mThis will require:\033[0m" +echo -e " \033[1;34m- Node v16 or higher\033[0m" +echo -e " \033[1;34m- npm v8.3.0 or higher\033[0m\n" + +echo -e "\033[1m4️⃣ Run the development server:\033[0m" +echo -e " \033[1;32mnpm run dev\033[0m\n" + +echo -e "\033[1mYour development server will be accessible at:\033[0m" +echo -e " \033[1;32mhttp://localhost:3000\033[0m\n" \ No newline at end of file diff --git a/apps/conductor/scripts/services/arranger/arranger_check.sh b/apps/conductor/scripts/services/arranger/arranger_check.sh new file mode 100755 index 00000000..b9a938a9 --- /dev/null +++ b/apps/conductor/scripts/services/arranger/arranger_check.sh @@ -0,0 +1,171 @@ +#!/bin/bash +# /conductor/scripts/services/arranger/arranger_check.sh + +# Define some basic configurations +RETRY_COUNT=0 +MAX_RETRIES=10 +RETRY_DELAY=20 +TIMEOUT=10 + +# Tip section - can be updated with specific troubleshooting steps +TROUBLESHOOTING_TIPS=" +Troubleshooting Tips: +1. Verify Arranger configuration includes the required 'documentType' property +2. Check if Elasticsearch indices are properly configured +3. Review Arranger logs for detailed error messages +4. Ensure environment variables for Arranger are correctly set +" + +# Function to parse host and port from URL +parse_url() { + local url="$1" + local regex='http://([^:/]+)(:([0-9]+))?' + if echo "$url" | grep -qE "$regex"; then + host=$(echo "$url" | sed -E "s|$regex|\1|") + port=$(echo "$url" | sed -E "s|$regex|\3|" || echo "5050") + else + printf "\033[1;31mError:\033[0m Invalid ARRANGER_URL format: %s\n" "$url" + return 1 + fi +} + +# Check if Arranger is properly configured by running a GraphQL query +check_arranger_functionality() { + local arranger_url="$1" + local instance="$2" + + # Try to get a response from the GraphQL endpoint + graphql_response=$(curl -s -X POST "${arranger_url}/graphql" \ + -H "Content-Type: application/json" \ + -d '{"query": "{ __schema { queryType { name } } }"}' \ + --max-time "$TIMEOUT" 2>/dev/null) + + # Check if we got a valid GraphQL response (no errors) + if [ -n "$graphql_response" ] && ! echo "$graphql_response" | grep -q "error"; then + printf "\033[1;32mSuccess:\033[0m Arranger GraphQL endpoint is functioning correctly\n" + return 0 + else + printf "\033[1;33mWarning:\033[0m Arranger is running but GraphQL endpoint has errors\n" + + # Check for the documentType error in Docker logs + local container_name="arranger-clinical" + recent_logs=$(docker logs --tail 20 "$container_name" 2>/dev/null) + + if echo "$recent_logs" | grep -q "documentType"; then + printf "\033[1;31mConfiguration Error:\033[0m Missing required 'documentType' property\n" + printf "Please check Arranger configuration in environment variables or config files\n" + elif echo "$recent_logs" | grep -q "Error thrown"; then + error_msg=$(echo "$recent_logs" | grep -A 1 "Error thrown" | grep -v "Error thrown") + printf "\033[1;31mArranger Error:\033[0m %s\n" "$error_msg" + fi + + return 1 + fi +} + +# Check Arranger Docker logs for errors +check_docker_logs() { + local instance="$1" + local container_name="arranger-clinical" + + printf "\033[1;36mInfo:\033[0m Checking Docker logs for errors\n" + + # Get recent logs from Docker container + recent_logs=$(docker logs --tail 50 "$container_name" 2>/dev/null) + + # Look for specific error patterns + if echo "$recent_logs" | grep -q "documentType"; then + printf "\033[1;31mConfiguration Error:\033[0m Missing required 'documentType' property\n" + printf "Please check Arranger configuration in environment variables or config files\n" + return 1 + elif echo "$recent_logs" | grep -q "Error thrown"; then + error_lines=$(echo "$recent_logs" | grep -n "Error thrown" | cut -d: -f1) + for line in $error_lines; do + next_line=$((line + 1)) + error_msg=$(echo "$recent_logs" | sed -n "${next_line}p" | sed 's/^[[:space:]]*//') + if [ -n "$error_msg" ]; then + printf "\033[1;31mError in Arranger logs:\033[0m %s\n" "$error_msg" + fi + done + return 1 + fi + + return 0 +} + +# Check Arranger instances based on ARRANGER_COUNT and related environment variables +check_arrangers() { + # Get the number of Arranger instances to check + arranger_count=${ARRANGER_COUNT:-0} + + printf "\033[1;36mConductor:\033[0m Checking %d Arranger instances\n" "$arranger_count" + + all_healthy=true + i=0 + while [ "$i" -lt "$arranger_count" ]; do + # Dynamically retrieve the URL for this instance + arranger_url_var="ARRANGER_${i}_URL" + arranger_url=$(eval "echo \$$arranger_url_var") + + # Skip if no URL + if [ -z "$arranger_url" ]; then + printf "\033[1;31mError:\033[0m No URL found for Arranger instance %d\n" "$i" + exit 1 + fi + + # Parse URL + if ! parse_url "$arranger_url"; then + exit 1 + fi + + printf "\033[1;36mChecking Arranger:\033[0m Instance %d at %s\n" "$i" "$arranger_url" + + # Check if Arranger is responsive with multiple retries + RETRY_COUNT=0 + is_responsive=false + + until [ "$is_responsive" = true ] || [ "$RETRY_COUNT" -ge "$MAX_RETRIES" ]; do + response=$(curl -s --max-time "$TIMEOUT" "${arranger_url}" 2>/dev/null) + + if [ -n "$response" ]; then + is_responsive=true + else + RETRY_COUNT=$((RETRY_COUNT + 1)) + printf "\033[1;36mInfo:\033[0m Attempt %d: Arranger instance %d not ready, retrying in %d seconds\n" "$RETRY_COUNT" "$i" "$RETRY_DELAY" + sleep "$RETRY_DELAY" + fi + done + + if [ "$is_responsive" = true ]; then + printf "\033[1;36mInfo:\033[0m Arranger instance %d is responsive\n" "$i" + + # Now check if Arranger is properly functioning + if ! check_arranger_functionality "$arranger_url" "$i"; then + all_healthy=false + fi + + # Also check Docker logs for errors + if ! check_docker_logs "$i"; then + all_healthy=false + fi + else + printf "\033[1;31mError:\033[0m Arranger instance %d is not available after %d attempts\n" "$i" "$MAX_RETRIES" + printf "\n%s\n" "$TROUBLESHOOTING_TIPS" + all_healthy=false + fi + + i=$((i + 1)) + done + + if [ "$all_healthy" = true ]; then + printf "\033[1;32mSuccess:\033[0m All Arranger instances are available and healthy\n" + exit 0 + else + printf "\033[1;33mWarning:\033[0m Arranger is responding but has configuration issues\n" + printf "\n%s\n" "$TROUBLESHOOTING_TIPS" + exit 1 + fi +} + +# Run the check +check_arrangers \ No newline at end of file diff --git a/apps/conductor/scripts/services/elasticsearch/clear_elasticsearch_data.sh b/apps/conductor/scripts/services/elasticsearch/clear_elasticsearch_data.sh new file mode 100755 index 00000000..49c22197 --- /dev/null +++ b/apps/conductor/scripts/services/elasticsearch/clear_elasticsearch_data.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +echo -e "\033[1;36mElasticsearch:\033[0m Clearing data from Elasticsearch" + +if ! curl -s -X POST "$ES_URL/_all/_delete_by_query" \ + -H "Content-Type: application/json" \ + -u "$ES_AUTH" \ + -d '{"query": {"match_all": {}}}' > /dev/null; then + echo -e "\033[1;31mError:\033[0m Failed to clear existing data" + exit 1 +fi + +echo -e "\033[1;32mSuccess:\033[0m Index data cleared" \ No newline at end of file diff --git a/apps/conductor/scripts/services/elasticsearch/elasticsearch_check.sh b/apps/conductor/scripts/services/elasticsearch/elasticsearch_check.sh new file mode 100755 index 00000000..5920f90c --- /dev/null +++ b/apps/conductor/scripts/services/elasticsearch/elasticsearch_check.sh @@ -0,0 +1,124 @@ +#!/bin/bash + +# Define some basic configurations +RETRY_COUNT=0 +MAX_RETRIES=10 +RETRY_DELAY=20 +TIMEOUT=10 +DEBUG=${DEBUG:-false} + +# Troubleshooting Tips +TROUBLESHOOTING_TIPS=" +Troubleshooting Tips for Elasticsearch: +1. Verify Elasticsearch service is running +2. Check network connectivity +3. Confirm correct Elasticsearch URL and credentials +4. Ensure firewall is not blocking connections +5. Review Elasticsearch service logs +6. Check system resource availability +7. Verify authentication credentials +8. Ensure correct Elasticsearch version compatibility +" + +# Debug function +debug() { + if [ "$DEBUG" = "true" ]; then + printf "\033[1;33mDEBUG:\033[0m %s\n" "$1" + fi +} + +# Validate Elasticsearch URL +if [ -z "$ES_URL" ]; then + printf "\n\033[1;31mError:\033[0m ES_URL environment variable is not set\n" + printf "\n%s\n" "$TROUBLESHOOTING_TIPS" + + printf "\n\033[1;33mConfiguration Requirements:\033[0m\n" + printf "- ES_URL must be set to the base URL of the Elasticsearch service\n" + printf "- Example: export ES_URL=http://elasticsearch:9200\n" + + exit 1 +fi + +# Validate URL format +if ! echo "$ES_URL" | grep -qE '^https?://[^/]+'; then + printf "\n\033[1;31mError:\033[0m Invalid ES_URL format\n" + printf "\n\033[1;33mURL Format Requirements:\033[0m\n" + printf "- Must start with http:// or https://\n" + printf "- Must include hostname\n" + printf "- Current value: %s\n" "$ES_URL" + + printf "\n%s\n" "$TROUBLESHOOTING_TIPS" + + exit 1 +fi + +# Validate credentials +if [ -z "$ES_USER" ] || [ -z "$ES_PASS" ]; then + printf "\n\033[1;31mError:\033[0m Elasticsearch credentials (ES_USER or ES_PASS) not fully configured\n" + printf "\n\033[1;33mConfiguration Requirements:\033[0m\n" + printf "- ES_USER must be set\n" + printf "- ES_PASS must be set\n" + + printf "\n%s\n" "$TROUBLESHOOTING_TIPS" + + exit 1 +fi + +# Clean URL function - removes any double slashes except for http:// +clean_url() { + echo "$1" | sed 's#([^:])//+#\1/#g' +} + +# Construct health check URL +HEALTH_URL="$ES_URL/_cluster/health" +HEALTH_URL=$(clean_url "$HEALTH_URL") + +debug "Using ES_URL: $ES_URL" +debug "Constructed health URL: $HEALTH_URL" + +printf "\033[1;36mConductor:\033[0m Checking Elasticsearch cluster health\n" + +until response=$(curl -s --max-time "$TIMEOUT" -u "${ES_USER}:${ES_PASS}" "$HEALTH_URL" -H "accept: application/json" 2>/dev/null); do + debug "Curl command: curl -s --max-time $TIMEOUT -u ${ES_USER}:${ES_PASS} $HEALTH_URL -H 'accept: application/json'" + RETRY_COUNT=$((RETRY_COUNT + 1)) + + if [ "$RETRY_COUNT" -ge "$MAX_RETRIES" ]; then + printf "\n\033[1;31mError:\033[0m Failed to connect to Elasticsearch after %d attempts\n" "$MAX_RETRIES" + + # Print troubleshooting tips + printf "\n%s\n" "$TROUBLESHOOTING_TIPS" + + # Additional debug information + printf "\n\033[1;33mAdditional Debug Information:\033[0m\n" + printf "Elasticsearch URL: %s\n" "$ES_URL" + printf "Health URL: %s\n" "$HEALTH_URL" + + exit 1 + fi + + printf "\033[1;36mElasticsearch:\033[0m Not reachable, retrying in %d seconds (Attempt %d/%d)\n" "$RETRY_DELAY" "$RETRY_COUNT" "$MAX_RETRIES" + debug "Attempt $RETRY_COUNT failed. Retrying in $RETRY_DELAY seconds" + sleep "$RETRY_DELAY" +done + +debug "Received response: $response" + +# Check cluster status +cluster_status=$(echo "$response" | grep -o '"status":"[^"]*' | cut -d'"' -f4) +if [ "$cluster_status" = "green" ] || [ "$cluster_status" = "yellow" ]; then + printf "\033[1;32mSuccess:\033[0m Elasticsearch cluster is healthy (Status: %s)\n" "$cluster_status" +else + printf "\n\033[1;31mError:\033[0m Elasticsearch cluster has unhealthy status\n" + + # Print troubleshooting tips + printf "\n%s\n" "$TROUBLESHOOTING_TIPS" + + # Additional debug information + printf "\n\033[1;33mAdditional Debug Information:\033[0m\n" + printf "Elasticsearch URL: %s\n" "$ES_URL" + printf "Health URL: %s\n" "$HEALTH_URL" + printf "Health Response: %s\n" "$response" + + debug "Cluster status is not green or yellow" + exit 1 +fi \ No newline at end of file diff --git a/apps/conductor/scripts/services/elasticsearch/setup_indices.sh b/apps/conductor/scripts/services/elasticsearch/setup_indices.sh new file mode 100755 index 00000000..7513a8ed --- /dev/null +++ b/apps/conductor/scripts/services/elasticsearch/setup_indices.sh @@ -0,0 +1,74 @@ +#!/bin/bash + +# Define some basic configurations +RETRY_COUNT=0 +MAX_RETRIES=10 +RETRY_DELAY=20 +TIMEOUT=10 + +printf "\033[1;36mConductor:\033[0m Checking if Elasticsearch is available\n" + +until response=$(curl -s --max-time "$TIMEOUT" -u "${ES_USER}:${ES_PASS}" "${ES_URL}/_cluster/health" -H "accept: */*" 2>/dev/null); do + RETRY_COUNT=$((RETRY_COUNT + 1)) + + if [ "$RETRY_COUNT" -ge "$MAX_RETRIES" ]; then + printf "\033[1;31mFailed to connect to Elasticsearch after %d attempts\033[0m\n" "$MAX_RETRIES" + exit 1 + fi + + printf "\033[1;36mElasticsearch:\033[0m Not yet available, checking again in %d seconds\n" "$RETRY_DELAY" + sleep "$RETRY_DELAY" +done + +printf "\033[1;32mSuccess:\033[0m Elasticsearch is available\n" + +# Setting up indices +INDEX_COUNT=${ES_INDEX_COUNT:-0} +printf "\033[1;36mElasticsearch:\033[0m Setting up %d indices\n" "$INDEX_COUNT" + +i=0 +while [ "$i" -lt "$INDEX_COUNT" ]; do + # Use indirect variable expansion with proper syntax + index_name_var="ES_INDEX_${i}_NAME" + template_file_var="ES_INDEX_${i}_TEMPLATE_FILE" + template_name_var="ES_INDEX_${i}_TEMPLATE_NAME" + alias_name_var="ES_INDEX_${i}_ALIAS_NAME" + + index_name=$(eval "echo \$$index_name_var") + template_file=$(eval "echo \$$template_file_var") + template_name=$(eval "echo \$$template_name_var") + alias_name=$(eval "echo \$$alias_name_var") + + if [ -z "$index_name" ]; then + i=$((i + 1)) + continue + fi + + printf "\033[1;36mSetting up index:\033[0m %s\n" "$index_name" + + if [ ! -f "$template_file" ]; then + printf "\n\033[1;31mError:\033[0m Template file not found at %s\n" "$template_file" + exit 1 + fi + + if ! curl -s -u "$ES_USER:$ES_PASS" "$ES_URL/_template/$template_name" | grep -q "\"index_patterns\""; then + curl -s -u "$ES_USER:$ES_PASS" -X PUT "$ES_URL/_template/$template_name" \ + -H "Content-Type: application/json" -d @"$template_file" > /dev/null \ + && printf "\033[1;36mInfo:\033[0m Created template %s\n" "$template_name" + else + printf "\033[1;36mInfo:\033[0m Template %s already exists, skipping\n" "$template_name" + fi + + if ! curl -s -f -u "$ES_USER:$ES_PASS" -X GET "$ES_URL/$index_name" > /dev/null 2>&1; then + curl -s -u "$ES_USER:$ES_PASS" -X PUT "$ES_URL/$index_name" \ + -H "Content-Type: application/json" \ + -d "{\"aliases\": {\"$alias_name\": {}}}" > /dev/null + printf "\033[1;36mInfo:\033[0m Created index %s with alias %s\n" "$index_name" "$alias_name" + else + printf "\033[1;36mInfo:\033[0m Index %s already exists\n" "$index_name" + fi + + i=$((i + 1)) +done + +printf "\033[1;32mSuccess:\033[0m Indices set up successfully\033[0m\n" \ No newline at end of file diff --git a/apps/conductor/scripts/services/lectern/lectern_check.sh b/apps/conductor/scripts/services/lectern/lectern_check.sh new file mode 100755 index 00000000..c453ed17 --- /dev/null +++ b/apps/conductor/scripts/services/lectern/lectern_check.sh @@ -0,0 +1,83 @@ +#!/bin/bash + +# Define some basic configurations +RETRY_COUNT=0 +MAX_RETRIES=10 +RETRY_DELAY=20 +TIMEOUT=10 + +# Troubleshooting Tips +TROUBLESHOOTING_TIPS=" +Troubleshooting Tips for Lectern: +1. Verify Lectern service is running +2. Check network connectivity +3. Confirm correct Lectern URL +4. Ensure firewall is not blocking connections +5. Review Lectern service logs +6. Check system resource availability +7. Verify application configuration +" + +# Validate Lectern URL +if [ -z "$LECTERN_URL" ]; then + printf "\n\033[1;31mError:\033[0m LECTERN_URL environment variable is not set\n" + printf "\n%s\n" "$TROUBLESHOOTING_TIPS" + + printf "\n\033[1;33mConfiguration Requirements:\033[0m\n" + printf "- LECTERN_URL must be set to the base URL of the Lectern service\n" + printf "- Example: export LECTERN_URL=http://lectern:8080\n" + + exit 1 +fi + +# Validate URL format +if ! echo "$LECTERN_URL" | grep -qE '^https?://[^/]+'; then + printf "\n\033[1;31mError:\033[0m Invalid LECTERN_URL format\n" + printf "\n\033[1;33mURL Format Requirements:\033[0m\n" + printf "- Must start with http:// or https://\n" + printf "- Must include hostname\n" + printf "- Current value: %s\n" "$LECTERN_URL" + + printf "\n%s\n" "$TROUBLESHOOTING_TIPS" + + exit 1 +fi + +printf "\033[1;36mConductor:\033[0m Checking if Lectern is healthy\n" + +until response=$(curl -s --max-time "$TIMEOUT" "$LECTERN_URL/health" -H "accept: */*" 2>/dev/null); do + RETRY_COUNT=$((RETRY_COUNT + 1)) + + if [ "$RETRY_COUNT" -ge "$MAX_RETRIES" ]; then + printf "\n\033[1;31mError:\033[0m Failed to connect to Lectern after %d attempts\n" "$MAX_RETRIES" + + # Print troubleshooting tips + printf "\n%s\n" "$TROUBLESHOOTING_TIPS" + + # Additional debug information + printf "\n\033[1;33mAdditional Debug Information:\033[0m\n" + printf "Lectern URL: %s\n" "$LECTERN_URL" + + exit 1 + fi + + printf "\033[1;36mLectern:\033[0m Not reachable, retrying in %d seconds (Attempt %d/%d)\n" "$RETRY_DELAY" "$RETRY_COUNT" "$MAX_RETRIES" + sleep "$RETRY_DELAY" +done + +# Check if app status is Up +if echo "$response" | grep -q '"appStatus":"Up"' 2>/dev/null; then + printf "\033[1;32mSuccess:\033[0m Lectern is healthy\n" +else + printf "\n\033[1;31mError:\033[0m Lectern returned unhealthy status\n" + + # Print troubleshooting tips + printf "\n%s\n" "$TROUBLESHOOTING_TIPS" + + # Additional debug information + printf "\n\033[1;33mAdditional Debug Information:\033[0m\n" + printf "Lectern URL: %s\n" "$LECTERN_URL" + printf "Health Response: %s\n" "$response" + + exit 1 +fi \ No newline at end of file diff --git a/apps/conductor/scripts/services/lyric/lyric_check.sh b/apps/conductor/scripts/services/lyric/lyric_check.sh new file mode 100755 index 00000000..1d08cbad --- /dev/null +++ b/apps/conductor/scripts/services/lyric/lyric_check.sh @@ -0,0 +1,58 @@ +#!/bin/sh + +# Define some basic configurations +RETRY_COUNT=0 +MAX_RETRIES=10 +RETRY_DELAY=20 +TIMEOUT=10 + +# Troubleshooting Tips +TROUBLESHOOTING_TIPS=" +Troubleshooting Tips for Lyric: +1. Verify Lyric service is running +2. Check network connectivity +3. Confirm correct Lyric URL +4. Ensure firewall is not blocking connections +5. Review Lyric service logs +6. Check system resource availability +7. Verify application configuration +" + +printf "\033[1;36mConductor:\033[0m Checking if Lyric is healthy\n" + +until response=$(curl -s --max-time "$TIMEOUT" "$LYRIC_URL/health" -H "accept: */*" 2>/dev/null); do + RETRY_COUNT=$((RETRY_COUNT + 1)) + + if [ "$RETRY_COUNT" -ge "$MAX_RETRIES" ]; then + printf "\n\033[1;31mError:\033[0m Failed to connect to Lyric after %d attempts\n" "$MAX_RETRIES" + + # Print troubleshooting tips + printf "\n%s\n" "$TROUBLESHOOTING_TIPS" + + # Additional debug information + printf "\n\033[1;33mAdditional Debug Information:\033[0m\n" + printf "Lyric URL: %s\n" "$LYRIC_URL" + + exit 1 + fi + + printf "\033[1;36mLyric:\033[0m Not reachable, retrying in %d seconds (Attempt %d/%d)\n" "$RETRY_DELAY" "$RETRY_COUNT" "$MAX_RETRIES" + sleep "$RETRY_DELAY" +done + +# Check if response contains message OK +if echo "$response" | grep -q '"message":"OK"' 2>/dev/null; then + printf "\033[1;32mSuccess:\033[0m Lyric is healthy\n" +else + printf "\n\033[1;31mError:\033[0m Lyric returned unhealthy status\n" + + # Print troubleshooting tips + printf "\n%s\n" "$TROUBLESHOOTING_TIPS" + + # Additional debug information + printf "\n\033[1;33mAdditional Debug Information:\033[0m\n" + printf "Lyric URL: %s\n" "$LYRIC_URL" + printf "Health Response: %s\n" "$response" + + exit 1 +fi \ No newline at end of file diff --git a/apps/conductor/scripts/services/maestro/indexTabularData.sh b/apps/conductor/scripts/services/maestro/indexTabularData.sh new file mode 100755 index 00000000..ee8a8155 --- /dev/null +++ b/apps/conductor/scripts/services/maestro/indexTabularData.sh @@ -0,0 +1,147 @@ +#!/bin/sh + +# Define some basic configurations +RETRY_COUNT=0 +MAX_RETRIES=10 +RETRY_DELAY=20 +TIMEOUT=10 +DEBUG=${DEBUG:-false} + +# Array of entity types to process +ENTITY_TYPES="clinical_data" +PAGE_SIZE=20 + +# Check if environment variables are set +if [ -z "$LYRIC_URL" ]; then + printf "\033[1;31mError:\033[0m LYRIC_URL environment variable is not set\n" + exit 1 +fi + +if [ -z "$MAESTRO_URL" ]; then + printf "\033[1;31mError:\033[0m MAESTRO_URL environment variable is not set\n" + exit 1 +fi + +# Debug function +debug() { + if [ "$DEBUG" = "true" ]; then + printf "\033[1;33mDEBUG:\033[0m %s\n" "$1" + fi +} + +printf "\033[1;36mConductor:\033[0m Checking if Data service is healthy\n" + +# Function to check Lyric health +check_lyric_health() { + debug "Checking Lyric health" + until response=$(curl -s --max-time "$TIMEOUT" "$LYRIC_URL/data/category/1" \ + -H "accept: application/json" 2>/dev/null); do + RETRY_COUNT=$((RETRY_COUNT + 1)) + + if [ "$RETRY_COUNT" -ge "$MAX_RETRIES" ]; then + printf "\033[1;31mFailed to connect to Data service after %d attempts\033[0m\n" "$MAX_RETRIES" + return 1 + fi + + printf "\033[1;36mData service:\033[0m Not yet healthy, checking again in %d seconds\n" "$RETRY_DELAY" + sleep "$RETRY_DELAY" + done + + if echo "$response" | grep -q '"records":\[' 2>/dev/null; then + printf "\033[1;32mSuccess:\033[0m Data service is healthy\n" + return 0 + else + printf "\033[1;31mError:\033[0m Data service returned invalid response\n" + return 1 + fi +} + +# Function to index a single system ID +index_system_id() { + local system_id=$1 + local entity_type=$2 + RETRY_COUNT=0 + + debug "Indexing system ID: $system_id for entity type: $entity_type" + + until index_response=$(curl -s -X POST \ + "$MAESTRO_URL/index/repository/lyric.overture/organization/OICR/id/$system_id" \ + -H "accept: application/json" \ + -d '' \ + --max-time "$TIMEOUT" 2>/dev/null); do + + RETRY_COUNT=$((RETRY_COUNT + 1)) + + if [ "$RETRY_COUNT" -ge "$MAX_RETRIES" ]; then + printf "\033[1;31mFailed to index system ID %s after %d attempts\033[0m\n" "$system_id" "$MAX_RETRIES" + return 1 + fi + + debug "Retry attempt $RETRY_COUNT for system ID: $system_id" + printf "\033[1;36mIndexing:\033[0m Retrying system ID %s, attempt %d\n" "$system_id" "$RETRY_COUNT" + sleep "$RETRY_DELAY" + done + + if [ -n "$index_response" ]; then + printf "\033[1;32mSuccess:\033[0m Indexed %s record with ID %s\n" "$entity_type" "$system_id" + return 0 + else + printf "\033[1;31mError:\033[0m Failed to index %s record with ID %s\n" "$entity_type" "$system_id" + return 1 + fi +} + +# Function to process records for an entity type +process_entity_type() { + local entity_type=$1 + local page=1 + local has_more=true + + debug "Processing entity type: $entity_type" + + while [ "$has_more" = true ]; do + debug "Fetching page $page for entity type: $entity_type" + + response=$(curl -s --max-time "$TIMEOUT" \ + "$LYRIC_URL/data/category/1?entityName=$entity_type&page=$page" \ + -H "accept: application/json" 2>/dev/null) + + if [ -z "$response" ]; then + printf "\033[1;31mError:\033[0m Empty response for %s page %d\n" "$entity_type" "$page" + return 1 + fi + + # Extract and process system IDs + echo "$response" | grep -o '"systemId":"[^"]*"' | sed 's/"systemId":"//g' | sed 's/"//g' | \ + while read -r system_id; do + if [ -n "$system_id" ]; then + index_system_id "$system_id" "$entity_type" + fi + done + + # Check if there are more pages + total_pages=$(echo "$response" | grep -o '"totalPages":[0-9]*' | cut -d':' -f2) + if [ "$page" -ge "$total_pages" ]; then + has_more=false + else + page=$((page + 1)) + fi + done +} + +# Main execution +debug "Starting indexing process" +debug "Environment settings:" +debug "LYRIC_URL: $LYRIC_URL" +debug "MAESTRO_URL: $MAESTRO_URL" +debug "ENTITY_TYPES: $ENTITY_TYPES" + +if check_lyric_health; then + for entity_type in $ENTITY_TYPES; do + printf "\033[1;36mProcessing:\033[0m Starting indexing for %s records\n" "$entity_type" + process_entity_type "$entity_type" + done + printf "\033[1;32mComplete:\033[0m Finished indexing all entity types\n" +else + exit 1 +fi \ No newline at end of file diff --git a/apps/conductor/scripts/services/maestro/maestro_check.sh b/apps/conductor/scripts/services/maestro/maestro_check.sh new file mode 100755 index 00000000..7783de8b --- /dev/null +++ b/apps/conductor/scripts/services/maestro/maestro_check.sh @@ -0,0 +1,114 @@ +#!/bin/bash + +# Define some basic configurations +RETRY_COUNT=3 +MAX_RETRIES=10 +RETRY_DELAY=30 +TIMEOUT=10 +DEBUG=${DEBUG:-false} + +# Troubleshooting Tips +TROUBLESHOOTING_TIPS=" +Troubleshooting Tips for Maestro: +1. Verify Maestro service is running +2. Check network connectivity +3. Confirm correct Maestro URL +4. Ensure firewall is not blocking connections +5. Review Maestro service logs +6. Check system resource availability +7. Verify application configuration +" + +# Debug function +debug() { + if [ "$DEBUG" = "true" ]; then + printf "\033[1;33mDEBUG:\033[0m %s\n" "$1" + fi +} + +# Validate Maestro URL +if [ -z "$MAESTRO_URL" ]; then + printf "\033[1;31mError:\033[0m MAESTRO_URL environment variable is not set\n" + printf "\n%s\n" "$TROUBLESHOOTING_TIPS" + + printf "\n\033[1;33mConfiguration Requirements:\033[0m\n" + printf "- MAESTRO_URL must be set to the base URL of the Maestro service\n" + printf "- Example: export MAESTRO_URL=http://maestro:8080\n" + + exit 1 +fi + +# Validate URL format +if ! echo "$MAESTRO_URL" | grep -qE '^https?://[^/]+'; then + printf "\033[1;31mError:\033[0m Invalid MAESTRO_URL format\n" + printf "\n\033[1;33mURL Format Requirements:\033[0m\n" + printf "- Must start with http:// or https://\n" + printf "- Must include hostname\n" + printf "- Current value: %s\n" "$MAESTRO_URL" + + printf "\n%s\n" "$TROUBLESHOOTING_TIPS" + + exit 1 +fi + +# Clean URL function - removes any double slashes except for http:// +clean_url() { + echo "$1" | sed 's#([^:])//+#\1/#g' +} + +# Construct health check URL +HEALTH_URL="$MAESTRO_URL/health" +HEALTH_URL=$(clean_url "$HEALTH_URL") + +debug "Using MAESTRO_URL: $MAESTRO_URL" +debug "Constructed health URL: $HEALTH_URL" + +printf "\033[1;36mConductor:\033[0m Checking if Maestro is reachable\n" + +until response=$(curl -s --max-time "$TIMEOUT" "$HEALTH_URL" -H "accept: */*" 2>/dev/null); do + debug "Curl command: curl -s --max-time $TIMEOUT $HEALTH_URL -H 'accept: */*'" + RETRY_COUNT=$((RETRY_COUNT + 1)) + + if [ "$RETRY_COUNT" -ge "$MAX_RETRIES" ]; then + printf "\033[1;31mError:\033[0m Failed to connect to Maestro after %d attempts\n" "$MAX_RETRIES" + + # Print troubleshooting tips + printf "\n%s\n" "$TROUBLESHOOTING_TIPS" + + # Additional debug information + printf "\n\033[1;33mAdditional Debug Information:\033[0m\n" + printf "Maestro URL: %s\n" "$MAESTRO_URL" + printf "Health URL: %s\n" "$HEALTH_URL" + + exit 1 + fi + + printf "\033[1;36mMaestro:\033[0m Not reachable, retrying in %d seconds (Attempt %d/%d)\n" "$RETRY_DELAY" "$RETRY_COUNT" "$MAX_RETRIES" + debug "Attempt $RETRY_COUNT failed. Retrying in $RETRY_DELAY seconds" + sleep "$RETRY_DELAY" +done + +debug "Received response: $response" + +if echo "$response" | grep -q '"message":"OK"'; then + printf "\033[1;32mSuccess:\033[0m Maestro is healthy\n" +else + printf "\n\033[1;31mError:\033[0m Maestro returned unexpected status\n" + + # Print troubleshooting tips + printf "\n%s\n" "$TROUBLESHOOTING_TIPS" + + # Additional debug information + printf "\n\033[1;33mAdditional Debug Information:\033[0m\n" + printf "Maestro URL: %s\n" "$MAESTRO_URL" + printf "Health URL: %s\n" "$HEALTH_URL" + printf "Health Response: %s\n" "$response" + + # If response is HTML, format it nicely + if echo "$response" | grep -q ''; then + echo "$response" | sed 's/conductor | //g' + fi + + debug "Response did not contain expected 'message':'OK'" + exit 1 +fi \ No newline at end of file diff --git a/apps/conductor/scripts/services/score/object_storage_check.sh b/apps/conductor/scripts/services/score/object_storage_check.sh new file mode 100755 index 00000000..439a0924 --- /dev/null +++ b/apps/conductor/scripts/services/score/object_storage_check.sh @@ -0,0 +1,45 @@ +#!/bin/sh + +# Define some basic configurations +RETRY_COUNT=0 +MAX_RETRIES=10 +RETRY_DELAY=15 +TIMEOUT=10 + +# Troubleshooting Tips +TROUBLESHOOTING_TIPS=" +Troubleshooting Tips for Object Storage: +1. Verify Object Storage service is running +2. Check network connectivity +3. Confirm correct Object Storage URL +4. Ensure firewall is not blocking connections +5. Review Object Storage service logs +6. Check system resource availability +7. Verify storage backend configuration +8. Confirm authentication and access credentials +" + +printf "\033[1;36mConductor:\033[0m Checking if object storage is reachable\n" + +until [ "$(curl -s --max-time "$TIMEOUT" -o /dev/null -w "%{http_code}" "$OBJECT_STORAGE_URL/minio/health/live")" = "200" ]; do + RETRY_COUNT=$((RETRY_COUNT + 1)) + + if [ "$RETRY_COUNT" -ge "$MAX_RETRIES" ]; then + printf "\n\033[1;31mError:\033[0m Failed to connect to object storage after %d attempts\n" "$MAX_RETRIES" + + # Print troubleshooting tips + printf "\n%s\n" "$TROUBLESHOOTING_TIPS" + + # Additional debug information + printf "\n\033[1;33mAdditional Debug Information:\033[0m\n" + printf "Object Storage URL: %s\n" "$OBJECT_STORAGE_URL" + printf "Health Endpoint: %s/minio/health/live\n" "$OBJECT_STORAGE_URL" + + exit 1 + fi + + printf "\033[1;36mObject Storage:\033[0m Not reachable, retrying in %d seconds (Attempt %d/%d)\n" "$RETRY_DELAY" "$RETRY_COUNT" "$MAX_RETRIES" + sleep "$RETRY_DELAY" +done + +printf "\033[1;32mSuccess:\033[0m Object storage is reachable\n" \ No newline at end of file diff --git a/apps/conductor/scripts/services/score/score_check.sh b/apps/conductor/scripts/services/score/score_check.sh new file mode 100755 index 00000000..4613f46f --- /dev/null +++ b/apps/conductor/scripts/services/score/score_check.sh @@ -0,0 +1,46 @@ +#!/bin/sh + +# Define some basic configurations +RETRY_COUNT=0 +MAX_RETRIES=10 +RETRY_DELAY=30 +TIMEOUT=10 + +# Troubleshooting Tips +TROUBLESHOOTING_TIPS=" +Troubleshooting Tips for Score: +1. Verify Score service is running +2. Check network connectivity +3. Confirm correct Score URL and authorization token +4. Ensure firewall is not blocking connections +5. Review Score service logs +6. Check system resource availability +" + +printf "\033[1;36mConductor:\033[0m Checking if Score is reachable\n" + +until [ "$(curl -s --max-time "$TIMEOUT" -o /dev/null -w "%{http_code}" "$SCORE_URL/download/ping" \ + -H "accept: */*" \ + -H "Authorization: 68fb42b4-f1ed-4e8c-beab-3724b99fe528" \ + -H "User-Agent: unknown")" = "200" ]; do + + RETRY_COUNT=$((RETRY_COUNT + 1)) + + if [ "$RETRY_COUNT" -ge "$MAX_RETRIES" ]; then + printf "\n\033[1;31mError:\033[0m Failed to connect to Score after %d attempts\n" "$MAX_RETRIES" + + # Print troubleshooting tips + printf "\n%s\n" "$TROUBLESHOOTING_TIPS" + + # Additional debug information + printf "\n\033[1;33mAdditional Debug Information:\033[0m\n" + printf "Score URL: %s\n" "$SCORE_URL" + + exit 1 + fi + + printf "\033[1;36mScore:\033[0m Not reachable, retrying in %d seconds (Attempt %d/%d)\n" "$RETRY_DELAY" "$RETRY_COUNT" "$MAX_RETRIES" + sleep "$RETRY_DELAY" +done + +printf "\033[1;32mSuccess:\033[0m Score is now reachable\n" \ No newline at end of file diff --git a/apps/conductor/scripts/services/song/song_check.sh b/apps/conductor/scripts/services/song/song_check.sh new file mode 100755 index 00000000..5ef26428 --- /dev/null +++ b/apps/conductor/scripts/services/song/song_check.sh @@ -0,0 +1,44 @@ +#!/bin/sh + +# Define some basic configurations +RETRY_COUNT=0 +MAX_RETRIES=10 +RETRY_DELAY=20 +TIMEOUT=10 + +# Troubleshooting Tips +TROUBLESHOOTING_TIPS=" +Troubleshooting Tips for Song: +1. Verify Song service is running +2. Check network connectivity +3. Confirm correct Song URL +4. Ensure firewall is not blocking connections +5. Review Song service logs +6. Check system resource availability +" + +printf "\033[1;36mConductor:\033[0m Checking if Song is reachable\n" + +until [ "$(curl -s --max-time "$TIMEOUT" -o /dev/null -w "%{http_code}" "$SONG_URL/isAlive" \ + -H "accept: */*")" = "200" ]; do + + RETRY_COUNT=$((RETRY_COUNT + 1)) + + if [ "$RETRY_COUNT" -ge "$MAX_RETRIES" ]; then + printf "\n\033[1;31mError:\033[0m Failed to connect to Song after %d attempts\n" "$MAX_RETRIES" + + # Print troubleshooting tips + printf "\n%s\n" "$TROUBLESHOOTING_TIPS" + + # Additional debug information + printf "\n\033[1;33mAdditional Debug Information:\033[0m\n" + printf "Song URL: %s\n" "$SONG_URL" + + exit 1 + fi + + printf "\033[1;36mSong:\033[0m Not reachable, retrying in %d seconds (Attempt %d/%d)\n" "$RETRY_DELAY" "$RETRY_COUNT" "$MAX_RETRIES" + sleep "$RETRY_DELAY" +done + +printf "\033[1;32mSuccess:\033[0m Song is now reachable\n" \ No newline at end of file diff --git a/apps/conductor/scripts/services/stage/stage_check.sh b/apps/conductor/scripts/services/stage/stage_check.sh new file mode 100755 index 00000000..8b933a16 --- /dev/null +++ b/apps/conductor/scripts/services/stage/stage_check.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +# Define some basic configurations +RETRY_COUNT=0 +MAX_RETRIES=10 +RETRY_DELAY=5 +TIMEOUT=10 + + +printf "\033[1;36mConductor:\033[0m Checking if Stage is reachable\n" + +until curl -s -f --max-time "$TIMEOUT" "$STAGE_URL" > /dev/null 2>&1; do + RETRY_COUNT=$((RETRY_COUNT + 1)) + + if [ "$RETRY_COUNT" -ge "$MAX_RETRIES" ]; then + printf "\033[1;31mFailed to connect to Stage after %d attempts\033[0m\n" "$MAX_RETRIES" + exit 1 + fi + + printf "Trying again in %d seconds...\n" "$RETRY_DELAY" + sleep "$RETRY_DELAY" +done + +printf "\033[1;32mSuccess:\033[0m Stage is now reachable\n" \ No newline at end of file diff --git a/apps/conductor/scripts/services/utils/healthcheck_cleanup.sh b/apps/conductor/scripts/services/utils/healthcheck_cleanup.sh new file mode 100755 index 00000000..e7138dac --- /dev/null +++ b/apps/conductor/scripts/services/utils/healthcheck_cleanup.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +# If the health check file exists on startup it needs to be removed +rm conductor/volumes/health/conductor_health 2>/dev/null \ No newline at end of file diff --git a/apps/conductor/scripts/services/utils/phaseOneSubmission.sh b/apps/conductor/scripts/services/utils/phaseOneSubmission.sh new file mode 100755 index 00000000..2d75acfe --- /dev/null +++ b/apps/conductor/scripts/services/utils/phaseOneSubmission.sh @@ -0,0 +1,96 @@ +#!/bin/sh + +# Configuration +CONDUCTOR_PATH="${CONDUCTOR_PATH:-/conductor}" + +# Validate and prepare data files and index names +validate_and_prepare_inputs() { + # Remove spaces from environment variables (comman seperate lists can have spaces) + DATA_FILES=$(echo "$DATA_FILES" | tr -d ' ') + INDEX_NAMES=$(echo "$INDEX_NAMES" | tr -d ' ') + + # Count the number of files and indices + DATA_FILES_COUNT=$(echo "$DATA_FILES" | awk -F, '{print NF}') + INDEX_NAMES_COUNT=$(echo "$INDEX_NAMES" | awk -F, '{print NF}') + + # Validate input arrays have equal length + if [ "$DATA_FILES_COUNT" -ne "$INDEX_NAMES_COUNT" ]; then + echo -e "\033[1;31mError:\033[0m Mismatch between DATA_FILES and INDEX_NAMES" + exit 1 + fi + + # Validate each file exists with improved error handling + IFS=',' + for file in $DATA_FILES; do + echo "Checking file: $file" + + if [ ! -f "$file" ]; then + # Try with absolute path if it doesn't start with / + if ! echo "$file" | grep -q "^/"; then + if [ -f "/$file" ]; then + echo "Found file at /$file instead of $file" + export DATA_FILES=$(echo "$DATA_FILES" | sed "s|$file|/$file|g") + file="/$file" + else + echo -e "\033[1;31mError:\033[0m Data file not found at $file" + echo "Files in parent directory: $(ls -la $(dirname "$file" 2>/dev/null || echo "/"))" + exit 1 + fi + else + # Check if file exists in parent directory + parent_dir=$(dirname "$file") + file_name=$(basename "$file") + echo "Checking parent directory: $parent_dir for file: $file_name" + ls -la "$parent_dir" + + echo -e "\033[1;31mError:\033[0m Data file not found at $file" + exit 1 + fi + else + echo "File found successfully: $file" + fi + done + unset IFS + +} + +# Main script execution +main() { + echo -e "\033[1;36mConductor:\033[0m Setting up elasticsearch ETL utility" + + # Validate inputs + validate_and_prepare_inputs + + # Install dependencies + echo -e "\033[1;35m[1/2]\033[0m Installing Conductor dependencies" + cd $CONDUCTOR_PATH && npm install --silent || { + echo -e "\033[1;31mError:\033[0m Failed to install dependencies" + exit 1 + } + + # Submit data for each file + echo -e "\033[1;35m[2/2]\033[0m Submitting tabular data to Elasticsearch" + + # Use IFS to correctly handle comma-separated lists + IFS=',' + FILE_INDEX=0 + for file in $DATA_FILES; do + # Get corresponding index name + INDEX_NAME=$(echo "$INDEX_NAMES" | cut -d',' -f$((FILE_INDEX+1))) + + echo "Processing file: $file with index: $INDEX_NAME" + + # Submit data using npx + npx ts-node src/main.ts -f "$file" -i "$INDEX_NAME" --url "$ES_URL" || { + echo -e "\033[1;31mError:\033[0m Failed to submit data to Elasticsearch index $INDEX_NAME" + exit 1 + } + + echo -e "\033[1;32m✓\033[0m Submitted $file to $INDEX_NAME" + FILE_INDEX=$((FILE_INDEX+1)) + done + unset IFS +} + +# Execute main function +main \ No newline at end of file diff --git a/apps/conductor/src/cli/environment.ts b/apps/conductor/src/cli/environment.ts new file mode 100644 index 00000000..dafb67b8 --- /dev/null +++ b/apps/conductor/src/cli/environment.ts @@ -0,0 +1,61 @@ +/** + * Environment Configuration Loader + * + * Loads environment variables and configuration settings + */ + +import * as fs from "fs"; +import * as path from "path"; +import { ConductorError, ErrorCodes } from "../utils/errors"; +import { Logger } from "../utils/logger"; + +// Dynamically load dotenv if it's available +let dotenv: any; +try { + // Using require instead of import to handle missing package gracefully + dotenv = require("dotenv"); +} catch (error) { + // dotenv is not installed, we'll handle this in the code +} + +export interface EnvironmentConfig { + elasticsearchUrl: string; + indexName?: string; + esUser?: string; + esPassword?: string; + logLevel: string; +} + +export function loadEnvironmentConfig(): EnvironmentConfig { + try { + // Try to load .env file if dotenv is available and .env exists + const envPath = path.resolve(process.cwd(), ".env"); + if (dotenv && fs.existsSync(envPath)) { + dotenv.config({ path: envPath }); + Logger.debug`Loaded environment from ${envPath}`; + } else if (!dotenv && fs.existsSync(envPath)) { + Logger.warn`Found .env file at ${envPath} but dotenv package is not installed. Environment variables from .env will not be loaded.`; + } else { + Logger.debug`No .env file found at ${envPath}`; + } + + // Return environment configuration with defaults + const config = { + elasticsearchUrl: + process.env.ELASTICSEARCH_URL || "http://localhost:9200", + indexName: process.env.ELASTICSEARCH_INDEX, + esUser: process.env.ELASTICSEARCH_USER || "elastic", + esPassword: process.env.ELASTICSEARCH_PASSWORD || "myelasticpassword", + logLevel: process.env.LOG_LEVEL || "info", + }; + + Logger.debugObject("Environment config", config); + return config; + } catch (error) { + throw new ConductorError( + "Failed to load environment configuration", + ErrorCodes.ENV_ERROR, + { originalError: error, envPath: path.resolve(process.cwd(), ".env") } + ); + } +} diff --git a/apps/conductor/src/cli/index.ts b/apps/conductor/src/cli/index.ts new file mode 100644 index 00000000..1fbc8159 --- /dev/null +++ b/apps/conductor/src/cli/index.ts @@ -0,0 +1,196 @@ +/** + * CLI Entry Point Module + * + * This module serves as the main entry point for the Conductor CLI application. + * It handles command-line argument parsing, environment configuration, and command setup. + * + * Responsibilities: + * 1. Parsing command line arguments using Commander.js + * 2. Loading and validating environment configuration + * 3. Setting up the command structure and options + * 4. Providing a standardized CLIOutput object to the command execution layer + * + * The flow of execution: + * - CLI arguments → Commander.js parsing → Environment validation → CLIOutput creation → Command execution + * + * Related files: + * - options.ts: Contains command-line option configuration and parsing logic + * - environment.ts: Handles loading environment variables and configuration + * - validations/environment.ts: Validates environment configuration + * - types/cli.ts: Contains CLI-related type definitions + * - types/constants.ts: Defines available profiles as constants + * - commands/commandFactory.ts: Creates command instances based on the profile + * + * Usage: + * The setupCLI() function is typically called from the main entry point (index.ts) + * which then passes the CLIOutput to the appropriate command. + */ + +import { Command } from "commander"; +import { Config } from "../types/cli"; +import { Profiles } from "../types/constants"; +import { parseCommandLineArgs } from "./options"; +import { configureCommandOptions } from "./options"; +import { loadEnvironmentConfig } from "./environment"; +import { validateEnvironment } from "../validations/environment"; +import { Logger } from "../utils/logger"; + +/** + * Type definition for supported CLI profiles. + * This should match the available profiles in the Profiles enum. + */ +export type CLIprofile = + | "upload" + | "indexManagement" + | "lecternUpload" + | "lyricRegister" + | "lyricUpload" + | "maestroIndex" + | "songUploadSchema" + | "songCreateStudy" + | "songSubmitAnalysis" + | "scoreManifestUpload" + | "songPublishAnalysis" + | "songScoreSubmit"; + +/** + * Standardized output from the CLI parsing process. + * This interface represents the fully processed command-line arguments + * and serves as the contract between the CLI layer and command execution layer. + */ +export interface CLIOutput { + /** Configuration settings for the command */ + config: Config; + + /** List of input file paths specified by the user */ + filePaths: string[]; + + /** The selected profile/command to execute */ + profile: CLIprofile; + + /** Optional output directory path */ + outputPath?: string; + + /** Environment configuration (loaded from .env or system environment) */ + envConfig: any; + + /** Raw command options for command-specific handling */ + options: any; +} + +/** + * Sets up the CLI environment and parses command-line arguments. + * + * This function: + * 1. Initializes the Commander.js instance + * 2. Loads environment configuration + * 3. Configures available commands and options + * 4. Parses command-line arguments + * 5. Validates the environment + * 6. Returns a standardized CLIOutput object + * + * @returns Promise resolving to a CLIOutput object for command execution + * @throws Error if environment validation fails or if command parsing fails + */ +export async function setupCLI(): Promise { + const program = new Command(); + + try { + Logger.debug("Conductor CLI"); + + // Load environment and parse options + const envConfig = loadEnvironmentConfig(); + configureCommandOptions(program); + + Logger.debug("Raw arguments:", process.argv); + program.parse(process.argv); + + // Get the command + const commandName = program.args[0]; + + // Get the specific command + const command = program.commands.find((cmd) => cmd.name() === commandName); + + // Extract options for the specific command + const options = command ? command.opts() : {}; + + Logger.debug("Parsed options:", options); + Logger.debug("Remaining arguments:", program.args); + // Determine the profile based on the command name + let profile: CLIprofile = Profiles.INDEX_MANAGEMENT; + switch (commandName) { + case "upload": + profile = Profiles.UPLOAD; + break; + case "lecternUpload": + profile = Profiles.LECTERN_UPLOAD; + break; + case "lyricRegister": + profile = Profiles.LYRIC_REGISTER; + break; + case "lyricUpload": + profile = Profiles.LYRIC_DATA; + break; + case "maestroIndex": + profile = Profiles.INDEX_REPOSITORY; + break; + case "songUploadSchema": + profile = Profiles.song_upload_schema; + break; + case "songCreateStudy": + profile = Profiles.song_create_study; + break; + case "songSubmitAnalysis": + profile = Profiles.song_submit_analysis; + break; + case "scoreManifestUpload": + profile = Profiles.score_manifest_upload; + break; + case "songPublishAnalysis": + profile = Profiles.song_publish_analysis; + break; + case "songScoreSubmit": + profile = Profiles.song_score_submit; + break; + case "indexManagement": + profile = Profiles.INDEX_MANAGEMENT; + break; + } + + // Validate options and environment if needed + // Skip Elasticsearch validation for Lectern, Lyric, and SONG operations + if ( + profile !== Profiles.LECTERN_UPLOAD && + profile !== Profiles.LYRIC_REGISTER && + profile !== Profiles.LYRIC_DATA && + profile !== Profiles.song_upload_schema && + profile !== Profiles.song_create_study && + profile !== Profiles.song_submit_analysis && + profile !== Profiles.score_manifest_upload && + profile !== Profiles.song_publish_analysis && + profile !== Profiles.song_score_submit + ) { + await validateEnvironment({ + elasticsearchUrl: options.url || envConfig.elasticsearchUrl, + }); + } + + // Parse command-line arguments into CLIOutput + const cliOutput = parseCommandLineArgs({ + ...options, + profile, + // Ensure schema file is added to filePaths for Lectern and SONG upload + ...(options.schemaFile ? { file: options.schemaFile } : {}), + // Ensure analysis file is added to filePaths for SONG analysis upload + ...(options.analysisFile ? { file: options.analysisFile } : {}), + }); + Logger.debug("CLI setup completed successfully"); + + return cliOutput; + } catch (error) { + console.error("Error during CLI setup:", error); + // Rethrow the error + + throw error; + } +} diff --git a/apps/conductor/src/cli/options.ts b/apps/conductor/src/cli/options.ts new file mode 100644 index 00000000..438525ff --- /dev/null +++ b/apps/conductor/src/cli/options.ts @@ -0,0 +1,532 @@ +/** + * CLI Options Module + * + * This module configures the command-line options for the Conductor CLI. + * It sets up the available commands, their options, and handles parsing arguments. + */ + +import { Command } from "commander"; +import { Profiles } from "../types/constants"; +import { CLIOutput } from "../types/cli"; +import { Logger } from "../utils/logger"; + +/** + * Configures the command-line options for the Conductor CLI + * @param program - The Commander.js program instance + */ +export function configureCommandOptions(program: Command): void { + // Global options + program + .version("1.0.0") + .description("Conductor: Data Processing Pipeline") + .option("--debug", "Enable debug mode") + // Add a custom action for the help option + .addHelpCommand("help [command]", "Display help for a specific command") + .on("--help", () => { + // Call the reference commands after the default help + Logger.showReferenceCommands(); + }); + + // Upload command + program + .command("upload") + .description("Upload data to Elasticsearch") + .option("-f, --file ", "Input files to process") + .option("-i, --index ", "Elasticsearch index name") + .option("-b, --batch-size ", "Batch size for uploads") + .option("--delimiter ", "CSV delimiter character") + .option("-o, --output ", "Output directory for generated files") + .option("--force", "Force overwrite of existing files") + .option("--url ", "Elasticsearch URL") + .option("--user ", "Elasticsearch username", "elastic") + .option( + "--password ", + "Elasticsearch password", + "myelasticpassword" + ) + .action(() => { + /* Handled by main.ts */ + }); + + // Setup indices command + program + .command("indexManagement") + .description("Set up Elasticsearch indices and templates") + .option("-t, --template-file ", "Template JSON file") + .option("-n, --template-name ", "Template name") + .option("-i, --index-name ", "Index name") + .option("-a, --alias-name ", "Alias name") + .option("-o, --output ", "Output directory for generated files") + .option("--force", "Force overwrite of existing files") + .option("--url ", "Elasticsearch URL") + .option("--user ", "Elasticsearch username", "elastic") + .option( + "--password ", + "Elasticsearch password", + "myelasticpassword" + ) + .action(() => { + /* Handled by main.ts */ + }); + + // Lectern schema upload command + program + .command("lecternUpload") + .description("Upload schema to Lectern server") + .option("-s, --schema-file ", "Schema JSON file to upload") + .option( + "-u, --lectern-url ", + "Lectern server URL", + process.env.LECTERN_URL || "http://localhost:3031" + ) + .option("-t, --auth-token ", "Authentication token", "") + .option("-o, --output ", "Output directory for response logs") + .option("--force", "Force overwrite of existing files") + .action(() => { + /* Handled by main.ts */ + }); + + // Lyric dictionary registration command + program + .command("lyricRegister") + .description("Register a dictionary with Lyric service") + .option( + "-u, --lyric-url ", + "Lyric server URL", + process.env.LYRIC_URL || "http://localhost:3030" + ) + .option("-c, --category-name ", "Category name") + .option("--dict-name ", "Dictionary name") + .option("-v, --dictionary-version ", "Dictionary version") + .option("-e, --default-centric-entity ", "Default centric entity") + .option("-o, --output ", "Output directory for response logs") + .option("--force", "Force overwrite of existing files") + .action(() => { + /* Handled by main.ts */ + }); + + // Lyric data loading command + program + .command("lyricUpload") + .description("Load data into Lyric service") + .option( + "-u, --lyric-url ", + "Lyric server URL", + process.env.LYRIC_URL || "http://localhost:3030" + ) + .option( + "-l, --lectern-url ", + "Lectern server URL", + process.env.LECTERN_URL || "http://localhost:3031" + ) + .option( + "-d, --data-directory ", + "Directory containing CSV data files", + process.env.LYRIC_DATA + ) + .option( + "-c, --category-id ", + "Category ID", + process.env.CATEGORY_ID || "1" + ) + .option( + "-g, --organization ", + "Organization name", + process.env.ORGANIZATION || "OICR" + ) + .option( + "-m, --max-retries ", + "Maximum number of retry attempts", + process.env.MAX_RETRIES || "10" + ) + .option( + "-r, --retry-delay ", + "Delay between retry attempts in milliseconds", + process.env.RETRY_DELAY || "1000" + ) + .option("-o, --output ", "Output directory for response logs") + .option("--force", "Force overwrite of existing files") + .action(() => { + /* Handled by main.ts */ + }); + + // SONG schema upload command + program + .command("songUploadSchema") + .description("Upload schema to SONG server") + .option("-s, --schema-file ", "Schema JSON file to upload") + .option( + "-u, --song-url ", + "SONG server URL", + process.env.SONG_URL || "http://localhost:8080" + ) + .option( + "-t, --auth-token ", + "Authentication token", + process.env.AUTH_TOKEN || "123" + ) + .option("-o, --output ", "Output directory for response logs") + .option("--force", "Force overwrite of existing files") + .action(() => { + /* Handled by main.ts */ + }); + + // SONG study creation command + program + .command("songCreateStudy") + .description("Create study in SONG server") + .option( + "-u, --song-url ", + "SONG server URL", + process.env.SONG_URL || "http://localhost:8080" + ) + .option("-i, --study-id ", "Study ID", process.env.STUDY_ID || "demo") + .option( + "-n, --study-name ", + "Study name", + process.env.STUDY_NAME || "string" + ) + .option( + "-g, --organization ", + "Organization name", + process.env.ORGANIZATION || "string" + ) + .option( + "--description ", + "Study description", + process.env.DESCRIPTION || "string" + ) + .option( + "-t, --auth-token ", + "Authentication token", + process.env.AUTH_TOKEN || "123" + ) + .option("-o, --output ", "Output directory for response logs") + .option("--force", "Force creation even if study exists", false) + .action(() => { + /* Handled by main.ts */ + }); + + // SONG analysis submission command + program + .command("songSubmitAnalysis") + .description("Submit analysis to SONG server") + .option("-a, --analysis-file ", "Analysis JSON file to submit") + .option( + "-u, --song-url ", + "SONG server URL", + process.env.SONG_URL || "http://localhost:8080" + ) + .option("-i, --study-id ", "Study ID", process.env.STUDY_ID || "demo") + .option("--allow-duplicates", "Allow duplicate analysis submissions", false) + .option( + "-t, --auth-token ", + "Authentication token", + process.env.AUTH_TOKEN || "123" + ) + .option("-o, --output ", "Output directory for response logs") + .option( + "--force", + "Force studyId from command line instead of from file", + false + ) + .action(() => { + /* Handled by main.ts */ + }); + + // Score manifest upload command + program + .command("scoreManifestUpload") + .description("Generate manifest and upload files with Score") + .option("-a, --analysis-id ", "Analysis ID from Song submission") + .option( + "-d, --data-dir ", + "Directory containing data files", + process.env.DATA_DIR || "./data" + ) + .option( + "-o, --output-dir ", + "Directory for manifest file output", + process.env.OUTPUT_DIR || "./output" + ) + .option( + "-m, --manifest-file ", + "Path for manifest file", + process.env.MANIFEST_FILE + ) + .option( + "-u, --song-url ", + "SONG server URL", + process.env.SONG_URL || "http://localhost:8080" + ) + .option( + "-s, --score-url ", + "Score server URL", + process.env.SCORE_URL || "http://localhost:8087" + ) + .option( + "-t, --auth-token ", + "Authentication token", + process.env.AUTH_TOKEN || "123" + ) + .action(() => { + /* Handled by main.ts */ + }); + + // Add this to the configureCommandOptions function, after the other commands + + // Repository indexing command + program + .command("maestroIndex") + .description("Index a repository with optional filtering") + .option( + "--index-url ", + "Indexing service URL", + process.env.INDEX_URL || "http://localhost:11235" + ) + .option( + "--repository-code ", + "Repository code to index", + process.env.REPOSITORY_CODE + ) + .option( + "--organization ", + "Organization name filter", + process.env.ORGANIZATION + ) + .option("--id ", "Specific ID to index", process.env.ID) + .option("-o, --output ", "Output directory for response logs") + .option("--force", "Skip confirmation prompts") + .option("--debug", "Enable detailed debug logging") + .action(() => { + /* Handled by main.ts */ + }); + + // Song publish analysis command + program + .command("songPublishAnalysis") + .description("Publish analysis in SONG server") + .option("-a, --analysis-id ", "Analysis ID to publish") + .option("-i, --study-id ", "Study ID", process.env.STUDY_ID || "demo") + .option( + "-u, --song-url ", + "SONG server URL", + process.env.SONG_URL || "http://localhost:8080" + ) + .option( + "-t, --auth-token ", + "Authentication token", + process.env.AUTH_TOKEN || "123" + ) + .option( + "--ignore-undefined-md5", + "Ignore files with undefined MD5 checksums", + false + ) + .action(() => { + /* Handled by main.ts */ + }); + + // Combined SONG/SCORE submission command + program + .command("songScoreSubmit") + .description( + "End-to-end workflow: Submit analysis to SONG, upload to SCORE, and publish" + ) + .option( + "-p, --analysis-path ", + "Path to analysis JSON file", + process.env.ANALYSIS_PATH || "./analysis.json" + ) + .option("-i, --study-id ", "Study ID", process.env.STUDY_ID || "demo") + .option( + "-u, --song-url ", + "SONG server URL", + process.env.SONG_URL || "http://localhost:8080" + ) + .option( + "-s, --score-url ", + "Score server URL", + process.env.SCORE_URL || "http://localhost:8087" + ) + .option( + "-d, --data-dir ", + "Directory containing data files", + process.env.DATA_DIR || "./data/fileData" + ) + .option( + "-o, --output-dir ", + "Directory for manifest file output", + process.env.OUTPUT_DIR || "./output" + ) + .option( + "-m, --manifest-file ", + "Path for manifest file", + process.env.MANIFEST_FILE + ) + .option( + "-t, --auth-token ", + "Authentication token", + process.env.AUTH_TOKEN || "123" + ) + .option( + "--ignore-undefined-md5", + "Ignore files with undefined MD5 checksums", + false + ) + .action(() => { + /* Handled by main.ts */ + }); +} +/** + * Parses command-line arguments into a standardized CLIOutput object + * + * @param options - Parsed command-line options + * @returns A CLIOutput object for command execution + */ +export function parseCommandLineArgs(options: any): CLIOutput { + // Log raw options for debugging + Logger.debug(`Raw options: ${JSON.stringify(options)}`); + Logger.debug(`Process argv: ${process.argv.join(" ")}`); + + // Determine the profile from options + let profile = options.profile || Profiles.UPLOAD; + + // Special handling for lyricData command to ensure data directory is captured + if (profile === Profiles.LYRIC_DATA) { + // Check for a positional argument that might be the data directory + const positionalArgs = process.argv + .slice(3) + .filter((arg) => !arg.startsWith("-")); + + if (positionalArgs.length > 0 && !options.dataDirectory) { + options.dataDirectory = positionalArgs[0]; + Logger.debug( + `Captured data directory from positional argument: ${options.dataDirectory}` + ); + } + } + + // Parse file paths + const filePaths = Array.isArray(options.file) + ? options.file + : options.file + ? [options.file] + : []; + + // Add template file to filePaths if present + if (options.templateFile && !filePaths.includes(options.templateFile)) { + filePaths.push(options.templateFile); + } + + // Add schema file to filePaths if present for Lectern or SONG upload + if (options.schemaFile && !filePaths.includes(options.schemaFile)) { + filePaths.push(options.schemaFile); + } + + // Add analysis file to filePaths if present for SONG analysis submission + if (options.analysisFile && !filePaths.includes(options.analysisFile)) { + filePaths.push(options.analysisFile); + } + + // Add analysis path to filePaths if present for songScoreSubmit command + if (options.analysisPath && !filePaths.includes(options.analysisPath)) { + filePaths.push(options.analysisPath); + } + + Logger.debug(`Parsed profile: ${profile}`); + Logger.debug(`Parsed file paths: ${filePaths.join(", ")}`); + + // Create config object with support for all services + const config = { + elasticsearch: { + url: + options.url || process.env.ELASTICSEARCH_URL || "http://localhost:9200", + user: options.user || process.env.ELASTICSEARCH_USER, + password: options.password || process.env.ELASTICSEARCH_PASSWORD, + index: options.index || options.indexName || "conductor-data", + templateFile: options.templateFile, + templateName: options.templateName, + alias: options.aliasName, + }, + lectern: { + url: + options.lecternUrl || + process.env.LECTERN_URL || + "http://localhost:3031", + authToken: options.authToken || process.env.LECTERN_AUTH_TOKEN || "", + }, + lyric: { + url: options.lyricUrl || process.env.LYRIC_URL || "http://localhost:3030", + categoryName: options.categoryName || process.env.CATEGORY_NAME, + dictionaryName: options.dictName || process.env.DICTIONARY_NAME, + dictionaryVersion: + options.dictionaryVersion || process.env.DICTIONARY_VERSION, + defaultCentricEntity: + options.defaultCentricEntity || process.env.DEFAULT_CENTRIC_ENTITY, + // Data loading specific options + dataDirectory: options.dataDirectory || process.env.LYRIC_DATA, + categoryId: options.categoryId || process.env.CATEGORY_ID, + organization: options.organization || process.env.ORGANIZATION, + maxRetries: options.maxRetries + ? parseInt(options.maxRetries) + : process.env.MAX_RETRIES + ? parseInt(process.env.MAX_RETRIES) + : 10, + retryDelay: options.retryDelay + ? parseInt(options.retryDelay) + : process.env.RETRY_DELAY + ? parseInt(process.env.RETRY_DELAY) + : 20000, + }, + song: { + url: options.songUrl || process.env.SONG_URL || "http://localhost:8080", + authToken: options.authToken || process.env.AUTH_TOKEN || "123", + schemaFile: options.schemaFile || process.env.SONG_SCHEMA, + studyId: options.studyId || process.env.STUDY_ID || "demo", + studyName: options.studyName || process.env.STUDY_NAME || "string", + organization: + options.organization || process.env.ORGANIZATION || "string", + description: options.description || process.env.DESCRIPTION || "string", + analysisFile: options.analysisFile || process.env.ANALYSIS_FILE, + analysisPath: options.analysisPath || process.env.ANALYSIS_PATH, + allowDuplicates: + options.allowDuplicates || + process.env.ALLOW_DUPLICATES === "true" || + false, + ignoreUndefinedMd5: + options.ignoreUndefinedMd5 || + process.env.IGNORE_UNDEFINED_MD5 === "true" || + false, + }, + score: { + url: options.scoreUrl || process.env.SCORE_URL || "http://localhost:8087", + authToken: options.authToken || process.env.AUTH_TOKEN || "123", + analysisId: options.analysisId || process.env.ANALYSIS_ID, + dataDir: options.dataDir || process.env.DATA_DIR || "./data", + outputDir: options.outputDir || process.env.OUTPUT_DIR || "./output", + manifestFile: options.manifestFile || process.env.MANIFEST_FILE, + }, + batchSize: options.batchSize ? parseInt(options.batchSize, 10) : 1000, + delimiter: options.delimiter || ",", + }; + + // Build the standardized CLI output + return { + profile, + filePaths, + outputPath: options.output, + config, + options, + envConfig: { + elasticsearchUrl: config.elasticsearch.url, + esUser: config.elasticsearch.user, + esPassword: config.elasticsearch.password, + indexName: config.elasticsearch.index, + lecternUrl: config.lectern.url, + lyricUrl: config.lyric.url, + songUrl: config.song.url, + scoreUrl: config.score.url, + }, + }; +} diff --git a/apps/conductor/src/cli/profiles.ts b/apps/conductor/src/cli/profiles.ts new file mode 100644 index 00000000..876d4bda --- /dev/null +++ b/apps/conductor/src/cli/profiles.ts @@ -0,0 +1,37 @@ +import { Profile, EnvConfig, Profiles } from "../types"; +import { ConductorError, ErrorCodes } from "../utils/errors"; +import { Logger } from "../utils/logger"; + +export const PROFILE_DESCRIPTIONS = new Map([ + [Profiles.UPLOAD, "Upload CSV files to Elasticsearch"], + [Profiles.INDEX_MANAGEMENT, "Set up Elasticsearch indices and templates"], +]); + +// Get all valid profiles +const VALID_PROFILES = Object.values(Profiles); + +export function validateProfile(profile: Profile): Profile { + Logger.debug`Validating profile: ${profile}`; + + if (!VALID_PROFILES.includes(profile)) { + throw new ConductorError( + `Invalid profile: ${profile}. Valid profiles are: ${VALID_PROFILES.join( + ", " + )}`, + ErrorCodes.INVALID_ARGS + ); + } + + Logger.debug`Profile validated: ${profile}`; + return profile; +} + +export function getDefaultOutputPath( + profile: Profile, + envConfig: EnvConfig +): string | undefined { + Logger.debug`Getting default output path for profile: ${profile}`; + + // You can add specific output path logic here if needed + return undefined; +} diff --git a/apps/conductor/src/cli/validation.ts b/apps/conductor/src/cli/validation.ts new file mode 100644 index 00000000..76496f1c --- /dev/null +++ b/apps/conductor/src/cli/validation.ts @@ -0,0 +1,104 @@ +/** + * CLI Validation Module + * + * Validates CLI options and arguments before processing. + */ + +import { createValidationError } from "../utils/errors"; +import { Logger } from "../utils/logger"; +import { CLIprofile } from "./index"; + +/** + * Validates that required CLI options are provided and have valid values + * @param options The CLI options to validate + * @param profile The command profile being executed + */ +export function validateCliOptions( + options: any, + profile: CLIprofile = "upload" +): void { + Logger.debug("CLI Options Validation"); + + // Validate based on command profile + switch (profile) { + case "upload": + validateUploadOptions(options); + break; + case "indexManagement": + validateindexManagementOptions(options); + break; + default: + // By default, use upload validation for backward compatibility + validateUploadOptions(options); + } + + // Log all validated options + Logger.debug`All CLI options are valid`; + Logger.debugObject("Validated CLI options", options); +} + +/** + * Validates options specific to the upload command + */ +function validateUploadOptions(options: any): void { + // Validate that files are provided + if (!options.files || options.files.length === 0) { + throw createValidationError( + "No input files specified. Use the --files option to specify input files.", + { parameter: "files", expected: "at least one file path" } + ); + } + + // Log the number of files + Logger.debug`Input files specified: ${options.files.length} file(s)`; + + // List all input files + if (options.files.length > 0) { + Logger.debug("Input files", options.files); + } + + // Validate batch size if provided + if (options.batchSize) { + const batchSize = parseInt(options.batchSize, 10); + if (isNaN(batchSize) || batchSize <= 0) { + throw createValidationError("Batch size must be a positive number", { + parameter: "batchSize", + provided: options.batchSize, + expected: "positive number", + }); + } + Logger.info`Batch size is valid: ${batchSize}`; + } + + // Validate delimiter if provided + if (options.delimiter && options.delimiter.length !== 1) { + throw createValidationError("Delimiter must be a single character", { + parameter: "delimiter", + provided: options.delimiter, + expected: "single character", + }); + } +} + +/** + * Validates options specific to the indexManagement command + */ +function validateindexManagementOptions(options: any): void { + // No template file validation here - we'll check existence in the command + // Just log the options for debugging purposes + if (options.templateFile) { + Logger.debug`Template file specified: ${options.templateFile}`; + } + + if (options.templateName) { + Logger.debug`Template name specified: ${options.templateName}`; + } + + if (options.indexName) { + Logger.debug`Index name specified: ${options.indexName}`; + } + + if (options.aliasName) { + Logger.debug`Alias name specified: ${options.aliasName}`; + } +} diff --git a/apps/conductor/src/commands/baseCommand.ts b/apps/conductor/src/commands/baseCommand.ts new file mode 100644 index 00000000..e739afc2 --- /dev/null +++ b/apps/conductor/src/commands/baseCommand.ts @@ -0,0 +1,335 @@ +/** + * Command Module + * + * Provides the base abstract class and interfaces for all command implementations. + * Commands follow the Command Pattern for encapsulating operations. + */ + +import { CLIOutput } from "../types/cli"; +import * as fs from "fs"; +import * as path from "path"; +import * as readline from "readline"; +import { Logger } from "../utils/logger"; +import { ConductorError, ErrorCodes } from "../utils/errors"; + +/** + * Command execution result + */ +export interface CommandResult { + /** Whether the command succeeded */ + success: boolean; + + /** Optional error message if the command failed */ + errorMessage?: string; + + /** Optional error code if the command failed */ + errorCode?: string; + + /** Additional result details */ + details?: Record; +} + +/** + * Abstract base class for all CLI commands in the conductor service. + * Provides common functionality for command execution, validation, and file handling. + */ +export abstract class Command { + /** Default directory where output files will be stored if not specified by user */ + protected defaultOutputPath: string; + + /** Default filename for output files */ + protected defaultOutputFileName: string = "output.json"; + + /** + * Creates a new Command instance. + * + * @param name - Name of the command for logging and identification + * @param defaultOutputPath - Optional custom default output directory + */ + constructor(protected name: string, defaultOutputPath?: string) { + this.defaultOutputPath = defaultOutputPath || "configs"; + } + + /** + * Main method to run the command with the provided CLI arguments. + * Handles validation, output path resolution, and error handling. + * + * @param cliOutput - The parsed command line arguments + * @returns A promise that resolves to a CommandResult object + */ + async run(cliOutput: CLIOutput): Promise { + const startTime = Date.now(); + + try { + // Enable debug logging if requested + if (cliOutput.debug) { + Logger.enableDebug(); + Logger.debug(`Running ${this.name} command with debug enabled`); + } + + // Validate input arguments - directly throws errors + try { + await this.validate(cliOutput); + } catch (validationError) { + Logger.debug(`Validation error: ${validationError}`); + if (validationError instanceof Error) { + throw validationError; + } + throw new ConductorError( + String(validationError), + ErrorCodes.VALIDATION_FAILED + ); + } + + Logger.debug(`Output path before check: ${cliOutput.outputPath}`); + + let usingDefaultPath = false; + + // If no output path specified, use the default + if (!cliOutput.outputPath?.trim()) { + Logger.debug("No output directory specified."); + usingDefaultPath = true; + cliOutput.outputPath = path.join(this.defaultOutputPath); + } + + const isDefaultPath = this.isUsingDefaultPath(cliOutput); + + // Inform user about output path + if (isDefaultPath || usingDefaultPath) { + Logger.info( + `Using default output path: ${cliOutput.outputPath}`, + "Use -o or --output to specify a different location" + ); + } else { + Logger.info(`Output directory set to: ${cliOutput.outputPath}`); + } + + // Check for existing files and confirm overwrite if needed + // Skip confirmation if force flag is set in options + const forceFlag = cliOutput.options?.force === true; + if (cliOutput.outputPath && !forceFlag) { + const shouldContinue = await this.checkForExistingFiles( + cliOutput.outputPath + ); + if (!shouldContinue) { + Logger.info("Operation cancelled by user."); + return { + success: false, + errorMessage: "Operation cancelled by user", + errorCode: "USER_CANCELLED", + }; + } + } else if (forceFlag) { + Logger.debug("Force flag enabled, skipping overwrite confirmation"); + } + + Logger.info(`Starting execution of ${this.name} command`); + + // Execute the specific command implementation + const result = await this.execute(cliOutput); + + // Calculate and log execution time + const endTime = Date.now(); + const executionTime = (endTime - startTime) / 1000; + + if (result.success) { + Logger.info( + `${ + this.name + } command completed successfully in ${executionTime.toFixed(2)}s` + ); + } else { + Logger.debug( + `${this.name} command failed after ${executionTime.toFixed(2)}s: ${ + result.errorMessage + }` + ); + } + + return result; + } catch (error: unknown) { + // Use Logger instead of console.error + Logger.debug(`ERROR IN ${this.name} COMMAND:`, error); + + const errorMessage = + error instanceof Error ? error.message : String(error); + Logger.debug(`Unexpected error in ${this.name} command: ${errorMessage}`); + + return { + success: false, + errorMessage, + errorCode: + error instanceof ConductorError + ? error.code + : ErrorCodes.UNKNOWN_ERROR, + details: { + error, + stack: error instanceof Error ? error.stack : undefined, + }, + }; + } + } + + /** + * Abstract method that must be implemented by derived classes. + * Contains the specific logic for each command. + * + * @param cliOutput - The parsed command line arguments + * @returns A promise that resolves to a CommandResult + */ + protected abstract execute(cliOutput: CLIOutput): Promise; + + /** + * Validates command line arguments. + * This base implementation checks for required input files. + * Derived classes should override to add additional validation. + * + * @param cliOutput - The parsed command line arguments + * @throws ConductorError if validation fails + */ + protected async validate(cliOutput: CLIOutput): Promise { + if (!cliOutput.filePaths?.length) { + throw new ConductorError( + "No input files provided", + ErrorCodes.INVALID_ARGS + ); + } + + // Validate each input file exists + for (const filePath of cliOutput.filePaths) { + if (!fs.existsSync(filePath)) { + throw new ConductorError( + `Input file not found: ${filePath}`, + ErrorCodes.FILE_NOT_FOUND + ); + } + + // Check if file is readable + try { + fs.accessSync(filePath, fs.constants.R_OK); + } catch (error) { + throw new ConductorError( + `File '${filePath}' is not readable`, + ErrorCodes.INVALID_FILE, + error + ); + } + + // Check if file has content + const stats = fs.statSync(filePath); + if (stats.size === 0) { + throw new ConductorError( + `File '${filePath}' is empty`, + ErrorCodes.INVALID_FILE + ); + } + } + } + + /** + * Checks if the current output path is the default one. + * + * @param cliOutput - The parsed command line arguments + * @returns true if using the default output path, false otherwise + */ + protected isUsingDefaultPath(cliOutput: CLIOutput): boolean { + return ( + cliOutput.outputPath === this.defaultOutputPath || + cliOutput.outputPath === + path.join(this.defaultOutputPath, this.defaultOutputFileName) + ); + } + + /** + * Creates a directory if it doesn't already exist. + * + * @param dirPath - Path to the directory to create + */ + protected createDirectoryIfNotExists(dirPath: string): void { + if (!fs.existsSync(dirPath)) { + fs.mkdirSync(dirPath, { recursive: true }); + Logger.info(`Created directory: ${dirPath}`); + } + } + + /** + * Checks if files in the output directory would be overwritten. + * Prompts the user for confirmation if files would be overwritten. + * + * @param outputPath - Path where output files will be written + * @returns A promise that resolves to true if execution should continue, false otherwise + */ + protected async checkForExistingFiles(outputPath: string): Promise { + let directoryPath = outputPath; + let outputFileName: string | undefined; + + // Determine if outputPath is a file or directory + if (path.extname(outputPath)) { + Logger.debug(`Output path appears to be a file: ${outputPath}`); + directoryPath = path.dirname(outputPath); + outputFileName = path.basename(outputPath); + Logger.debug( + `Using directory: ${directoryPath}, fileName: ${outputFileName}` + ); + } + + // Create the output directory if it doesn't exist + this.createDirectoryIfNotExists(directoryPath); + + // Get existing entries in the directory + const existingEntries = fs.existsSync(directoryPath) + ? fs.readdirSync(directoryPath) + : []; + + // Filter existing files that would be overwritten + const filesToOverwrite = existingEntries.filter((entry) => { + const fullPath = path.join(directoryPath, entry); + + // If specific file name is given, only check that exact file + if (outputFileName) { + return entry === outputFileName && fs.statSync(fullPath).isFile(); + } + + // If no specific file name, check if entry is a file and would match generated output + return ( + fs.statSync(fullPath).isFile() && + (entry.endsWith(".json") || + entry.startsWith(this.defaultOutputFileName.split(".")[0])) + ); + }); + + // If no files would be overwritten, continue without prompting + if (filesToOverwrite.length === 0) { + return true; + } + + // Display list of files that would be overwritten + Logger.info( + "The following file(s) in the output directory will be overwritten:" + ); + filesToOverwrite.forEach((file) => Logger.info(`- ${file}`)); + + // Create readline interface for user input + const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, + }); + + // Prompt user for confirmation + return new Promise((resolve) => { + rl.question("Do you wish to continue? [y/n]: ", (answer) => { + rl.close(); + resolve(answer.toLowerCase() === "y"); + }); + }); + } + + /** + * Logs information about a generated file. + * + * @param filePath - Path to the generated file + */ + protected logGeneratedFile(filePath: string): void { + Logger.info(`Generated file: ${filePath}`); + } +} diff --git a/apps/conductor/src/commands/commandFactory.ts b/apps/conductor/src/commands/commandFactory.ts new file mode 100644 index 00000000..cbc3040a --- /dev/null +++ b/apps/conductor/src/commands/commandFactory.ts @@ -0,0 +1,162 @@ +/** + * Command Factory Module + * + * This module implements the Factory Pattern to create command instances based on the provided profile. + * It serves as the central registry for all available commands in the Conductor service and + * decouples command selection from command execution. + * + * The factory pattern allows for: + * 1. Dynamic command creation based on runtime configuration + * 2. Centralized command registration + * 3. Easy addition of new commands without modifying existing code (Open/Closed Principle) + * 4. Validation of profiles and helpful error messages + * + * Related files: + * - baseCommand.ts: Defines the abstract Command class and interface + * - types/cli.ts: Contains CLI argument interfaces and type definitions + * - types/constants.ts: Defines available profiles as constants + * - Individual command implementations (uploadCommand.ts, indexManagementCommand.ts, etc.) + */ + +import type { Profile } from "../types"; +import { Profiles } from "../types/constants"; +import { Command } from "./baseCommand"; +import { ConductorError, ErrorCodes, handleError } from "../utils/errors"; +import { Logger } from "../utils/logger"; + +// Import individual commands +import { UploadCommand } from "./uploadCsvCommand"; +import { IndexManagementCommand } from "./indexManagementCommand"; +import { LecternUploadCommand } from "./lecternUploadCommand"; +import { LyricRegistrationCommand } from "./lyricRegistrationCommand"; +import { LyricUploadCommand } from "./lyricUploadCommand"; +import { SongUploadSchemaCommand } from "./songUploadSchemaCommand"; +import { SongCreateStudyCommand } from "./songCreateStudyCommand"; +import { SongSubmitAnalysisCommand } from "./songSubmitAnalysisCommand"; +import { ScoreManifestUploadCommand } from "./scoreManifestUploadCommand"; +import { SongPublishAnalysisCommand } from "./songPublishAnalysisCommand"; +import { SongScoreSubmitCommand } from "./songScoreSubmitCommand"; +import { MaestroIndexCommand } from "./maestroIndexCommand"; + +/** + * Type definition for command class constructors. + * This type allows for both command classes that implement the Command interface + * and those that extend the abstract Command class. + */ +type CommandConstructor = new () => + | Command + | { run(cliOutput: any): Promise }; + +/** + * Maps each profile to its corresponding command constructor. + * Used for type-checking the PROFILE_TO_COMMAND mapping. + */ +type CommandMap = { + [K in Profile]: CommandConstructor; +}; + +/** + * Maps profile identifiers to user-friendly display names. + * Used for logging and error messages to improve user experience. + */ +const PROFILE_DISPLAY_NAMES: Record = { + [Profiles.UPLOAD]: "CSV Upload", + [Profiles.INDEX_MANAGEMENT]: "Elasticsearch Indices Management", + [Profiles.LECTERN_UPLOAD]: "Lectern Schema Upload", + [Profiles.LYRIC_REGISTER]: "Lyric Dictionary Registration", + [Profiles.LYRIC_DATA]: "Lyric Data Loading", + [Profiles.song_upload_schema]: "SONG Schema Upload", + [Profiles.song_create_study]: "SONG Study Creation", + [Profiles.song_submit_analysis]: "SONG Analysis Submission", + [Profiles.score_manifest_upload]: "Score Manifest Upload", + [Profiles.song_publish_analysis]: "SONG Analysis Publication", + [Profiles.song_score_submit]: "SONG/SCORE End-to-End Workflow", +}; + +/** + * Maps profile identifiers to their corresponding command classes. + * This is the core registry of available commands in the system. + * + * When adding a new command: + * 1. Create the command class extending the base Command class + * 2. Import it at the top of this file + * 3. Add the profile to the Profiles enum in types/constants.ts + * 4. Add an entry to this mapping + * 5. Add a display name to PROFILE_DISPLAY_NAMES + */ +const PROFILE_TO_COMMAND: Partial = { + [Profiles.UPLOAD]: UploadCommand, + [Profiles.INDEX_MANAGEMENT]: IndexManagementCommand, + [Profiles.LECTERN_UPLOAD]: LecternUploadCommand, + [Profiles.LYRIC_REGISTER]: LyricRegistrationCommand, + [Profiles.LYRIC_DATA]: LyricUploadCommand, + [Profiles.INDEX_REPOSITORY]: MaestroIndexCommand, + [Profiles.song_upload_schema]: SongUploadSchemaCommand, + [Profiles.song_create_study]: SongCreateStudyCommand, + [Profiles.song_submit_analysis]: SongSubmitAnalysisCommand, + [Profiles.score_manifest_upload]: ScoreManifestUploadCommand, + [Profiles.song_publish_analysis]: SongPublishAnalysisCommand, + [Profiles.song_score_submit]: SongScoreSubmitCommand, +} as const; + +/** + * Factory class responsible for creating command instances based on the requested profile. + * + * The factory pattern encapsulates the logic of selecting and instantiating the appropriate + * command, providing a clean interface for the CLI entry point. + */ +export class CommandFactory { + /** + * Creates a command instance based on the specified profile. + * + * @param profile - The profile identifier from the CLI arguments + * @returns An instance of the appropriate Command implementation + * @throws ConductorError if the profile is not supported + * + * Usage: + * ``` + * const command = CommandFactory.createCommand(cliOutput.profile); + * await command.run(cliOutput); + * ``` + */ + static createCommand( + profile: Profile + ): Command | { run(cliOutput: any): Promise } { + Logger.debug(`Creating command for profile: ${profile}`); + const CommandClass = PROFILE_TO_COMMAND[profile]; + + if (!CommandClass) { + const error = new ConductorError( + `Unsupported profile: ${profile}`, + ErrorCodes.INVALID_ARGS + ); + + // Handle the error by showing available profiles and example commands + handleError(error, () => { + // Use the section method for better organization in the console output + Logger.section("Available Profiles"); + + // List all available profiles with their user-friendly display names + Object.entries(PROFILE_TO_COMMAND).forEach(([profileName]) => { + const displayName = PROFILE_DISPLAY_NAMES[profileName] || profileName; + Logger.commandInfo(profileName, displayName); + }); + + // Show reference commands with improved formatting for user guidance + Logger.header(`Example Commands`); + Logger.showReferenceCommands(); + }); + + // This will never be reached if handleError works as expected, + // but we add it for type safety + throw error; + } + + // Instantiate the command and return it + const command = new CommandClass(); + const displayName = PROFILE_DISPLAY_NAMES[profile] || profile; + + Logger.debug(`Created ${displayName} command instance`); + return command; + } +} diff --git a/apps/conductor/src/commands/indexManagementCommand.ts b/apps/conductor/src/commands/indexManagementCommand.ts new file mode 100644 index 00000000..13328d2f --- /dev/null +++ b/apps/conductor/src/commands/indexManagementCommand.ts @@ -0,0 +1,337 @@ +/** + * Index Management Command + * + * Command implementation for managing Elasticsearch indices and templates. + * Handles creation and configuration of templates, indices, and aliases. + */ + +import * as fs from "fs"; +import { Command, CommandResult } from "./baseCommand"; +import { CLIOutput } from "../types/cli"; +import { Logger } from "../utils/logger"; +import { ConductorError, ErrorCodes } from "../utils/errors"; +import { + createClientFromConfig, + validateConnection, + indexExists, + createIndex, +} from "../services/elasticsearch"; +import { + templateExists, + createTemplate, + extractTemplateInfo, + TemplateInfo, +} from "../services/elasticsearch/templates"; +import * as path from "path"; + +export class IndexManagementCommand extends Command { + constructor() { + super("indexManagement"); + this.defaultOutputFileName = "elasticsearch-setup.json"; + } + + /** + * Validates command line arguments and configuration + * @param cliOutput The CLI configuration and inputs + * @throws ConductorError if validation fails + */ + protected async validate(cliOutput: CLIOutput): Promise { + const { config, options } = cliOutput; + + // Extract and validate template file + const templateFile = + options.templateFile || config.elasticsearch?.templateFile; + + if (!templateFile) { + throw new ConductorError( + "Template file not specified. Use --template-file or configure in settings.", + ErrorCodes.INVALID_ARGS + ); + } + + // Resolve to absolute path and validate file existence + const resolvedTemplatePath = path.resolve(process.cwd(), templateFile); + + if (!fs.existsSync(resolvedTemplatePath)) { + throw new ConductorError( + `Template file not found at ${resolvedTemplatePath}`, + ErrorCodes.FILE_NOT_FOUND + ); + } + + // Validate template file can be parsed + try { + const rawContent = fs.readFileSync(resolvedTemplatePath, "utf-8"); + JSON.parse(rawContent); + } catch (error) { + throw new ConductorError( + `Failed to parse template file: ${ + error instanceof Error ? error.message : String(error) + }`, + ErrorCodes.INVALID_FILE, + error + ); + } + + // Validate Elasticsearch connection configuration + const elasticsearchUrl = + config.elasticsearch?.url || process.env.ELASTICSEARCH_URL; + + if (!elasticsearchUrl) { + throw new ConductorError( + "Elasticsearch URL not specified. Use --url or set ELASTICSEARCH_URL environment variable.", + ErrorCodes.INVALID_ARGS + ); + } + + // Validate username and password + const username = + config.elasticsearch?.user || process.env.ELASTICSEARCH_USER; + + const password = + config.elasticsearch?.password || process.env.ELASTICSEARCH_PASSWORD; + + if (!username || !password) { + throw new ConductorError( + "Elasticsearch username or password not specified.", + ErrorCodes.INVALID_ARGS + ); + } + + // Optional additional validations + const templateName = + options.templateName || config.elasticsearch?.templateName; + + const indexName = options.indexName || config.elasticsearch?.index; + + const aliasName = options.aliasName || config.elasticsearch?.alias; + + // While these are optional, we can add some basic validation + if (templateName && typeof templateName !== "string") { + throw new ConductorError( + "Invalid template name format.", + ErrorCodes.INVALID_ARGS + ); + } + + if (indexName && typeof indexName !== "string") { + throw new ConductorError( + "Invalid index name format.", + ErrorCodes.INVALID_ARGS + ); + } + + if (aliasName && typeof aliasName !== "string") { + throw new ConductorError( + "Invalid alias name format.", + ErrorCodes.INVALID_ARGS + ); + } + } + + /** + * Executes the index management process + * @param cliOutput The CLI configuration and inputs + * @returns A CommandResult indicating success or failure + */ + protected async execute(cliOutput: CLIOutput): Promise { + const { config, options } = cliOutput; + + try { + // Extract template file path + const templateFile = + options.templateFile || config.elasticsearch?.templateFile; + + // Load template content + const rawContent = fs.readFileSync(templateFile, "utf-8"); + const templateContent = JSON.parse(rawContent); + + // Extract information from template + const templateInfo = extractTemplateInfo(templateContent); + + // Set template name, index name, and alias with smart defaults + const templateName = + options.templateName || + config.elasticsearch?.templateName || + `template-${Date.now()}`; + + // Use index name from CLI/config or extract from template, or generate default + const indexName = + options.indexName || + config.elasticsearch?.index || + templateInfo.defaultIndexName || + `index-${Date.now()}`; + + // Use alias from CLI/config or extract from template, or use indexName with suffix + const aliasName = + options.aliasName || + config.elasticsearch?.alias || + templateInfo.defaultAliasName || + `${indexName}-alias`; + + // Log names + if (!options.templateName && !config.elasticsearch?.templateName) { + Logger.info( + `No template name provided. Using generated name: ${templateName}` + ); + } + + if ( + !options.indexName && + !config.elasticsearch?.index && + templateInfo.defaultIndexName + ) { + Logger.info(`Using index name from template pattern: ${indexName}`); + } else if (!options.indexName && !config.elasticsearch?.index) { + Logger.info( + `No index name provided. Using generated name: ${indexName}` + ); + } + + if (templateInfo.defaultAliasName) { + Logger.info(`Using alias from template: ${aliasName}`); + } + + // Create Elasticsearch client + const client = createClientFromConfig(config); + + // Validate Elasticsearch connection + Logger.info(`Validating Elasticsearch connection...`); + try { + await validateConnection(client); + Logger.info( + `Connected to Elasticsearch at ${config.elasticsearch.url}` + ); + } catch (error) { + const errorMessage = + error instanceof Error ? error.message : String(error); + + // Log more detailed connection failure information + Logger.error(`Failed to connect to Elasticsearch: ${errorMessage}`); + + // Provide more specific guidance based on the error + if (errorMessage.includes("ECONNREFUSED")) { + Logger.error("Connection refused. Is Elasticsearch running?"); + } else if (errorMessage.includes("authentication")) { + Logger.error( + "Authentication failed. Check your username and password." + ); + } + + throw new ConductorError( + `Elasticsearch connection failed: ${errorMessage}`, + ErrorCodes.CONNECTION_ERROR, + error + ); + } + + // Step 1: Check if template exists + Logger.info(`Checking if template ${templateName} exists...`); + const isTemplateExists = await templateExists(client, templateName); + + // Step 2: Create template if it doesn't exist + if (!isTemplateExists) { + Logger.info(`Template ${templateName} does not exist, creating...`); + try { + await createTemplate(client, templateName, templateContent); + Logger.info( + `Elasticsearch ${templateName} template created successfully` + ); + } catch (error) { + const errorMessage = + error instanceof Error ? error.message : String(error); + Logger.error( + `Failed to create template ${templateName}: ${errorMessage}` + ); + throw new ConductorError( + `Failed to create template ${templateName}`, + ErrorCodes.ES_ERROR, + error + ); + } + } else { + Logger.info( + `Template ${templateName} already exists, skipping creation.` + ); + } + + // Step 3: Check if index exists + Logger.info(`Checking if index ${indexName} exists...`); + const isIndexExists = await indexExists(client, indexName); + + // Step 4: Create index with alias if it doesn't exist + if (!isIndexExists) { + Logger.info( + `Index ${indexName} does not exist, creating with alias ${aliasName}...` + ); + try { + // Create index with the alias, using settings from template if available + const indexSettings: Record = { + aliases: { + [aliasName]: {}, + }, + }; + + // Apply settings from template explicitly if available + if (templateInfo.numberOfShards || templateInfo.numberOfReplicas) { + indexSettings.settings = { + number_of_shards: templateInfo.numberOfShards, + number_of_replicas: templateInfo.numberOfReplicas, + }; + } + + await createIndex(client, indexName, indexSettings); + Logger.info(`Created index: ${indexName}`); + Logger.info( + `Index ${indexName} with alias ${aliasName} created successfully.` + ); + } catch (error) { + const errorMessage = + error instanceof Error ? error.message : String(error); + Logger.error( + `Failed to create index ${indexName}. Error: ${errorMessage}` + ); + throw new ConductorError( + `Failed to create index ${indexName} with alias ${aliasName}`, + ErrorCodes.ES_ERROR, + error + ); + } + } else { + Logger.info(`Index ${indexName} already exists, skipping creation.`); + } + + Logger.info(`Elasticsearch setup completed successfully.`); + + // Return successful result + return { + success: true, + details: { + templateName, + indexName, + aliasName, + templateInfo: { + defaultIndexNameFromPattern: templateInfo.defaultIndexName, + defaultAliasFromTemplate: templateInfo.defaultAliasName, + shards: templateInfo.numberOfShards, + replicas: templateInfo.numberOfReplicas, + }, + }, + }; + } catch (error) { + // Handle errors and return failure result + const errorMessage = + error instanceof Error ? error.message : String(error); + const errorCode = + error instanceof ConductorError + ? error.code + : ErrorCodes.CONNECTION_ERROR; + + return { + success: false, + errorMessage, + errorCode, + }; + } + } +} diff --git a/apps/conductor/src/commands/lecternUploadCommand.ts b/apps/conductor/src/commands/lecternUploadCommand.ts new file mode 100644 index 00000000..55c55d77 --- /dev/null +++ b/apps/conductor/src/commands/lecternUploadCommand.ts @@ -0,0 +1,225 @@ +import * as fs from "fs"; +import axios from "axios"; +import { Command, CommandResult } from "./baseCommand"; +import { CLIOutput } from "../types/cli"; +import { Logger } from "../utils/logger"; +import chalk from "chalk"; +import { ConductorError, ErrorCodes } from "../utils/errors"; +import { LecternService } from "../services/lectern/lecternService"; + +// Define an interface for the health check response +interface LecternHealthResponse { + appStatus?: string; + status?: string; + [key: string]: any; +} + +export class LecternUploadCommand extends Command { + private readonly MAX_RETRIES = 10; + private readonly RETRY_DELAY = 20000; // 20 seconds + private readonly TIMEOUT = 10000; // 10 seconds + + constructor() { + super("Lectern Schema Upload"); + } + + /** + * Override the base validate method since we don't require input files in filePaths + * but instead use the schema file directly. + */ + protected async validate(cliOutput: CLIOutput): Promise { + const { options } = cliOutput; + const schemaFile = options.schemaFile || process.env.LECTERN_SCHEMA; + + if (!schemaFile) { + throw new ConductorError( + "Schema file not specified. Use --schema-file or set LECTERN_SCHEMA environment variable.", + ErrorCodes.INVALID_ARGS + ); + } + + // Use debug logging for additional details + if (options.debug) { + Logger.debug(`Checking schema file existence at: ${schemaFile}`); + } + + if (!fs.existsSync(schemaFile)) { + throw new ConductorError( + `Schema file not found: ${schemaFile}`, + ErrorCodes.FILE_NOT_FOUND + ); + } + // We passed validation + console.log("Schema file validation successful"); + } + + /** + * Normalize URL for health check + * @param url Original URL + * @returns Base URL for health check + */ + private normalizeHealthCheckUrl(url: string): string { + // Remove /dictionary or /dictionaries if present + return url + .replace(/\/dictionaries?$/, "") + .replace(/\/dictionary$/, "") + .replace(/\/$/, ""); + } + + /** + * Checks Lectern service health + * @param url Lectern service URL + * @returns Promise resolving to boolean indicating health status + */ + private async checkLecternHealth(url: string): Promise { + const baseUrl = this.normalizeHealthCheckUrl(url); + const healthUrl = `${baseUrl}/health`; + + for (let attempt = 1; attempt <= this.MAX_RETRIES; attempt++) { + try { + Logger.info( + `Checking Lectern health (Attempt ${attempt}): ${healthUrl}` + ); + + const response = await axios.get(healthUrl, { + timeout: this.TIMEOUT, + headers: { accept: "*/*" }, + }); + + // Check for health status (multiple possible keys) + const isHealthy = + response.data?.appStatus === "Up" || + response.data?.status === "Up" || + response.data?.status === "Healthy"; + + if (isHealthy) { + Logger.info(`\x1b[32mSuccess:\x1b[0m Lectern is healthy`); + return true; + } + + Logger.warn( + `Lectern health check failed. Status: ${JSON.stringify( + response.data + )}` + ); + } catch (error) { + Logger.warn(`Lectern health check attempt ${attempt} failed`); + + if (attempt === this.MAX_RETRIES) { + Logger.error( + `\x1b[31mFailed to connect to Lectern after ${this.MAX_RETRIES} attempts\x1b[0m` + ); + return false; + } + } + + // Wait before next retry + await new Promise((resolve) => setTimeout(resolve, this.RETRY_DELAY)); + } + + return false; + } + + /** + * Executes the Lectern schema upload process + * @param cliOutput The CLI configuration and inputs + * @returns A CommandResult indicating success or failure + */ + protected async execute(cliOutput: CLIOutput): Promise { + const { options } = cliOutput; + + try { + // Extract configuration from options or environment + const schemaFile = options.schemaFile || process.env.LECTERN_SCHEMA; + const lecternUrl = options.lecternUrl || process.env.LECTERN_URL; + const authToken = + options.authToken || process.env.LECTERN_AUTH_TOKEN || "bearer123"; + + // Validate required parameters + if (!schemaFile) { + throw new ConductorError( + "Schema file not specified. Use --schema-file or set LECTERN_SCHEMA environment variable.", + ErrorCodes.INVALID_ARGS + ); + } + + if (!lecternUrl) { + throw new ConductorError( + "Lectern URL not specified. Use --lectern-url or set LECTERN_URL environment variable.", + ErrorCodes.INVALID_ARGS + ); + } + + // First, check Lectern service health + const isHealthy = await this.checkLecternHealth(lecternUrl); + if (!isHealthy) { + throw new ConductorError( + "Unable to establish connection with Lectern service", + ErrorCodes.CONNECTION_ERROR + ); + } + + // Validate schema file exists + if (!fs.existsSync(schemaFile)) { + Logger.error(`Schema file not found at ${schemaFile}`); + throw new ConductorError( + `Schema file not found at ${schemaFile}`, + ErrorCodes.FILE_NOT_FOUND + ); + } + + // Create Lectern service + const lecternService = new LecternService(lecternUrl, authToken); + + // Read schema file + Logger.info(`Reading schema file: ${schemaFile}`); + const schemaContent = fs.readFileSync(schemaFile, "utf-8"); + + // Validate JSON + try { + JSON.parse(schemaContent); + } catch (error) { + throw new ConductorError( + `Schema file contains invalid JSON: ${ + error instanceof Error ? error.message : String(error) + }`, + ErrorCodes.INVALID_FILE + ); + } + + // Upload schema + Logger.info(`Uploading schema to ${lecternService.getUrl()}`); + const result = await lecternService.uploadSchema(schemaContent); + + Logger.success(`Schema uploaded successfully`); + Logger.generic(" "); + Logger.generic(chalk.gray(` - Schema ID: ${result.id || "N/A"}`)); + Logger.generic( + chalk.gray(` - Schema Name: ${result.name || "Unnamed"}`) + ); + Logger.generic( + chalk.gray(` - Schema Version: ${result.version || "N/A"}`) + ); + Logger.generic(" "); + + return { + success: true, + details: result, + }; + } catch (error) { + // Handle errors and return failure result + const errorMessage = + error instanceof Error ? error.message : String(error); + const errorCode = + error instanceof ConductorError + ? error.code + : ErrorCodes.CONNECTION_ERROR; + + return { + success: false, + errorMessage, + errorCode, + }; + } + } +} diff --git a/apps/conductor/src/commands/lyricRegistrationCommand.ts b/apps/conductor/src/commands/lyricRegistrationCommand.ts new file mode 100644 index 00000000..a8918565 --- /dev/null +++ b/apps/conductor/src/commands/lyricRegistrationCommand.ts @@ -0,0 +1,501 @@ +import axios from "axios"; +import { Command, CommandResult } from "./baseCommand"; +import { CLIOutput } from "../types/cli"; +import { Logger } from "../utils/logger"; +import chalk from "chalk"; +import { ConductorError, ErrorCodes } from "../utils/errors"; +import { LyricService } from "../services/lyric/lyricService"; + +/** + * Interface for Lectern schema response + */ +interface LecternSchema { + name: string; + description?: string; + fields?: any[]; + meta?: any; +} + +/** + * Interface for Lectern dictionary response + */ +interface LecternDictionary { + _id: string; + name: string; + version: string; + schemas: LecternSchema[]; +} + +/** + * Command for registering a dictionary with the Lyric service + */ +export class LyricRegistrationCommand extends Command { + private readonly MAX_RETRIES = 1; + private readonly RETRY_DELAY = 5000; // 5 seconds + + constructor() { + super("Lyric Dictionary Registration"); + } + + /** + * Fetches dictionary schema from Lectern to validate centric entity + * @param lecternUrl Lectern server URL + * @param dictionaryName Dictionary name + * @param dictionaryVersion Dictionary version + * @returns Promise resolving to array of schema names + */ + private async fetchDictionarySchemas( + lecternUrl: string, + dictionaryName: string, + dictionaryVersion: string + ): Promise { + try { + // Normalize URL + const baseUrl = lecternUrl.endsWith("/") + ? lecternUrl.slice(0, -1) + : lecternUrl; + + // First, get all dictionaries to find the ID + Logger.debug(`Fetching dictionaries from ${baseUrl}/dictionaries`); + const dictionariesResponse = await axios.get(`${baseUrl}/dictionaries`); + + if ( + !dictionariesResponse.data || + !Array.isArray(dictionariesResponse.data) + ) { + throw new Error("Invalid response from Lectern"); + } + + // Find the specific dictionary by name and version + const dictionary = dictionariesResponse.data.find( + (dict: any) => + dict.name === dictionaryName && dict.version === dictionaryVersion + ); + + if (!dictionary || !dictionary._id) { + throw new Error( + `Dictionary '${dictionaryName}' version '${dictionaryVersion}' not found in Lectern` + ); + } + + const dictId = dictionary._id; + + // Now fetch the dictionary details with schemas + Logger.debug( + `Fetching dictionary schema from ${baseUrl}/dictionaries/${dictId}` + ); + const response = await axios.get(`${baseUrl}/dictionaries/${dictId}`); + + if (!response.data) { + throw new Error("Invalid dictionary schema response: empty data"); + } + + // Ensure we have a properly typed response with schemas + const dictionary_data = response.data as LecternDictionary; + + if (!dictionary_data.schemas || !Array.isArray(dictionary_data.schemas)) { + throw new Error( + "Invalid dictionary schema response: missing or invalid schemas array" + ); + } + + // Extract schema names + const schemaNames = dictionary_data.schemas.map((schema) => schema.name); + Logger.debug( + `Available schemas in dictionary: ${schemaNames.join(", ")}` + ); + + return schemaNames; + } catch (error) { + Logger.debug( + `Error fetching schema information: ${ + error instanceof Error ? error.message : String(error) + }` + ); + throw error; + } + } + + /** + * Executes the Lyric dictionary registration process + * @param cliOutput The CLI configuration and inputs + * @returns A CommandResult indicating success or failure + */ + protected async execute(cliOutput: CLIOutput): Promise { + const { options } = cliOutput; + + try { + // Extract configuration from options or environment + const lyricUrl = options.lyricUrl || process.env.LYRIC_URL; + const lecternUrl = + options.lecternUrl || + process.env.LECTERN_URL || + "http://localhost:3031"; + const categoryName = options.categoryName || process.env.CATEGORY_NAME; + const dictionaryName = options.dictName || process.env.DICTIONARY_NAME; + const dictionaryVersion = + options.dictionaryVersion || process.env.DICTIONARY_VERSION; + const defaultCentricEntity = + options.defaultCentricEntity || process.env.DEFAULT_CENTRIC_ENTITY; + + // Check if required parameters are provided + if (!lyricUrl || !categoryName || !dictionaryName || !dictionaryVersion) { + throw new ConductorError( + "Missing required parameters. Ensure all required parameters are provided.", + ErrorCodes.INVALID_ARGS + ); + } + + // Create Lyric service + const lyricService = new LyricService(lyricUrl); + + // Check Lyric service health + const isHealthy = await lyricService.checkHealth(); + if (!isHealthy) { + throw new ConductorError( + "Unable to establish connection with Lyric service", + ErrorCodes.CONNECTION_ERROR, + { + url: lyricUrl, + suggestion: + "Verify the Lyric service is running and accessible at the provided URL", + } + ); + } + + // Warn that centric entity is required by the API even though Swagger marks it as optional + if (!defaultCentricEntity) { + // Try to fetch entities to suggest valid options + try { + const entities = await this.fetchDictionarySchemas( + lecternUrl, + dictionaryName, + dictionaryVersion + ); + + if (entities.length > 0) { + throw new ConductorError( + "The Lyric API requires a defaultCentricEntity parameter.\n Use -e or --default-centric-entity to specify a valid entity from the dictionary.\n ", + ErrorCodes.INVALID_ARGS, + { + availableEntities: entities, + suggestion: `Available entities are: ${entities.join(", ")}`, + } + ); + } + } catch (error) { + // If we couldn't fetch schemas, use a simpler error + if (!(error instanceof ConductorError)) { + Logger.error( + `Could not fetch available entities: ${ + error instanceof Error ? error.message : String(error) + }` + ); + throw new ConductorError( + "The Lyric API requires a defaultCentricEntity parameter.", + ErrorCodes.INVALID_ARGS, + { + suggestion: `Use -e or --default-centric-entity to specify a valid entity from the dictionary`, + } + ); + } + throw error; + } + } + + // Validate centric entity against dictionary schemas if provided + let availableEntities: string[] = []; + try { + availableEntities = await this.fetchDictionarySchemas( + lecternUrl, + dictionaryName, + dictionaryVersion + ); + + if (!availableEntities.includes(defaultCentricEntity)) { + throw new ConductorError( + `Entity '${defaultCentricEntity}' does not exist in this dictionary`, + ErrorCodes.VALIDATION_FAILED, + { + availableEntities: availableEntities, + suggestion: `Choose one of the available entities: ${availableEntities.join( + ", " + )}`, + } + ); + } + + Logger.debug( + `Confirmed entity '${defaultCentricEntity}' exists in dictionary.` + ); + } catch (error) { + // If we can't validate the schema, log a warning but continue + // This prevents the command from failing if Lectern is unreachable + Logger.warn( + `Could not validate centric entity against dictionary schema: ${ + error instanceof Error ? error.message : String(error) + }` + ); + Logger.warn(`Proceeding with registration without validation...`); + } + + // Print registration information + Logger.info(`\x1b[1;36mRegistering Dictionary:\x1b[0m`); + Logger.info(`URL: ${lyricService.getUrl()}/dictionary/register`); + Logger.info(`Category: ${categoryName}`); + Logger.info(`Dictionary: ${dictionaryName}`); + Logger.info(`Version: ${dictionaryVersion}`); + Logger.info(`Centric Entity: ${defaultCentricEntity}`); + + // Register dictionary with retries + let result; + let attempt = 0; + let lastError; + + while (attempt < this.MAX_RETRIES) { + attempt++; + try { + // Register dictionary + result = await lyricService.registerDictionary({ + categoryName, + dictionaryName, + dictionaryVersion, + defaultCentricEntity, + }); + + // Registration successful + break; + } catch (error) { + lastError = error; + + // Special handling for entity not found errors + if ( + error instanceof ConductorError && + error.message.includes("Entity") && + error.message.includes("does not exist in this dictionary") + ) { + // If we already have the list of available entities, use it + if (availableEntities.length > 0) { + throw new ConductorError( + `Entity '${defaultCentricEntity}' does not exist in this dictionary`, + ErrorCodes.VALIDATION_FAILED, + { + availableEntities: availableEntities, + suggestion: `Available entities are: ${availableEntities.join( + ", " + )}. Try again with: conductor lyricRegister -c ${categoryName} --dict-name ${dictionaryName} -v ${dictionaryVersion} -e [entity]`, + } + ); + } else { + // Otherwise try to fetch them now for the error message + try { + const schemas = await this.fetchDictionarySchemas( + lecternUrl, + dictionaryName, + dictionaryVersion + ); + + throw new ConductorError( + `Entity '${defaultCentricEntity}' does not exist in this dictionary`, + ErrorCodes.VALIDATION_FAILED, + { + availableEntities: schemas, + suggestion: `Available entities are: ${schemas.join( + ", " + )}. Try again with: conductor lyricRegister -c ${categoryName} --dict-name ${dictionaryName} -v ${dictionaryVersion} -e [entity]`, + } + ); + } catch (schemaError) { + // If we can't fetch schemas, just show a generic message + throw new ConductorError( + `Entity '${defaultCentricEntity}' does not exist in this dictionary`, + ErrorCodes.VALIDATION_FAILED, + { + suggestion: `Check the dictionary schema and use a valid entity name with -e parameter`, + } + ); + } + } + } + + // If it's a bad request (invalid parameters), don't retry + if ( + error instanceof ConductorError && + error.details && + typeof error.details === "object" && + error.details.status === 400 + ) { + throw error; + } + + if (attempt < this.MAX_RETRIES) { + Logger.warn( + `Registration attempt ${attempt} failed, retrying in ${ + this.RETRY_DELAY / 1000 + }s...` + ); + await new Promise((resolve) => + setTimeout(resolve, this.RETRY_DELAY) + ); + } + } + } + + // Check if registration succeeded + if (!result) { + throw ( + lastError || + new ConductorError( + "Failed to register dictionary after multiple attempts", + ErrorCodes.CONNECTION_ERROR, + { + attempts: this.MAX_RETRIES, + suggestion: "Check network connectivity and Lyric service status", + } + ) + ); + } + + // Log success message + Logger.success(`Dictionary registered successfully`); + Logger.generic(" "); + Logger.generic(chalk.gray(` - Category: ${categoryName}`)); + Logger.generic(chalk.gray(` - Dictionary: ${dictionaryName}`)); + Logger.generic(chalk.gray(` - Version: ${dictionaryVersion}`)); + Logger.generic( + chalk.gray(` - Centric Entity: ${defaultCentricEntity}`) + ); + Logger.generic(" "); + + return { + success: true, + details: result, + }; + } catch (error) { + // Special handling for common API errors to make them more user-friendly + if ( + error instanceof ConductorError && + error.details && + typeof error.details === "object" + ) { + const details = error.details; + + // For Bad Request where dictionary already exists + if ( + details.status === 400 && + ((details.message && + details.message.toString().includes("already exists")) || + error.message.includes("already exists")) + ) { + Logger.info( + "\nThis dictionary may already exist in the Lyric service." + ); + Logger.info( + "Try with different parameters or check if it was previously registered." + ); + + // Add additional context for debugging + if (details.params) { + Logger.debug("Registration parameters:"); + Object.entries(details.params).forEach(([key, value]) => { + Logger.debug(` ${key}: ${value}`); + }); + } + } + + // Special handling for entity not found errors + if ( + error.message.includes("Entity") && + error.message.includes("does not exist") && + details.availableEntities + ) { + Logger.info( + `\nAvailable entities in this dictionary are: ${details.availableEntities.join( + ", " + )}` + ); + if (details.suggestion) { + Logger.tip(details.suggestion); + } + } + + // Add suggestions for other error types + if (details.suggestion) { + Logger.tip(details.suggestion); + } + } + + // Handle errors and return failure result + const errorMessage = + error instanceof Error ? error.message : String(error); + const errorCode = + error instanceof ConductorError + ? error.code + : ErrorCodes.CONNECTION_ERROR; + + // Extract additional details if available + const errorDetails = + error instanceof ConductorError ? error.details : undefined; + + return { + success: false, + errorMessage, + errorCode, + details: errorDetails, + }; + } + } + + /** + * Validates command line arguments. + * + * @param cliOutput - The parsed command line arguments + * @returns A promise that resolves when validation is complete or rejects with an error + */ + protected async validate(cliOutput: CLIOutput): Promise { + const { options } = cliOutput; + + // Validate Lyric URL + const lyricUrl = options.lyricUrl || process.env.LYRIC_URL; + if (!lyricUrl) { + throw new ConductorError( + "Lyric URL not specified. Use --lyric-url option or set LYRIC_URL environment variable.", + ErrorCodes.INVALID_ARGS + ); + } + + // Validate dictionary name + const dictionaryName = options.dictName || process.env.DICTIONARY_NAME; + if (!dictionaryName) { + throw new ConductorError( + "Dictionary name not specified. Use --dict-name option or set DICTIONARY_NAME environment variable.", + ErrorCodes.INVALID_ARGS + ); + } + + // Validate category name + const categoryName = options.categoryName || process.env.CATEGORY_NAME; + if (!categoryName) { + throw new ConductorError( + "Category name not specified. Use -c or --category-name option or set CATEGORY_NAME environment variable.", + ErrorCodes.INVALID_ARGS + ); + } + + // Validate dictionary version + const dictionaryVersion = + options.dictionaryVersion || process.env.DICTIONARY_VERSION; + if (!dictionaryVersion) { + throw new ConductorError( + "Dictionary version not specified. Use -v or --dictionary-version option or set DICTIONARY_VERSION environment variable.", + ErrorCodes.INVALID_ARGS + ); + } + + // Note about centric entity - technically optional in our interface but required by API + // We'll validate in execute() and provide helpful errors rather than failing early here + + // Validation passed + return; + } +} diff --git a/apps/conductor/src/commands/lyricUploadCommand.ts b/apps/conductor/src/commands/lyricUploadCommand.ts new file mode 100644 index 00000000..c2be7f10 --- /dev/null +++ b/apps/conductor/src/commands/lyricUploadCommand.ts @@ -0,0 +1,830 @@ +import { Command, CommandResult } from "./baseCommand"; +import { CLIOutput } from "../types/cli"; +import { Logger } from "../utils/logger"; +import chalk from "chalk"; +import { ConductorError, ErrorCodes } from "../utils/errors"; +import * as fs from "fs"; +import * as path from "path"; +import axios from "axios"; +const { exec } = require("child_process"); + +/** + * Interface for Lyric submission response + */ +interface LyricSubmissionResponse { + submissionId: string; + status: string; + [key: string]: any; +} + +/** + * Expands directory paths to individual file paths, filtering by extension if specified + * @param paths Array of file or directory paths + * @param extensions Optional array of extensions to filter by (e.g., ['.csv', '.json']) + * @returns Array of expanded file paths + */ +function expandDirectoryPaths( + paths: string[], + extensions?: string[] +): string[] { + if (!paths || paths.length === 0) { + return []; + } + + let expandedPaths: string[] = []; + + paths.forEach((inputPath) => { + try { + const stats = fs.statSync(inputPath); + + if (stats.isDirectory()) { + Logger.debug(`Processing directory: ${inputPath}`); + + // Read all files in the directory + const filesInDir = fs + .readdirSync(inputPath) + .map((file) => path.join(inputPath, file)) + .filter((file) => { + try { + const fileStat = fs.statSync(file); + + // Skip if not a file + if (!fileStat.isFile()) { + return false; + } + + // Filter by extension if specified + if (extensions && extensions.length > 0) { + const ext = path.extname(file).toLowerCase(); + return extensions.includes(ext); + } + + return true; + } catch (error) { + Logger.debug(`Error accessing file ${file}: ${error}`); + return false; + } + }); + + if (filesInDir.length === 0) { + if (extensions && extensions.length > 0) { + Logger.warn( + `No files with extensions ${extensions.join( + ", " + )} found in directory: ${inputPath}` + ); + } else { + Logger.warn(`Directory is empty: ${inputPath}`); + } + } else { + Logger.debug( + `Found ${filesInDir.length} files in directory ${inputPath}` + ); + expandedPaths = [...expandedPaths, ...filesInDir]; + } + } else { + // It's a file, check extension if needed + if (extensions && extensions.length > 0) { + const ext = path.extname(inputPath).toLowerCase(); + if (extensions.includes(ext)) { + expandedPaths.push(inputPath); + } else { + Logger.debug( + `Skipping file with unsupported extension: ${inputPath}` + ); + } + } else { + expandedPaths.push(inputPath); + } + } + } catch (error) { + Logger.debug(`Error accessing path ${inputPath}: ${error}`); + throw new ConductorError( + `Cannot access path: ${inputPath}`, + ErrorCodes.FILE_NOT_FOUND, + error + ); + } + }); + + return expandedPaths; +} + +/** + * Gets all CSV files from the provided directory + * @param dirPath Directory path to scan + * @returns Array of CSV file paths + */ +function getCSVFiles(dirPath: string): string[] { + return expandDirectoryPaths([dirPath], [".csv"]); +} + +/** + * Command for loading data into Lyric + */ +export class LyricUploadCommand extends Command { + private readonly MAX_RETRIES = 1; + private readonly RETRY_DELAY = 5000; + + constructor() { + super("Lyric Data Loading"); + } + + /** + * Executes the Lyric data loading process + * @param cliOutput The CLI configuration and inputs + * @returns A CommandResult indicating success or failure + */ + protected async execute(cliOutput: CLIOutput): Promise { + // Ensure config exists + if (!cliOutput.config) { + throw new ConductorError( + "Configuration is missing", + ErrorCodes.INVALID_ARGS + ); + } + + // Extract configuration with fallbacks + const lyricUrl = + cliOutput.config.lyric?.url || + process.env.LYRIC_URL || + "http://localhost:3030"; + const lecternUrl = + cliOutput.config.lectern?.url || + process.env.LECTERN_URL || + "http://localhost:3031"; + const dataDirectory = this.resolveDataDirectory(cliOutput); + const categoryId = + cliOutput.config.lyric?.categoryId || process.env.CATEGORY_ID || "1"; + const organization = + cliOutput.config.lyric?.organization || + process.env.ORGANIZATION || + "OICR"; + const maxRetries = parseInt( + String( + cliOutput.config.lyric?.maxRetries || process.env.MAX_RETRIES || "10" + ) + ); + const retryDelay = parseInt( + String( + cliOutput.config.lyric?.retryDelay || process.env.RETRY_DELAY || "20000" + ) + ); + + try { + // Print data loading information + Logger.info(`\x1b[1;36mStarting data loading process...\x1b[0m`); + Logger.info(`Lyric URL: ${lyricUrl}`); + Logger.info(`Lectern URL: ${lecternUrl}`); + Logger.info(`Data Directory: ${dataDirectory}`); + Logger.info(`Category ID: ${categoryId}`); + Logger.info(`Organization: ${organization}`); + Logger.info(`Max Retries: ${maxRetries}`); + + // Find all CSV files in the directory + const csvFilePaths = this.findCSVFiles(dataDirectory); + + if (csvFilePaths.length === 0) { + throw new ConductorError( + `No CSV files found in ${dataDirectory}`, + ErrorCodes.FILE_NOT_FOUND, + { + suggestion: "Make sure your directory contains valid CSV files.", + } + ); + } + + Logger.info(`Found ${csvFilePaths.length} CSV files to submit:`); + csvFilePaths.forEach((file) => { + Logger.info(`- ${path.basename(file)}`); + }); + + // Submit all files to Lyric using curl + const result = await this.submitFilesWithCurl({ + categoryId, + organization, + csvFilePaths, + lyricUrl, + maxRetries, + retryDelay, + }); + + // Log success message + Logger.success(`Data loading completed successfully`); + Logger.generic(" "); + Logger.generic(chalk.gray(` - Submission ID: ${result.submissionId}`)); + Logger.generic(chalk.gray(` - Status: ${result.status}`)); + Logger.generic(" "); + + return { + success: true, + details: result, + }; + } catch (error) { + // Handle errors and provide helpful messages + return this.handleExecutionError(error, lyricUrl); + } + } + + /** + * Resolves the data directory with fallback and validation + * @param cliOutput The CLI configuration and inputs + * @returns A resolved, absolute path to the data directory + */ + private resolveDataDirectory(cliOutput: CLIOutput): string { + // First check command-line options.dataDirectory which is set by -d flag + const fromCommandLine = cliOutput.options?.dataDirectory; + + // Then check the config object and environment + const fromConfig = cliOutput.config.lyric?.dataDirectory; + const fromEnv = process.env.LYRIC_DATA; + + // Use the first available source, with fallback to "./data" + const rawDataDirectory = + fromCommandLine || fromConfig || fromEnv || "./data"; + + // Log where we found the directory path + if (fromCommandLine) { + Logger.debug( + `Using data directory from command line: ${fromCommandLine}` + ); + } else if (fromConfig) { + Logger.debug(`Using data directory from config: ${fromConfig}`); + } else if (fromEnv) { + Logger.debug(`Using data directory from environment: ${fromEnv}`); + } else { + Logger.debug(`Using default data directory: ./data`); + } + + // Resolve to an absolute path + const resolvedPath = path.resolve(process.cwd(), rawDataDirectory); + Logger.debug(`Resolved data directory path: ${resolvedPath}`); + + // Validate the directory exists + if (!fs.existsSync(resolvedPath)) { + throw new ConductorError( + `Data directory not found: ${resolvedPath}`, + ErrorCodes.FILE_NOT_FOUND, + { + providedPath: rawDataDirectory, + resolvedPath, + suggestion: "Make sure the directory exists and is accessible.", + } + ); + } + + // Validate it's actually a directory + if (!fs.statSync(resolvedPath).isDirectory()) { + throw new ConductorError( + `Path exists but is not a directory: ${resolvedPath}`, + ErrorCodes.INVALID_ARGS, + { + providedPath: rawDataDirectory, + resolvedPath, + suggestion: "Provide a valid directory path, not a file path.", + } + ); + } + + return resolvedPath; + } + + /** + * Finds all CSV files in the directory + * @param directory Directory to search + * @returns Array of CSV file paths (with full paths) + */ + private findCSVFiles(directory: string): string[] { + try { + // Use the utility function to get all CSV files + const csvFilePaths = getCSVFiles(directory); + + if (csvFilePaths.length === 0) { + Logger.warn(`No CSV files found in directory: ${directory}`); + } else { + Logger.debug(`Found ${csvFilePaths.length} CSV files in ${directory}`); + } + + return csvFilePaths; + } catch (error) { + throw new ConductorError( + `Error reading directory contents: ${ + error instanceof Error ? error.message : String(error) + }`, + ErrorCodes.FILE_NOT_FOUND, + { + directory, + error: error instanceof Error ? error.message : String(error), + suggestion: "Check directory permissions and path spelling.", + } + ); + } + } + + /** + * Submit files to Lyric using curl + * @param params Parameters for submission + * @returns Lyric submission response + */ + private async submitFilesWithCurl(params: { + categoryId: string; + organization: string; + csvFilePaths: string[]; + lyricUrl: string; + maxRetries: number; + retryDelay: number; + }): Promise { + const { + categoryId, + organization, + csvFilePaths, + lyricUrl, + maxRetries, + retryDelay, + } = params; + + try { + // Normalize URL + const url = `${lyricUrl.replace( + /\/$/, + "" + )}/submission/category/${categoryId}/data`; + + // Filter out any invalid CSV files + const validFiles = csvFilePaths.filter((filePath) => { + try { + const stats = fs.statSync(filePath); + return stats.isFile() && stats.size > 0; + } catch (err) { + Logger.warn( + `Skipping ${path.basename(filePath)} - error accessing file: ${ + err instanceof Error ? err.message : String(err) + }` + ); + return false; + } + }); + + if (validFiles.length === 0) { + throw new ConductorError( + "No valid CSV files to submit after filtering", + ErrorCodes.INVALID_ARGS, + { + suggestion: "Ensure your CSV files are valid and not empty.", + } + ); + } + + // Build curl command + let command = `curl -X 'POST' '${url}' -H 'accept: application/json' -H 'Content-Type: multipart/form-data'`; + + // Add each file + for (const filePath of validFiles) { + command += ` -F 'files=@${filePath};type=text/csv'`; + } + + // Add organization + command += ` -F 'organization=${organization}'`; + + // Log the submission information + Logger.info(`\x1b[1;36mSubmitting Data:\x1b[0m`); + Logger.info(`API URL: ${url}`); + Logger.info( + `Files to submit: ${validFiles + .map((file) => path.basename(file)) + .join(", ")}` + ); + Logger.info(`Organization: ${organization}`); + + // Execute the curl command + Logger.debug(`Executing curl command: ${command}`); + const { stdout, stderr } = await this.execCommand(command); + + if (stderr && stderr.trim()) { + Logger.debug(`Curl stderr output: ${stderr}`); + } + + // Parse the JSON response from curl + let responseData; + try { + responseData = JSON.parse(stdout); + } catch (parseError) { + Logger.error(`Failed to parse curl response as JSON: ${stdout}`); + throw new ConductorError( + `Failed to parse curl response: ${ + parseError instanceof Error + ? parseError.message + : String(parseError) + }`, + ErrorCodes.CONNECTION_ERROR, + { stdout, stderr } + ); + } + + // Extract submission ID from response + const submissionId = responseData?.submissionId; + if (!submissionId) { + throw new ConductorError( + "Could not extract submission ID from response", + ErrorCodes.CONNECTION_ERROR, + { response: responseData } + ); + } + + Logger.success(`Submission created with ID: ${submissionId}`); + + // Wait for validation to complete + const status = await this.waitForValidation( + submissionId, + lyricUrl, + maxRetries, + retryDelay + ); + + // Commit the submission if valid + if (status === "VALID") { + await this.commitSubmission(categoryId, submissionId, lyricUrl); + return { + submissionId: submissionId.toString(), + status: "COMMITTED", + }; + } else { + throw new ConductorError( + `Submission has unexpected status: ${status}`, + ErrorCodes.VALIDATION_FAILED, + { + submissionId, + status, + suggestion: "Check Lyric server logs for validation details.", + } + ); + } + } catch (error) { + if (error instanceof ConductorError) { + throw error; + } + + throw new ConductorError( + `Data submission failed: ${ + error instanceof Error ? error.message : String(error) + }`, + ErrorCodes.CONNECTION_ERROR, + { + error: error instanceof Error ? error.stack : String(error), + suggestion: "Check your network connection and Lyric server status.", + } + ); + } + } + + /** + * Wait for validation to complete + * @param submissionId Submission ID to check + * @param lyricUrl Lyric URL + * @param maxRetries Maximum number of retries + * @param retryDelay Delay between retries in milliseconds + * @returns Final validation status + */ + private async waitForValidation( + submissionId: string, + lyricUrl: string, + maxRetries: number, + retryDelay: number + ): Promise { + let retries = 0; + + Logger.info(`Waiting for server to validate submission ${submissionId}...`); + Logger.info( + `This may take a few minutes depending on file size and complexity.` + ); + + while (retries < maxRetries) { + Logger.info( + `Checking validation status (attempt ${retries + 1}/${maxRetries})...` + ); + + try { + const response = await axios.get( + `${lyricUrl}/submission/${submissionId}`, + { + headers: { accept: "application/json" }, + timeout: 10000, // 10 second timeout for status check + } + ); + + const responseData = response.data as { status?: string }; + const status = responseData?.status; + + if (!status) { + throw new ConductorError( + "Could not extract status from response", + ErrorCodes.CONNECTION_ERROR, + { + response: responseData, + suggestion: + "Response format may have changed. Check Lyric server documentation.", + } + ); + } + + Logger.info(`Current status: ${status}`); + + if (status === "VALID") { + Logger.success(`Submission validation passed`); + return status; + } else if (status === "INVALID") { + throw new ConductorError( + "Submission validation failed", + ErrorCodes.VALIDATION_FAILED, + { + submissionId, + status, + suggestion: `Check validation details at ${lyricUrl}/submission/${submissionId} in your browser`, + } + ); + } + + // Wait for next check + Logger.info( + `Waiting ${retryDelay / 1000} seconds before next check...` + ); + await new Promise((resolve) => setTimeout(resolve, retryDelay)); + retries++; + } catch (error) { + if (error instanceof ConductorError) { + throw error; + } + + if ( + this.isAxiosError(error) && + (error as any).response?.status === 404 + ) { + throw new ConductorError( + `Submission ${submissionId} not found. It may have been deleted or never created.`, + ErrorCodes.CONNECTION_ERROR, + { + submissionId, + suggestion: "Check the submission ID and Lyric server status.", + } + ); + } + + throw new ConductorError( + `Error checking submission status: ${ + error instanceof Error ? error.message : String(error) + }`, + ErrorCodes.CONNECTION_ERROR, + { + error: error instanceof Error ? error.stack : String(error), + submissionId, + retryCount: retries, + suggestion: + "Check your network connection and Lyric server status.", + } + ); + } + } + + throw new ConductorError( + `Validation timed out after ${maxRetries} attempts`, + ErrorCodes.CONNECTION_ERROR, + { + submissionId, + attempts: maxRetries, + totalWaitTime: `${(maxRetries * retryDelay) / 1000} seconds`, + suggestion: `Your submission may still be processing. Check status manually at ${lyricUrl}/submission/${submissionId}`, + } + ); + } + + /** + * Commit a submission + * @param categoryId Category ID + * @param submissionId Submission ID + * @param lyricUrl Lyric URL + * @returns True if commit successful + */ + private async commitSubmission( + categoryId: string, + submissionId: string, + lyricUrl: string + ): Promise { + try { + Logger.info(`\x1b[1;36mCommitting Submission:\x1b[0m ${submissionId}`); + + // Make commit request + const commitUrl = `${lyricUrl}/submission/category/${categoryId}/commit/${submissionId}`; + const response = await axios.post(commitUrl, null, { + headers: { + accept: "application/json", + }, + timeout: 20000, + }); + + Logger.success(`Submission committed successfully`); + return true; + } catch (error) { + // Handle commit errors with more context + if (this.isAxiosError(error)) { + const axiosError = error as any; + + // Special handling for 409 Conflict (already committed) + if (axiosError.response?.status === 409) { + Logger.warn(`Submission may already be committed`); + return true; + } + + throw new ConductorError( + `Failed to commit submission: ${axiosError.response?.status || ""} ${ + axiosError.message + }`, + ErrorCodes.CONNECTION_ERROR, + { + status: axiosError.response?.status, + statusText: axiosError.response?.statusText, + data: axiosError.response?.data, + submissionId, + categoryId, + suggestion: "Check Lyric server logs for more details.", + } + ); + } + + throw new ConductorError( + `Failed to commit submission: ${ + error instanceof Error ? error.message : String(error) + }`, + ErrorCodes.CONNECTION_ERROR, + { + error: error instanceof Error ? error.stack : String(error), + submissionId, + categoryId, + suggestion: "Check your network connection and Lyric server status.", + } + ); + } + } + + /** + * Execute a command via child_process.exec + * @param command Command to execute + * @returns Promise resolving to stdout and stderr + */ + private async execCommand( + command: string + ): Promise<{ stdout: string; stderr: string }> { + return new Promise((resolve, reject) => { + exec( + command, + { maxBuffer: 10 * 1024 * 1024 }, + (error: Error | null, stdout: string, stderr: string) => { + if (error) { + reject( + new ConductorError( + `Command execution failed: ${error.message}`, + ErrorCodes.CONNECTION_ERROR, + { error, stderr, command } + ) + ); + return; + } + resolve({ stdout, stderr }); + } + ); + }); + } + + /** + * Type guard to check if an error is an Axios error + * @param error Error to check + * @returns True if error is an Axios error + */ + private isAxiosError(error: any): boolean { + return Boolean( + error && + typeof error === "object" && + "isAxiosError" in error && + error.isAxiosError === true + ); + } + + /** + * Handle execution errors with helpful user feedback + * @param error The caught error + * @param lyricUrl The Lyric URL for context + * @returns CommandResult with error details + */ + private handleExecutionError( + error: unknown, + lyricUrl: string + ): CommandResult { + // Special handling for common error scenarios + if (error instanceof ConductorError) { + // Validation failures + if (error.code === ErrorCodes.VALIDATION_FAILED) { + Logger.info( + "\nSubmission validation failed. Please check your data files for errors." + ); + + if (error.details?.status) { + Logger.info(`Status: ${error.details.status}`); + } + + if (error.details?.submissionId) { + Logger.info(`Submission ID: ${error.details.submissionId}`); + Logger.info( + `You can check the submission details at: ${lyricUrl}/submission/${error.details.submissionId}` + ); + } + } + // File not found + else if (error.code === ErrorCodes.FILE_NOT_FOUND) { + Logger.info( + "\nFile or directory issue detected. Check paths and permissions." + ); + + if (error.details?.suggestion) { + Logger.info(`Suggestion: ${error.details.suggestion}`); + } + } + // Connection errors + else if (error.code === ErrorCodes.CONNECTION_ERROR) { + Logger.info( + "\nConnection error. Check network and server availability." + ); + + if (error.details?.suggestion) { + Logger.info(`Suggestion: ${error.details.suggestion}`); + } + } + + return { + success: false, + errorMessage: error.message, + errorCode: error.code, + details: error.details, + }; + } + + // Handle generic errors + const errorMessage = error instanceof Error ? error.message : String(error); + return { + success: false, + errorMessage, + errorCode: ErrorCodes.CONNECTION_ERROR, + details: { + error: error instanceof Error ? error.stack : String(error), + suggestion: + "An unexpected error occurred. Try running with --debug for more information.", + }, + }; + } + + /** + * Validates command line arguments + * @param cliOutput The CLI configuration and inputs + * @returns A CommandResult indicating success or failure + */ + protected async validate(cliOutput: CLIOutput): Promise { + // Ensure config exists + if (!cliOutput.config) { + throw new ConductorError( + "Configuration is missing", + ErrorCodes.INVALID_ARGS + ); + } + + // Extract key parameters + const lyricUrl = cliOutput.config.lyric?.url || process.env.LYRIC_URL; + const lecternUrl = cliOutput.config.lectern?.url || process.env.LECTERN_URL; + + // Try to get data directory from CLI first, then config, then env + const dataDirectoryFromCli = cliOutput.options?.dataDirectory; + const dataDirectoryFromConfig = cliOutput.config.lyric?.dataDirectory; + const dataDirectoryFromEnv = process.env.LYRIC_DATA; + const dataDirectory = + dataDirectoryFromCli || dataDirectoryFromConfig || dataDirectoryFromEnv; + + // Validate required parameters + if (!lyricUrl) { + throw new ConductorError( + "No Lyric URL provided. Use --lyric-url option or set LYRIC_URL environment variable.", + ErrorCodes.INVALID_ARGS + ); + } + + if (!lecternUrl) { + throw new ConductorError( + "No Lectern URL provided. Use --lectern-url option or set LECTERN_URL environment variable.", + ErrorCodes.INVALID_ARGS + ); + } + + if (!dataDirectory) { + throw new ConductorError( + "No data directory provided. Use --data-directory (-d) option or set LYRIC_DATA environment variable.", + ErrorCodes.INVALID_ARGS + ); + } + } +} diff --git a/apps/conductor/src/commands/maestroIndexCommand.ts b/apps/conductor/src/commands/maestroIndexCommand.ts new file mode 100644 index 00000000..09111a22 --- /dev/null +++ b/apps/conductor/src/commands/maestroIndexCommand.ts @@ -0,0 +1,207 @@ +import axios from "axios"; +import { Command, CommandResult } from "./baseCommand"; +import { CLIOutput } from "../types/cli"; +import { Logger } from "../utils/logger"; +import chalk from "chalk"; +import { ConductorError, ErrorCodes } from "../utils/errors"; + +/** + * Response from index repository request + */ +interface IndexRepositoryResponse { + message?: string; + status?: string; + [key: string]: unknown; +} + +/** + * Command for indexing a repository with optional organization and ID filters + */ +export class MaestroIndexCommand extends Command { + private readonly TIMEOUT = 30000; // 30 seconds + + constructor() { + super("maestroIndex"); + this.defaultOutputFileName = "index-repository-results.json"; + } + + /** + * Executes the repository indexing process + * @param cliOutput The CLI configuration and inputs + * @returns A CommandResult indicating success or failure + */ + protected async execute(cliOutput: CLIOutput): Promise { + const { options } = cliOutput; + + try { + // Extract configuration from options or environment variables + const indexUrl = + options.indexUrl || process.env.INDEX_URL || "http://localhost:11235"; + const repositoryCode = + options.repositoryCode || process.env.REPOSITORY_CODE; + const organization = options.organization || process.env.ORGANIZATION; + const id = options.id || process.env.ID; + + // Validate required parameters + if (!repositoryCode) { + throw new ConductorError( + "Repository code not specified. Use --repository-code or set REPOSITORY_CODE environment variable.", + ErrorCodes.INVALID_ARGS + ); + } + + // Construct the URL based on provided parameters + let url = `${indexUrl}/index/repository/${repositoryCode}`; + if (organization) { + url += `/organization/${organization}`; + if (id) { + url += `/id/${id}`; + } + } + + // Log indexing information + Logger.info(`\x1b[1;36mIndexing Repository:\x1b[0m`); + Logger.info(`URL: ${url}`); + Logger.info(`Repository Code: ${repositoryCode}`); + if (organization) Logger.info(`Organization: ${organization}`); + if (id) Logger.info(`ID: ${id}`); + + // Make the request + Logger.info("Sending indexing request..."); + const response = await axios.post(url, "", { + headers: { + accept: "application/json", + }, + timeout: this.TIMEOUT, + }); + + // Process response + const responseData = response.data as IndexRepositoryResponse; + + // Log success message + Logger.success(`Repository indexing request successful`); + Logger.generic(" "); + Logger.generic(chalk.gray(` - Repository: ${repositoryCode}`)); + if (organization) + Logger.generic(chalk.gray(` - Organization: ${organization}`)); + if (id) Logger.generic(chalk.gray(` - ID: ${id}`)); + if (responseData && responseData.message) { + Logger.generic(chalk.gray(` - Message: ${responseData.message}`)); + } + Logger.generic(" "); + + return { + success: true, + details: { + repository: repositoryCode, + organization: organization || "All", + id: id || "All", + response: responseData, + }, + }; + } catch (error: unknown) { + // Handle errors and return failure result + if (error instanceof ConductorError) { + throw error; + } + + // Handle Axios errors with more detail + if (this.isAxiosError(error)) { + const axiosError = error as any; + const status = axiosError.response?.status; + const responseData = axiosError.response?.data as + | Record + | undefined; + + let errorMessage = `Repository indexing failed: ${axiosError.message}`; + let errorDetails: Record = { + status, + responseData, + }; + + // Handle common error cases + if (status === 404) { + errorMessage = `Repository not found: The specified repository code may be invalid`; + } else if (status === 401 || status === 403) { + errorMessage = `Authentication error: Ensure you have proper permissions`; + } else if (status === 400) { + errorMessage = `Bad request: ${ + responseData?.message || "Invalid parameters" + }`; + } else if (status === 500) { + errorMessage = `Server error: The indexing service encountered an internal error`; + } else if (axiosError.code === "ECONNREFUSED") { + errorMessage = `Connection refused: The indexing service at ${ + options.indexUrl || "http://localhost:11235" + } is not available`; + } else if (axiosError.code === "ETIMEDOUT") { + errorMessage = `Request timeout: The indexing service did not respond in time`; + } + + Logger.error(errorMessage); + + // Provide some helpful tips based on error type + if (status === 404 || status === 400) { + Logger.tip( + `Verify that the repository code "${options.repositoryCode}" is correct` + ); + } else if (axiosError.code === "ECONNREFUSED") { + Logger.tip( + `Ensure the indexing service is running on ${ + options.indexUrl || "http://localhost:11235" + }` + ); + } + + throw new ConductorError( + errorMessage, + ErrorCodes.CONNECTION_ERROR, + errorDetails + ); + } + + // Generic error handling + const errorMessage = + error instanceof Error ? error.message : String(error); + + throw new ConductorError( + `Repository indexing failed: ${errorMessage}`, + ErrorCodes.CONNECTION_ERROR, + error + ); + } + } + + /** + * Type guard to check if an error is an Axios error + * @param error Any error object + * @returns Whether the error is an Axios error + */ + private isAxiosError(error: unknown): boolean { + return Boolean( + error && + typeof error === "object" && + "isAxiosError" in error && + (error as { isAxiosError: boolean }).isAxiosError === true + ); + } + + /** + * Validates command line arguments + * @param cliOutput - The parsed command line arguments + * @returns Promise that resolves when validation is complete + * @throws ConductorError if validation fails + */ + protected async validate(cliOutput: CLIOutput): Promise { + const { options } = cliOutput; + const repositoryCode = + options.repositoryCode || process.env.REPOSITORY_CODE; + + if (!repositoryCode) { + throw new ConductorError( + "No repository code provided. Use --repository-code option or set REPOSITORY_CODE environment variable.", + ErrorCodes.INVALID_ARGS + ); + } + } +} diff --git a/apps/conductor/src/commands/scoreManifestUploadCommand.ts b/apps/conductor/src/commands/scoreManifestUploadCommand.ts new file mode 100644 index 00000000..0454c904 --- /dev/null +++ b/apps/conductor/src/commands/scoreManifestUploadCommand.ts @@ -0,0 +1,546 @@ +import { Command, CommandResult } from "./baseCommand"; +import { CLIOutput } from "../types/cli"; +import { Logger } from "../utils/logger"; +import { ConductorError, ErrorCodes } from "../utils/errors"; + +// Use require for Node.js built-in modules to avoid TypeScript import issues +const fs = require("fs"); +const path = require("path"); +const childProcess = require("child_process"); +const util = require("util"); +const axios = require("axios"); + +// Create a promisified version of exec +const execPromise = util.promisify(childProcess.exec); + +/** + * Command for generating manifests and uploading files with Score + * Uses Docker containers for song-client and score-client if available + */ +export class ScoreManifestUploadCommand extends Command { + private readonly SONG_EXEC_TIMEOUT = 60000; // 60 seconds + private readonly SCORE_EXEC_TIMEOUT = 300000; // 5 minutes for larger uploads + + constructor() { + super("Score Manifest Upload"); + this.defaultOutputFileName = "manifest.txt"; + this.defaultOutputPath = "./output"; + } + + /** + * Executes the Score manifest upload process using song-client and score-client + * @param cliOutput The CLI configuration and inputs + * @returns A CommandResult indicating success or failure + */ + protected async execute(cliOutput: CLIOutput): Promise { + const { config, options } = cliOutput; + + try { + // Extract configuration + const analysisId = + options.analysisId || + config.score?.analysisId || + (process?.env?.ANALYSIS_ID as string | undefined); + const songUrl = + options.songUrl || + config.song?.url || + process?.env?.SONG_URL || + "http://localhost:8080"; + const scoreUrl = + options.scoreUrl || + config.score?.url || + process?.env?.SCORE_URL || + "http://localhost:8087"; + const dataDir = + options.dataDir || + config.score?.dataDir || + process?.env?.DATA_DIR || + "./data"; + const outputDir = + options.outputDir || + config.score?.outputDir || + process?.env?.OUTPUT_DIR || + "./output"; + const manifestFile = + options.manifestFile || + config.score?.manifestFile || + process?.env?.MANIFEST_FILE || + path.join(outputDir, "manifest.txt"); + const authToken = + options.authToken || + config.score?.authToken || + config.song?.authToken || + process?.env?.AUTH_TOKEN || + "123"; + + // Validate required parameters + if (!analysisId) { + throw new ConductorError( + "Analysis ID not specified. Use --analysis-id or set ANALYSIS_ID environment variable.", + ErrorCodes.INVALID_ARGS + ); + } + + // Create output directory if it doesn't exist + this.createDirectoryIfNotExists(path.dirname(manifestFile)); + + // Log the configuration + Logger.info(`\x1b[1;36mScore Manifest Upload Configuration:\x1b[0m`); + Logger.info(`Analysis ID: ${analysisId}`); + Logger.info(`Song URL: ${songUrl}`); + Logger.info(`Score URL: ${scoreUrl}`); + Logger.info(`Data Directory: ${dataDir}`); + Logger.info(`Output Directory: ${outputDir}`); + Logger.info(`Manifest File: ${manifestFile}`); + + // Check if Docker is available and containers are running + const useSongDocker = await this.checkIfDockerContainerRunning( + "song-client" + ); + const useScoreDocker = await this.checkIfDockerContainerRunning( + "score-client" + ); + + // Step 1: Generate manifest file + Logger.info(`\x1b[1;36mGenerating Manifest:\x1b[0m`); + + if (useSongDocker) { + Logger.info(`Using Song Docker client to generate manifest`); + await this.generateManifestWithSongClient( + analysisId, + manifestFile, + dataDir, + authToken, + songUrl + ); + } else { + Logger.info(`Using direct manifest generation approach`); + await this.generateManifestDirect( + analysisId, + manifestFile, + dataDir, + authToken, + songUrl + ); + } + Logger.success(`Successfully generated manifest at ${manifestFile}`); + + // Step 2: Upload files using the manifest + Logger.info(`\x1b[1;36mUploading Files with Score:\x1b[0m`); + + if (useScoreDocker) { + Logger.info(`Using Score Docker client to upload files`); + await this.uploadWithScoreClient(manifestFile, authToken, scoreUrl); + } else { + Logger.warn( + `Direct file upload without Score client is not recommended.` + ); + Logger.info( + `Please install and run the score-client Docker container for reliable uploads.` + ); + throw new ConductorError( + "Direct file upload requires Score client. Please ensure score-client Docker container is running.", + ErrorCodes.INVALID_ARGS + ); + } + + // Verify manifest file contents + let manifestContent = ""; + try { + manifestContent = fs.readFileSync(manifestFile, "utf8"); + Logger.debug(`Manifest file content: \n${manifestContent}`); + } catch (error) { + Logger.warn( + `Could not read manifest file: ${ + error instanceof Error ? error.message : String(error) + }` + ); + } + + // Log success details + Logger.success(`Successfully uploaded files with Score`); + Logger.generic(" "); + Logger.generic(` - Analysis ID: ${analysisId}`); + Logger.generic(` - Manifest file: ${manifestFile}`); + Logger.generic(" "); + + return { + success: true, + details: { + analysisId, + manifestFile, + manifestContent: manifestContent || "Manifest content not available", + }, + }; + } catch (error) { + // Handle and log errors + if (error instanceof ConductorError) { + throw error; + } + + const errorMessage = + error instanceof Error ? error.message : String(error); + + Logger.error(`Score Manifest Upload failed: ${errorMessage}`); + + throw new ConductorError( + `Score Manifest Upload failed: ${errorMessage}`, + ErrorCodes.CONNECTION_ERROR, + error + ); + } + } + + /** + * Check if a Docker container is running + */ + private async checkIfDockerContainerRunning( + containerName: string + ): Promise { + try { + const command = `docker ps -q -f name=${containerName}`; + Logger.debug(`Checking if container is running: ${command}`); + + const { stdout } = await execPromise(command); + return stdout.trim().length > 0; + } catch (error) { + Logger.debug( + `Docker container check failed: ${ + error instanceof Error ? error.message : String(error) + }` + ); + return false; + } + } + + /** + * Generate manifest file using SONG client via Docker + */ + /** + * Generate manifest file using SONG client via Docker + */ + /** + * Generate manifest file using SONG client via Docker + */ + private async generateManifestWithSongClient( + analysisId: string, + manifestFile: string, + dataDir: string, + authToken: string, + songUrl: string + ): Promise { + try { + // Convert local paths to container paths + const containerManifestPath = "/output/manifest.txt"; + const containerDataDir = "/data/fileData"; + + // Construct Docker song-client manifest command + const command = [ + `docker exec`, + `song-client`, + `sh -c "sing manifest -a ${analysisId} -f ${containerManifestPath} -d ${containerDataDir}"`, + ].join(" "); + + Logger.debug(`Executing: ${command}`); + + // Execute the command + const { stdout, stderr } = await execPromise(command, { + timeout: this.SONG_EXEC_TIMEOUT, + }); + + // Log output + if (stdout) Logger.debug(`SONG manifest stdout: ${stdout}`); + if (stderr) Logger.warn(`SONG manifest stderr: ${stderr}`); + + // Check if manifest file exists after generation (using local path) + if (!fs.existsSync(manifestFile)) { + throw new ConductorError( + `Manifest file not generated at expected path: ${manifestFile}`, + ErrorCodes.FILE_NOT_FOUND + ); + } + + // Log manifest file content + const manifestContent = fs.readFileSync(manifestFile, "utf8"); + Logger.debug(`Generated manifest content: \n${manifestContent}`); + } catch (error: any) { + // Handle execution errors + Logger.error(`SONG client manifest generation failed`); + + if (error.stdout) Logger.debug(`Stdout: ${error.stdout}`); + if (error.stderr) Logger.debug(`Stderr: ${error.stderr}`); + + throw new ConductorError( + `Failed to generate manifest: ${error.message || "Unknown error"}`, + ErrorCodes.CONNECTION_ERROR, + error + ); + } + } + + /** + * Upload files using score-client via Docker + */ + private async uploadWithScoreClient( + manifestFile: string, + authToken: string, + scoreUrl: string + ): Promise { + try { + // Convert local path to container path + const containerManifestPath = "/output/manifest.txt"; + + // Construct Docker score-client upload command + const command = [ + `docker exec`, + `score-client`, + `sh -c "score-client upload --manifest ${containerManifestPath}"`, + ].join(" "); + + Logger.debug(`Executing: ${command}`); + + // Execute the command + const { stdout, stderr } = await execPromise(command, { + timeout: this.SCORE_EXEC_TIMEOUT, + }); + + // Log output + if (stdout) Logger.debug(`SCORE upload stdout: ${stdout}`); + if (stderr) Logger.warn(`SCORE upload stderr: ${stderr}`); + } catch (error: any) { + // Handle execution errors + Logger.error(`Score client upload failed`); + + if (error.stdout) Logger.debug(`Stdout: ${error.stdout}`); + if (error.stderr) Logger.debug(`Stderr: ${error.stderr}`); + + throw new ConductorError( + `Failed to upload with Score: ${error.message || "Unknown error"}`, + ErrorCodes.CONNECTION_ERROR, + error + ); + } + } + /** + * Generate manifest file directly without using Song client + * This creates a manifest based on the analysis information retrieved from the SONG API + */ + /** + * Generate manifest file directly without using Song client + * This creates a manifest based on the analysis information retrieved from the SONG API + */ + private async generateManifestDirect( + analysisId: string, + manifestFile: string, + dataDir: string, + authToken: string, + songUrl: string + ): Promise { + try { + // 1. Get analysis details from SONG API + Logger.info(`Fetching analysis ${analysisId} details from SONG API`); + + // Remove trailing slash from URL if present + const baseUrl = songUrl.endsWith("/") ? songUrl.slice(0, -1) : songUrl; + + // We need to find the study ID for this analysis (it's required for the SONG API) + // First, try the studies/all endpoint to get all studies + const studies = await this.fetchAllStudies(baseUrl, authToken); + + if (!studies || studies.length === 0) { + throw new ConductorError( + "No studies found in SONG server", + ErrorCodes.CONNECTION_ERROR + ); + } + + Logger.debug(`Found ${studies.length} studies on SONG server`); + + // We need to look through studies to find which one contains our analysis + let studyId = null; + let analysis = null; + + for (const study of studies) { + try { + // Try to fetch the analysis from this study + Logger.debug(`Checking study ${study} for analysis ${analysisId}`); + const url = `${baseUrl}/studies/${study}/analysis/${analysisId}`; + + const response = await axios.get(url, { + headers: { + Accept: "application/json", + Authorization: authToken.startsWith("Bearer ") + ? authToken + : `Bearer ${authToken}`, + }, + }); + + if (response.status === 200) { + studyId = study; + analysis = response.data; + Logger.info(`Found analysis ${analysisId} in study ${studyId}`); + break; + } + } catch (error) { + // Continue to next study if analysis not found + continue; + } + } + + if (!analysis || !studyId) { + throw new ConductorError( + `Analysis ${analysisId} not found in any study`, + ErrorCodes.CONNECTION_ERROR + ); + } + + // 2. Extract file information from the analysis + const files = analysis.files || []; + + if (files.length === 0) { + throw new ConductorError( + `No files found in analysis ${analysisId}`, + ErrorCodes.VALIDATION_FAILED + ); + } + + Logger.info(`Found ${files.length} files in analysis ${analysisId}`); + + // 3. Generate manifest content with the correct format + // First line: analysis ID followed by two tabs + let manifestContent = `${analysisId}\t\t\n`; + + for (const file of files) { + // Extract required fields + const objectId = file.objectId; + const fileName = file.fileName; + const fileMd5sum = file.fileMd5sum; + + if (!objectId || !fileName || !fileMd5sum) { + Logger.warn( + `Missing required fields for file: ${JSON.stringify(file)}` + ); + continue; + } + + // Use absolute path format for the container + // Convert from local path to container path + const containerFilePath = `/data/fileData/${fileName}`; + + // Add file entry with the correct format + manifestContent += `${objectId}\t${containerFilePath}\t${fileMd5sum}\n`; + } + + // 4. Write the manifest to file + Logger.debug( + `Writing manifest content to ${manifestFile}:\n${manifestContent}` + ); + + // Create directory if it doesn't exist + const manifestDir = path.dirname(manifestFile); + if (!fs.existsSync(manifestDir)) { + fs.mkdirSync(manifestDir, { recursive: true }); + } + + fs.writeFileSync(manifestFile, manifestContent); + + Logger.info(`Successfully generated manifest at ${manifestFile}`); + } catch (error: any) { + // Handle errors + Logger.error(`Direct manifest generation failed`); + + throw new ConductorError( + `Failed to generate manifest: ${error.message || "Unknown error"}`, + ErrorCodes.CONNECTION_ERROR, + error + ); + } + } + + /** + * Fetch all studies from SONG server + */ + private async fetchAllStudies( + baseUrl: string, + authToken: string + ): Promise { + const url = `${baseUrl}/studies/all`; + + try { + const response = await axios.get(url, { + headers: { + Accept: "application/json", + Authorization: authToken.startsWith("Bearer ") + ? authToken + : `Bearer ${authToken}`, + }, + }); + + if (response.status !== 200) { + throw new Error( + `HTTP error ${response.status}: ${response.statusText}` + ); + } + + return response.data; + } catch (error: any) { + throw new ConductorError( + `Failed to fetch studies: ${error.message || "Unknown error"}`, + ErrorCodes.CONNECTION_ERROR, + error + ); + } + } + + /** + * Update the validate method to throw errors directly + */ + protected async validate(cliOutput: CLIOutput): Promise { + const { options } = cliOutput; + const analysisId = + options.analysisId || + cliOutput.config.score?.analysisId || + (process?.env?.ANALYSIS_ID as string | undefined); + const dataDir = + options.dataDir || + cliOutput.config.score?.dataDir || + process?.env?.DATA_DIR || + "./data/fileData"; + + // Validate analysis ID + if (!analysisId) { + throw new ConductorError( + "No analysis ID provided. Use --analysis-id option or set ANALYSIS_ID environment variable.", + ErrorCodes.INVALID_ARGS + ); + } + + // Verify data directory exists + if (!fs.existsSync(dataDir)) { + throw new ConductorError( + `Data directory not found: ${dataDir}`, + ErrorCodes.FILE_NOT_FOUND + ); + } + + // Check if Docker is available + try { + await execPromise("docker --version"); + } catch (error) { + Logger.warn( + `Docker not available. This command requires Docker with song-client and score-client containers.` + ); + Logger.tip( + `Install Docker and start the required containers before running this command.` + ); + throw new ConductorError( + "Docker is required for this command", + ErrorCodes.INVALID_ARGS, + { + suggestion: + "Install Docker and ensure song-client and score-client containers are running", + } + ); + } + } +} diff --git a/apps/conductor/src/commands/songCreateStudyCommand.ts b/apps/conductor/src/commands/songCreateStudyCommand.ts new file mode 100644 index 00000000..21039e4a --- /dev/null +++ b/apps/conductor/src/commands/songCreateStudyCommand.ts @@ -0,0 +1,391 @@ +import axios from "axios"; +import { Command, CommandResult } from "./baseCommand"; +import { CLIOutput } from "../types/cli"; +import { Logger } from "../utils/logger"; +import chalk from "chalk"; +import { ConductorError, ErrorCodes } from "../utils/errors"; + +/** + * Response from SONG study creation + */ +export interface SongStudyResponse { + /** The study ID */ + studyId?: string; + + /** The name of the study */ + name?: string; + + /** The organization for the study */ + organization?: string; + + /** Any error message returned by SONG */ + error?: string; + + /** Additional response details */ + [key: string]: any; +} + +/** + * Command for creating a new study in the SONG service + */ +export class SongCreateStudyCommand extends Command { + private readonly MAX_RETRIES = 3; + private readonly RETRY_DELAY = 5000; // 5 seconds + private readonly TIMEOUT = 10000; // 10 seconds + + constructor() { + super("SONG Study Creation"); + } + + /** + * Normalize URL to ensure it has the proper format + * @param url Original URL + * @returns Normalized URL + */ + private normalizeUrl(url: string): string { + // Remove trailing slash if present + return url.endsWith("/") ? url.slice(0, -1) : url; + } + + /** + * Checks SONG service health + * @param url SONG service URL + * @returns Promise resolving to boolean indicating health status + */ + private async checkSongHealth(url: string): Promise { + // Use isAlive endpoint for SONG health check + const healthUrl = `${url}/isAlive`; + + try { + Logger.info(`Checking SONG health: ${healthUrl}`); + + const response = await axios.get(healthUrl, { + timeout: this.TIMEOUT, + headers: { accept: "*/*" }, + }); + + // Check for health status + const isHealthy = response.status === 200; + + if (isHealthy) { + Logger.info(`\x1b[32mSuccess:\x1b[0m SONG is healthy`); + return true; + } + + Logger.warn(`SONG health check failed. Status: ${response.status}`); + return false; + } catch (error) { + Logger.warn(`SONG health check failed`); + Logger.error(`\x1b[31mFailed to connect to SONG service\x1b[0m`); + return false; + } + } + + /** + * Checks if a study already exists + * @param url SONG service URL + * @param studyId Study ID to check + * @param authToken Authentication token + * @returns Promise resolving to boolean indicating if study exists + */ + private async checkStudyExists( + url: string, + studyId: string, + authToken: string + ): Promise { + try { + const studyUrl = `${url}/studies/${studyId}`; + Logger.debug(`Checking if study exists: ${studyUrl}`); + + const response = await axios.get(studyUrl, { + timeout: this.TIMEOUT, + headers: { + accept: "*/*", + Authorization: authToken, + }, + }); + + return response.status === 200; + } catch (error: any) { + // If we get a 404, study doesn't exist + if (error.response && error.response.status === 404) { + return false; + } + + // For other errors, log and assume study doesn't exist + Logger.warn(`Error checking if study exists: ${error.message}`); + return false; + } + } + + /** + * Executes the SONG study creation process + * @param cliOutput The CLI configuration and inputs + * @returns A CommandResult indicating success or failure + */ + protected async execute(cliOutput: CLIOutput): Promise { + const { options } = cliOutput; + + try { + // Extract configuration from options or environment + const songUrl = options.songUrl || process.env.SONG_URL; + const studyId = options.studyId || process.env.STUDY_ID || "demo"; + const studyName = options.studyName || process.env.STUDY_NAME || "string"; + const organization = + options.organization || process.env.ORGANIZATION || "string"; + const description = + options.description || process.env.DESCRIPTION || "string"; + const authToken = options.authToken || process.env.AUTH_TOKEN || "123"; + const force = options.force || false; + + // Validate required parameters + if (!songUrl) { + throw new ConductorError( + "SONG URL not specified. Use --song-url or set SONG_URL environment variable.", + ErrorCodes.INVALID_ARGS + ); + } + + // Normalize URL + const normalizedUrl = this.normalizeUrl(songUrl); + + // First, check SONG service health + const isHealthy = await this.checkSongHealth(normalizedUrl); + if (!isHealthy) { + throw new ConductorError( + "Unable to establish connection with SONG service", + ErrorCodes.CONNECTION_ERROR + ); + } + + // Check if study already exists + const studyExists = await this.checkStudyExists( + normalizedUrl, + studyId, + authToken + ); + if (studyExists && !force) { + Logger.warn(`Study ID ${studyId} already exists`); + + return { + success: true, + details: { + studyId, + status: "EXISTING", + message: `Study ID ${studyId} already exists`, + }, + }; + } else if (studyExists && force) { + Logger.warn( + `Study ID ${studyId} already exists, continuing with force option` + ); + } + + // Prepare study payload + const studyPayload = { + description, + info: {}, + name: studyName, + organization, + studyId, + }; + + // Upload study + Logger.info( + `\x1b[1;36mStudy Upload:\x1b[0m Uploading study to ${normalizedUrl}/studies/${studyId}/` + ); + + let response; + let attempt = 0; + let lastError; + + while (attempt < this.MAX_RETRIES) { + attempt++; + try { + response = await axios.post( + `${normalizedUrl}/studies/${studyId}/`, + studyPayload, + { + headers: { + accept: "*/*", + Authorization: authToken, + "Content-Type": "application/json", + }, + timeout: this.TIMEOUT, + } + ); + + // Upload successful + break; + } catch (error: any) { + lastError = error; + + // Extract detailed error information from Axios error + if (error.response) { + // Server responded with non-2xx status code + const status = error.response.status; + const responseData = error.response.data; + + Logger.error(`Server responded with status ${status}`); + + // Handle existing study error + if (status === 409) { + Logger.warn(`Study ID ${studyId} already exists`); + + // Return success with existing status if the study already exists + return { + success: true, + details: { + studyId, + status: "EXISTING", + message: `Study ID ${studyId} already exists`, + }, + }; + } + + // Handle standard SONG error format + if (responseData && typeof responseData === "object") { + if (responseData.message) { + Logger.error(`Error message: ${responseData.message}`); + } + + if (responseData.debugMessage) { + Logger.error(`Debug message: ${responseData.debugMessage}`); + } + } else { + // Log raw response if not in expected format + Logger.error( + `Raw error response: ${JSON.stringify(responseData)}` + ); + } + } else if (error.request) { + // Request was made but no response received + Logger.error(`No response received from server: ${error.message}`); + } else { + // Error in setting up the request + Logger.error(`Error setting up request: ${error.message}`); + } + + if (attempt < this.MAX_RETRIES) { + Logger.warn( + `Study creation attempt ${attempt} failed, retrying in ${ + this.RETRY_DELAY / 1000 + }s...` + ); + await new Promise((resolve) => + setTimeout(resolve, this.RETRY_DELAY) + ); + } + } + } + + // Check if upload succeeded + if (!response) { + throw ( + lastError || + new ConductorError( + "Failed to create study after multiple attempts", + ErrorCodes.CONNECTION_ERROR + ) + ); + } + + // Process response + const result = response.data; + + // Create strongly typed result object + const typedResult: SongStudyResponse = { + studyId, + name: studyName, + organization, + }; + + Logger.success(`Study created successfully`); + Logger.generic(" "); + Logger.generic( + chalk.gray(` - Study ID: ${typedResult.studyId || studyId}`) + ); + Logger.generic( + chalk.gray(` - Study Name: ${typedResult.name || studyName}`) + ); + Logger.generic( + chalk.gray( + ` - Organization: ${typedResult.organization || organization}` + ) + ); + Logger.generic(" "); + + return { + success: true, + details: { + ...typedResult, + status: "CREATED", + }, + }; + } catch (error) { + // Handle errors and return failure result + const errorMessage = + error instanceof Error ? error.message : String(error); + const errorCode = + error instanceof ConductorError + ? error.code + : ErrorCodes.CONNECTION_ERROR; + + // Add extra details to the error result + const details = error instanceof ConductorError ? error.details : {}; + + return { + success: false, + errorMessage, + errorCode, + details, + }; + } + } + + /** + * Validates command line arguments. + * This implementation ensures that SONG URL is provided. + * + * @param cliOutput - The parsed command line arguments + * @throws ConductorError if validation fails + */ + protected async validate(cliOutput: CLIOutput): Promise { + const { options } = cliOutput; + + // Validate SONG URL + const songUrl = options.songUrl || process.env.SONG_URL; + if (!songUrl) { + throw new ConductorError( + "No SONG URL provided. Use --song-url option or set SONG_URL environment variable.", + ErrorCodes.INVALID_ARGS + ); + } + + // Optional additional validations + const studyId = options.studyId || process.env.STUDY_ID || "demo"; + if (!studyId) { + throw new ConductorError( + "Study ID is invalid or not specified.", + ErrorCodes.INVALID_ARGS + ); + } + + const studyName = options.studyName || process.env.STUDY_NAME || "string"; + if (!studyName) { + throw new ConductorError( + "Study name is invalid or not specified.", + ErrorCodes.INVALID_ARGS + ); + } + + const organization = + options.organization || process.env.ORGANIZATION || "string"; + if (!organization) { + throw new ConductorError( + "Organization is invalid or not specified.", + ErrorCodes.INVALID_ARGS + ); + } + } +} diff --git a/apps/conductor/src/commands/songPublishAnalysisCommand.ts b/apps/conductor/src/commands/songPublishAnalysisCommand.ts new file mode 100644 index 00000000..2bb79663 --- /dev/null +++ b/apps/conductor/src/commands/songPublishAnalysisCommand.ts @@ -0,0 +1,269 @@ +import axios from "axios"; +import { Command, CommandResult } from "./baseCommand"; +import { CLIOutput } from "../types/cli"; +import { Logger } from "../utils/logger"; +import chalk from "chalk"; +import { ConductorError, ErrorCodes } from "../utils/errors"; + +/** + * Command for publishing a Song analysis after file upload + * Uses the SONG REST API directly based on the Swagger spec + */ +export class SongPublishAnalysisCommand extends Command { + private readonly MAX_RETRIES = 1; + private readonly RETRY_DELAY = 5000; // 5 seconds + private readonly TIMEOUT = 10000; // 10 seconds + + constructor() { + super("SONG Analysis Publication"); + } + + /** + * Executes the SONG analysis publication process + * @param cliOutput The CLI configuration and inputs + * @returns A CommandResult indicating success or failure + */ + protected async execute(cliOutput: CLIOutput): Promise { + const { options } = cliOutput; + + try { + // Extract configuration from options or environment + const analysisId = options.analysisId || process.env.ANALYSIS_ID; + const studyId = options.studyId || process.env.STUDY_ID || "demo"; + const songUrl = + options.songUrl || process.env.SONG_URL || "http://localhost:8080"; + const authToken = options.authToken || process.env.AUTH_TOKEN || "123"; + const ignoreUndefinedMd5 = options.ignoreUndefinedMd5 || false; + + // Validate required parameters + if (!analysisId) { + throw new ConductorError( + "Analysis ID not specified. Use --analysis-id or set ANALYSIS_ID environment variable.", + ErrorCodes.INVALID_ARGS + ); + } + + // Log publication details + Logger.info(`\x1b[1;36mPublishing Analysis:\x1b[0m`); + Logger.info(`Analysis ID: ${analysisId}`); + Logger.info(`Study ID: ${studyId}`); + Logger.info(`Song URL: ${songUrl}`); + + // Publish the analysis via REST API + const publishResult = await this.publishAnalysisViaAPI( + studyId, + analysisId, + songUrl, + authToken, + ignoreUndefinedMd5 + ); + + // Log success + Logger.success(`Analysis published successfully`); + Logger.generic(" "); + Logger.generic(chalk.gray(` - Analysis ID: ${analysisId}`)); + Logger.generic(chalk.gray(` - Study ID: ${studyId}`)); + Logger.generic(" "); + + return { + success: true, + details: { + analysisId, + studyId, + message: publishResult.message || "Successfully published", + }, + }; + } catch (error) { + // Handle errors and return failure result + const errorMessage = + error instanceof Error ? error.message : String(error); + const errorCode = + error instanceof ConductorError + ? error.code + : ErrorCodes.CONNECTION_ERROR; + const details = error instanceof ConductorError ? error.details : {}; + + // Special handling for common error cases + if (errorMessage.includes("not found")) { + Logger.tip( + "Make sure the analysis ID exists and belongs to the specified study" + ); + } else if ( + errorMessage.includes("unauthorized") || + errorMessage.includes("permission") + ) { + Logger.tip("Check that you have the correct authorization token"); + } + + return { + success: false, + errorMessage, + errorCode, + details, + }; + } + } + + /** + * Publishes an analysis using the SONG REST API + * Based on the SONG Swagger specification for the publish endpoint + * + * @param studyId - Study ID + * @param analysisId - Analysis ID to publish + * @param songUrl - Song server URL + * @param authToken - Authorization token + * @param ignoreUndefinedMd5 - Whether to ignore undefined MD5 checksums + * @returns Object with the publish result + */ + private async publishAnalysisViaAPI( + studyId: string, + analysisId: string, + songUrl: string, + authToken: string, + ignoreUndefinedMd5: boolean + ): Promise<{ message: string }> { + Logger.info("Using SONG REST API to publish analysis"); + + // Normalize URL by removing trailing slash if present + const baseUrl = songUrl.endsWith("/") ? songUrl.slice(0, -1) : songUrl; + + // Construct the publish endpoint URL + // Format: /studies/{studyId}/analysis/publish/{analysisId} + const publishUrl = `${baseUrl}/studies/${studyId}/analysis/publish/${analysisId}`; + + // Set up headers with authorization + const headers = { + Accept: "application/json", + Authorization: authToken.startsWith("Bearer ") + ? authToken + : `Bearer ${authToken}`, + }; + + // Add the ignoreUndefinedMd5 query parameter if needed + const params: Record = {}; + if (ignoreUndefinedMd5) { + params.ignoreUndefinedMd5 = true; + } + + Logger.debug(`Making PUT request to: ${publishUrl}`); + Logger.debug(`Headers: ${JSON.stringify(headers)}`); + Logger.debug(`Params: ${JSON.stringify(params)}`); + + try { + // Make the PUT request + // According to the SONG API Swagger spec, the publish endpoint is a PUT request + // with no request body, and optional ignoreUndefinedMd5 query parameter + const response = await axios.put(publishUrl, null, { + headers, + params, + timeout: this.TIMEOUT, + }); + + Logger.debug(`Publish response: ${JSON.stringify(response.data)}`); + + // Return the response message + // Fixed type checking error by properly handling different response types + return { + message: + typeof response.data === "object" && + response.data !== null && + "message" in response.data + ? String(response.data.message) + : "Successfully published", + }; + } catch (error: any) { + // Extract detailed error information if available + if (error.response) { + const status = error.response.status; + const data = error.response.data; + + Logger.error(`API error ${status}: ${JSON.stringify(data)}`); + + // For common status codes, provide more helpful error messages + if (status === 401 || status === 403) { + throw new ConductorError( + `Authentication failed: Invalid or expired token`, + ErrorCodes.CONNECTION_ERROR, + { status, responseData: data } + ); + } else if (status === 404) { + throw new ConductorError( + `Analysis not found: Check that analysis ${analysisId} exists in study ${studyId}`, + ErrorCodes.FILE_NOT_FOUND, + { status, responseData: data } + ); + } else if (status === 409) { + throw new ConductorError( + `Conflict: The analysis may already be published or in an invalid state`, + ErrorCodes.VALIDATION_FAILED, + { status, responseData: data } + ); + } + + // Generic error with the available details + throw new ConductorError( + `Publishing failed with status ${status}: ${ + typeof data === "object" && data !== null && "message" in data + ? String(data.message) + : "Unknown error" + }`, + ErrorCodes.CONNECTION_ERROR, + { status, responseData: data } + ); + } + + // Network errors, timeouts, etc. + throw new ConductorError( + `Failed to connect to SONG API: ${error.message}`, + ErrorCodes.CONNECTION_ERROR, + error + ); + } + } + + /** + * Validates command line arguments. + * This implementation ensures that analysis ID is provided. + * + * @param cliOutput - The parsed command line arguments + * @throws ConductorError if validation fails + */ + protected async validate(cliOutput: CLIOutput): Promise { + const { options } = cliOutput; + + // Validate analysis ID + const analysisId = + options.analysisId || + cliOutput.config.score?.analysisId || + process.env.ANALYSIS_ID; + if (!analysisId) { + throw new ConductorError( + "No analysis ID provided. Use --analysis-id option or set ANALYSIS_ID environment variable.", + ErrorCodes.INVALID_ARGS + ); + } + + // Validate SONG URL + const songUrl = + options.songUrl || cliOutput.config.song?.url || process.env.SONG_URL; + if (!songUrl) { + throw new ConductorError( + "No SONG URL provided. Use --song-url option or set SONG_URL environment variable.", + ErrorCodes.INVALID_ARGS + ); + } + + // Optional validations + const studyId = + options.studyId || + cliOutput.config.song?.studyId || + process.env.STUDY_ID || + "demo"; + if (!studyId) { + throw new ConductorError( + "Study ID is invalid or not specified.", + ErrorCodes.INVALID_ARGS + ); + } + } +} diff --git a/apps/conductor/src/commands/songScoreSubmitCommand.ts b/apps/conductor/src/commands/songScoreSubmitCommand.ts new file mode 100644 index 00000000..8c1f24de --- /dev/null +++ b/apps/conductor/src/commands/songScoreSubmitCommand.ts @@ -0,0 +1,758 @@ +import { Command, CommandResult } from "./baseCommand"; +import { CLIOutput } from "../types/cli"; +import { Logger } from "../utils/logger"; +import { ConductorError, ErrorCodes } from "../utils/errors"; +import axios from "axios"; +import * as fs from "fs"; +import * as path from "path"; +import { promisify } from "util"; +import { exec } from "child_process"; + +const execPromise = promisify(exec); + +/** + * Command for submitting analysis to SONG, generating a manifest, and uploading files to SCORE in one operation + */ +export class SongScoreSubmitCommand extends Command { + private readonly SONG_EXEC_TIMEOUT = 60000; // 60 seconds + private readonly SCORE_EXEC_TIMEOUT = 300000; // 5 minutes for larger uploads + private readonly TIMEOUT = 10000; // 10 seconds + + constructor() { + super("SONG/SCORE Analysis Submission"); + this.defaultOutputFileName = "manifest.txt"; + this.defaultOutputPath = "./output"; + } + + /** + * Executes the combined SONG/SCORE submission process + * @param cliOutput The CLI configuration and inputs + * @returns A CommandResult indicating success or failure + */ + protected async execute(cliOutput: CLIOutput): Promise { + const { config, options } = cliOutput; + + try { + // Extract configuration + const analysisPath = + options.analysisPath || + config.song?.analysisPath || + process?.env?.ANALYSIS_PATH || + "./analysis.json"; + + const studyId = + options.studyId || + config.song?.studyId || + process?.env?.STUDY_ID || + "demo"; + + const songUrl = + options.songUrl || + config.song?.url || + process?.env?.SONG_URL || + "http://localhost:8080"; + + const scoreUrl = + options.scoreUrl || + config.score?.url || + process?.env?.SCORE_URL || + "http://localhost:8087"; + + const dataDir = + options.dataDir || + config.score?.dataDir || + process?.env?.DATA_DIR || + "./data/fileData"; + + const outputDir = + options.outputDir || + config.score?.outputDir || + process?.env?.OUTPUT_DIR || + "./output"; + + const manifestFile = + options.manifestFile || + config.score?.manifestFile || + process?.env?.MANIFEST_FILE || + path.join(outputDir, "manifest.txt"); + + const authToken = + options.authToken || + config.score?.authToken || + config.song?.authToken || + process?.env?.AUTH_TOKEN || + "123"; + + // Validate required parameters + if (!fs.existsSync(analysisPath)) { + throw new ConductorError( + `Analysis file not found at: ${analysisPath}`, + ErrorCodes.FILE_NOT_FOUND + ); + } + + // Create output directory if it doesn't exist + this.createDirectoryIfNotExists(path.dirname(manifestFile)); + + // Log the configuration + Logger.info(`\x1b[1;36mSONG/SCORE Submission Configuration:\x1b[0m`); + Logger.info(`Analysis File: ${analysisPath}`); + Logger.info(`Study ID: ${studyId}`); + Logger.info(`Song URL: ${songUrl}`); + Logger.info(`Score URL: ${scoreUrl}`); + Logger.info(`Data Directory: ${dataDir}`); + Logger.info(`Output Directory: ${outputDir}`); + Logger.info(`Manifest File: ${manifestFile}`); + + // STEP 1: Submit analysis to SONG and get analysis ID + Logger.info(`\x1b[1;36mSubmitting Analysis to SONG:\x1b[0m`); + const analysisId = await this.submitAnalysisToSong( + analysisPath, + studyId, + songUrl, + authToken + ); + Logger.success(`Successfully submitted analysis with ID: ${analysisId}`); + + // Check if Docker containers are available + const useSongDocker = await this.checkIfDockerContainerRunning( + "song-client" + ); + const useScoreDocker = await this.checkIfDockerContainerRunning( + "score-client" + ); + + // STEP 2: Generate manifest file + Logger.info(`\x1b[1;36mGenerating Manifest:\x1b[0m`); + if (useSongDocker) { + Logger.info(`Using Song Docker client to generate manifest`); + await this.generateManifestWithSongClient( + analysisId, + manifestFile, + dataDir, + authToken, + songUrl + ); + } else { + Logger.info(`Using direct manifest generation approach`); + await this.generateManifestDirect( + analysisId, + manifestFile, + dataDir, + authToken, + songUrl + ); + } + Logger.success(`Successfully generated manifest at ${manifestFile}`); + + // STEP 3: Upload files using the manifest + Logger.info(`\x1b[1;36mUploading Files with Score:\x1b[0m`); + if (useScoreDocker) { + Logger.info(`Using Score Docker client to upload files`); + await this.uploadWithScoreClient(manifestFile, authToken, scoreUrl); + } else { + Logger.warn( + `Direct file upload without Score client is not recommended.` + ); + Logger.info( + `Please install and run the score-client Docker container for reliable uploads.` + ); + throw new ConductorError( + "Direct file upload requires Score client. Please ensure score-client Docker container is running.", + ErrorCodes.INVALID_ARGS + ); + } + Logger.success(`Successfully uploaded files with Score`); + + // STEP 4: Publish the analysis + Logger.info(`\x1b[1;36mPublishing Analysis:\x1b[0m`); + await this.publishAnalysis(studyId, analysisId, songUrl, authToken); + Logger.success(`Successfully published analysis ${analysisId}`); + + // Log success details + Logger.generic(" "); + Logger.generic(` - Analysis ID: ${analysisId}`); + Logger.generic(` - Study ID: ${studyId}`); + Logger.generic(` - Manifest file: ${manifestFile}`); + Logger.generic(" "); + + return { + success: true, + details: { + analysisId, + studyId, + manifestFile, + }, + }; + } catch (error) { + // Handle and log errors + if (error instanceof ConductorError) { + throw error; + } + + const errorMessage = + error instanceof Error ? error.message : String(error); + + Logger.error(`SONG/SCORE submission failed: ${errorMessage}`); + + throw new ConductorError( + `SONG/SCORE submission failed: ${errorMessage}`, + ErrorCodes.CONNECTION_ERROR, + error + ); + } + } + + /** + * Submit analysis to SONG and get the analysis ID + */ + private async submitAnalysisToSong( + analysisPath: string, + studyId: string, + songUrl: string, + authToken: string + ): Promise { + try { + // Read analysis file + const analysisData = JSON.parse(fs.readFileSync(analysisPath, "utf8")); + + // Normalize URL + const baseUrl = songUrl.endsWith("/") ? songUrl.slice(0, -1) : songUrl; + const submitUrl = `${baseUrl}/submit/${studyId}`; + + Logger.info(`Submitting analysis to: ${submitUrl}`); + + // Make the request + const response = await axios.post(submitUrl, analysisData, { + headers: { + "Content-Type": "application/json", + Authorization: authToken.startsWith("Bearer ") + ? authToken + : `Bearer ${authToken}`, + }, + }); + + // Extract analysis ID from response + const responseData = response.data as { analysisId?: string }; + let analysisId; + + if (responseData && responseData.analysisId) { + analysisId = responseData.analysisId; + } else if (typeof response.data === "string") { + // Try to extract from string response + const match = response.data.match(/"analysisId"\s*:\s*"([^"]+)"/); + if (match && match[1]) { + analysisId = match[1]; + } + } + + if (!analysisId) { + throw new Error("No analysis ID returned from SONG API"); + } + + return analysisId; + } catch (error: any) { + Logger.error(`Analysis submission failed`); + + // More detailed error logging + if (error.response) { + // Server responded with a status code outside of 2xx range + Logger.error(`Status: ${error.response.status}`); + Logger.error(`Data: ${JSON.stringify(error.response.data)}`); + } else if (error.request) { + // Request was made but no response received + Logger.error(`No response received: ${error.request}`); + } else { + // Something happened in setting up the request + Logger.error(`Error: ${error.message}`); + } + + throw new ConductorError( + `Failed to submit analysis: ${ + error.response?.data?.message || error.message || "Unknown error" + }`, + ErrorCodes.CONNECTION_ERROR, + error + ); + } + } + + // For the error at line 143 (6 arguments instead of 5) + private async generateManifestWithSongClient( + analysisId: string, + manifestFile: string, + dataDir: string, + authToken: string, + songUrl: string + ): Promise { + try { + // Convert local paths to container paths + const containerManifestPath = "/output/manifest.txt"; + const containerDataDir = "/data/fileData"; + + // Construct Docker song-client manifest command + const command = [ + `docker exec`, + `song-client`, + `sh -c "sing manifest -a ${analysisId} -f ${containerManifestPath} -d ${containerDataDir}"`, + ].join(" "); + + Logger.debug(`Executing: ${command}`); + + // Execute the command + const { stdout, stderr } = await execPromise(command, { + timeout: this.SONG_EXEC_TIMEOUT, + }); + + // Log output + if (stdout) Logger.debug(`SONG manifest stdout: ${stdout}`); + if (stderr) Logger.warn(`SONG manifest stderr: ${stderr}`); + + // Check if manifest file exists after generation + if (!fs.existsSync(manifestFile)) { + throw new ConductorError( + `Manifest file not generated at expected path: ${manifestFile}`, + ErrorCodes.FILE_NOT_FOUND + ); + } + + // Log manifest file content + const manifestContent = fs.readFileSync(manifestFile, "utf8"); + Logger.debug(`Generated manifest content: \n${manifestContent}`); + } catch (error: any) { + // Handle execution errors + Logger.error(`SONG client manifest generation failed`); + + if (error.stdout) Logger.debug(`Stdout: ${error.stdout}`); + if (error.stderr) Logger.debug(`Stderr: ${error.stderr}`); + + throw new ConductorError( + `Failed to generate manifest: ${error.message || "Unknown error"}`, + ErrorCodes.CONNECTION_ERROR, + error + ); + } + } + + // For the error at line 413 (files property not existing) + private async generateManifestDirect( + analysisId: string, + manifestFile: string, + dataDir: string, + authToken: string, + songUrl: string + ): Promise { + try { + // Typed interface for analysis response + interface AnalysisResponse { + files?: Array<{ + objectId?: string; + fileName?: string; + fileMd5sum?: string; + }>; + studyId?: string; + [key: string]: any; + } + + // Remove trailing slash from URL if present + const baseUrl = songUrl.endsWith("/") ? songUrl.slice(0, -1) : songUrl; + + // First, try to get all studies + const studies = await this.fetchAllStudies(baseUrl, authToken); + + if (!studies || studies.length === 0) { + throw new ConductorError( + "No studies found in SONG server", + ErrorCodes.CONNECTION_ERROR + ); + } + + let analysis: AnalysisResponse | null = null; + let studyId: string | null = null; + + for (const study of studies) { + try { + Logger.debug(`Checking study ${study} for analysis ${analysisId}`); + const url = `${baseUrl}/studies/${study}/analysis/${analysisId}`; + + const response = await axios.get(url, { + headers: { + Accept: "application/json", + Authorization: authToken.startsWith("Bearer ") + ? authToken + : `Bearer ${authToken}`, + }, + }); + + if (response.status === 200) { + analysis = response.data; + studyId = study; + break; + } + } catch (error) { + // Continue to next study if analysis not found + continue; + } + } + + if (!analysis || !studyId) { + throw new ConductorError( + `Analysis ${analysisId} not found in any study`, + ErrorCodes.CONNECTION_ERROR + ); + } + + // 2. Extract file information from the analysis + const files = analysis.files || []; + + if (files.length === 0) { + throw new ConductorError( + `No files found in analysis ${analysisId}`, + ErrorCodes.VALIDATION_FAILED + ); + } + + Logger.info(`Found ${files.length} files in analysis ${analysisId}`); + + // 3. Generate manifest content with the correct format + // First line: analysis ID followed by two tabs + let manifestContent = `${analysisId}\t\t\n`; + + for (const file of files) { + // Extract required fields + const objectId = file.objectId; + const fileName = file.fileName; + const fileMd5sum = file.fileMd5sum; + + if (!objectId || !fileName || !fileMd5sum) { + Logger.warn( + `Missing required fields for file: ${JSON.stringify(file)}` + ); + continue; + } + + // Use absolute path for the file in the data directory + const filePath = path.join(dataDir, fileName); + + // Add file entry with the correct format + manifestContent += `${objectId}\t${filePath}\t${fileMd5sum}\n`; + } + + // 4. Write the manifest to file + Logger.debug( + `Writing manifest content to ${manifestFile}:\n${manifestContent}` + ); + + // Create directory if it doesn't exist + const manifestDir = path.dirname(manifestFile); + if (!fs.existsSync(manifestDir)) { + fs.mkdirSync(manifestDir, { recursive: true }); + } + + fs.writeFileSync(manifestFile, manifestContent); + + Logger.info(`Successfully generated manifest at ${manifestFile}`); + } catch (error: any) { + // Handle errors + Logger.error(`Direct manifest generation failed`); + + throw new ConductorError( + `Failed to generate manifest: ${error.message || "Unknown error"}`, + ErrorCodes.CONNECTION_ERROR, + error + ); + } + } + + /** + * Fetch all studies from SONG server + */ + private async fetchAllStudies( + baseUrl: string, + authToken: string + ): Promise { + const url = `${baseUrl}/studies/all`; + + try { + const response = await axios.get(url, { + headers: { + Accept: "application/json", + Authorization: authToken.startsWith("Bearer ") + ? authToken + : `Bearer ${authToken}`, + }, + }); + + if (response.status !== 200) { + throw new Error( + `HTTP error ${response.status}: ${response.statusText}` + ); + } + + // Ensure we always return an array of strings + return Array.isArray(response.data) + ? response.data + : [response.data as string]; + } catch (error: any) { + throw new ConductorError( + `Failed to fetch studies: ${error.message || "Unknown error"}`, + ErrorCodes.CONNECTION_ERROR, + error + ); + } + } + + /** + * Upload files using score-client via Docker + */ + private async uploadWithScoreClient( + manifestFile: string, + authToken: string, + scoreUrl: string + ): Promise { + try { + // Convert local path to container path + const containerManifestPath = "/output/manifest.txt"; + + // Construct Docker score-client upload command + const command = [ + `docker exec`, + `score-client`, + `sh -c "score-client upload --manifest ${containerManifestPath}"`, + ].join(" "); + + Logger.debug(`Executing: ${command}`); + + // Execute the command + const { stdout, stderr } = await execPromise(command, { + timeout: this.SCORE_EXEC_TIMEOUT, + }); + + // Log output + if (stdout) Logger.debug(`SCORE upload stdout: ${stdout}`); + if (stderr) Logger.warn(`SCORE upload stderr: ${stderr}`); + } catch (error: any) { + // Handle execution errors + Logger.error(`Score client upload failed`); + + if (error.stdout) Logger.debug(`Stdout: ${error.stdout}`); + if (error.stderr) Logger.debug(`Stderr: ${error.stderr}`); + + throw new ConductorError( + `Failed to upload with Score: ${error.message || "Unknown error"}`, + ErrorCodes.CONNECTION_ERROR, + error + ); + } + } + /** + * Publishes an analysis using the SONG REST API + * Based on the SONG Swagger specification for the publish endpoint + * + * @param studyId - Study ID + * @param analysisId - Analysis ID to publish + * @param songUrl - Song server URL + * @param authToken - Authorization token + * @param ignoreUndefinedMd5 - Whether to ignore undefined MD5 checksums + * @returns Object with the publish result + */ + private async publishAnalysis( + studyId: string, + analysisId: string, + songUrl: string, + authToken: string + ): Promise<{ message: string }> { + Logger.info("Using SONG REST API to publish analysis"); + + // Normalize URL by removing trailing slash if present + const baseUrl = songUrl.endsWith("/") ? songUrl.slice(0, -1) : songUrl; + + // Construct the publish endpoint URL + // Format: /studies/{studyId}/analysis/publish/{analysisId} + const publishUrl = `${baseUrl}/studies/${studyId}/analysis/publish/${analysisId}`; + + // Set up headers with authorization + const headers = { + Accept: "application/json", + Authorization: authToken.startsWith("Bearer ") + ? authToken + : `Bearer ${authToken}`, + }; + + Logger.debug(`Making PUT request to: ${publishUrl}`); + Logger.debug(`Headers: ${JSON.stringify(headers)}`); + + try { + // Make the PUT request + // According to the SONG API Swagger spec, the publish endpoint is a PUT request + // with no request body, and optional ignoreUndefinedMd5 query parameter + const response = await axios.put(publishUrl, null, { + headers, + timeout: this.TIMEOUT, + }); + + Logger.debug(`Publish response: ${JSON.stringify(response.data)}`); + + // Return the response message + // Fixed type checking error by properly handling different response types + return { + message: + typeof response.data === "object" && + response.data !== null && + "message" in response.data + ? String(response.data.message) + : "Successfully published", + }; + } catch (error: any) { + // Extract detailed error information if available + if (error.response) { + const status = error.response.status; + const data = error.response.data; + + Logger.error(`API error ${status}: ${JSON.stringify(data)}`); + + // For common status codes, provide more helpful error messages + if (status === 401 || status === 403) { + throw new ConductorError( + `Authentication failed: Invalid or expired token`, + ErrorCodes.CONNECTION_ERROR, + { status, responseData: data } + ); + } else if (status === 404) { + throw new ConductorError( + `Analysis not found: Check that analysis ${analysisId} exists in study ${studyId}`, + ErrorCodes.FILE_NOT_FOUND, + { status, responseData: data } + ); + } else if (status === 409) { + throw new ConductorError( + `Conflict: The analysis may already be published or in an invalid state`, + ErrorCodes.VALIDATION_FAILED, + { status, responseData: data } + ); + } + + // Generic error with the available details + throw new ConductorError( + `Publishing failed with status ${status}: ${ + typeof data === "object" && data !== null && "message" in data + ? String(data.message) + : "Unknown error" + }`, + ErrorCodes.CONNECTION_ERROR, + { status, responseData: data } + ); + } + + // Network errors, timeouts, etc. + throw new ConductorError( + `Failed to connect to SONG API: ${error.message}`, + ErrorCodes.CONNECTION_ERROR, + error + ); + } + } + + /** + * Check if a Docker container is running + */ + private async checkIfDockerContainerRunning( + containerName: string + ): Promise { + try { + const command = `docker ps -q -f name=${containerName}`; + Logger.debug(`Checking if container is running: ${command}`); + + const { stdout } = await execPromise(command); + return stdout.trim().length > 0; + } catch (error) { + Logger.debug( + `Docker container check failed: ${ + error instanceof Error ? error.message : String(error) + }` + ); + return false; + } + } + + /** + * Validates command line arguments + */ + protected async validate(cliOutput: CLIOutput): Promise { + const { options } = cliOutput; + + // Verify analysis file exists + const analysisPath = + options.analysisPath || + cliOutput.config.song?.analysisPath || + process?.env?.ANALYSIS_PATH || + "./analysis.json"; + + if (!fs.existsSync(analysisPath)) { + throw new ConductorError( + `Analysis file not found: ${analysisPath}`, + ErrorCodes.FILE_NOT_FOUND + ); + } + + // Verify data directory exists + const dataDir = + options.dataDir || + cliOutput.config.score?.dataDir || + process?.env?.DATA_DIR || + "./data/fileData"; + + if (!fs.existsSync(dataDir)) { + throw new ConductorError( + `Data directory not found: ${dataDir}`, + ErrorCodes.FILE_NOT_FOUND + ); + } + + // Validate SONG URL + const songUrl = + options.songUrl || + cliOutput.config.song?.url || + process?.env?.SONG_URL || + "http://localhost:8080"; + if (!songUrl) { + throw new ConductorError( + "No SONG URL provided. Use --song-url option or set SONG_URL environment variable.", + ErrorCodes.INVALID_ARGS + ); + } + + // Validate Score URL + const scoreUrl = + options.scoreUrl || + cliOutput.config.score?.url || + process?.env?.SCORE_URL || + "http://localhost:8087"; + if (!scoreUrl) { + throw new ConductorError( + "No Score URL provided. Use --score-url option or set SCORE_URL environment variable.", + ErrorCodes.INVALID_ARGS + ); + } + + // Optional Docker availability check + try { + await execPromise("docker --version"); + } catch (error) { + Logger.warn( + `Docker not available. This command requires Docker with song-client and score-client containers.` + ); + Logger.tip( + `Install Docker and start the required containers before running this command.` + ); + throw new ConductorError( + "Docker is required for this command", + ErrorCodes.INVALID_ARGS, + { + suggestion: + "Install Docker and ensure song-client and score-client containers are running", + } + ); + } + } +} diff --git a/apps/conductor/src/commands/songSubmitAnalysisCommand.ts b/apps/conductor/src/commands/songSubmitAnalysisCommand.ts new file mode 100644 index 00000000..fede1282 --- /dev/null +++ b/apps/conductor/src/commands/songSubmitAnalysisCommand.ts @@ -0,0 +1,573 @@ +import * as fs from "fs"; +import axios from "axios"; +import { Command, CommandResult } from "./baseCommand"; +import { CLIOutput } from "../types/cli"; +import { Logger } from "../utils/logger"; +import chalk from "chalk"; +import { ConductorError, ErrorCodes } from "../utils/errors"; + +/** + * Response from SONG analysis submission + */ +export interface SongSubmissionResponse { + /** The analysis ID returned by SONG */ + analysisId?: string; + + /** Any error message returned by SONG */ + error?: string; + + /** Additional response details */ + [key: string]: any; +} + +/** + * Command for submitting analysis data to the SONG service + */ +export class SongSubmitAnalysisCommand extends Command { + private readonly MAX_RETRIES = 1; + private readonly RETRY_DELAY = 5000; // 5 seconds + private readonly TIMEOUT = 20000; // 20 seconds + + constructor() { + super("SONG Analysis Submission"); + } + + /** + * Normalize URL to ensure it has the proper format + * @param url Original URL + * @returns Normalized URL + */ + private normalizeUrl(url: string): string { + // Remove trailing slash if present + return url.endsWith("/") ? url.slice(0, -1) : url; + } + + /** + * Checks SONG service health + * @param url SONG service URL + * @returns Promise resolving to boolean indicating health status + */ + private async checkSongHealth(url: string): Promise { + // Use isAlive endpoint for SONG health check + const healthUrl = `${url}/isAlive`; + + try { + Logger.info(`Checking SONG health: ${healthUrl}`); + + const response = await axios.get(healthUrl, { + timeout: this.TIMEOUT, + headers: { accept: "*/*" }, + }); + + // Check for health status + const isHealthy = response.status === 200; + + if (isHealthy) { + Logger.info(`\x1b[32mSuccess:\x1b[0m SONG is healthy`); + return true; + } + + Logger.warn(`SONG health check failed. Status: ${response.status}`); + return false; + } catch (error) { + Logger.warn(`SONG health check failed`); + Logger.error(`\x1b[31mFailed to connect to SONG service\x1b[0m`); + return false; + } + } + + /** + * Parses error messages from SONG server responses + * @param responseData Response data from SONG server + * @returns Structured error information with specific guidance + */ + private parseErrorMessage(responseData: any): { + errorType: string; + message: string; + suggestion: string; + } { + // Default values + let errorType = "UNKNOWN"; + let message = "Unknown error occurred"; + let suggestion = "Check server logs for more details"; + + if (!responseData || typeof responseData !== "object") { + return { errorType, message, suggestion }; + } + + // Extract message if available + if (responseData.message) { + message = responseData.message; + } + + // Check for specific error patterns + if (typeof message === "string") { + // Analysis type not found + if (message.includes("analysis.type.not.found")) { + errorType = "ANALYSIS_TYPE_NOT_FOUND"; + suggestion = + "Verify the analysisType.name in your JSON matches a schema that was uploaded with songUploadSchema"; + + // Try to extract the schema name if it's in the error message + const schemaMatch = message.match(/name '([^']+)'/); + if (schemaMatch && schemaMatch[1]) { + suggestion += `\nThe schema name '${schemaMatch[1]}' was not found on the server`; + } else { + // If we can't extract it, look at our analysis data + suggestion += + "\nCheck the value of analysisType.name in your analysis file"; + } + } + // Study not found + else if (message.includes("not.found") && message.includes("stud")) { + errorType = "STUDY_NOT_FOUND"; + suggestion = "Create the study first using the songCreateStudy command"; + } + // Schema validation error + else if ( + message.includes("schema") && + (message.includes("validation") || message.includes("invalid")) + ) { + errorType = "SCHEMA_VALIDATION"; + suggestion = + "Your analysis data doesn't match the required schema format"; + + if (responseData.debugMessage) { + message += "\n" + responseData.debugMessage; + } + } + // Duplicate analysis + else if ( + message.includes("duplicate") || + message.includes("already exists") + ) { + errorType = "DUPLICATE_ANALYSIS"; + suggestion = "Use --allow-duplicates to submit anyway"; + } + // Authentication error + else if ( + message.includes("auth") || + message.includes("permission") || + message.includes("unauthorized") + ) { + errorType = "AUTHENTICATION"; + suggestion = "Check your authorization token"; + } + } + + return { errorType, message, suggestion }; + } + + /** + * Executes the SONG analysis submission process + * @param cliOutput The CLI configuration and inputs + * @returns A CommandResult indicating success or failure + */ + protected async execute(cliOutput: CLIOutput): Promise { + const { options } = cliOutput; + + try { + // Extract configuration from options or environment + const analysisFile = options.analysisFile || process.env.ANALYSIS_FILE; + const songUrl = options.songUrl || process.env.SONG_URL; + const studyId = options.studyId || process.env.STUDY_ID || "demo"; + const allowDuplicates = + options.allowDuplicates === true || + process.env.ALLOW_DUPLICATES === "true" || + false; + const authToken = options.authToken || process.env.AUTH_TOKEN || "123"; + + // Validate required parameters + if (!analysisFile) { + throw new ConductorError( + "Analysis file not specified. Use --analysis-file or set ANALYSIS_FILE environment variable.", + ErrorCodes.INVALID_ARGS + ); + } + + if (!songUrl) { + throw new ConductorError( + "SONG URL not specified. Use --song-url or set SONG_URL environment variable.", + ErrorCodes.INVALID_ARGS + ); + } + + // Normalize URL + const normalizedUrl = this.normalizeUrl(songUrl); + + // First, check SONG service health + const isHealthy = await this.checkSongHealth(normalizedUrl); + if (!isHealthy) { + throw new ConductorError( + "Unable to establish connection with SONG service", + ErrorCodes.CONNECTION_ERROR + ); + } + + // Validate analysis file exists + if (!fs.existsSync(analysisFile)) { + Logger.error(`Analysis file not found at ${analysisFile}`); + throw new ConductorError( + `Analysis file not found at ${analysisFile}`, + ErrorCodes.FILE_NOT_FOUND + ); + } + + // Read analysis file + Logger.info(`Reading analysis file: ${analysisFile}`); + let analysisContent = fs.readFileSync(analysisFile, "utf-8"); + + // Validate JSON format + let analysisJson: any; + try { + analysisJson = JSON.parse(analysisContent); + + // Basic validation of analysis JSON + if (!analysisJson.studyId) { + Logger.warn( + "Analysis JSON is missing studyId. Using provided studyId parameter." + ); + // This is not critical as we'll use the studyId parameter + } + + if (!analysisJson.analysisType || !analysisJson.analysisType.name) { + throw new ConductorError( + "Invalid analysis format: Missing required field 'analysisType.name'", + ErrorCodes.INVALID_FILE + ); + } else { + // Log the analysis type name for debugging + Logger.info(`Analysis type name: ${analysisJson.analysisType.name}`); + } + + if ( + !analysisJson.files || + !Array.isArray(analysisJson.files) || + analysisJson.files.length === 0 + ) { + throw new ConductorError( + "Invalid analysis format: 'files' must be a non-empty array", + ErrorCodes.INVALID_FILE + ); + } + + // Ensure studyId in the file matches the provided/default studyId + if (analysisJson.studyId && analysisJson.studyId !== studyId) { + Logger.warn( + `StudyId in file (${analysisJson.studyId}) differs from provided studyId (${studyId})` + ); + if (!options.force) { + Logger.info("Use --force to override studyId in file"); + // We'll proceed with the original file content, warning is enough + } else { + Logger.info(`Forcing studyId to be ${studyId}`); + analysisJson.studyId = studyId; + // Reserialize the JSON with updated studyId + analysisContent = JSON.stringify(analysisJson); + } + } + + Logger.info("Analysis validation passed"); + } catch (error) { + if (error instanceof ConductorError) { + throw error; + } + throw new ConductorError( + `Analysis file contains invalid JSON: ${ + error instanceof Error ? error.message : String(error) + }`, + ErrorCodes.INVALID_FILE + ); + } + + // Submit analysis + const submitUrl = `${normalizedUrl}/submit/${studyId}?allowDuplicates=${allowDuplicates}`; + Logger.info(`Submitting analysis to ${submitUrl}`); + + let response; + let attempt = 0; + let lastError; + + while (attempt < this.MAX_RETRIES) { + attempt++; + try { + response = await axios.post(submitUrl, analysisContent, { + headers: { + accept: "*/*", + Authorization: `bearer ${authToken}`, + "Content-Type": "application/json", + }, + timeout: this.TIMEOUT, + }); + + // Submission successful + break; + } catch (error: any) { + lastError = error; + + // Extract detailed error information from Axios error + if (error.response) { + // Server responded with non-2xx status code + const status = error.response.status; + const responseData = error.response.data; + + Logger.error(`Server responded with status ${status}`); + + // Handle standard SONG error format + if (responseData && typeof responseData === "object") { + // Parse and display specific error information + if (responseData.message) { + Logger.error(`Error message: ${responseData.message}`); + } + + if (responseData.debugMessage) { + Logger.error( + `Debug message: ${responseData.debugMessage || "N/A"}` + ); + } + + // Use improved error parsing + const { errorType, message, suggestion } = + this.parseErrorMessage(responseData); + + // Only log error type if it's not the direct message + if (errorType !== "UNKNOWN" && !message.includes(errorType)) { + Logger.error(`Error type: ${errorType}`); + } + + // Display an appropriate suggestion based on the error type + Logger.tip(suggestion); + } else { + // Log raw response if not in expected format + Logger.error( + `Raw error response: ${JSON.stringify(responseData)}` + ); + } + } else if (error.request) { + // Request was made but no response received + Logger.error(`No response received from server: ${error.message}`); + } else { + // Error in setting up the request + Logger.error(`Error setting up request: ${error.message}`); + } + + if (attempt < this.MAX_RETRIES) { + Logger.warn( + `Submission attempt ${attempt} failed, retrying in ${ + this.RETRY_DELAY / 1000 + }s...` + ); + await new Promise((resolve) => + setTimeout(resolve, this.RETRY_DELAY) + ); + } + } + } + + // Check if submission succeeded + if (!response) { + if ( + lastError && + lastError.response && + lastError.response.status === 409 && + allowDuplicates + ) { + // If we're allowing duplicates and got a 409, this is actually okay + Logger.warn( + "Submission already exists, but --allow-duplicates was specified" + ); + // Try to extract the analysisId from the error response if possible + let analysisId = ""; + try { + if ( + lastError.response.data && + typeof lastError.response.data === "object" && + lastError.response.data.message + ) { + // Try to extract ID from error message + const match = lastError.response.data.message.match( + /analysisId: ([a-f0-9-]+)/i + ); + if (match && match[1]) { + analysisId = match[1]; + } + } + } catch (parseError) { + // Ignore parse errors, just means we couldn't extract the ID + } + + return { + success: true, + details: { + analysisId: analysisId || "UNKNOWN", + status: "DUPLICATE", + message: "Analysis already exists", + }, + }; + } + + throw ( + lastError || + new ConductorError( + "Failed to submit analysis after multiple attempts", + ErrorCodes.CONNECTION_ERROR + ) + ); + } + + // Process response + const result = response.data; + + // Extract analysis ID from response + let analysisId = ""; + if (result && typeof result === "object") { + // Use type assertion to tell TypeScript this object might have analysisId + const resultObj = result as { analysisId?: string }; + analysisId = resultObj.analysisId || ""; + } else if (typeof result === "string") { + // Try to extract from string response + const match = result.match(/"analysisId"\s*:\s*"([^"]+)"/); + if (match && match[1]) { + analysisId = match[1]; + } + } + + if (!analysisId) { + Logger.warn("Unable to extract analysis ID from response"); + } + + Logger.success(`Analysis submitted successfully`); + Logger.generic(" "); + Logger.generic( + chalk.gray(` - Analysis ID: ${analysisId || "UNKNOWN"}`) + ); + Logger.generic(chalk.gray(` - Study ID: ${studyId}`)); + Logger.generic( + chalk.gray(` - Analysis Type: ${analysisJson.analysisType.name}`) + ); + Logger.generic(" "); + + return { + success: true, + details: { + analysisId, + studyId, + analysisType: analysisJson.analysisType.name, + status: "CREATED", + }, + }; + } catch (error) { + // Handle errors and return failure result + const errorMessage = + error instanceof Error ? error.message : String(error); + const errorCode = + error instanceof ConductorError + ? error.code + : ErrorCodes.CONNECTION_ERROR; + + // Add extra details to the error result + const details = error instanceof ConductorError ? error.details : {}; + + return { + success: false, + errorMessage, + errorCode, + details, + }; + } + } + + /** + * Validates command line arguments. + * This implementation ensures that required parameters are provided. + * + * @param cliOutput - The parsed command line arguments + * @throws ConductorError if validation fails + */ + protected async validate(cliOutput: CLIOutput): Promise { + const { options } = cliOutput; + + // Validate analysis file + const analysisFile = + options.analysisFile || + cliOutput.config.song?.analysisFile || + process.env.ANALYSIS_FILE; + + if (!analysisFile) { + throw new ConductorError( + "No analysis file provided. Use --analysis-file option or set ANALYSIS_FILE environment variable.", + ErrorCodes.INVALID_ARGS + ); + } + + // Verify analysis file exists + if (!fs.existsSync(analysisFile)) { + throw new ConductorError( + `Analysis file not found: ${analysisFile}`, + ErrorCodes.FILE_NOT_FOUND + ); + } + + // Validate SONG URL + const songUrl = + options.songUrl || cliOutput.config.song?.url || process.env.SONG_URL; + + if (!songUrl) { + throw new ConductorError( + "No SONG URL provided. Use --song-url option or set SONG_URL environment variable.", + ErrorCodes.INVALID_ARGS + ); + } + + // Validate analysis JSON structure + try { + const analysisContent = fs.readFileSync(analysisFile, "utf-8"); + const analysisJson = JSON.parse(analysisContent); + + // Basic validation of required fields + if (!analysisJson.analysisType || !analysisJson.analysisType.name) { + throw new ConductorError( + "Invalid analysis format: Missing required field 'analysisType.name'", + ErrorCodes.INVALID_FILE + ); + } + + if ( + !analysisJson.files || + !Array.isArray(analysisJson.files) || + analysisJson.files.length === 0 + ) { + throw new ConductorError( + "Invalid analysis format: 'files' must be a non-empty array", + ErrorCodes.INVALID_FILE + ); + } + } catch (error) { + if (error instanceof ConductorError) { + throw error; + } + + throw new ConductorError( + `Analysis file contains invalid JSON: ${ + error instanceof Error ? error.message : String(error) + }`, + ErrorCodes.INVALID_FILE, + error + ); + } + + // Optional validations + const studyId = + options.studyId || + cliOutput.config.song?.studyId || + process.env.STUDY_ID || + "demo"; + + if (!studyId) { + throw new ConductorError( + "Study ID is invalid or not specified.", + ErrorCodes.INVALID_ARGS + ); + } + } +} diff --git a/apps/conductor/src/commands/songUploadSchemaCommand.ts b/apps/conductor/src/commands/songUploadSchemaCommand.ts new file mode 100644 index 00000000..f77e6d01 --- /dev/null +++ b/apps/conductor/src/commands/songUploadSchemaCommand.ts @@ -0,0 +1,465 @@ +import * as fs from "fs"; +import axios from "axios"; +import { Command, CommandResult } from "./baseCommand"; +import { CLIOutput } from "../types/cli"; +import { Logger } from "../utils/logger"; +import chalk from "chalk"; +import { ConductorError, ErrorCodes } from "../utils/errors"; +import { validateSongSchema } from "../services/song/songSchemaValidator"; + +/** + * Response from SONG schema upload + */ +export interface SongUploadResponse { + /** The unique identifier for the uploaded schema */ + id?: string; + + /** The name of the schema */ + name?: string; + + /** The version of the schema */ + version?: string; + + /** Any error message returned by SONG */ + error?: string; + + /** Additional response details */ + [key: string]: any; +} + +/** + * Command for uploading schemas to the SONG service + */ +export class SongUploadSchemaCommand extends Command { + private readonly MAX_RETRIES = 3; + private readonly RETRY_DELAY = 5000; // 5 seconds + private readonly TIMEOUT = 10000; // 10 seconds + + constructor() { + super("SONG Schema Upload"); + } + + /** + * Normalize URL to ensure it includes the /schemas endpoint + * @param url Original URL + * @returns Normalized URL + */ + private normalizeSchemaUrl(url: string): string { + // Remove trailing slash if present + url = url.replace(/\/$/, ""); + + // Add /schemas if not already present + if (!url.endsWith("/schemas")) { + url = `${url}/schemas`; + } + + return url; + } + + /** + * Checks SONG service health + * @param url SONG service URL + * @returns Promise resolving to boolean indicating health status + */ + private async checkSongHealth(url: string): Promise { + // Remove /schemas from the URL if present to get base URL for health check + const baseUrl = url.replace(/\/schemas$/, ""); + const healthUrl = `${baseUrl}/isAlive`; + + try { + Logger.info(`Checking SONG health: ${healthUrl}`); + + const response = await axios.get(healthUrl, { + timeout: this.TIMEOUT, + headers: { accept: "*/*" }, + }); + + // Check for health status + const isHealthy = response.status === 200; + + if (isHealthy) { + Logger.info(`\x1b[32mSuccess:\x1b[0m SONG is healthy`); + return true; + } + + Logger.warn(`SONG health check failed. Status: ${response.status}`); + return false; + } catch (error) { + Logger.warn(`SONG health check failed`); + Logger.error(`\x1b[31mFailed to connect to SONG service\x1b[0m`); + return false; + } + } + + /** + * Executes the SONG schema upload process + * @param cliOutput The CLI configuration and inputs + * @returns A CommandResult indicating success or failure + */ + protected async execute(cliOutput: CLIOutput): Promise { + const { options } = cliOutput; + + try { + // Extract configuration from options or environment + const schemaFile = options.schemaFile || process.env.SONG_SCHEMA; + const songUrl = options.songUrl || process.env.SONG_URL; + const authToken = + options.authToken || process.env.SONG_AUTH_TOKEN || "123"; + + // Validate required parameters + if (!schemaFile) { + throw new ConductorError( + "Schema file not specified. Use --schema-file or set SONG_SCHEMA environment variable.", + ErrorCodes.INVALID_ARGS + ); + } + + if (!songUrl) { + throw new ConductorError( + "SONG URL not specified. Use --song-url or set SONG_URL environment variable.", + ErrorCodes.INVALID_ARGS + ); + } + + // Normalize URL + const normalizedUrl = this.normalizeSchemaUrl(songUrl); + + // First, check SONG service health + const isHealthy = await this.checkSongHealth(normalizedUrl); + if (!isHealthy) { + throw new ConductorError( + "Unable to establish connection with SONG service", + ErrorCodes.CONNECTION_ERROR + ); + } + + // Validate schema file exists + if (!fs.existsSync(schemaFile)) { + Logger.error(`Schema file not found at ${schemaFile}`); + throw new ConductorError( + `Schema file not found at ${schemaFile}`, + ErrorCodes.FILE_NOT_FOUND + ); + } + + // Read schema file + Logger.info(`Reading schema file: ${schemaFile}`); + const schemaContent = fs.readFileSync(schemaFile, "utf-8"); + + // Validate JSON and schema structure + let schemaJson: any; + try { + schemaJson = JSON.parse(schemaContent); + + // Validate against SONG-specific requirements + const { isValid, warnings } = validateSongSchema(schemaJson); + + // Log any warnings + if (warnings.length > 0) { + Logger.warn("Schema validation warnings:"); + warnings.forEach((warning) => { + Logger.warn(` - ${warning}`); + }); + } + + Logger.info("Schema validation passed"); + } catch (error) { + if (error instanceof ConductorError) { + throw error; + } + throw new ConductorError( + `Schema file contains invalid JSON: ${ + error instanceof Error ? error.message : String(error) + }`, + ErrorCodes.INVALID_FILE + ); + } + + // Upload schema + Logger.info(`Uploading schema to ${normalizedUrl}`); + + let response; + let attempt = 0; + let lastError; + + while (attempt < this.MAX_RETRIES) { + attempt++; + try { + response = await axios.post(normalizedUrl, schemaContent, { + headers: { + accept: "*/*", + Authorization: authToken, + "Content-Type": "application/json", + }, + timeout: this.TIMEOUT, + }); + + // Upload successful + break; + } catch (error: any) { + lastError = error; + + // Extract detailed error information from Axios error + if (error.response) { + // Server responded with non-2xx status code + const status = error.response.status; + const responseData = error.response.data; + + Logger.error(`Server responded with status ${status}`); + + // Handle standard SONG error format + if (responseData && typeof responseData === "object") { + if (responseData.message) { + Logger.error(`Error message: ${responseData.message}`); + } + + if (responseData.debugMessage) { + Logger.error(`Debug message: ${responseData.debugMessage}`); + } + + if ( + responseData.stackTrace && + Array.isArray(responseData.stackTrace) + ) { + // Show first few lines of stack trace for context + const relevantStackTrace = responseData.stackTrace.slice(0, 3); + Logger.info("Server stack trace (first 3 lines):"); + relevantStackTrace.forEach((line: string) => { + Logger.generic(chalk.gray(` ${line}`)); + }); + } + + // Check for common errors + const errorString = JSON.stringify(responseData); + + // Check for missing name field + if ( + errorString.includes("NullPointerException") || + (responseData.message && + responseData.message.includes("required field")) + ) { + Logger.error( + `The schema appears to be missing required fields` + ); + Logger.tip( + `Check your schema structure against the SONG documentation, ensuring it has required fields 'name' and 'schema'` + ); + } + + // Check for validation errors + if ( + errorString.includes("ValidationException") || + (responseData.message && + responseData.message.includes("validation")) + ) { + Logger.error(`Schema validation failed on the server`); + Logger.tip( + `The schema structure may be correct but fails server-side validation rules. Review the error message for details.` + ); + } + } else { + // Log raw response if not in expected format + Logger.error( + `Raw error response: ${JSON.stringify(responseData)}` + ); + } + } else if (error.request) { + // Request was made but no response received + Logger.error(`No response received from server: ${error.message}`); + } else { + // Error in setting up the request + Logger.error(`Error setting up request: ${error.message}`); + } + + if (attempt < this.MAX_RETRIES) { + Logger.warn( + `Upload attempt ${attempt} failed, retrying in ${ + this.RETRY_DELAY / 1000 + }s...` + ); + await new Promise((resolve) => + setTimeout(resolve, this.RETRY_DELAY) + ); + } + } + } + + // Check if upload succeeded + if (!response) { + if ( + lastError && + lastError.response && + lastError.response.status === 500 + ) { + throw new ConductorError( + `Server error (500) during schema upload. Check server logs for details.`, + ErrorCodes.CONNECTION_ERROR, + { + statusCode: 500, + lastError: lastError.message, + suggestion: + "The schema may be missing required fields or contain invalid structure", + } + ); + } + + throw ( + lastError || + new ConductorError( + "Failed to upload schema after multiple attempts", + ErrorCodes.CONNECTION_ERROR + ) + ); + } + + // Process response + const result = response.data; + + // Create strongly typed result object + const typedResult: SongUploadResponse = + result && typeof result === "object" + ? (result as SongUploadResponse) + : {}; + + // Check for error in response body + if (typedResult.error) { + throw new ConductorError( + `SONG schema upload error: ${typedResult.error}`, + ErrorCodes.CONNECTION_ERROR + ); + } + + Logger.success(`Schema uploaded successfully`); + Logger.generic(" "); + Logger.generic( + chalk.gray(` - Schema Name: ${typedResult.name || "Unnamed"}`) + ); + Logger.generic( + chalk.gray(` - Schema Version: ${typedResult.version || "N/A"}`) + ); + Logger.generic(" "); + + return { + success: true, + details: typedResult as Record, + }; + } catch (error) { + // Handle errors and return failure result + const errorMessage = + error instanceof Error ? error.message : String(error); + const errorCode = + error instanceof ConductorError + ? error.code + : ErrorCodes.CONNECTION_ERROR; + + // Add extra details to the error result + const details = error instanceof ConductorError ? error.details : {}; + + return { + success: false, + errorMessage, + errorCode, + details, + }; + } + } + + /** + * Validates command line arguments. + * This implementation ensures that SONG URL and schema file are provided. + * + * @param cliOutput - The parsed command line arguments + * @throws ConductorError if validation fails + */ + protected async validate(cliOutput: CLIOutput): Promise { + const { options } = cliOutput; + + // Validate SONG URL + const songUrl = + options.songUrl || cliOutput.config.song?.url || process.env.SONG_URL; + + if (!songUrl) { + throw new ConductorError( + "No SONG URL provided. Use --song-url option or set SONG_URL environment variable.", + ErrorCodes.INVALID_ARGS + ); + } + + // Validate schema file + const schemaFile = + options.schemaFile || + cliOutput.config.song?.schemaFile || + process.env.SONG_SCHEMA; + + if (!schemaFile) { + throw new ConductorError( + "No schema file provided. Use --schema-file option or set SONG_SCHEMA environment variable.", + ErrorCodes.INVALID_ARGS + ); + } + + // Verify schema file exists + if (!fs.existsSync(schemaFile)) { + throw new ConductorError( + `Schema file not found: ${schemaFile}`, + ErrorCodes.FILE_NOT_FOUND + ); + } + + // Validate schema JSON structure + try { + const schemaContent = fs.readFileSync(schemaFile, "utf-8"); + const schemaJson = JSON.parse(schemaContent); + + // Basic schema validation + if (!schemaJson.name) { + throw new ConductorError( + "Invalid schema format: Missing required field 'name'", + ErrorCodes.INVALID_FILE + ); + } + + if (!schemaJson.schema || typeof schemaJson.schema !== "object") { + throw new ConductorError( + "Invalid schema format: Missing or invalid 'schema' field", + ErrorCodes.INVALID_FILE + ); + } + + // Optional schema option validations + if (schemaJson.options) { + if ( + schemaJson.options.fileTypes && + !Array.isArray(schemaJson.options.fileTypes) + ) { + throw new ConductorError( + "Invalid schema format: 'fileTypes' must be an array", + ErrorCodes.INVALID_FILE + ); + } + + if ( + schemaJson.options.externalValidations && + !Array.isArray(schemaJson.options.externalValidations) + ) { + throw new ConductorError( + "Invalid schema format: 'externalValidations' must be an array", + ErrorCodes.INVALID_FILE + ); + } + } + } catch (error) { + if (error instanceof ConductorError) { + throw error; + } + + throw new ConductorError( + `Schema file contains invalid JSON: ${ + error instanceof Error ? error.message : String(error) + }`, + ErrorCodes.INVALID_FILE, + error + ); + } + } +} diff --git a/apps/conductor/src/commands/uploadCsvCommand.ts b/apps/conductor/src/commands/uploadCsvCommand.ts new file mode 100644 index 00000000..c1a0a409 --- /dev/null +++ b/apps/conductor/src/commands/uploadCsvCommand.ts @@ -0,0 +1,217 @@ +/** + * Upload Command + * + * Command implementation for uploading CSV data to Elasticsearch. + */ + +import { validateBatchSize } from "../validations/elasticsearchValidator"; +import { validateDelimiter } from "../validations/utils"; +import { Command, CommandResult } from "./baseCommand"; +import { CLIOutput } from "../types/cli"; +import { Logger } from "../utils/logger"; +import { ConductorError, ErrorCodes } from "../utils/errors"; +import { + createClientFromConfig, + validateConnection, +} from "../services/elasticsearch"; +import { processCSVFile } from "../services/csvProcessor"; +import { + validateCSVStructure, + validateElasticsearchConnection, + validateIndex, + validateFiles, +} from "../validations"; +import { parseCSVLine } from "../services/csvProcessor/csvParser"; +import * as fs from "fs"; +import * as path from "path"; + +export class UploadCommand extends Command { + /** + * Creates a new UploadCommand instance. + */ + constructor() { + super("upload"); + this.defaultOutputFileName = "upload-results.json"; + } + + /** + * Executes the upload process for all specified files + * @param cliOutput The CLI configuration and inputs + * @returns Promise with success/failure information + */ + protected async execute(cliOutput: CLIOutput): Promise { + const { config, filePaths } = cliOutput; + + Logger.info(`Input files specified: ${filePaths.length}`, filePaths); + + // Process each file + let successCount = 0; + let failureCount = 0; + const failureDetails: Record = {}; + + for (const filePath of filePaths) { + Logger.debug(`Processing File: ${filePath}`); + + try { + await this.processFile(filePath, config); + Logger.debug(`Successfully processed ${filePath}`); + successCount++; + } catch (error) { + failureCount++; + // Log the error but continue to the next file + if (error instanceof ConductorError) { + Logger.debug( + `Skipping file '${filePath}': [${error.code}] ${error.message}` + ); + if (error.details) { + Logger.debug(`Error details: ${JSON.stringify(error.details)}`); + } + failureDetails[filePath] = { + code: error.code, + message: error.message, + details: error.details, + }; + } else if (error instanceof Error) { + Logger.debug(`Skipping file '${filePath}': ${error.message}`); + failureDetails[filePath] = { + message: error.message, + }; + } else { + Logger.debug(`Skipping file '${filePath}' due to an error`); + failureDetails[filePath] = { + message: "Unknown error", + }; + } + } + } + + // Return the CommandResult + if (failureCount === 0) { + return { + success: true, + details: { + filesProcessed: successCount, + }, + }; + } else if (successCount === 0) { + return { + success: false, + errorMessage: `Failed to process all ${failureCount} files`, + errorCode: ErrorCodes.VALIDATION_FAILED, + details: failureDetails, + }; + } else { + // Partial success + return { + success: true, + details: { + filesProcessed: successCount, + filesFailed: failureCount, + failureDetails, + }, + }; + } + } + + /** + * Validates command line arguments and configuration + * @param cliOutput The CLI configuration and inputs + * @throws ConductorError if validation fails + */ + protected async validate(cliOutput: CLIOutput): Promise { + const { config, filePaths } = cliOutput; + + // Validate files first + const fileValidationResult = await validateFiles(filePaths); + if (!fileValidationResult.valid) { + throw new ConductorError("Invalid input files", ErrorCodes.INVALID_FILE, { + errors: fileValidationResult.errors, + }); + } + + // Validate delimiter + try { + validateDelimiter(config.delimiter); + } catch (error) { + throw new ConductorError( + "Invalid delimiter", + ErrorCodes.VALIDATION_FAILED, + error + ); + } + + // Validate batch size + try { + validateBatchSize(config.batchSize); + } catch (error) { + throw new ConductorError( + "Invalid batch size", + ErrorCodes.VALIDATION_FAILED, + error + ); + } + + // Validate each file's CSV headers + for (const filePath of filePaths) { + await this.validateFileHeaders(filePath, config.delimiter); + } + } + + /** + * Validates headers for a single file + */ + private async validateFileHeaders( + filePath: string, + delimiter: string + ): Promise { + try { + const fileContent = fs.readFileSync(filePath, "utf-8"); + const [headerLine] = fileContent.split("\n"); + + if (!headerLine) { + throw new ConductorError( + `CSV file is empty or has no headers: ${filePath}`, + ErrorCodes.INVALID_FILE + ); + } + + const parseResult = parseCSVLine(headerLine, delimiter, true); + if (!parseResult || !parseResult[0]) { + throw new ConductorError( + `Failed to parse CSV headers: ${filePath}`, + ErrorCodes.PARSING_ERROR + ); + } + + const headers = parseResult[0]; + + // Validate CSV structure using our validation function + await validateCSVStructure(headers); + } catch (error) { + if (error instanceof ConductorError) { + // Rethrow ConductorErrors + throw error; + } + throw new ConductorError( + `Error validating CSV headers: ${filePath}`, + ErrorCodes.VALIDATION_FAILED, + error + ); + } + } + + /** + * Processes a single file + */ + private async processFile(filePath: string, config: any): Promise { + // Set up Elasticsearch client + const client = createClientFromConfig(config); + + // Validate Elasticsearch connection and index + await validateConnection(client); + await validateIndex(client, config.elasticsearch.index); + + // Process the file + await processCSVFile(filePath, config, client); + } +} diff --git a/apps/conductor/src/main.ts b/apps/conductor/src/main.ts new file mode 100644 index 00000000..c7bb99df --- /dev/null +++ b/apps/conductor/src/main.ts @@ -0,0 +1,56 @@ +#!/usr/bin/env node + +import { setupCLI } from "./cli"; +import { CommandFactory } from "./commands/commandFactory"; +import { ConductorError, ErrorCodes, handleError } from "./utils/errors"; // Add ConductorError and ErrorCodes +import { Logger } from "./utils/logger"; +import chalk from "chalk"; + +// Add global unhandled rejection handler +process.on("unhandledRejection", (reason, promise) => { + console.error("Unhandled Rejection at:", promise, "reason:", reason); +}); + +async function main() { + try { + const cliOutput = await setupCLI(); + + Logger.header(`Conductor: Data Processing Pipeline`); + Logger.info(chalk.grey.italic` Version: 1.0.0`); + Logger.info(chalk.grey.italic` Profile: ${cliOutput.profile}`); + Logger.generic(" "); + Logger.initialize(); + Logger.debug`Starting CLI setup`; + + Logger.debug`Creating command instance`; + const command = CommandFactory.createCommand(cliOutput.profile); + + Logger.debug`Running command`; + const result = await command.run(cliOutput); + + // Check command result and handle errors + if (!result.success) { + throw new ConductorError( + result.errorMessage || "Command execution failed", + result.errorCode || ErrorCodes.UNKNOWN_ERROR, + result.details + ); + } + } catch (error) { + // Simplified error logging with optional debug details + if (process.argv.includes("--debug")) { + console.error("FATAL ERROR:", error); + } + + // Let the handleError function handle this error + handleError(error); + } +} + +// Replace the catch with a simpler approach that defers to handleError +main().catch((error) => { + if (process.argv.includes("--debug")) { + console.error("UNCAUGHT ERROR IN MAIN:", error); + } + handleError(error); +}); diff --git a/apps/conductor/src/services/csvProcessor/csvParser.ts b/apps/conductor/src/services/csvProcessor/csvParser.ts new file mode 100644 index 00000000..b3e92858 --- /dev/null +++ b/apps/conductor/src/services/csvProcessor/csvParser.ts @@ -0,0 +1,138 @@ +import * as fs from "fs"; // File system operations +import * as readline from "readline"; // Reading files line by line +import { parse as csvParse } from "csv-parse/sync"; // CSV parsing functionality +import { Logger } from "../../utils/logger"; + +/** + * CSV Processing utility + * + * This module provides core functionality for processing CSV files: + * - Counting lines in CSV files (excluding headers) + * - Parsing individual CSV lines into arrays + * - Converting CSV rows into structured records with proper type conversion + * + * Used by the Conductor to prepare data for Elasticsearch ingestion. + * Handles type conversion, null values, and submitter metadata. + */ + +/** + * Counts the total number of lines in a file, excluding the header + * @param filePath - Path to the CSV file + * @returns Promise resolving to number of data lines (excluding header) + */ + +export async function countFileLines(filePath: string): Promise { + // Notify user that counting is in progress + + Logger.debug(`csvParser: Beginning data transfer`); + Logger.debug(`csvParser: Calculating records to upload`); + + // Create a readline interface to read file line by line + const rl = readline.createInterface({ + input: fs.createReadStream(filePath), + crlfDelay: Infinity, // Handle different line endings + }); + + let lines = 0; + // Count each line in file + for await (const _ of rl) { + lines++; + } + + const recordCount = lines - 1; // Subtract header line from total count + Logger.debug`Found ${recordCount} data records in ${filePath}`; + return recordCount; +} + +/** + * Parses a single line of CSV data into an array of values + * @param line - Raw CSV line string + * @param delimiter - CSV delimiter character + * @returns Array of parsed values from the CSV line + */ + +export function parseCSVLine( + line: string, + delimiter: string, + isHeaderRow: boolean = true +): any[] { + try { + const parseOptions = { + delimiter: delimiter, + trim: true, + skipEmptyLines: true, + relax_column_count: true, + }; + + // If it's a header row, only parse the first line + if (isHeaderRow) { + Logger.debug`Parsing header row with delimiter '${delimiter}'`; + const result = csvParse(line, parseOptions); + return result[0] ? [result[0]] : []; + } + + // For data rows, parse normally + Logger.debug`Parsing data row with delimiter '${delimiter}'`; + return csvParse(line, parseOptions); + } catch (error) { + Logger.error`Error parsing CSV line: ${ + error instanceof Error ? error.message : String(error) + }`; + Logger.debug`Failed line content: ${line.substring(0, 100)}${ + line.length > 100 ? "..." : "" + }`; + return []; + } +} +/** + * Creates a record object from CSV row data with proper type conversion + * @param rowValues - Array of values from CSV row + * @param headers - Array of column headers + * @param metadata - Additional metadata to include in record + * @returns Record object with processed values and metadata + */ + +export function createRecordFromRow( + rowValues: any[], + headers: string[], + metadata: any +): Record { + Logger.debug`Creating record from row with ${rowValues.length} values and ${headers.length} headers`; + + // Initialize record with metadata + const record: Record = { + submission_metadata: metadata, + }; + + // Process each value in the row + headers.forEach((header, index) => { + const rowValue = rowValues[index]; + + // Handle null/empty values + if ( + rowValue === undefined || + rowValue === null || + rowValue === "" || + (typeof rowValue === "string" && rowValue.trim() === "") + ) { + record[header] = null; + } + // Convert numeric strings to numbers + else if (!isNaN(Number(rowValue)) && rowValue.toString().trim() !== "") { + record[header] = Number(rowValue); + } + // Clean and store string values + else { + record[header] = rowValue.toString().trim(); + } + }); + + // Log detailed conversion in debug mode + Logger.debugObject("Record conversion result", { + recordFields: Object.keys(record).length - 1, // Subtract metadata + hasMetadata: !!record.submission_metadata, + sampleFields: Object.keys(record).slice(0, 3), + }); + + return record; +} diff --git a/apps/conductor/src/services/csvProcessor/index.ts b/apps/conductor/src/services/csvProcessor/index.ts new file mode 100644 index 00000000..2450ee95 --- /dev/null +++ b/apps/conductor/src/services/csvProcessor/index.ts @@ -0,0 +1,194 @@ +import * as fs from "fs"; +import * as readline from "readline"; +import { Client } from "@elastic/elasticsearch"; +import { Config } from "../../types"; +import { countFileLines, parseCSVLine } from "./csvParser"; +import { Logger } from "../../utils/logger"; +import { + validateCSVStructure, + validateHeadersMatchMappings, +} from "../../validations"; +import { ConductorError, ErrorCodes } from "../../utils/errors"; +import { CSVProcessingErrorHandler } from "./logHandler"; +import { sendBulkWriteRequest } from "../elasticsearch"; +import { formatDuration, calculateETA, createProgressBar } from "./progressBar"; +import { createRecordMetadata } from "./metadata"; + +/** + * Updates the progress display in the console + * + * @param processed - Number of processed records + * @param total - Total number of records + * @param startTime - When processing started + */ +export function updateProgressDisplay( + processed: number, + total: number, + startTime: number +): void { + const elapsedMs = Math.max(1, Date.now() - startTime); + const progress = Math.min(100, (processed / total) * 100); + const progressBar = createProgressBar(progress); + const eta = calculateETA(processed, total, elapsedMs / 1000); + const recordsPerSecond = Math.round(processed / (elapsedMs / 1000)); + + // Use \r to overwrite previous line + process.stdout.write("\r"); + process.stdout.write( + ` ${progressBar} | ` + // Added space before progress bar + `${processed}/${total} | ` + + `⏱ ${formatDuration(elapsedMs)} | ` + + `🏁 ${eta} | ` + + `⚡${recordsPerSecond} rows/sec` // Added space after rows/sec + ); +} + +/** + * Processes a CSV file and indexes the data into Elasticsearch. + * + * @param filePath - Path to the CSV file to process + * @param config - Configuration object + * @param client - Elasticsearch client for indexing + */ +export async function processCSVFile( + filePath: string, + config: Config, + client: Client +): Promise { + let isFirstLine = true; + let headers: string[] = []; + let processedRecords = 0; + let failedRecords = 0; + const startTime = Date.now(); + const batchedRecords: object[] = []; + const processingStartTime = new Date().toISOString(); + + // Get total lines upfront to avoid repeated calls + const totalLines = await countFileLines(filePath); + + Logger.info`Processing file: ${filePath}`; + + const fileStream = fs.createReadStream(filePath); + const rl = readline.createInterface({ + input: fileStream, + crlfDelay: Infinity, + }); + + try { + for await (const line of rl) { + try { + if (isFirstLine) { + headers = parseCSVLine(line, config.delimiter, true)[0] || []; + Logger.info`Validating headers against the ${config.elasticsearch.index} mapping`; + await validateCSVStructure(headers); + Logger.info("Headers validated against index mapping"); + await validateHeadersMatchMappings( + client, + headers, + config.elasticsearch.index + ); + isFirstLine = false; + + Logger.generic(`\n Processing data into elasticsearch...\n`); + continue; + } + + const rowValues = parseCSVLine(line, config.delimiter)[0] || []; + const metadata = createRecordMetadata( + filePath, + processingStartTime, + processedRecords + 1 + ); + const record = { + submission_metadata: metadata, + data: Object.fromEntries(headers.map((h, i) => [h, rowValues[i]])), + }; + + batchedRecords.push(record); + processedRecords++; + + // Update progress more frequently + if (processedRecords % 10 === 0) { + updateProgressDisplay( + processedRecords, + totalLines - 1, // Subtract 1 to account for header + startTime + ); + } + + if (batchedRecords.length >= config.batchSize) { + await sendBatchToElasticsearch( + client, + batchedRecords, + config.elasticsearch.index, + (count) => { + failedRecords += count; + } + ); + batchedRecords.length = 0; + } + } catch (lineError) { + // Handle individual line processing errors + Logger.warn`Error processing line: ${line.substring(0, 50)}`; + failedRecords++; + } + } + + // Final batch and progress update + if (batchedRecords.length > 0) { + await sendBatchToElasticsearch( + client, + batchedRecords, + config.elasticsearch.index, + (count) => { + failedRecords += count; + } + ); + } + + // Ensure final progress is displayed + updateProgressDisplay(processedRecords, totalLines, startTime); + + // Display final summary + CSVProcessingErrorHandler.displaySummary( + processedRecords, + failedRecords, + startTime + ); + } catch (error) { + rl.close(); + + // Use the error handler to process and throw the error + CSVProcessingErrorHandler.handleProcessingError( + error, + processedRecords, + isFirstLine, + config.delimiter + ); + } +} + +/** + * Sends a batch of records to Elasticsearch + * + * @param client - Elasticsearch client + * @param records - Records to send + * @param indexName - Target index + * @param onFailure - Callback to track failed records + */ +async function sendBatchToElasticsearch( + client: Client, + records: object[], + indexName: string, + onFailure: (count: number) => void +): Promise { + try { + await sendBulkWriteRequest(client, records, indexName, onFailure); + } catch (error) { + throw new ConductorError( + "Failed to send batch to Elasticsearch", + ErrorCodes.CONNECTION_ERROR, + error + ); + } +} diff --git a/apps/conductor/src/services/csvProcessor/logHandler.ts b/apps/conductor/src/services/csvProcessor/logHandler.ts new file mode 100644 index 00000000..028268f2 --- /dev/null +++ b/apps/conductor/src/services/csvProcessor/logHandler.ts @@ -0,0 +1,99 @@ +import { ConductorError, ErrorCodes } from "../../utils/errors"; +import { Logger } from "../../utils/logger"; +import { formatDuration } from "./progressBar"; + +/** + * Error handler for CSV processing operations. + * Manages CSV-specific errors and generates appropriate error logs. + */ +export class CSVProcessingErrorHandler { + /** + * Handles errors during CSV processing + * + * @param error - The error that occurred + * @param processedRecords - Number of records processed before error + * @param isFirstLine - Whether the error occurred on the first line (headers) + * @param delimiter - CSV delimiter character + * @throws ConductorError with appropriate error code and message + */ + public static handleProcessingError( + error: unknown, + processedRecords: number, + isFirstLine: boolean, + delimiter: string + ): never { + // Convert to string for guaranteed safe output + const errorMessage = error instanceof Error ? error.message : String(error); + + if (isFirstLine) { + // First line errors are usually header parsing issues + Logger.error(`CSV header parsing failed: ${errorMessage}`); + Logger.tip(`Make sure your CSV file uses '${delimiter}' as a delimiter`); + + throw new ConductorError( + "Failed to parse CSV headers", + ErrorCodes.VALIDATION_FAILED, + { originalError: error } + ); + } else { + // General processing errors + Logger.error( + `CSV processing failed after ${processedRecords} records: ${errorMessage}` + ); + + throw new ConductorError( + "CSV processing failed", + ErrorCodes.CSV_ERROR, // Using CSV_ERROR instead of PROCESSING_FAILED + { + recordsProcessed: processedRecords, + originalError: error, + } + ); + } + } + + /** + * Displays a summary of the CSV processing operation + * + * @param processed - Total number of processed records + * @param failed - Number of failed records + * @param startTime - When the processing started + */ + public static displaySummary( + processed: number, + failed: number, + startTime: number + ): void { + const elapsedMs = Date.now() - startTime; + const recordsPerSecond = Math.max( + 0.1, + processed / Math.max(1, elapsedMs / 1000) + ); + const successfulRecords = Math.max(0, processed - failed); // Ensure it's never negative + + // Clear the current line + process.stdout.write("\n"); + + if (failed > 0) { + Logger.warn(`Transfer to elasticsearch completed with partial errors`); + } else if (processed === 0) { + Logger.warn(`No records were processed`); + } else { + Logger.success(`Transfer to elasticsearch completed successfully`); + } + + // Print summary + Logger.generic(` ▸ Total Records processed: ${processed}`); + Logger.generic(` ▸ Records Successfully transferred: ${successfulRecords}`); + + if (failed > 0) { + Logger.warn(` ▸ Records Unsuccessfully transferred: ${failed}`); + Logger.generic(` ▸ Error logs outputted to: /logs/`); + } + + Logger.generic( + ` ▸ Processing speed: ${Math.round(recordsPerSecond)} rows/sec` + ); + Logger.generic(` ⏱ Total processing time: ${formatDuration(elapsedMs)}`); + } +} diff --git a/apps/conductor/src/services/csvProcessor/metadata.ts b/apps/conductor/src/services/csvProcessor/metadata.ts new file mode 100644 index 00000000..2330c9bb --- /dev/null +++ b/apps/conductor/src/services/csvProcessor/metadata.ts @@ -0,0 +1,22 @@ +import * as os from "os"; +import { v4 as uuidv4 } from "uuid"; + +export function generateSubmitterId(): string { + return uuidv4(); +} + +export function createRecordMetadata( + filePath: string, + processingStartTime: string, + recordNumber: number +): Record { + return { + submitter_id: generateSubmitterId(), + processing_started: processingStartTime, + processed_at: new Date().toISOString(), + source_file: filePath, + record_number: recordNumber, + hostname: os.hostname(), + username: os.userInfo().username, + }; +} diff --git a/apps/conductor/src/services/csvProcessor/progressBar.ts b/apps/conductor/src/services/csvProcessor/progressBar.ts new file mode 100644 index 00000000..2e949ee3 --- /dev/null +++ b/apps/conductor/src/services/csvProcessor/progressBar.ts @@ -0,0 +1,86 @@ +import chalk from "chalk"; + +/** + * Utility functions for progress tracking, duration formatting, + * user interaction, and unique ID generation. + * + * This module provides helper functions to: + * - Format time durations + * - Calculate estimated time to completion (ETA) + * - Create visual progress bars + * - Generate unique submission identifiers + * - Prompt users for confirmation + */ + +export function formatDuration(ms: number): string { + if (!isFinite(ms) || ms < 0) return chalk.red("Invalid duration"); + + const seconds = Math.floor(ms / 1000); + const minutes = Math.floor(seconds / 60); + const hours = Math.floor(minutes / 60); + + return chalk.magenta(`${hours}h ${minutes % 60}m ${seconds % 60}s`); +} + +export function calculateETA( + processed: number, + total: number, + elapsedSeconds: number +): string { + // Validate inputs + if (!isFinite(processed) || !isFinite(total) || !isFinite(elapsedSeconds)) { + return chalk.yellow("Invalid calculation"); + } + + if (processed <= 0 || total <= 0 || elapsedSeconds <= 0) { + return chalk.cyan("Calculating..."); + } + + try { + const recordsPerSecond = processed / elapsedSeconds; + const remainingRecords = total - processed; + const remainingSeconds = remainingRecords / recordsPerSecond; + + if (!isFinite(remainingSeconds) || remainingSeconds < 0) { + return chalk.cyan("Calculating..."); + } + + return formatDuration(remainingSeconds * 1000); + } catch (error) { + return chalk.red("ETA calculation error"); + } +} + +export function createProgressBar( + progress: number, + width: number = 30 +): string { + try { + // Validate and normalize inputs + if (!isFinite(progress) || !isFinite(width)) { + return chalk.yellow("[Invalid progress value]"); + } + + // Clamp progress between 0 and 100 + const normalizedProgress = Math.max(0, Math.min(100, progress || 0)); + // Ensure width is reasonable + const normalizedWidth = Math.max(10, Math.min(100, width)); + + // Calculate bar segments + const filledWidth = Math.round( + normalizedWidth * (normalizedProgress / 100) + ); + const emptyWidth = normalizedWidth - filledWidth; + + // Create bar segments with boundary checks + const filledBar = chalk.green("█").repeat(Math.max(0, filledWidth)); + const emptyBar = chalk.gray("░").repeat(Math.max(0, emptyWidth)); + + // Return formatted progress bar + return `${filledBar}${emptyBar} ${chalk.green( + normalizedProgress.toFixed(1) + "%" + )}`; + } catch (error) { + return chalk.yellow("[Progress calculation error]"); + } +} diff --git a/apps/conductor/src/services/elasticsearch/bulk.ts b/apps/conductor/src/services/elasticsearch/bulk.ts new file mode 100644 index 00000000..d3840c4e --- /dev/null +++ b/apps/conductor/src/services/elasticsearch/bulk.ts @@ -0,0 +1,147 @@ +/** + * Elasticsearch Bulk Operations Module + * + * Provides functions for bulk indexing operations in Elasticsearch. + */ + +import { Client } from "@elastic/elasticsearch"; +import { ConductorError, ErrorCodes } from "../../utils/errors"; +import { Logger } from "../../utils/logger"; + +/** + * Interface for bulk operation options + */ +export interface BulkOptions { + /** Maximum number of retries for failed bulk operations */ + maxRetries?: number; + + /** Whether to refresh the index after the operation */ + refresh?: boolean; +} + +/** + * Sends a bulk write request to Elasticsearch. + * + * @param client - The Elasticsearch client instance + * @param records - An array of records to be indexed + * @param indexName - The name of the Elasticsearch index + * @param onFailure - Callback function to handle failed records + * @param options - Optional configuration for bulk operations + * @throws Error after all retries are exhausted + */ +export async function sendBulkWriteRequest( + client: Client, + records: object[], + indexName: string, + onFailure: (count: number) => void, + options: BulkOptions = {} +): Promise { + const maxRetries = options.maxRetries || 3; + const refresh = options.refresh !== undefined ? options.refresh : true; + + let attempt = 0; + let success = false; + + while (attempt < maxRetries && !success) { + try { + const body = records.flatMap((doc) => [ + { index: { _index: indexName } }, + doc, + ]); + + const { body: result } = await client.bulk({ + body, + refresh, + }); + + if (result.errors) { + let failureCount = 0; + result.items.forEach((item: any, index: number) => { + if (item.index?.error) { + failureCount++; + Logger.error( + `Bulk indexing error for record ${index}: status=${ + item.index.status + }, error=${JSON.stringify(item.index.error)}, document=${ + item.index._id + }` + ); + } + }); + + onFailure(failureCount); + + // If some records succeeded, consider it a partial success + if (failureCount < records.length) { + success = true; + } else { + attempt++; + } + } else { + success = true; + } + } catch (error) { + Logger.error( + `Error sending to Elasticsearch (Attempt ${attempt + 1}): ${ + error instanceof Error ? error.message : String(error) + }` + ); + onFailure(records.length); + attempt++; + + if (attempt < maxRetries) { + Logger.info(`Retrying... (${attempt}/${maxRetries})`); + // Add backoff delay between retries + await new Promise((resolve) => setTimeout(resolve, 1000 * attempt)); + } + } + } + + if (!success) { + Logger.error(`Failed to send bulk request after ${maxRetries} attempts.`); + throw new ConductorError( + "Failed to send bulk request after retries", + ErrorCodes.ES_ERROR + ); + } +} + +/** + * Sends a batch of records to Elasticsearch with improved error handling. + * + * @param client - The Elasticsearch client instance + * @param records - An array of records to be indexed + * @param indexName - The name of the Elasticsearch index + * @param onFailure - Callback function to handle failed records + * @param options - Optional configuration for bulk operations + */ +export async function sendBatchToElasticsearch( + client: Client, + records: object[], + indexName: string, + onFailure: (count: number) => void, + options?: BulkOptions +): Promise { + if (records.length === 0) { + Logger.debug("No records to send to Elasticsearch"); + return; + } + + try { + Logger.debug( + `Sending batch of ${records.length} records to index: ${indexName}` + ); + await sendBulkWriteRequest(client, records, indexName, onFailure, options); + } catch (error) { + Logger.error( + `Failed to send batch to Elasticsearch: ${ + error instanceof Error ? error.message : String(error) + }` + ); + throw new ConductorError( + "Failed to send batch to Elasticsearch", + ErrorCodes.ES_ERROR, + error + ); + } +} diff --git a/apps/conductor/src/services/elasticsearch/client.ts b/apps/conductor/src/services/elasticsearch/client.ts new file mode 100644 index 00000000..b9a35fe2 --- /dev/null +++ b/apps/conductor/src/services/elasticsearch/client.ts @@ -0,0 +1,95 @@ +/** + * Elasticsearch Client Module + * + * Provides functions for creating and managing Elasticsearch client connections. + */ + +import { Client, ClientOptions } from "@elastic/elasticsearch"; +import { Config } from "../../types/cli"; +import { ConductorError, ErrorCodes } from "../../utils/errors"; +import { Logger } from "../../utils/logger"; + +/** + * Interface for Elasticsearch client options + */ +export interface ESClientOptions { + url: string; + username?: string; + password?: string; + requestTimeout?: number; +} + +/** + * Creates an Elasticsearch client using the provided configuration. + * + * @param options - Configuration options for the Elasticsearch client + * @returns A configured Elasticsearch client instance + * @throws ConductorError if client creation fails + */ +export function createClient(options: ESClientOptions): Client { + const clientOptions: ClientOptions = { + node: options.url, + requestTimeout: options.requestTimeout || 10000, // 10 seconds timeout + }; + + if (options.username && options.password) { + clientOptions.auth = { + username: options.username, + password: options.password, + }; + } + + try { + return new Client(clientOptions); + } catch (error) { + const errorMessage = error instanceof Error ? error.message : String(error); + throw new ConductorError( + `Failed to create Elasticsearch client: ${errorMessage}`, + ErrorCodes.CONNECTION_ERROR, + error + ); + } +} + +/** + * Creates an Elasticsearch client from application config. + * + * @param config - Application configuration + * @returns A configured Elasticsearch client instance + */ +export function createClientFromConfig(config: Config): Client { + // Use a default localhost URL if no URL is provided + const url = config.elasticsearch.url || "http://localhost:9200"; + + Logger.info(`Connecting to Elasticsearch at: ${url}`); + + return createClient({ + url, + username: config.elasticsearch.user, + password: config.elasticsearch.password, + }); +} + +/** + * Validates connection to Elasticsearch + * + * @param client - Elasticsearch client instance + * @returns Promise resolving to true if connection is valid + * @throws ConductorError if connection fails + */ +export async function validateConnection(client: Client): Promise { + try { + const result = await client.info(); + Logger.debug( + `Connected to Elasticsearch cluster: ${result.body.cluster_name}` + ); + return true; + } catch (error) { + const errorMessage = error instanceof Error ? error.message : String(error); + throw new ConductorError( + `Failed to connect to Elasticsearch: ${errorMessage}`, + ErrorCodes.CONNECTION_ERROR, + error + ); + } +} diff --git a/apps/conductor/src/services/elasticsearch/index.ts b/apps/conductor/src/services/elasticsearch/index.ts new file mode 100644 index 00000000..2ef49d98 --- /dev/null +++ b/apps/conductor/src/services/elasticsearch/index.ts @@ -0,0 +1,40 @@ +/** + * Elasticsearch Service + * + * Main entry point for Elasticsearch functionality. + * Re-exports functions from specialized modules. + */ + +// Re-export client functionality +export { + createClient, + createClientFromConfig, + validateConnection, + type ESClientOptions, +} from "./client"; + +// Re-export index operations +export { + indexExists, + createIndex, + deleteIndex, + updateIndexSettings, +} from "./indices"; + +// Re-export bulk operations +export { + sendBulkWriteRequest, + sendBatchToElasticsearch, + type BulkOptions, +} from "./bulk"; + +// Re-export template operations +export { + templateExists, + createTemplate, + updateTemplate, + deleteTemplate, +} from "./templates"; + +// Re-export aliases functionality if implemented +// export { ... } from './aliases'; diff --git a/apps/conductor/src/services/elasticsearch/indices.ts b/apps/conductor/src/services/elasticsearch/indices.ts new file mode 100644 index 00000000..23d1cad6 --- /dev/null +++ b/apps/conductor/src/services/elasticsearch/indices.ts @@ -0,0 +1,116 @@ +/** + * Elasticsearch Indices Module + * + * Provides functions for managing Elasticsearch indices. + */ + +import { Client } from "@elastic/elasticsearch"; +import { ConductorError, ErrorCodes } from "../../utils/errors"; +import { Logger } from "../../utils/logger"; + +/** + * Checks if an index exists in Elasticsearch + * + * @param client - Elasticsearch client + * @param indexName - Name of the index to check + * @returns Promise resolving to true if index exists, false otherwise + * @throws ConductorError if the check fails + */ +export async function indexExists( + client: Client, + indexName: string +): Promise { + try { + const response = await client.indices.exists({ index: indexName }); + return response.body; + } catch (error) { + const errorMessage = error instanceof Error ? error.message : String(error); + throw new ConductorError( + `Failed to check if index ${indexName} exists: ${errorMessage}`, + ErrorCodes.ES_ERROR, + error + ); + } +} + +/** + * Creates an index in Elasticsearch + * + * @param client - Elasticsearch client + * @param indexName - Name of the index to create + * @param settings - Optional index settings and mappings + * @throws ConductorError if index creation fails + */ +export async function createIndex( + client: Client, + indexName: string, + settings?: Record +): Promise { + try { + await client.indices.create({ + index: indexName, + body: settings, + }); + Logger.info(`Created index: ${indexName}`); + } catch (error) { + const errorMessage = error instanceof Error ? error.message : String(error); + throw new ConductorError( + `Failed to create index ${indexName}: ${errorMessage}`, + ErrorCodes.ES_ERROR, + error + ); + } +} + +/** + * Deletes an index from Elasticsearch + * + * @param client - Elasticsearch client + * @param indexName - Name of the index to delete + * @throws ConductorError if index deletion fails + */ +export async function deleteIndex( + client: Client, + indexName: string +): Promise { + try { + await client.indices.delete({ index: indexName }); + Logger.info(`Deleted index: ${indexName}`); + } catch (error) { + const errorMessage = error instanceof Error ? error.message : String(error); + throw new ConductorError( + `Failed to delete index ${indexName}: ${errorMessage}`, + ErrorCodes.ES_ERROR, + error + ); + } +} + +/** + * Updates settings for an existing index + * + * @param client - Elasticsearch client + * @param indexName - Name of the index to update + * @param settings - Settings to apply to the index + * @throws ConductorError if settings update fails + */ +export async function updateIndexSettings( + client: Client, + indexName: string, + settings: Record +): Promise { + try { + await client.indices.putSettings({ + index: indexName, + body: settings, + }); + Logger.info(`Updated settings for index: ${indexName}`); + } catch (error) { + const errorMessage = error instanceof Error ? error.message : String(error); + throw new ConductorError( + `Failed to update settings for index ${indexName}: ${errorMessage}`, + ErrorCodes.ES_ERROR, + error + ); + } +} diff --git a/apps/conductor/src/services/elasticsearch/templates.ts b/apps/conductor/src/services/elasticsearch/templates.ts new file mode 100644 index 00000000..373e40df --- /dev/null +++ b/apps/conductor/src/services/elasticsearch/templates.ts @@ -0,0 +1,209 @@ +/** + * Elasticsearch Templates Module + * + * Provides functions for managing Elasticsearch index templates. + */ + +import { Client } from "@elastic/elasticsearch"; +import { ConductorError, ErrorCodes } from "../../utils/errors"; +import { Logger } from "../../utils/logger"; + +/** + * Interface for template extraction results + */ +export interface TemplateInfo { + /** Default index name derived from template pattern */ + defaultIndexName?: string; + + /** Default alias name from template */ + defaultAliasName?: string; + + /** Number of shards from template settings */ + numberOfShards?: number; + + /** Number of replicas from template settings */ + numberOfReplicas?: number; +} + +/** + * Checks if a template exists in Elasticsearch + * + * @param client - Elasticsearch client + * @param templateName - Name of the template to check + * @returns Promise resolving to true if template exists, false otherwise + * @throws ConductorError if the check fails + */ +export async function templateExists( + client: Client, + templateName: string +): Promise { + try { + const response = await client.indices.existsTemplate({ + name: templateName, + }); + return response.body; + } catch (error) { + const errorMessage = error instanceof Error ? error.message : String(error); + throw new ConductorError( + `Failed to check if template ${templateName} exists: ${errorMessage}`, + ErrorCodes.ES_ERROR, + error + ); + } +} + +/** + * Creates a template in Elasticsearch + * + * @param client - Elasticsearch client + * @param templateName - Name of the template to create + * @param templateBody - Template configuration object + * @throws ConductorError if template creation fails + */ +export async function createTemplate( + client: Client, + templateName: string, + templateBody: Record +): Promise { + try { + await client.indices.putTemplate({ + name: templateName, + body: templateBody, + }); + Logger.info(`Created template: ${templateName}`); + } catch (error) { + const errorMessage = error instanceof Error ? error.message : String(error); + throw new ConductorError( + `Failed to create template ${templateName}: ${errorMessage}`, + ErrorCodes.ES_ERROR, + error + ); + } +} + +/** + * Updates an existing template in Elasticsearch + * + * @param client - Elasticsearch client + * @param templateName - Name of the template to update + * @param templateBody - Template configuration object + * @throws ConductorError if template update fails + */ +export async function updateTemplate( + client: Client, + templateName: string, + templateBody: Record +): Promise { + try { + // Check if template exists first + const exists = await templateExists(client, templateName); + if (!exists) { + throw new ConductorError( + `Template ${templateName} does not exist`, + ErrorCodes.ES_ERROR + ); + } + + // Update the template + await client.indices.putTemplate({ + name: templateName, + body: templateBody, + }); + Logger.info(`Updated template: ${templateName}`); + } catch (error) { + const errorMessage = error instanceof Error ? error.message : String(error); + throw new ConductorError( + `Failed to update template ${templateName}: ${errorMessage}`, + ErrorCodes.ES_ERROR, + error + ); + } +} + +/** + * Deletes a template from Elasticsearch + * + * @param client - Elasticsearch client + * @param templateName - Name of the template to delete + * @throws ConductorError if template deletion fails + */ +export async function deleteTemplate( + client: Client, + templateName: string +): Promise { + try { + await client.indices.deleteTemplate({ + name: templateName, + }); + Logger.info(`Deleted template: ${templateName}`); + } catch (error) { + const errorMessage = error instanceof Error ? error.message : String(error); + throw new ConductorError( + `Failed to delete template ${templateName}: ${errorMessage}`, + ErrorCodes.ES_ERROR, + error + ); + } +} + +/** + * Extracts useful information from a template body + * + * @param templateBody - Template configuration object + * @returns Template information including default index name and alias + */ +export function extractTemplateInfo( + templateBody: Record +): TemplateInfo { + const info: TemplateInfo = {}; + + try { + // Extract default index name from index patterns + if ( + templateBody.index_patterns && + Array.isArray(templateBody.index_patterns) && + templateBody.index_patterns.length > 0 + ) { + const pattern = templateBody.index_patterns[0]; + // Replace wildcard with timestamp + info.defaultIndexName = pattern.replace(/\*$/, Date.now()); + Logger.debug( + `Extracted default index name: ${info.defaultIndexName} from pattern: ${pattern}` + ); + } + + // Extract default alias from aliases + if (templateBody.aliases && typeof templateBody.aliases === "object") { + const aliasNames = Object.keys(templateBody.aliases); + if (aliasNames.length > 0) { + info.defaultAliasName = aliasNames[0]; + Logger.debug(`Extracted default alias name: ${info.defaultAliasName}`); + } + } + + // Extract settings information + if (templateBody.settings) { + if (templateBody.settings.number_of_shards) { + info.numberOfShards = parseInt( + templateBody.settings.number_of_shards, + 10 + ); + } + + if (templateBody.settings.number_of_replicas) { + info.numberOfReplicas = parseInt( + templateBody.settings.number_of_replicas, + 10 + ); + } + } + } catch (error) { + Logger.warn( + `Failed to extract template information: ${ + error instanceof Error ? error.message : String(error) + }` + ); + } + + return info; +} diff --git a/apps/conductor/src/services/lectern/lecternService.ts b/apps/conductor/src/services/lectern/lecternService.ts new file mode 100644 index 00000000..b8bea475 --- /dev/null +++ b/apps/conductor/src/services/lectern/lecternService.ts @@ -0,0 +1,230 @@ +import axios from "axios"; +import chalk from "chalk"; +import { ConductorError, ErrorCodes } from "../../utils/errors"; +import { Logger } from "../../utils/logger"; + +// Type definition for Axios error (since direct import isn't working) +interface AxiosErrorResponse { + response?: { + status?: number; + data?: unknown; + }; + message: string; +} + +/** + * Response from Lectern schema upload + */ +export interface LecternUploadResponse { + /** The unique identifier for the uploaded schema */ + id?: string; + + /** The name of the schema */ + name?: string; + + /** The version of the schema */ + version?: string; + + /** Any error message returned by Lectern */ + error?: string; + + /** Additional response details */ + [key: string]: any; +} + +/** + * Formats and logs detailed error information + * @param errorData Error details from Lectern API + */ +function formatLecternError(errorData: any): void { + // Handle different error scenarios with more descriptive messages + switch (errorData.error) { + case "BadRequest": + Logger.generic(chalk.gray(" ")); + Logger.generic(chalk.gray(" Possible reasons:")); + Logger.generic(chalk.gray(" ")); + Logger.generic(chalk.gray(" - Schema might already exist")); + Logger.generic(chalk.gray(" - Invalid schema format")); + Logger.generic(chalk.gray(" - Duplicate upload attempt")); + break; + case "SchemaParsingError": + Logger.generic(chalk.gray("Schema validation failed:")); + if (Array.isArray(errorData.message)) { + errorData.message.forEach((validationError: any, index: number) => { + Logger.generic( + chalk.gray( + ` ${index + 1}. Field: ${validationError.path?.join(".")} ` + ) + ); + Logger.generic( + chalk.gray(` - Validation: ${validationError.validation}`) + ); + Logger.generic(chalk.gray(` - Code: ${validationError.code}`)); + Logger.generic( + chalk.gray(` - Message: ${validationError.message}`) + ); + }); + } + break; + default: + Logger.generic( + chalk.gray(`Error Details: ${JSON.stringify(errorData, null, 2)}`) + ); + } +} + +/** + * Service class for Lectern operations + */ +export class LecternService { + private url: string; + private authToken: string; + + /** + * Creates a new LecternService instance + * + * @param baseUrl - Base URL for the Lectern service + * @param authToken - Authentication token for API access + */ + constructor(baseUrl: string, authToken: string) { + this.url = this.normalizeUrl(baseUrl); + this.authToken = authToken; + } + + /** + * Gets the normalized Lectern URL + * + * @returns The normalized URL for the Lectern dictionaries endpoint + */ + getUrl(): string { + return this.url; + } + + /** + * Uploads a schema to the Lectern server + * + * @param schemaContent - The schema content as a JSON string + * @returns Promise resolving to the upload response + */ + async uploadSchema(schemaContent: string): Promise { + try { + // Parse schema to validate JSON before sending + const schemaData = JSON.parse(schemaContent); + + // Make request to Lectern API + const response = await axios.post( + this.url, + schemaData, + { + headers: { + Accept: "*/*", + Authorization: this.authToken, + "Content-Type": "application/json", + }, + } + ); + + // Check if response contains error + if (response.data && "error" in response.data && response.data.error) { + throw new ConductorError( + `Lectern API error: ${response.data.error}`, + ErrorCodes.CONNECTION_ERROR + ); + } + + return response.data; + } catch (error: unknown) { + // Type guard to check if error is an Axios error + const isAxiosError = (err: unknown): err is AxiosErrorResponse => + err !== null && + typeof err === "object" && + "response" in err && + "message" in err; + + // Handle axios errors + if (isAxiosError(error)) { + const statusCode = error.response?.status; + const responseData = error.response?.data; + + let errorMessage = `Failed to upload schema: ${error.message}`; + + // Detailed error parsing + if (responseData && typeof responseData === "object") { + // Try to extract more detailed error information + const detailedError = responseData as { + error?: string; + message?: string | any[]; + details?: string; + }; + + // Format and log detailed Lectern error + if (detailedError.error || detailedError.message) { + // Log error type + Logger.error(`Type: ${detailedError.error || "Unknown"}`); + + // Provide more context based on error type + formatLecternError(detailedError); + } + + errorMessage = `Lectern API error: ${ + detailedError.error || + (Array.isArray(detailedError.message) + ? detailedError.message[0]?.message + : detailedError.message) || + detailedError.details || + "Unknown error" + }`; + } + + throw new ConductorError( + errorMessage, + statusCode === 401 || statusCode === 403 + ? ErrorCodes.AUTH_ERROR + : ErrorCodes.CONNECTION_ERROR, + error + ); + } + + // Re-throw ConductorError as is + if (error instanceof ConductorError) { + throw error; + } + + // Wrap JSON parsing errors + if (error instanceof SyntaxError) { + throw new ConductorError( + `Invalid schema format: ${error.message}`, + ErrorCodes.INVALID_FILE, + error + ); + } + + // Wrap other errors + const errorMessage = + error instanceof Error ? error.message : String(error); + throw new ConductorError( + `Failed to upload schema: ${errorMessage}`, + ErrorCodes.CONNECTION_ERROR, + error + ); + } + } + + /** + * Normalizes the Lectern URL to ensure it points to the dictionaries endpoint + * + * @param url - Input URL + * @returns Normalized URL + */ + private normalizeUrl(url: string): string { + // Remove trailing slash if present + let normalizedUrl = url.endsWith("/") ? url.slice(0, -1) : url; + + // Ensure URL ends with /dictionaries + if (!normalizedUrl.endsWith("/dictionaries")) { + normalizedUrl = `${normalizedUrl}/dictionaries`; + } + + return normalizedUrl; + } +} diff --git a/apps/conductor/src/services/lyric/lyricDataService.ts b/apps/conductor/src/services/lyric/lyricDataService.ts new file mode 100644 index 00000000..dc5987ba --- /dev/null +++ b/apps/conductor/src/services/lyric/lyricDataService.ts @@ -0,0 +1,644 @@ +import axios from "axios"; +import * as fs from "fs"; +import * as path from "path"; +import { ConductorError, ErrorCodes } from "../../utils/errors"; +import { Logger } from "../../utils/logger"; + +/** + * Lectern dictionary information + */ +interface LecternDictionaryInfo { + /** Dictionary ID */ + id: string; + + /** Dictionary name */ + name: string; + + /** Schema name */ + schemaName: string; +} + +/** + * Parameters for data submission to Lyric + */ +export interface LyricDataSubmissionParams { + /** Category ID */ + categoryId: string; + + /** Organization name */ + organization: string; + + /** Data directory path */ + dataDirectory: string; + + /** Max retry attempts for validation check */ + maxRetries?: number; + + /** Delay between retry attempts in milliseconds */ + retryDelay?: number; +} + +/** + * Response from Lyric data submission + */ +export interface LyricSubmissionResponse { + /** Submission ID */ + submissionId: string; + + /** Submission status */ + status: string; + + /** Additional response details */ + [key: string]: any; +} + +/** + * Lectern schema response type + */ +interface LecternSchemaResponse { + schemas?: Array<{ + name: string; + [key: string]: any; + }>; + [key: string]: any; +} + +/** + * Lyric submission status response type + */ +interface LyricSubmissionStatusResponse { + status?: string; + [key: string]: any; +} + +/** + * Helper function to safely extract error message + * @param err - Any error object + * @returns String representation of the error + */ +function getErrorMessage(err: unknown): string { + if (err instanceof Error) { + return err.message; + } + return String(err); +} + +/** + * Enhanced LyricService with data loading functionality + */ +export class LyricDataService { + private lyricUrl: string; + private lecternUrl: string; + private readonly MAX_RETRIES: number = 10; + private readonly RETRY_DELAY: number = 20000; // 20 seconds + private readonly TIMEOUT: number = 10000; // 10 seconds + + // Cache for dictionary information + private dictionaryInfo: LecternDictionaryInfo | null = null; + + /** + * Creates a new LyricDataService instance + * + * @param lyricUrl - Lyric service URL + * @param lecternUrl - Lectern service URL + */ + constructor(lyricUrl: string, lecternUrl: string) { + if (!lyricUrl) { + throw new ConductorError( + "Lyric URL is required for service initialization", + ErrorCodes.INVALID_ARGS + ); + } + + if (!lecternUrl) { + throw new ConductorError( + "Lectern URL is required for dictionary information", + ErrorCodes.INVALID_ARGS + ); + } + + this.lyricUrl = this.normalizeUrl(lyricUrl); + this.lecternUrl = this.normalizeUrl(lecternUrl); + } + + /** + * Gets dictionary information from Lectern + * + * @returns Promise resolving to dictionary information + */ + async getDictionaryInfo(): Promise { + // Return cached info if available + if (this.dictionaryInfo) { + return this.dictionaryInfo; + } + + Logger.info("Fetching dictionary information from Lectern..."); + + try { + // Get dictionary list + const dictResponse = await axios.get(`${this.lecternUrl}/dictionaries`, { + headers: { accept: "application/json" }, + timeout: this.TIMEOUT, + }); + + // Make sure we have dictionary data + if (!dictResponse.data || !Array.isArray(dictResponse.data)) { + throw new ConductorError( + "Invalid response from Lectern - no dictionaries found", + ErrorCodes.CONNECTION_ERROR + ); + } + + // Get the first dictionary (matching the bash script behavior) + const dictionary = dictResponse.data[0]; + + if (!dictionary || !dictionary._id || !dictionary.name) { + throw new ConductorError( + "Could not find dictionary in Lectern", + ErrorCodes.CONNECTION_ERROR + ); + } + + const dictId = dictionary._id; + const dictName = dictionary.name; + + Logger.debug(`Found dictionary: ${dictName} (ID: ${dictId})`); + + // Get schema details + const schemaResponse = await axios.get( + `${this.lecternUrl}/dictionaries/${dictId}`, + { + headers: { accept: "application/json" }, + timeout: this.TIMEOUT, + } + ); + + const schemaData = schemaResponse.data; + + if ( + !schemaData || + !schemaData.schemas || + !Array.isArray(schemaData.schemas) || + schemaData.schemas.length === 0 + ) { + throw new ConductorError( + "Could not find schema in dictionary", + ErrorCodes.CONNECTION_ERROR + ); + } + + const schemaName = schemaData.schemas[0].name; + + if (!schemaName) { + throw new ConductorError( + "Could not find schema name in dictionary", + ErrorCodes.CONNECTION_ERROR + ); + } + + Logger.debug(`Found schema name: ${schemaName}`); + + // Cache and return the dictionary info + this.dictionaryInfo = { + id: dictId, + name: dictName, + schemaName: schemaName, + }; + + return this.dictionaryInfo; + } catch (unknownError) { + if (unknownError instanceof ConductorError) { + throw unknownError; + } + + throw new ConductorError( + `Failed to fetch dictionary information from Lectern: ${getErrorMessage( + unknownError + )}`, + ErrorCodes.CONNECTION_ERROR, + unknownError + ); + } + } + + /** + * Validates and finds files matching the schema name in the data directory + * + * @param dataDirectory - Directory containing CSV files + * @returns Promise resolving to an array of valid file paths + */ + async findValidFiles(dataDirectory: string): Promise { + // Verify directory exists + if (!fs.existsSync(dataDirectory)) { + throw new ConductorError( + `Directory not found: ${dataDirectory}`, + ErrorCodes.FILE_NOT_FOUND + ); + } + + // Get dictionary info to check schema name + const dictInfo = await this.getDictionaryInfo(); + const schemaName = dictInfo.schemaName; + + Logger.info(`Valid schema name from dictionary: ${schemaName}`); + + // Find all CSV files in the directory + const files = fs + .readdirSync(dataDirectory) + .filter( + (file) => + file.endsWith(".csv") && + fs.statSync(path.join(dataDirectory, file)).isFile() + ); + + if (files.length === 0) { + throw new ConductorError( + `No CSV files found in ${dataDirectory}`, + ErrorCodes.INVALID_ARGS + ); + } + + // Validate each file against schema name + const validFiles: string[] = []; + const renamedFiles: string[] = []; + + for (const file of files) { + const basename = path.basename(file, ".csv"); + + if (basename === schemaName) { + // Exact match + validFiles.push(file); + } else if (basename.startsWith(schemaName)) { + // File starts with schema name - rename it + const oldPath = path.join(dataDirectory, file); + const newFileName = `${schemaName}.csv`; + const newPath = path.join(dataDirectory, newFileName); + + try { + fs.renameSync(oldPath, newPath); + Logger.info(`Renamed ${file} to ${newFileName}`); + validFiles.push(newFileName); + renamedFiles.push(newFileName); + } catch (unknownError) { + Logger.warn( + `Failed to rename ${file} to ${newFileName}: ${getErrorMessage( + unknownError + )}` + ); + } + } else { + Logger.warn(`File '${file}' does not match schema name.`); + } + } + + if (validFiles.length === 0) { + throw new ConductorError( + `No valid schema-matching files found in ${dataDirectory}`, + ErrorCodes.INVALID_ARGS, + { + suggestion: `Please rename your files to match the valid schema name: ${schemaName}.csv`, + } + ); + } + + Logger.info( + `Found ${validFiles.length} valid CSV files matching schema: ${schemaName}` + ); + for (const file of validFiles) { + Logger.info(`- ${file}`); + } + + return validFiles; + } + + /** + * Submits data files to Lyric + * + * @param params - Data submission parameters + * @returns Promise resolving to submission response + */ + async submitData( + params: LyricDataSubmissionParams + ): Promise { + const { categoryId, organization, dataDirectory } = params; + + try { + // Find valid files + const validFiles = await this.findValidFiles(dataDirectory); + + // Prepare form data + const formData = new FormData(); + + // Add each file to form data + for (const file of validFiles) { + const filePath = path.join(dataDirectory, file); + const fileData = fs.readFileSync(filePath); + const blob = new Blob([fileData], { type: "text/csv" }); + formData.append("files", blob, file); + } + + // Add organization + formData.append("organization", organization); + + // Log submission information + Logger.info(`\x1b[1;36mSubmitting Data:\x1b[0m`); + Logger.info(`API URL: ${this.lyricUrl}`); + Logger.info(`Category ID: ${categoryId}`); + Logger.info(`Organization: ${organization}`); + Logger.info(`Data Directory: ${dataDirectory}`); + Logger.info(`Files to submit: ${validFiles.join(", ")}`); + + // Submit data + const response = await axios.post<{ submissionId?: string }>( + `${this.lyricUrl}/submission/category/${categoryId}/data`, + formData, + { + headers: { + accept: "application/json", + "Content-Type": "multipart/form-data", + }, + } + ); + + const responseData = response.data; + + // Extract submission ID + const submissionId = responseData?.submissionId; + + if (!submissionId) { + throw new ConductorError( + "Could not extract submission ID from response", + ErrorCodes.CONNECTION_ERROR, + { + response: responseData, + } + ); + } + + Logger.success(`Submission ID: ${submissionId}`); + + return { + submissionId: submissionId.toString(), + status: "PENDING", + ...(responseData && typeof responseData === "object" + ? responseData + : {}), + }; + } catch (unknownError) { + if (unknownError instanceof ConductorError) { + throw unknownError; + } + + if (this.isAxiosError(unknownError)) { + const error = unknownError as any; + const errorMessage = + (error.response?.data?.message + ? String(error.response.data.message) + : "") || (error.message ? String(error.message) : "Unknown error"); + + throw new ConductorError( + `Data submission failed: ${errorMessage}`, + ErrorCodes.CONNECTION_ERROR, + { + status: error.response?.status, + response: error.response?.data, + } + ); + } + + throw new ConductorError( + `Data submission failed: ${getErrorMessage(unknownError)}`, + ErrorCodes.CONNECTION_ERROR, + unknownError + ); + } + } + + /** + * Checks submission status + * + * @param categoryId - Category ID + * @param submissionId - Submission ID + * @returns Promise resolving to the submission status + */ + async checkSubmissionStatus( + categoryId: string, + submissionId: string + ): Promise { + try { + const response = await axios.get( + `${this.lyricUrl}/submission/${submissionId}`, + { + headers: { accept: "application/json" }, + } + ); + + const responseData = response.data; + const status = responseData?.status; + + if (!status) { + throw new ConductorError( + "Could not extract status from response", + ErrorCodes.CONNECTION_ERROR, + { + response: responseData, + } + ); + } + + Logger.info(`Current status: ${status}`); + return status; + } catch (unknownError) { + if (unknownError instanceof ConductorError) { + throw unknownError; + } + + throw new ConductorError( + `Failed to check submission status: ${getErrorMessage(unknownError)}`, + ErrorCodes.CONNECTION_ERROR, + unknownError + ); + } + } + + /** + * Waits for submission validation to complete + * + * @param categoryId - Category ID + * @param submissionId - Submission ID + * @param maxRetries - Maximum number of retry attempts + * @param retryDelay - Delay between retries in milliseconds + * @returns Promise resolving to the final submission status + */ + async waitForValidation( + categoryId: string, + submissionId: string, + maxRetries: number = 10, + retryDelay: number = 20000 + ): Promise { + let retries = 0; + + while (retries < maxRetries) { + Logger.info( + `Checking submission status (attempt ${retries + 1}/${maxRetries})...` + ); + + try { + const status = await this.checkSubmissionStatus( + categoryId, + submissionId + ); + + if (status === "VALID") { + Logger.success(`Submission is valid`); + return status; + } else if (status === "INVALID") { + throw new ConductorError( + "Submission validation failed", + ErrorCodes.VALIDATION_FAILED, + { + submissionId, + status, + } + ); + } + + // Wait for next check + await new Promise((resolve) => setTimeout(resolve, retryDelay)); + retries++; + } catch (unknownError) { + if (unknownError instanceof ConductorError) { + throw unknownError; + } + + throw new ConductorError( + `Error checking submission status: ${getErrorMessage(unknownError)}`, + ErrorCodes.CONNECTION_ERROR, + unknownError + ); + } + } + + throw new ConductorError( + `Validation timed out after ${maxRetries} attempts`, + ErrorCodes.CONNECTION_ERROR, + { + submissionId, + attempts: maxRetries, + } + ); + } + + /** + * Commits a validated submission + * + * @param categoryId - Category ID + * @param submissionId - Submission ID + * @returns Promise resolving to true if commit successful + */ + async commitSubmission( + categoryId: string, + submissionId: string + ): Promise { + try { + Logger.info(`\x1b[1;36mCommitting Submission:\x1b[0m ${submissionId}`); + + const response = await axios.post( + `${this.lyricUrl}/submission/category/${categoryId}/commit/${submissionId}`, + "", + { + headers: { accept: "application/json" }, + } + ); + + Logger.success(`Submission committed successfully`); + return true; + } catch (unknownError) { + throw new ConductorError( + `Failed to commit submission: ${getErrorMessage(unknownError)}`, + ErrorCodes.CONNECTION_ERROR, + unknownError + ); + } + } + + /** + * Loads data into Lyric by submitting, validating, and committing in one operation + * + * @param params - Data submission parameters + * @returns Promise resolving to the final submission response + */ + async loadData( + params: LyricDataSubmissionParams + ): Promise { + const { categoryId, maxRetries, retryDelay } = params; + + try { + // Submit data + const submission = await this.submitData(params); + const submissionId = submission.submissionId; + + // Wait for validation to complete + const status = await this.waitForValidation( + categoryId, + submissionId, + maxRetries || this.MAX_RETRIES, + retryDelay || this.RETRY_DELAY + ); + + // Commit the submission if valid + if (status === "VALID") { + await this.commitSubmission(categoryId, submissionId); + + return { + ...submission, + status: "COMMITTED", + }; + } else { + throw new ConductorError( + `Submission has unexpected status: ${status}`, + ErrorCodes.VALIDATION_FAILED, + { + submissionId, + status, + } + ); + } + } catch (unknownError) { + if (unknownError instanceof ConductorError) { + throw unknownError; + } + + throw new ConductorError( + `Data loading failed: ${getErrorMessage(unknownError)}`, + ErrorCodes.CONNECTION_ERROR, + unknownError + ); + } + } + + /** + * Normalizes a URL by removing trailing slash + * + * @param url - URL to normalize + * @returns Normalized URL + */ + private normalizeUrl(url: string): string { + return url.endsWith("/") ? url.slice(0, -1) : url; + } + + /** + * Type guard to check if an error is an Axios error + * + * @param error - Error to check + * @returns Whether the error is an Axios error + */ + private isAxiosError(error: any): boolean { + return Boolean( + error && + typeof error === "object" && + "isAxiosError" in error && + error.isAxiosError === true + ); + } +} diff --git a/apps/conductor/src/services/lyric/lyricService.ts b/apps/conductor/src/services/lyric/lyricService.ts new file mode 100644 index 00000000..59217182 --- /dev/null +++ b/apps/conductor/src/services/lyric/lyricService.ts @@ -0,0 +1,325 @@ +import axios from "axios"; +import { ConductorError, ErrorCodes } from "../../utils/errors"; +import { Logger } from "../../utils/logger"; + +/** + * Response from Lyric dictionary registration + */ +export interface LyricRegistrationResponse { + /** Whether the registration was successful */ + success: boolean; + + /** Status message */ + message?: string; + + /** Error message if registration failed */ + error?: string; + + /** Additional response details */ + [key: string]: any; +} + +/** + * Parameters for dictionary registration + */ +export interface DictionaryRegistrationParams { + /** Category name for the dictionary */ + categoryName: string; + + /** Dictionary name */ + dictionaryName: string; + + /** Dictionary version */ + dictionaryVersion: string; + + /** Default centric entity */ + defaultCentricEntity: string; +} + +/** + * Type definition for API response data + */ +interface ApiResponseData { + error?: string; + message?: string; + status?: string; + [key: string]: any; +} + +/** + * Service class for Lyric operations + */ +export class LyricService { + private url: string; + + /** + * Creates a new LyricService instance + * + * @param baseUrl - Base URL for the Lyric service + */ + constructor(baseUrl: string) { + if (!baseUrl) { + throw new ConductorError( + "Lyric URL is required for service initialization", + ErrorCodes.INVALID_ARGS + ); + } + + this.url = this.normalizeUrl(baseUrl); + } + + /** + * Gets the normalized Lyric URL + * + * @returns The normalized URL for the Lyric service + */ + getUrl(): string { + return this.url; + } + + /** + * Registers a dictionary with the Lyric service + * + * @param params - Dictionary registration parameters + * @returns Promise resolving to the registration response + */ + async registerDictionary( + params: DictionaryRegistrationParams + ): Promise { + try { + const { + categoryName, + dictionaryName, + dictionaryVersion, + defaultCentricEntity, + } = params; + + // Validate required parameters + if ( + !categoryName || + !dictionaryName || + !dictionaryVersion || + !defaultCentricEntity + ) { + throw new ConductorError( + "Missing required parameters for dictionary registration", + ErrorCodes.INVALID_ARGS + ); + } + + // Construct the registration endpoint URL + const registerUrl = `${this.url}/dictionary/register`; + + Logger.info(`Registering dictionary to ${registerUrl}`, { + categoryName, + dictionaryName, + dictionaryVersion, + defaultCentricEntity, + }); + + // Construct form data (as URLSearchParams for application/x-www-form-urlencoded) + const formData = new URLSearchParams(); + formData.append("categoryName", categoryName); + formData.append("dictionaryName", dictionaryName); + formData.append("dictionaryVersion", dictionaryVersion); + formData.append("defaultCentricEntity", defaultCentricEntity); + + // Make the API call + const response = await axios.post( + registerUrl, + formData.toString(), + { + headers: { + "Content-Type": "application/x-www-form-urlencoded", + Accept: "application/json", + }, + } + ); + + const responseData = response.data; + + // Check if response contains error + if ( + responseData && + typeof responseData === "object" && + "error" in responseData && + responseData.error + ) { + throw new ConductorError( + `Lyric API error: ${responseData.error}`, + ErrorCodes.CONNECTION_ERROR + ); + } + + Logger.info("Dictionary registration successful", { + response: responseData, + }); + + return { + success: true, + message: "Dictionary registered successfully", + ...(typeof responseData === "object" ? responseData : {}), + }; + } catch (error) { + // Handle axios errors + if (this.isAxiosError(error)) { + const statusCode = error.response?.status; + const responseData = error.response?.data as + | ApiResponseData + | undefined; + + // Start with a basic error message + let errorMessage = `Failed to register dictionary: ${error.message}`; + let errorDetails: any = {}; + + // Detailed error parsing + if (responseData && typeof responseData === "object") { + // Extract all useful information + errorDetails = { + status: statusCode, + endpoint: `${this.url}/dictionary/register`, + params: { + categoryName: params.categoryName, + dictionaryName: params.dictionaryName, + dictionaryVersion: params.dictionaryVersion, + defaultCentricEntity: params.defaultCentricEntity, + }, + }; + + // Add response data to the details if available + if (responseData.error) errorDetails.error = responseData.error; + if (responseData.message) errorDetails.message = responseData.message; + if (responseData.details) errorDetails.details = responseData.details; + if (responseData.code) errorDetails.code = responseData.code; + + // Format the main error message + if (statusCode === 400) { + errorMessage = `Lyric API error: Bad Request - ${ + responseData.message || + (responseData.error === "Bad Request" + ? "The dictionary registration request was rejected by the server" + : responseData.error) || + "Invalid request parameters" + }`; + + // Add more context for common bad request causes + if ( + errorMessage.includes("already exists") || + (responseData.message && + responseData.message.toString().includes("already exists")) + ) { + errorDetails.suggestion = + "A dictionary with these parameters may already exist in the Lyric service"; + } else if (errorMessage.includes("invalid")) { + errorDetails.suggestion = + "Check the format and values of all parameters"; + } + } else { + errorMessage = `Lyric API error: ${ + responseData.error || + responseData.message || + `HTTP Error ${statusCode}` + }`; + } + } + + // Log detailed information for debugging + Logger.debug( + `Detailed error information: ${JSON.stringify(errorDetails, null, 2)}` + ); + + // Create appropriate error code based on status + const errorCode = + statusCode === 401 || statusCode === 403 + ? ErrorCodes.AUTH_ERROR + : ErrorCodes.CONNECTION_ERROR; + + throw new ConductorError(errorMessage, errorCode, errorDetails); + } + + // Re-throw ConductorError as is + if (error instanceof ConductorError) { + throw error; + } + + // Wrap other errors + const errorMessage = + error instanceof Error ? error.message : String(error); + throw new ConductorError( + `Failed to register dictionary: ${errorMessage}`, + ErrorCodes.CONNECTION_ERROR, + error + ); + } + } + + /** + * Checks the health of the Lyric service + * @returns Promise resolving to a boolean indicating health status + */ + async checkHealth(): Promise { + try { + const healthUrl = `${this.url.replace( + /\/dictionary\/register$/, + "" + )}/health`; + + Logger.info(`Checking Lyric health at ${healthUrl}`); + + const response = await axios.get(healthUrl, { + timeout: 10000, // 10 seconds timeout + headers: { accept: "*/*" }, + }); + + const responseData = response.data; + const isHealthy = + response.status === 200 && + (!responseData.status || + responseData.status === "UP" || + responseData.status === "Healthy"); + + if (isHealthy) { + Logger.info(`\x1b[32mSuccess:\x1b[0m Lyric service is healthy`); + return true; + } else { + Logger.warn( + `Lyric health check failed. Status: ${JSON.stringify(responseData)}` + ); + return false; + } + } catch (error) { + Logger.error( + `Failed to check Lyric health: ${ + error instanceof Error ? error.message : String(error) + }` + ); + return false; + } + } + + /** + * Normalizes the Lyric URL + * + * @param url - Input URL + * @returns Normalized URL + */ + private normalizeUrl(url: string): string { + // Remove trailing slash if present + return url.endsWith("/") ? url.slice(0, -1) : url; + } + + /** + * Type guard to check if an error is an Axios error + * + * @param error - The error to check + * @returns Whether the error is an Axios error + */ + private isAxiosError(error: unknown): error is any { + return Boolean( + error && + typeof error === "object" && + "isAxiosError" in error && + (error as any).isAxiosError === true + ); + } +} diff --git a/apps/conductor/src/services/song/songSchemaValidator.ts b/apps/conductor/src/services/song/songSchemaValidator.ts new file mode 100644 index 00000000..2e665e37 --- /dev/null +++ b/apps/conductor/src/services/song/songSchemaValidator.ts @@ -0,0 +1,173 @@ +/** + * SONG Schema Validator + * + * Validates schema files against SONG-specific requirements based on SONG documentation. + */ +import { ConductorError, ErrorCodes } from "../../utils/errors"; + +/** + * Required fields for SONG analysis schemas + */ +const REQUIRED_FIELDS = ["name", "schema"]; + +/** + * Validates a schema against SONG-specific requirements + * + * @param schema - The schema object to validate + * @returns Validation result with warnings + * @throws ConductorError if validation fails with critical issues + */ +export function validateSongSchema(schema: any): { + isValid: boolean; + warnings: string[]; +} { + const warnings: string[] = []; + + // Check if schema is an object + if (!schema || typeof schema !== "object") { + throw new ConductorError( + "Invalid schema format: Schema must be a JSON object", + ErrorCodes.INVALID_FILE + ); + } + + // Check for required fields + for (const field of REQUIRED_FIELDS) { + if (typeof schema[field] === "undefined" || schema[field] === null) { + throw new ConductorError( + `Invalid schema: Missing required field '${field}'`, + ErrorCodes.INVALID_FILE, + { + details: `The SONG server requires '${field}' to be present`, + suggestion: `Add a '${field}' field to your schema`, + } + ); + } + } + + // Validate the "schema" field is an object + if (typeof schema.schema !== "object") { + throw new ConductorError( + "Invalid schema: The 'schema' field must be an object", + ErrorCodes.INVALID_FILE, + { + details: + "The 'schema' field defines the JSON schema for this analysis type", + suggestion: + "Make sure 'schema' is an object containing at least 'type' and 'properties'", + } + ); + } + + // Check schema.schema has required properties for a JSON schema + if (!schema.schema.type) { + warnings.push( + "The schema should specify a 'type' property (usually 'object')" + ); + } + + // Validate schema name format if present + if (schema.name && typeof schema.name === "string") { + if (!/^[a-zA-Z0-9_-]+$/.test(schema.name)) { + warnings.push( + "Schema name should contain only letters, numbers, hyphens, and underscores" + ); + } + } + + // Validate options if provided + if (schema.options) { + // Options should be an object + if (typeof schema.options !== "object") { + warnings.push("The 'options' field should be an object"); + } else { + // Check fileTypes if present + if (schema.options.fileTypes !== undefined) { + if (!Array.isArray(schema.options.fileTypes)) { + warnings.push( + "The 'options.fileTypes' should be an array of strings" + ); + } else { + // Check if each fileType is a string + for (const fileType of schema.options.fileTypes) { + if (typeof fileType !== "string") { + warnings.push( + "Each fileType in 'options.fileTypes' should be a string" + ); + break; + } + } + } + } + + // Check externalValidations if present + if (schema.options.externalValidations !== undefined) { + if (!Array.isArray(schema.options.externalValidations)) { + warnings.push( + "The 'options.externalValidations' should be an array of validation objects" + ); + } else { + // Check each external validation + for (const validation of schema.options.externalValidations) { + if (typeof validation !== "object") { + warnings.push( + "Each validation in 'options.externalValidations' should be an object" + ); + continue; + } + + // Check for required fields in each validation + if (!validation.url) { + warnings.push( + "Each external validation should have a 'url' property" + ); + } else if (typeof validation.url !== "string") { + warnings.push( + "The 'url' in external validation should be a string" + ); + } else { + // Check for valid URL format with valid placeholders + const urlPlaceholders = + validation.url.match(/\{([^}]+)\}/g) || []; + for (const placeholder of urlPlaceholders) { + const placeholderName = placeholder.slice(1, -1); // Remove { and } + if ( + placeholderName !== "study" && + placeholderName !== "value" + ) { + warnings.push( + `URL placeholder ${placeholder} is not valid. Only {study} and {value} are allowed.` + ); + } + } + } + + if (!validation.jsonPath) { + warnings.push( + "Each external validation should have a 'jsonPath' property" + ); + } else if (typeof validation.jsonPath !== "string") { + warnings.push( + "The 'jsonPath' in external validation should be a string" + ); + } + } + } + } + } + } + + // Check if schema.schema has a properties field + if (!schema.schema.properties) { + warnings.push( + "The schema should have a 'properties' field defining the structure" + ); + } else if (typeof schema.schema.properties !== "object") { + warnings.push("The 'properties' field should be an object"); + } + + return { + isValid: true, + warnings, + }; +} diff --git a/apps/conductor/src/types/cli.ts b/apps/conductor/src/types/cli.ts new file mode 100644 index 00000000..34b8ab1c --- /dev/null +++ b/apps/conductor/src/types/cli.ts @@ -0,0 +1,157 @@ +import { Profiles } from "./constants"; + +export type Profile = (typeof Profiles)[keyof typeof Profiles]; + +export interface Config { + elasticsearch: { + url: string; + user?: string; + password?: string; + index: string; + templateFile?: string; + templateName?: string; + alias?: string; + }; + lectern?: { + url?: string; + authToken?: string; + }; + lyric?: { + url?: string; + categoryName?: string; + dictionaryName?: string; + dictionaryVersion?: string; + defaultCentricEntity?: string; + dataDirectory?: string; + categoryId?: string; + organization?: string; + maxRetries?: number; + retryDelay?: number; + }; + song?: { + url?: string; + authToken?: string; + schemaFile?: string; + studyId?: string; + studyName?: string; + organization?: string; + description?: string; + analysisFile?: string; + analysisPath?: string; + allowDuplicates?: boolean; + ignoreUndefinedMd5?: boolean; + }; + score?: { + url?: string; + authToken?: string; + analysisId?: string; + dataDir?: string; + outputDir?: string; + manifestFile?: string; + }; + maestroIndex?: { + url?: string; + repositoryCode?: string; + organization?: string; + id?: string; + }; + batchSize: number; + delimiter: string; +} + +export interface CLIOutput { + profile: Profile; + debug?: boolean; + filePaths: string[]; + config: Config; + outputPath?: string; + envConfig: EnvConfig; + options: any; // Allows for flexible option handling +} + +export interface EnvConfig { + elasticsearchUrl: string; + esUser?: string; + esPassword?: string; + indexName?: string; + lecternUrl?: string; + lyricUrl?: string; + songUrl?: string; + scoreUrl?: string; + lyricData?: string; + categoryId?: string; + organization?: string; +} + +export interface UploadOptions { + files: string[]; + index?: string; + batchSize?: number; + delimiter?: string; +} + +export interface IndexManagementOptions { + templateFile: string; + templateName: string; + indexName: string; + aliasName?: string; +} + +export interface LyricDataOptions { + lyricUrl?: string; + lecternUrl?: string; + dataDirectory?: string; + categoryId?: string; + organization?: string; + maxRetries?: number; + retryDelay?: number; +} + +export interface SongStudyOptions { + songUrl?: string; + studyId?: string; + studyName?: string; + organization?: string; + description?: string; + authToken?: string; + force?: boolean; +} + +export interface SongAnalysisOptions { + songUrl?: string; + analysisFile: string; + studyId?: string; + allowDuplicates?: boolean; + authToken?: string; + force?: boolean; +} + +export interface ScoreManifestOptions { + analysisId: string; + dataDir?: string; + outputDir?: string; + manifestFile?: string; + songUrl?: string; + scoreUrl?: string; + authToken?: string; +} + +export interface SongPublishOptions { + analysisId: string; + studyId?: string; + songUrl?: string; + authToken?: string; + ignoreUndefinedMd5?: boolean; +} + +export interface SongScoreSubmitOptions { + analysisPath: string; + studyId?: string; + dataDir?: string; + outputDir?: string; + manifestFile?: string; + songUrl?: string; + scoreUrl?: string; + authToken?: string; + ignoreUndefinedMd5?: boolean; +} diff --git a/apps/conductor/src/types/constants.ts b/apps/conductor/src/types/constants.ts new file mode 100644 index 00000000..0d64233d --- /dev/null +++ b/apps/conductor/src/types/constants.ts @@ -0,0 +1,92 @@ +/** + * Constants used throughout the application + * + * This file defines constants for profiles, error codes, and other application-wide values. + * New profiles should be added here to make them available throughout the application. + */ + +/** + * Available command profiles + */ +export const Profiles = { + /** Upload data to Elasticsearch */ + UPLOAD: "upload", + + /** Setup Elasticsearch indices and templates */ + INDEX_MANAGEMENT: "indexManagement", + + /** Upload schema to Lectern server */ + LECTERN_UPLOAD: "lecternUpload", + + /** Register a Lectern dictionary with Lyric */ + LYRIC_REGISTER: "lyricRegister", + + /** Upload data into Lyric */ + LYRIC_DATA: "lyricUpload", + + /** Index data using Maestro */ + INDEX_REPOSITORY: "maestroIndex", + + /** Upload schema to SONG server */ + song_upload_schema: "songUploadSchema", + + /** Create study in SONG server */ + song_create_study: "songCreateStudy", + + /** Submit analysis to SONG server */ + song_submit_analysis: "songSubmitAnalysis", + + /** Generate manifest and upload with Score */ + score_manifest_upload: "scoreManifestUpload", + + /** Publish analysis in SONG server */ + song_publish_analysis: "songPublishAnalysis", + + /** Combined SONG/SCORE workflow */ + song_score_submit: "songScoreSubmit", +} as const; + +/** + * UI-friendly descriptions for profiles + */ +export const ProfileDescriptions = { + [Profiles.UPLOAD]: "Upload data to Elasticsearch", + [Profiles.INDEX_MANAGEMENT]: "Setup Elasticsearch indices and templates", + [Profiles.LECTERN_UPLOAD]: "Upload schema to Lectern server", + [Profiles.LYRIC_REGISTER]: "Register a Lectern dictionary with Lyric", + [Profiles.LYRIC_DATA]: "Load data into Lyric service", + [Profiles.INDEX_REPOSITORY]: "Repository Indexing", + [Profiles.song_upload_schema]: "Upload schema to SONG server", + [Profiles.song_create_study]: "Create study in SONG server", + [Profiles.song_submit_analysis]: "Submit analysis to SONG server", + [Profiles.score_manifest_upload]: + "Generate manifest and upload files with Score", + [Profiles.song_publish_analysis]: "Publish analysis in SONG server", + [Profiles.song_score_submit]: "End-to-end SONG/SCORE workflow", +}; + +/** + * Default values used throughout the application + */ +export const Defaults = { + /** Default port for the application */ + PORT: 3000, + + /** Default batch size for uploads */ + BATCH_SIZE: 1000, + + /** Default delimiter for CSV files */ + DELIMITER: ",", + + /** Default max retries for Lyric operations */ + MAX_RETRIES: 10, + + /** Default retry delay in milliseconds */ + RETRY_DELAY: 20000, + + /** Default category ID for Lyric */ + CATEGORY_ID: "1", + + /** Default organization name */ + ORGANIZATION: "OICR", +}; diff --git a/apps/conductor/src/types/elasticsearch.ts b/apps/conductor/src/types/elasticsearch.ts new file mode 100644 index 00000000..96b0be87 --- /dev/null +++ b/apps/conductor/src/types/elasticsearch.ts @@ -0,0 +1,87 @@ +/** + * Elasticsearch Types + * + * Type definitions for Elasticsearch operations and responses. + */ + +/** + * Elasticsearch bulk operation response item + */ +export interface ESBulkResponseItem { + index?: { + _index: string; + _type?: string; + _id: string; + _version?: number; + result?: string; + _shards?: { + total: number; + successful: number; + failed: number; + }; + status: number; + error?: { + type: string; + reason: string; + index_uuid?: string; + shard?: string; + index?: string; + }; + }; +} + +/** + * Elasticsearch bulk operation response + */ +export interface ESBulkResponse { + took: number; + errors: boolean; + items: ESBulkResponseItem[]; +} + +/** + * Elasticsearch index mapping property + */ +export interface ESMappingProperty { + type: string; + fields?: { + [key: string]: { + type: string; + ignore_above?: number; + }; + }; + properties?: { + [key: string]: ESMappingProperty; + }; +} + +/** + * Elasticsearch index mapping + */ +export interface ESIndexMapping { + properties: { + [key: string]: ESMappingProperty; + }; +} + +/** + * Elasticsearch index settings + */ +export interface ESIndexSettings { + number_of_shards: number; + number_of_replicas: number; + [key: string]: any; +} + +/** + * Elasticsearch index information response + */ +export interface ESIndexInfo { + [indexName: string]: { + aliases: Record; + mappings: ESIndexMapping; + settings: { + index: ESIndexSettings; + }; + }; +} diff --git a/apps/conductor/src/types/index.ts b/apps/conductor/src/types/index.ts new file mode 100644 index 00000000..81a0358b --- /dev/null +++ b/apps/conductor/src/types/index.ts @@ -0,0 +1,14 @@ +/** + * Types Module + * + * Export all type definitions used across the application. + * This file serves as the central hub for all shared types. + */ + +// Export all other types +export * from "./cli"; +export * from "./constants"; +export * from "./elasticsearch"; +export * from "./validations"; +export * from "./processor"; +export * from "./lectern"; diff --git a/apps/conductor/src/types/lectern.ts b/apps/conductor/src/types/lectern.ts new file mode 100644 index 00000000..1ee8e431 --- /dev/null +++ b/apps/conductor/src/types/lectern.ts @@ -0,0 +1,19 @@ +/** + * Response from Lectern schema upload + */ +export interface LecternUploadResponse { + /** The unique identifier for the uploaded schema */ + id?: string; + + /** The name of the schema */ + name?: string; + + /** The version of the schema */ + version?: string; + + /** Any error message returned by Lectern */ + error?: string; + + /** Additional response details */ + [key: string]: any; +} diff --git a/apps/conductor/src/types/processor.ts b/apps/conductor/src/types/processor.ts new file mode 100644 index 00000000..be837b85 --- /dev/null +++ b/apps/conductor/src/types/processor.ts @@ -0,0 +1,72 @@ +/** + * Processor Types + * + * Type definitions for CSV processing and record handling. + */ + +/** + * Record metadata for tracking and audit purposes + */ +export interface RecordMetadata { + /** Unique submission identifier */ + submitter_id: string; + + /** When the overall processing job started */ + processing_started: string; + + /** When this specific record was processed */ + processed_at: string; + + /** Source file path */ + source_file: string; + + /** Position in the file (row number) */ + record_number: number; + + /** Processing host name */ + hostname: string; + + /** Operating system username */ + username: string; +} + +/** + * Processed record structure + */ +export interface ProcessedRecord { + /** Metadata for tracking and auditing */ + submission_metadata: RecordMetadata; + + /** The actual CSV data fields */ + data: Record; +} + +/** + * Progress tracking callback + */ +export type ProgressCallback = (current: number, total: number) => void; + +/** + * Batch failure callback + */ +export type FailureCallback = (count: number) => void; + +/** + * Processing statistics + */ +export interface ProcessingStats { + /** Total number of processed records */ + processed: number; + + /** Number of failed records */ + failed: number; + + /** Processing start time */ + startTime: number; + + /** Processing end time */ + endTime: number; + + /** Time taken in milliseconds */ + elapsedMs: number; +} diff --git a/apps/conductor/src/types/validations.ts b/apps/conductor/src/types/validations.ts new file mode 100644 index 00000000..d7f741c2 --- /dev/null +++ b/apps/conductor/src/types/validations.ts @@ -0,0 +1,75 @@ +/** + * Validation Types + * + * Type definitions for the validation system. + */ + +/** + * Basic validation result returned by all validators + */ +export interface ValidationResult { + /** Whether validation passed */ + valid: boolean; + + /** List of validation errors */ + errors: string[]; + + /** Optional warnings that don't fail validation */ + warnings?: string[]; +} + +/** + * Header validation result with field information + */ +export interface HeaderValidation extends ValidationResult { + /** List of valid fields */ + fields?: string[]; + + /** List of invalid fields */ + invalidFields?: string[]; +} + +/** + * Detailed CSV validation result + */ +export interface CSVValidationResult extends ValidationResult { + /** Header validation result */ + header?: HeaderValidation; + + /** Number of rows in the CSV */ + rowCount?: number; + + /** Number of rows sampled for validation */ + sampleSize?: number; + + /** Detected or used delimiter */ + delimiter?: string; +} + +/** + * Elasticsearch index validation result + */ +export interface IndexValidationResult extends ValidationResult { + /** Whether the index exists */ + exists?: boolean; + + /** Index mappings if available */ + mappings?: any; + + /** Index settings if available */ + settings?: any; +} + +/** + * Elasticsearch connection validation result + */ +export interface ConnectionValidationResult extends ValidationResult { + /** Elasticsearch version */ + version?: string; + + /** Cluster name */ + clusterName?: string; + + /** Response time in milliseconds */ + responseTimeMs?: number; +} diff --git a/apps/conductor/src/utils/elasticsearch.ts b/apps/conductor/src/utils/elasticsearch.ts new file mode 100644 index 00000000..727f1e94 --- /dev/null +++ b/apps/conductor/src/utils/elasticsearch.ts @@ -0,0 +1,78 @@ +import { Client, ClientOptions } from "@elastic/elasticsearch"; +import { Logger } from "./logger"; +import { ConductorError, ErrorCodes } from "./errors"; + +/** + * Creates an Elasticsearch client using the provided configuration. + * + * @param url - Elasticsearch server URL + * @param username - Optional username for authentication + * @param password - Optional password for authentication + * @returns A configured Elasticsearch client instance. + */ +export function createElasticsearchClient(options: { + url: string; + username?: string; + password?: string; +}): Client { + const clientConfig: ClientOptions = { + node: options.url, + requestTimeout: 10000, // 10 seconds timeout + }; + + if (options.username && options.password) { + clientConfig.auth = { + username: options.username, + password: options.password, + }; + } + + try { + const client = new Client(clientConfig); + return client; + } catch (error) { + Logger.error(`Failed to create Elasticsearch client: ${error}`); + throw new ConductorError( + `Failed to create Elasticsearch client: ${error}`, + ErrorCodes.CONNECTION_ERROR, + error + ); + } +} + +/** + * Validates connection to Elasticsearch + * + * @param client - Elasticsearch client instance + * @returns Promise resolving to connection status + */ +export async function validateElasticsearchConnection( + client: Client +): Promise { + try { + const result = await client.info(); + Logger.debug( + `Elasticsearch cluster info: ${JSON.stringify(result.body, null, 2)}` + ); + return true; + } catch (error) { + Logger.error(`Detailed Elasticsearch connection validation error:`, error); + + // More comprehensive error logging + if (error instanceof Error) { + Logger.error(`Error name: ${error.name}`); + Logger.error(`Error message: ${error.message}`); + + // Additional error details + if ("response" in error) { + const detailedError = error as any; + Logger.error(`Response status: ${detailedError.response?.status}`); + Logger.error( + `Response data: ${JSON.stringify(detailedError.response?.data)}` + ); + } + } + + return false; + } +} diff --git a/apps/conductor/src/utils/errors.ts b/apps/conductor/src/utils/errors.ts new file mode 100644 index 00000000..d2ef9475 --- /dev/null +++ b/apps/conductor/src/utils/errors.ts @@ -0,0 +1,96 @@ +import { Logger } from "./logger"; + +export class ConductorError extends Error { + constructor(message: string, public code: string, public details?: any) { + super(message); + this.name = "ConductorError"; + } + + toString(): string { + return `${this.message}${ + this.details ? `\nDetails: ${JSON.stringify(this.details, null, 2)}` : "" + }`; + } +} + +export const ErrorCodes = { + INVALID_ARGS: "[INVALID_ARGS]", + FILE_NOT_FOUND: "[FILE_NOT_FOUND]", + INVALID_FILE: "[INVALID_FILE]", + VALIDATION_FAILED: "[VALIDATION_FAILED]", + ENV_ERROR: "[ENV_ERROR]", + PARSING_ERROR: "[PARSING_ERROR]", + FILE_ERROR: "[FILE_ERROR]", + FILE_WRITE_ERROR: "[FILE_WRITE_ERROR]", + CONNECTION_ERROR: "[CONNECTION_ERROR]", + AUTH_ERROR: "[AUTH_ERROR]", + INDEX_NOT_FOUND: "[INDEX_NOT_FOUND]", + TRANSFORM_ERROR: "[TRANSFORM_ERROR]", + CLI_ERROR: "[CLI_ERROR]", + CSV_ERROR: "[CSV_ERROR]", + ES_ERROR: "[ES_ERROR]", + UNKNOWN_ERROR: "[UNKNOWN_ERROR]", + USER_CANCELLED: "[USER_CANCELLED]", +} as const; + +export type ErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes]; + +function formatErrorDetails(details: any): string { + if (typeof details === "string") { + return details; + } + if (details instanceof Error) { + return details.message; + } + try { + return JSON.stringify(details, null, 2); + } catch { + return String(details); + } +} + +export function handleError( + error: unknown, + showAvailableProfiles?: () => void +): never { + if (error instanceof ConductorError) { + // Basic error message for all users + Logger.error(`${error.message}`); + + // Detailed error only in debug mode + if (process.argv.includes("--debug")) { + if (error.details) { + Logger.debug("Error details:"); + Logger.debug(formatErrorDetails(error.details)); + } + + Logger.debug("Stack trace:"); + Logger.debug(error.stack || "No stack trace available"); + } + + if (showAvailableProfiles) { + showAvailableProfiles(); + } + } else { + // For unexpected errors, just output the message + Logger.error( + `Unexpected error: ${ + error instanceof Error ? error.message : String(error) + }` + ); + + if (process.argv.includes("--debug") && error instanceof Error) { + Logger.debug("Stack trace:"); + Logger.debug(error.stack || "No stack trace available"); + } + } + + process.exit(1); +} + +export function createValidationError( + message: string, + details?: any +): ConductorError { + return new ConductorError(message, ErrorCodes.VALIDATION_FAILED, details); +} diff --git a/apps/conductor/src/utils/logger.ts b/apps/conductor/src/utils/logger.ts new file mode 100644 index 00000000..c28b59a5 --- /dev/null +++ b/apps/conductor/src/utils/logger.ts @@ -0,0 +1,601 @@ +import chalk from "chalk"; + +export enum LogLevel { + DEBUG = 0, + INFO = 1, + SUCCESS = 2, + WARN = 3, + ERROR = 4, + TIP = 5, + GENERIC = 6, + SECTION = 7, + INPUT = 8, +} + +interface LoggerConfig { + level: LogLevel; + debug: boolean; +} + +export class Logger { + private static config: LoggerConfig = { + level: LogLevel.INFO, + debug: false, + }; + + private static formatMessage(message: string, level: LogLevel): string { + const icons = { + [LogLevel.DEBUG]: "🔍", + [LogLevel.INFO]: "▸", + [LogLevel.SUCCESS]: "✓", + [LogLevel.WARN]: "⚠", + [LogLevel.ERROR]: "✗", + [LogLevel.TIP]: "\n💡", + [LogLevel.GENERIC]: "", + [LogLevel.SECTION]: "", + [LogLevel.INPUT]: "❔", + }; + + const colors: Record string> = { + [LogLevel.DEBUG]: chalk.bold.gray, + [LogLevel.INFO]: chalk.bold.cyan, + [LogLevel.SUCCESS]: chalk.bold.green, + [LogLevel.WARN]: chalk.bold.yellow, + [LogLevel.ERROR]: chalk.bold.red, + [LogLevel.TIP]: chalk.bold.yellow, + [LogLevel.GENERIC]: chalk.white, + [LogLevel.SECTION]: chalk.bold.green, + [LogLevel.INPUT]: chalk.bold.yellow, + }; + + const levelLabels = { + [LogLevel.DEBUG]: "Debug", + [LogLevel.INFO]: "Info", + [LogLevel.SUCCESS]: "Success", + [LogLevel.WARN]: "Warn", + [LogLevel.ERROR]: "Error", + [LogLevel.TIP]: "Tip", + [LogLevel.GENERIC]: "", + [LogLevel.SECTION]: "", + [LogLevel.INPUT]: "User Input", + }; + + const needsNewLine = [ + LogLevel.ERROR, + LogLevel.INPUT, + LogLevel.WARN, + LogLevel.SUCCESS, + ].includes(level); + + const prefix = needsNewLine ? "\n" : ""; + + if (level === LogLevel.GENERIC) { + return colors[level](message); + } + + if (level === LogLevel.SECTION) { + return `${prefix}\n${colors[level](`\n${icons[level]} ${message}\n`)}`; + } + + return `${prefix}${colors[level]( + `${icons[level]} ${levelLabels[level]} ` + )}${message}`; + } + + static setLevel(level: LogLevel): void { + this.config.level = level; + } + + static enableDebug(): void { + this.config.debug = true; + this.config.level = LogLevel.DEBUG; + console.log(chalk.gray("🔍 **Debug profile enabled**")); + } + + /** + * Tagged template helper that automatically bolds interpolated values. + */ + static formatVariables( + strings: TemplateStringsArray, + ...values: any[] + ): string { + return strings.reduce((result, string, i) => { + const value = + i < values.length ? chalk.bold.whiteBright(String(values[i])) : ""; + return result + string + value; + }, ""); + } + + /** + * Core log function that accepts either a tagged template literal or a plain string. + */ + private static log( + level: LogLevel, + strings: TemplateStringsArray | string, + ...values: any[] + ): void { + if (this.config.level > level && level !== LogLevel.DEBUG) return; + if (!this.config.debug && level === LogLevel.DEBUG) return; + + const message = + typeof strings === "string" + ? strings + : this.formatVariables(strings, ...values); + + const formattedMessage = this.formatMessage(message, level); + + if (level === LogLevel.WARN) { + console.warn(formattedMessage); + } else if (level === LogLevel.ERROR) { + console.error(formattedMessage); + } else { + console.log(formattedMessage); + } + } + + static debug(strings: TemplateStringsArray | string, ...values: any[]): void { + this.log(LogLevel.DEBUG, strings, ...values); + } + + static info(strings: TemplateStringsArray | string, ...values: any[]): void { + this.log(LogLevel.INFO, strings, ...values); + } + + static success( + strings: TemplateStringsArray | string, + ...values: any[] + ): void { + this.log(LogLevel.SUCCESS, strings, ...values); + } + + static warn(strings: TemplateStringsArray | string, ...values: any[]): void { + this.log(LogLevel.WARN, strings, ...values); + } + + static error(strings: TemplateStringsArray | string, ...values: any[]): void { + this.log(LogLevel.ERROR, strings, ...values); + } + + static tip(strings: TemplateStringsArray | string, ...values: any[]): void { + this.log(LogLevel.TIP, strings, ...values); + } + + static generic(message: string): void { + console.log(this.formatMessage(message, LogLevel.GENERIC)); + } + + static input(message: string): string { + return this.formatMessage(message, LogLevel.INPUT); + } + + static section(text: string): void { + console.log(this.formatMessage(text, LogLevel.SECTION)); + } + + static header(text: string): void { + const separator = "═".repeat(text.length + 6); + console.log(`\n${chalk.bold.magenta(separator)}`); + console.log(`${chalk.bold.magenta(" " + text + " ")}`); + console.log(`${chalk.bold.magenta(separator)}\n`); + } + + static commandInfo(command: string, description: string): void { + console.log`${chalk.bold.blue(command)}: ${description}`; + } + + static defaultValueInfo(message: string, overrideCommand: string): void { + if (this.config.level <= LogLevel.INFO) { + console.log(this.formatMessage(message, LogLevel.INFO)); + console.log(chalk.gray` Override with: ${overrideCommand}\n`); + } + } + + static commandValueTip(message: string, overrideCommand: string): void { + if (this.config.level <= LogLevel.TIP) { + console.log(this.formatMessage(message, LogLevel.TIP)); + console.log(chalk.gray` Override with: ${overrideCommand}\n`); + } + } + + static debugObject(label: string, obj: any): void { + if (this.config.debug) { + console.log(chalk.gray`🔍 ${label}:`); + Object.entries(obj).forEach(([key, value]) => { + console.log(chalk.gray` ${key}:`, value || "Not set"); + }); + } + } + + static initialize(): void { + if (process.env.DEBUG === "true") { + this.enableDebug(); + } + } + + static timing(label: string, timeMs: number): void { + const formattedTime = + timeMs < 1000 + ? `${timeMs.toFixed(1)}ms` + : `${(timeMs / 1000).toFixed(2)}s`; + + console.log(chalk.gray`⏱ ${label}: ${formattedTime}`); + } + + static warnfileList(title: string, files: string[]): void { + if (files.length === 0) return; + Logger.warn`${title}:`; + files.forEach((file) => { + console.log(chalk.gray` - ${file}`); + }); + } + + static infofileList(title: string, files: string[]): void { + if (files.length === 0) return; + Logger.info`${title}:`; + files.forEach((file) => { + console.log(chalk.gray` - ${file}`); + }); + } + + static showReferenceCommands(): void { + this.header("Command Examples"); + + // Common options displayed at the top + this.generic(chalk.bold.yellow("Common Options (all commands):")); + this.generic(chalk.gray("--debug Enable detailed debug logging")); + this.generic(chalk.gray("--config Use configuration file")); + this.generic(""); + + // Upload commands + this.generic(chalk.bold.magenta("CSV Upload Commands:")); + this.generic(chalk.white("conductor upload -f data.csv")); + this.generic(chalk.gray("Options:")); + this.generic( + chalk.gray("-f, --file CSV files to upload (required)") + ); + this.generic( + chalk.gray("-i, --index Target Elasticsearch index") + ); + this.generic( + chalk.gray("-b, --batch-size Batch size (default: 1000)") + ); + this.generic( + chalk.gray("--delimiter CSV delimiter (default: ,)") + ); + this.generic(chalk.gray("-o, --output Output path for logs")); + this.generic(""); + this.generic( + chalk.gray("Example: conductor upload -f data.csv -i my-index -b 2000") + ); + this.generic(""); + + // Repository Indexing commands + this.generic(chalk.bold.magenta("Repository Indexing Commands:")); + this.generic( + chalk.white("conductor maestroIndex --repository-code lyric.overture") + ); + this.generic(chalk.gray("Options:")); + this.generic( + chalk.gray( + "--repository-code Repository code to index (required)" + ) + ); + this.generic( + chalk.gray( + "--index-url Indexing service URL (default: http://localhost:11235)" + ) + ); + this.generic( + chalk.gray( + "--organization Filter indexing to a specific organization" + ) + ); + this.generic( + chalk.gray("--id Index only a specific document ID") + ); + this.generic(chalk.gray("-o, --output Output path for logs")); + this.generic(""); + this.generic( + chalk.gray( + "Example: conductor maestroIndex --repository-code lyric.overture --organization OICR" + ) + ); + this.generic(""); + + // Lectern Upload commands + this.generic(chalk.bold.magenta("Lectern Schema Upload Command:")); + this.generic(chalk.white("conductor lecternUpload -s dictionary.json")); + this.generic(chalk.gray("Options:")); + this.generic( + chalk.gray( + "-s, --schema-file Schema JSON file to upload (required)" + ) + ); + this.generic( + chalk.gray( + "-u, --lectern-url Lectern server URL (default: http://localhost:3031)" + ) + ); + this.generic( + chalk.gray("-t, --auth-token Authentication token (optional)") + ); + this.generic( + chalk.gray("-o, --output Output directory for logs") + ); + this.generic(""); + this.generic( + chalk.gray("Example: conductor lecternUpload -s data-dictionary.json") + ); + this.generic(""); + + // Lyric Register commands + this.generic(chalk.bold.magenta("Lyric Register Dictionary Command:")); + this.generic( + chalk.white( + "conductor lyricRegister -c category1 --dict-name dictionary1 -v 1.0 -e entity1" + ) + ); + this.generic(chalk.gray("Options:")); + this.generic( + chalk.gray( + "-u, --lyric-url Lyric server URL (default: http://localhost:3030)" + ) + ); + this.generic( + chalk.gray("-c, --category-name Category name (required)") + ); + this.generic( + chalk.gray("--dict-name Dictionary name (required)") + ); + this.generic( + chalk.gray( + "-v, --dictionary-version Dictionary version (required)" + ) + ); + this.generic( + chalk.gray( + "-e, --default-centric-entity Default centric entity (required) - must be a valid schema in the dictionary" + ) + ); + this.generic(""); + this.generic( + chalk.gray( + "Example: conductor lyricRegister -c my-category --dict-name my-dictionary -v 2.0 -e donor" + ) + ); + this.generic(""); + + // Lyric Data commands + this.generic(chalk.bold.magenta("Lyric Data Upload Command:")); + this.generic(chalk.white("conductor lyricData -d ./data-directory")); + this.generic(chalk.gray("Options:")); + this.generic( + chalk.gray( + "-u, --lyric-url Lyric server URL (default: http://localhost:3030)" + ) + ); + this.generic( + chalk.gray( + "-l, --lectern-url Lectern server URL (default: http://localhost:3031)" + ) + ); + this.generic( + chalk.gray( + "-d, --data-directory Directory containing CSV data files" + ) + ); + this.generic( + chalk.gray("-c, --category-id Category ID (default: 1)") + ); + this.generic( + chalk.gray("-g, --organization Organization name (default: OICR)") + ); + this.generic( + chalk.gray( + "-m, --max-retries Maximum retry attempts (default: 10)" + ) + ); + this.generic(""); + this.generic( + chalk.gray("Example: conductor lyricData -d ./my-data -c 2 -g MyOrg") + ); + this.generic(""); + + // Song Upload commands + this.generic(chalk.bold.magenta("Song Schema Upload Commands:")); + this.generic(chalk.white("conductor songUploadSchema -s schema.json")); + this.generic(chalk.gray("Options:")); + this.generic( + chalk.gray( + "-s, --schema-file Schema JSON file to upload (required)" + ) + ); + this.generic( + chalk.gray( + "-u, --song-url Song server URL (default: http://localhost:8080)" + ) + ); + this.generic( + chalk.gray( + "-t, --auth-token Authentication token (default: 123)" + ) + ); + this.generic( + chalk.gray("-o, --output Output directory for logs") + ); + this.generic(""); + this.generic( + chalk.gray( + "Example: conductor songUploadSchema -s analysis-schema.json -u http://song-api:8080" + ) + ); + this.generic(""); + + // Song Create Study commands + this.generic(chalk.bold.magenta("Song Create Study Commands:")); + this.generic( + chalk.white("conductor songCreateStudy -i study-id -n study-name") + ); + this.generic(chalk.gray("Options:")); + this.generic( + chalk.gray( + "-u, --song-url Song server URL (default: http://localhost:8080)" + ) + ); + this.generic( + chalk.gray("-i, --study-id Study ID (default: demo)") + ); + this.generic( + chalk.gray("-n, --study-name Study name (default: string)") + ); + this.generic( + chalk.gray( + "-g, --organization Organization name (default: string)" + ) + ); + this.generic( + chalk.gray( + "--description Study description (default: string)" + ) + ); + this.generic( + chalk.gray( + "-t, --auth-token Authentication token (default: 123)" + ) + ); + this.generic( + chalk.gray( + "--force Force creation even if study exists" + ) + ); + this.generic(""); + this.generic( + chalk.gray( + "Example: conductor songCreateStudy -i my-study -n 'My Research Study' -g MyOrg" + ) + ); + this.generic(""); + + // Song Submit Analysis commands + this.generic(chalk.bold.magenta("Song Submit Analysis Commands:")); + this.generic( + chalk.white("conductor songSubmitAnalysis -a analysis.json -i study-id") + ); + this.generic(chalk.gray("Options:")); + this.generic( + chalk.gray( + "-a, --analysis-file Analysis JSON file to submit (required)" + ) + ); + this.generic( + chalk.gray( + "-u, --song-url Song server URL (default: http://localhost:8080)" + ) + ); + this.generic( + chalk.gray("-i, --study-id Study ID (default: demo)") + ); + this.generic( + chalk.gray( + "--allow-duplicates Allow duplicate analysis submissions" + ) + ); + this.generic( + chalk.gray( + "-t, --auth-token Authentication token (default: 123)" + ) + ); + this.generic( + chalk.gray( + "--force Force studyId from command line instead of from file" + ) + ); + this.generic(""); + this.generic( + chalk.gray( + "Example: conductor songSubmitAnalysis -a metadata.json -i my-study" + ) + ); + this.generic(""); + + // Score Manifest Upload commands + this.generic(chalk.bold.magenta("Score Manifest Upload Commands:")); + this.generic( + chalk.white("conductor scoreManifestUpload -a analysis-id -d ./data") + ); + this.generic(chalk.gray("Options:")); + this.generic( + chalk.gray( + "-a, --analysis-id Analysis ID from Song submission (required)" + ) + ); + this.generic( + chalk.gray( + "-d, --data-dir Directory containing data files (default: ./data)" + ) + ); + this.generic( + chalk.gray( + "-o, --output-dir Directory for manifest output (default: ./output)" + ) + ); + this.generic( + chalk.gray("-m, --manifest-file Path for manifest file (optional)") + ); + this.generic( + chalk.gray( + "-u, --song-url Song server URL (default: http://localhost:8080)" + ) + ); + this.generic( + chalk.gray( + "-s, --score-url Score server URL (default: http://localhost:8087)" + ) + ); + this.generic( + chalk.gray( + "-t, --auth-token Authentication token (default: 123)" + ) + ); + this.generic(""); + this.generic( + chalk.gray( + "Example: conductor scoreManifestUpload -a 4d9ed1c5-1053-4377-9ed1-c51053f3771f -d ./my-data" + ) + ); + this.generic(""); + + // Song Publish Analysis commands + this.generic(chalk.bold.magenta("Song Publish Analysis Commands:")); + this.generic(chalk.white("conductor songPublishAnalysis -a analysis-id")); + this.generic(chalk.gray("Options:")); + this.generic( + chalk.gray("-a, --analysis-id Analysis ID to publish (required)") + ); + this.generic( + chalk.gray("-i, --study-id Study ID (default: demo)") + ); + this.generic( + chalk.gray( + "-u, --song-url Song server URL (default: http://localhost:8080)" + ) + ); + this.generic( + chalk.gray( + "-t, --auth-token Authentication token (default: 123)" + ) + ); + this.generic( + chalk.gray( + "--ignore-undefined-md5 Ignore files with undefined MD5 checksums" + ) + ); + this.generic(""); + this.generic( + chalk.gray( + "Example: conductor songPublishAnalysis -a 4d9ed1c5-1053-4377-9ed1-c51053f3771f -i my-study" + ) + ); + this.generic(""); + } +} diff --git a/apps/conductor/src/validations/constants.ts b/apps/conductor/src/validations/constants.ts new file mode 100644 index 00000000..239ddeb5 --- /dev/null +++ b/apps/conductor/src/validations/constants.ts @@ -0,0 +1,37 @@ +/** + * Validation Constants + * + * Shared constants used throughout the validation system. + */ + +/** + * Allowed file extensions for processing + */ +export const ALLOWED_EXTENSIONS = [".csv", ".tsv"]; + +/** + * Maximum number of rows to sample when validating CSV files + */ +export const CSV_SAMPLE_SIZE = 1000; + +/** + * Timeout in milliseconds for Elasticsearch connection tests + */ +export const ES_CONNECTION_TIMEOUT = 5000; // 5 seconds + +/** + * Maximum number of CSV header columns allowed + */ +export const MAX_HEADER_COLUMNS = 1000; + +/** + * Minimum number of CSV header columns required + */ +export const MIN_HEADER_COLUMNS = 1; + +export const VALIDATION_CONSTANTS = { + INVALID_CHARS: ["$", "%", "^", "&"], + MAX_HEADER_LENGTH: 50, + RESERVED_WORDS: ["null", "undefined", "class", "function"], + GRAPHQL_NAME_PATTERN: /^[a-zA-Z_][a-zA-Z0-9_]*$/, +}; diff --git a/apps/conductor/src/validations/csvValidator.ts b/apps/conductor/src/validations/csvValidator.ts new file mode 100644 index 00000000..254e46b7 --- /dev/null +++ b/apps/conductor/src/validations/csvValidator.ts @@ -0,0 +1,367 @@ +import * as fs from "fs"; +import { Client } from "@elastic/elasticsearch"; +import { ConductorError, ErrorCodes } from "../utils/errors"; +import { parseCSVLine } from "../services/csvProcessor/csvParser"; +import { VALIDATION_CONSTANTS } from "./constants"; +import { Logger } from "../utils/logger"; + +/** + * Module for validating CSV files against structural and naming rules. + * Includes validation for headers, content structure, and naming conventions. + */ + +/** + * Validates the header structure of a CSV file. + * Reads the first line of the file and validates the headers. + * + * @param filePath - Path to the CSV file + * @param delimiter - Character used to separate values in the CSV + * @returns Promise resolving to true if headers are valid + * @throws ConductorError if headers are invalid or file can't be read + */ +export async function validateCSVHeaders( + filePath: string, + delimiter: string +): Promise { + Logger.debug`Validating CSV headers in ${filePath} with delimiter '${delimiter}'`; + + try { + const fileContent = fs.readFileSync(filePath, "utf-8"); + const [headerLine] = fileContent.split("\n"); + + if (!headerLine) { + throw new ConductorError( + "CSV file is empty or has no headers", + ErrorCodes.INVALID_FILE + ); + } + + // Check if the headerLine contains the delimiter + if (!headerLine.includes(delimiter)) { + Logger.error`CSV header does not contain the specified delimiter '${delimiter}'`; + Logger.info`First 50 characters of header: ${headerLine.substring( + 0, + 50 + )}...`; + Logger.tip`If your data is not properly delimited, try reformatting your CSV file or check if the correct delimiter is specified`; + + // Try to guess potential delimiters + const potentialDelimiters = [",", ";", "\t", "|"]; + const foundDelimiters = potentialDelimiters.filter((d: string) => + headerLine.includes(d) + ); + + if (foundDelimiters.length > 0) { + Logger.tip`Potential delimiters found in the header: ${foundDelimiters.join( + ", " + )}`; + Logger.tip`Try using one of these with the --delimiter flag`; + } + + throw new ConductorError( + `CSV header is not properly delimited with '${delimiter}'`, + ErrorCodes.INVALID_FILE + ); + } + + const parseResult = parseCSVLine(headerLine, delimiter, true); + if (!parseResult || !parseResult[0]) { + throw new ConductorError( + "Failed to parse CSV headers", + ErrorCodes.INVALID_FILE + ); + } + + const headers = parseResult[0]; + Logger.debug`Found ${headers.length} headers in CSV file`; + + // Check for suspiciously long headers that might indicate parsing issues + const longHeaders = headers.filter((h: string) => h.length > 30); + if (longHeaders.length > 0) { + Logger.warn`Detected unusually long header names which may indicate parsing issues:`; + longHeaders.forEach((header: string) => { + Logger.warn`Long header: "${header}"`; + }); + Logger.tip`Check if your CSV is using the correct delimiter`; + } + + return validateCSVStructure(headers); + } catch (error: any) { + if (error instanceof ConductorError) { + Logger.error`CSV header validation failed: ${error.message}`; + throw error; + } + Logger.error`Error validating CSV headers: ${ + error instanceof Error ? error.message : String(error) + }`; + throw new ConductorError( + "Error validating CSV headers", + ErrorCodes.VALIDATION_FAILED, + error + ); + } +} + +/** + * Validates CSV headers against naming conventions and rules. + * Checks: + * - Special character restrictions + * - Maximum length limits + * - Reserved word restrictions + * - GraphQL naming conventions + * - Duplicate prevention + * + * @param headers - Array of header strings to validate + * @returns Promise resolving to true if all headers are valid + * @throws ConductorError with details if validation fails + */ +export async function validateCSVStructure( + headers: string[] +): Promise { + Logger.debug`Validating CSV structure with ${headers.length} headers`; + + try { + // Clean and filter headers + const cleanedHeaders = headers + .map((header) => header.trim()) + .filter((header) => header !== ""); + + // Validate basic header presence + if (cleanedHeaders.length === 0) { + throw new ConductorError( + "No valid headers found in CSV file", + ErrorCodes.VALIDATION_FAILED + ); + } + + if (cleanedHeaders.length !== headers.length) { + Logger.warn`Empty or whitespace-only headers detected`; + throw new ConductorError( + "Empty or whitespace-only headers detected", + ErrorCodes.VALIDATION_FAILED + ); + } + + // Validate headers against all rules + const invalidHeaders = cleanedHeaders.filter((header: string) => { + const hasInvalidChars = VALIDATION_CONSTANTS.INVALID_CHARS.some((char) => + header.includes(char) + ); + const isTooLong = + Buffer.from(header).length > VALIDATION_CONSTANTS.MAX_HEADER_LENGTH; + const isReserved = VALIDATION_CONSTANTS.RESERVED_WORDS.includes( + header.toLowerCase() + ); + const isValidGraphQLName = + VALIDATION_CONSTANTS.GRAPHQL_NAME_PATTERN.test(header); + + return hasInvalidChars || isTooLong || isReserved || !isValidGraphQLName; + }); + + if (invalidHeaders.length > 0) { + Logger.error`Invalid header names detected: ${invalidHeaders.join(", ")}`; + throw new ConductorError( + "Invalid header names detected", + ErrorCodes.VALIDATION_FAILED, + { invalidHeaders } + ); + } + + // Check for duplicate headers + const headerCounts: Record = cleanedHeaders.reduce( + (acc: Record, header: string) => { + acc[header] = (acc[header] || 0) + 1; + return acc; + }, + {} + ); + + const duplicates = Object.entries(headerCounts) + .filter(([_, count]) => count > 1) + .map(([header]) => header); + + if (duplicates.length > 0) { + Logger.error`Duplicate headers found in CSV file: ${duplicates.join( + ", " + )}`; + throw new ConductorError( + "Duplicate headers found in CSV file", + ErrorCodes.VALIDATION_FAILED, + { duplicates, counts: headerCounts } + ); + } + + // Optional: Check for generic headers + const genericHeaders = cleanedHeaders.filter((header) => + ["col1", "col2", "column1", "column2", "0", "1", "2"].includes( + header.toLowerCase() + ) + ); + + if (genericHeaders.length > 0) { + Logger.warn`Generic headers detected:`; + genericHeaders.forEach((header) => { + Logger.warn`Generic header: "${header}"`; + }); + Logger.tip`Consider using more descriptive column names`; + } + + Logger.debug`CSV header structure matches valid`; + + // Log all headers in debug mode + Logger.debugObject("CSV Headers", cleanedHeaders); + + return true; + } catch (error) { + if (error instanceof ConductorError) { + throw error; + } + Logger.error`Error validating CSV structure: ${ + error instanceof Error ? error.message : String(error) + }`; + throw new ConductorError( + "Error validating CSV structure", + ErrorCodes.VALIDATION_FAILED, + error + ); + } +} + +/** + * Validates CSV headers against Elasticsearch index mappings. + * Ensures CSV structure matches expected index fields. + * + * @param client - Elasticsearch client instance + * @param headers - Array of CSV headers to validate + * @param indexName - Target Elasticsearch index name + * @returns Promise resolving to true if headers match mappings + * @throws ConductorError if validation fails + */ +export async function validateHeadersMatchMappings( + client: Client, + headers: string[], + indexName: string +): Promise { + Logger.debug`Validating headers against index ${indexName} mappings`; + + try { + // Try to get mappings from the existing index + const { body } = await client.indices.getMapping({ + index: indexName, + }); + + // Type-safe navigation + const mappings = body[indexName]?.mappings; + if (!mappings) { + Logger.error`No mappings found for index ${indexName}`; + throw new ConductorError( + "No mappings found for the specified index", + ErrorCodes.VALIDATION_FAILED + ); + } + + // Navigate to the nested properties + const expectedFields = mappings.properties?.data?.properties + ? Object.keys(mappings.properties.data.properties) + : []; + + Logger.debug`Found ${expectedFields.length} fields in existing index mapping`; + + // Clean up headers for comparison + const cleanedHeaders = headers + .map((header: string) => header.trim()) + .filter((header: string) => header !== ""); + + if (cleanedHeaders.length === 0) { + Logger.error`No valid headers found`; + throw new ConductorError( + "No valid headers found", + ErrorCodes.VALIDATION_FAILED + ); + } + + // Check for extra headers not in the mapping + const extraHeaders = cleanedHeaders.filter( + (header: string) => !expectedFields.includes(header) + ); + + // Check for fields in the mapping that aren't in the headers + const missingRequiredFields = expectedFields.filter( + (field: string) => + field !== "submission_metadata" && !cleanedHeaders.includes(field) + ); + + // Log appropriate warnings + if (extraHeaders.length > 0) { + Logger.warn`Extra headers not in index mapping: ${extraHeaders.join( + ", " + )}`; + Logger.tip`These fields will be added to documents but may not be properly indexed`; + } + + if (missingRequiredFields.length > 0) { + Logger.warn`Missing fields from index mapping: ${missingRequiredFields.join( + ", " + )}`; + Logger.tip`Data for these fields will be null in the indexed documents`; + } + + // Raise error if there's a significant mismatch between the headers and mapping + if ( + extraHeaders.length > expectedFields.length * 0.5 || + missingRequiredFields.length > expectedFields.length * 0.5 + ) { + Logger.error`Significant header/field mismatch detected`; + throw new ConductorError( + "Significant header/field mismatch detected - the CSV structure doesn't match the index mapping", + ErrorCodes.VALIDATION_FAILED, + { + extraHeaders, + missingRequiredFields, + details: { + expected: expectedFields, + found: cleanedHeaders, + }, + } + ); + } + + Logger.debug`Headers validated against index mapping`; + return true; + } catch (error: any) { + // If the index doesn't exist, provide a clear error + if ( + error.meta && + error.meta.body && + error.meta.body.error.type === "index_not_found_exception" + ) { + Logger.error`Index ${indexName} does not exist`; + throw new ConductorError( + `Index ${indexName} does not exist - create it first or use a different index name`, + ErrorCodes.INDEX_NOT_FOUND + ); + } + + // Type-safe error handling for other errors + if (error instanceof ConductorError) { + throw error; + } + + // Add more detailed error logging + Logger.error`Error validating headers against index: ${ + error instanceof Error ? error.message : String(error) + }`; + Logger.debug`Error details: ${ + error instanceof Error ? error.stack : "No stack trace available" + }`; + + throw new ConductorError( + "Error validating headers against index", + ErrorCodes.VALIDATION_FAILED, + { + originalError: error instanceof Error ? error.message : String(error), + errorType: error instanceof Error ? error.name : "Unknown Error", + } + ); + } +} diff --git a/apps/conductor/src/validations/elasticsearchValidator.ts b/apps/conductor/src/validations/elasticsearchValidator.ts new file mode 100644 index 00000000..ec629226 --- /dev/null +++ b/apps/conductor/src/validations/elasticsearchValidator.ts @@ -0,0 +1,132 @@ +import { Client } from "@elastic/elasticsearch"; +import { + ConductorError, + ErrorCodes, + createValidationError, +} from "../utils/errors"; +import { Logger } from "../utils/logger"; +import { ConnectionValidationResult, IndexValidationResult } from "../types"; + +/** + * Validates Elasticsearch connection by making a ping request + */ +export async function validateElasticsearchConnection( + client: Client, + config: any +): Promise { + try { + Logger.info`Testing connection to Elasticsearch at ${config.elasticsearch.url}`; + + const startTime = Date.now(); + const response = await client.ping(); + const responseTime = Date.now() - startTime; + + Logger.info`Connected to Elasticsearch successfully in ${responseTime}ms`; + + return { + valid: true, + errors: [], + responseTimeMs: responseTime, + }; + } catch (error: any) { + const errorMessage = error instanceof Error ? error.message : String(error); + + // Log the error message + Logger.error`Failed to connect to Elasticsearch: ${errorMessage}`; + + // Add a warning with the override command info + Logger.commandValueTip( + "Check Elasticsearch is running and that the correct URL and auth params are in use", + "--url -u -p " + ); + + throw new ConductorError( + `Failed to connect to Elasticsearch at ${config.elasticsearch.url}`, + ErrorCodes.CONNECTION_ERROR, + error + ); + } +} + +/** + * Validates that an index exists + */ +export async function validateIndex( + client: Client, + indexName: string +): Promise { + try { + Logger.info`Checking if index ${indexName} exists`; + + // Use the more reliable get method with a try/catch + try { + const { body } = await client.indices.get({ index: indexName }); + + // Check if we actually got back information about the requested index + if (!body || !body[indexName]) { + Logger.error`Index ${indexName} not found in response`; + throw new ConductorError( + `Index ${indexName} not found`, + ErrorCodes.INDEX_NOT_FOUND + ); + } + + Logger.info`Index ${indexName} exists`; + + return { + valid: true, + errors: [], + exists: true, + }; + } catch (indexError: any) { + // Check if the error is specifically about the index not existing + if ( + indexError.meta && + indexError.meta.body && + (indexError.meta.body.error.type === "index_not_found_exception" || + indexError.meta.body.status === 404) + ) { + Logger.error`Index ${indexName} does not exist`; + Logger.commandValueTip( + "Create the index first or use a different index name", + "-i " + ); + + throw new ConductorError( + `Index ${indexName} does not exist. Create the index first or use a different index name.`, + ErrorCodes.INDEX_NOT_FOUND, + indexError + ); + } else { + // Some other error occurred + throw indexError; + } + } + } catch (error: any) { + const errorMessage = error instanceof Error ? error.message : String(error); + Logger.error`Index check failed: ${errorMessage}`; + + throw new ConductorError( + `Failed to check if index ${indexName} exists`, + ErrorCodes.INDEX_NOT_FOUND, + error + ); + } +} + +/** + * Validates that batch size is a positive number + */ +export function validateBatchSize(batchSize: number): void { + if (!batchSize || isNaN(batchSize) || batchSize <= 0) { + throw createValidationError("Batch size must be a positive number", { + provided: batchSize, + }); + } + + if (batchSize > 10000) { + Logger.warn`Batch size ${batchSize} is quite large and may cause performance issues`; + } else { + Logger.debug`Batch size validated: ${batchSize}`; + } +} diff --git a/apps/conductor/src/validations/environment.ts b/apps/conductor/src/validations/environment.ts new file mode 100644 index 00000000..4379017a --- /dev/null +++ b/apps/conductor/src/validations/environment.ts @@ -0,0 +1,35 @@ +/** + * Environment Validation + * + * Validates the runtime environment configuration and requirements. + */ + +import { createValidationError } from "../utils/errors"; +import { Logger } from "../utils/logger"; + +interface EnvironmentValidationParams { + elasticsearchUrl: string; + // Add other relevant environment parameters +} + +/** + * Validates the environment configuration and requirements + */ +export async function validateEnvironment( + params: EnvironmentValidationParams +): Promise { + Logger.debug("Environment Validation"); + + // Validate Elasticsearch URL is provided + if (!params.elasticsearchUrl) { + throw createValidationError("Elasticsearch URL is required", { + parameter: "elasticsearchUrl", + expected: "valid URL", + }); + } + Logger.debug`Elasticsearch URL is provided: ${params.elasticsearchUrl}`; + + // Add additional environment validations as needed + + Logger.debug`Environment validation passed`; +} diff --git a/apps/conductor/src/validations/fileValidator.ts b/apps/conductor/src/validations/fileValidator.ts new file mode 100644 index 00000000..9610a22c --- /dev/null +++ b/apps/conductor/src/validations/fileValidator.ts @@ -0,0 +1,101 @@ +/** + * File Validator + * + * Validates file existence, permissions, and basic properties + * before processing CSV files into Elasticsearch. + */ + +import * as fs from "fs"; +import * as path from "path"; +import { ValidationResult } from "../types/validations"; +import { Logger } from "../utils/logger"; +import { ALLOWED_EXTENSIONS } from "./constants"; + +/** + * Validates that files exist, have an extension, and that the extension is allowed. + * Returns a structured result with a validity flag and error messages. + */ +export async function validateFiles( + filePaths: string[] +): Promise { + if (!filePaths || filePaths.length === 0) { + return { valid: false, errors: ["No input files specified"] }; + } + + const notFoundFiles: string[] = []; + const invalidExtensions: string[] = []; + const missingExtensions: string[] = []; + + for (const filePath of filePaths) { + const extension = path.extname(filePath).toLowerCase(); + if (!extension) { + // File extension is missing, so record that as a warning. + missingExtensions.push(filePath); + continue; + } + + // Check if the extension is allowed. + if (!ALLOWED_EXTENSIONS.includes(extension)) { + invalidExtensions.push(`${filePath} (${extension})`); + continue; + } + + // Check file existence. + if (!fs.existsSync(filePath)) { + notFoundFiles.push(filePath); + continue; + } + } + + const errors: string[] = []; + + // Log missing extension files as warnings + if (missingExtensions.length > 0) { + Logger.warn( + `Missing file extension for: ${missingExtensions.join( + ", " + )}. Allowed extensions: ${ALLOWED_EXTENSIONS.join(", ")}` + ); + } + + // Only generate the error messages but don't log them directly + // Let the error handling system do the logging + if (invalidExtensions.length > 0) { + errors.push( + `Invalid file extensions: ${invalidExtensions.join( + ", " + )}. Allowed extensions: ${ALLOWED_EXTENSIONS.join(", ")}` + ); + } + + if (notFoundFiles.length > 0) { + errors.push(`Files not found: ${notFoundFiles.join(", ")}`); + } + + return { valid: errors.length === 0, errors }; +} + +/** + * Checks if a file is readable by attempting to open and read a portion of it. + * Returns a structured result with a validity flag and error messages. + */ +export async function validateFileReadable( + filePath: string +): Promise { + try { + const fd = fs.openSync(filePath, "r"); + const buffer = Buffer.alloc(1024); + fs.readSync(fd, buffer, 0, 1024, 0); + fs.closeSync(fd); + return { valid: true, errors: [] }; + } catch (error) { + return { + valid: false, + errors: [ + `File ${filePath} is not readable: ${ + error instanceof Error ? error.message : String(error) + }`, + ], + }; + } +} diff --git a/apps/conductor/src/validations/index.ts b/apps/conductor/src/validations/index.ts new file mode 100644 index 00000000..8367190e --- /dev/null +++ b/apps/conductor/src/validations/index.ts @@ -0,0 +1,76 @@ +/** + * Validation Module + * + * A comprehensive set of validation utilities for ensuring data integrity, + * system readiness, and configuration correctness. + */ + +export * from "./csvValidator"; +export * from "./elasticsearchValidator"; +export * from "./fileValidator"; +export * from "./environment"; + +// Add central file validation utility +import * as fs from "fs"; +import { ConductorError, ErrorCodes } from "../utils/errors"; +import { Logger } from "../utils/logger"; + +/** + * Validates that a file exists, is readable, and has content + * + * @param filePath - Path to the file to validate + * @throws ConductorError if validation fails + */ +export function validateFile(filePath: string): void { + if (!filePath) { + throw new ConductorError("No file path provided", ErrorCodes.INVALID_ARGS); + } + + Logger.debug(`Validating file: ${filePath}`); + + // Check existence + if (!fs.existsSync(filePath)) { + Logger.error(`File not found: ${filePath}`); + throw new ConductorError( + `File not found: ${filePath}`, + ErrorCodes.FILE_NOT_FOUND + ); + } + + // Check readability + try { + fs.accessSync(filePath, fs.constants.R_OK); + } catch (error) { + Logger.error(`File is not readable: ${filePath}`); + throw new ConductorError( + `File '${filePath}' is not readable`, + ErrorCodes.INVALID_FILE, + error + ); + } + + // Check if empty + const stats = fs.statSync(filePath); + if (stats.size === 0) { + Logger.error(`File is empty: ${filePath}`); + throw new ConductorError( + `File '${filePath}' is empty`, + ErrorCodes.INVALID_FILE + ); + } + + Logger.debug(`File validation passed: ${filePath}`); +} + +/** + * Validates that a delimiter is a single character + */ +export function validateDelimiter(delimiter: string): void { + if (!delimiter || delimiter.length !== 1) { + throw new ConductorError( + "Delimiter must be a single character", + ErrorCodes.INVALID_ARGS + ); + } + Logger.debug(`Delimiter validated: '${delimiter}'`); +} diff --git a/apps/conductor/src/validations/utils.ts b/apps/conductor/src/validations/utils.ts new file mode 100644 index 00000000..ddb27fdc --- /dev/null +++ b/apps/conductor/src/validations/utils.ts @@ -0,0 +1,20 @@ +/** + * Common Validation Utilities + * + * Simple validators for common primitive values and configurations. + */ + +import { createValidationError } from "../utils/errors"; +import { Logger } from "../utils/logger"; + +/** + * Validates that a delimiter is a single character + */ +export function validateDelimiter(delimiter: string): void { + if (!delimiter || delimiter.length !== 1) { + throw createValidationError("Delimiter must be a single character", { + provided: delimiter, + }); + } + Logger.debug`Delimiter validated: '${delimiter}'`; +} diff --git a/apps/conductor/tsconfig.json b/apps/conductor/tsconfig.json new file mode 100644 index 00000000..a91b7d29 --- /dev/null +++ b/apps/conductor/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "target": "es2018", + "module": "commonjs", + "lib": ["es2018"], + "outDir": "./dist", + "rootDir": "./src", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] +} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/heliograph/fs.json b/apps/conductor/volumes/data-minio/.minio.sys/buckets/object/data/heliograph/fs.json similarity index 100% rename from persistentStorage/data-minio/.minio.sys/buckets/object/data/heliograph/fs.json rename to apps/conductor/volumes/data-minio/.minio.sys/buckets/object/data/heliograph/fs.json diff --git a/persistentStorage/data-minio/.minio.sys/format.json b/apps/conductor/volumes/data-minio/.minio.sys/format.json similarity index 100% rename from persistentStorage/data-minio/.minio.sys/format.json rename to apps/conductor/volumes/data-minio/.minio.sys/format.json diff --git a/persistentStorage/data-minio/object/data/heliograph b/apps/conductor/volumes/data-minio/object/data/heliograph similarity index 100% rename from persistentStorage/data-minio/object/data/heliograph rename to apps/conductor/volumes/data-minio/object/data/heliograph diff --git a/apps/stage/.dockerignore b/apps/stage/.dockerignore new file mode 100644 index 00000000..2b40976c --- /dev/null +++ b/apps/stage/.dockerignore @@ -0,0 +1,6 @@ +.env.local +.env.test +.env.schema +.next +node_modules +Dockerfile \ No newline at end of file diff --git a/apps/stage/.env.stage b/apps/stage/.env.stage new file mode 100644 index 00000000..534839b4 --- /dev/null +++ b/apps/stage/.env.stage @@ -0,0 +1,45 @@ +# Stage Variables +NEXTAUTH_URL=http://localhost:3000/api/auth +NEXT_PUBLIC_LAB_NAME=Prelude Development Portal +NEXT_PUBLIC_ADMIN_EMAIL=example@example.com +NEXT_PUBLIC_DEBUG=true +NEXT_PUBLIC_SHOW_MOBILE_WARNING=true +NEXT_PUBLIC_ENABLE_DOWNLOADS=true + +# DATATABLE 1 +NEXT_PUBLIC_ARRANGER_DATATABLE_1_API=http://localhost:5050 +NEXT_PUBLIC_ARRANGER_DATATABLE_1_DOCUMENT_TYPE=file +NEXT_PUBLIC_ARRANGER_DATATABLE_1_INDEX=datatable1_centric +# DATATABLE 2 +NEXT_PUBLIC_ARRANGER_DATATABLE_2_API=http://localhost:5051 +NEXT_PUBLIC_ARRANGER_DATATABLE_2_DOCUMENT_TYPE=file +NEXT_PUBLIC_ARRANGER_DATATABLE_2_INDEX=datatable2_centric +# DATATABLE 3 +NEXT_PUBLIC_ARRANGER_DATATABLE_3_API=http://localhost:5052 +NEXT_PUBLIC_ARRANGER_DATATABLE_3_DOCUMENT_TYPE=file +NEXT_PUBLIC_ARRANGER_DATATABLE_3_INDEX=datatable3_centric +# DATATABLE 4 +NEXT_PUBLIC_ARRANGER_DATATABLE_4_API=http://localhost:5053 +NEXT_PUBLIC_ARRANGER_DATATABLE_4_DOCUMENT_TYPE=file +NEXT_PUBLIC_ARRANGER_DATATABLE_4_INDEX=datatable4_centric +# DATATABLE 5 +NEXT_PUBLIC_ARRANGER_DATATABLE_5_API=http://localhost:5054 +NEXT_PUBLIC_ARRANGER_DATATABLE_5_DOCUMENT_TYPE=file +NEXT_PUBLIC_ARRANGER_DATATABLE_5_INDEX=datatable5_centric + + + +# MOLECULAR Arranger Variables +NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_API=http://arranger-molecular:5055 +NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_DOCUMENT_TYPE=file +NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_INDEX=file_centric +NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_MANIFEST_COLUMNS=repositories.code, analysis.analysis_id, object_id, study_id, file.name, file.size, file.md5sum, file_access, analysis.experiment.acknowledgements.strategy, file.data_type, analysis.experiment.data.sequence_length + +# Song Variables (For Swagger Pages) +NEXT_PUBLIC_SONG_API=http://localhost:8080 + +# Secret for NextAuth +NEXTAUTH_SECRET=your-secure-secret-here + +# For customizable banner +REACT_APP_BANNERS= \ No newline at end of file diff --git a/apps/stage/.gitignore b/apps/stage/.gitignore new file mode 100644 index 00000000..e5c66cfe --- /dev/null +++ b/apps/stage/.gitignore @@ -0,0 +1,36 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env.local +.env.development.local +.env.test.local +.env.production.local + +# vercel +.vercel + +.env diff --git a/apps/stage/.npmrc b/apps/stage/.npmrc new file mode 100644 index 00000000..4fd02195 --- /dev/null +++ b/apps/stage/.npmrc @@ -0,0 +1 @@ +engine-strict=true \ No newline at end of file diff --git a/apps/stage/.prettierignore b/apps/stage/.prettierignore new file mode 100644 index 00000000..2e1fa2d5 --- /dev/null +++ b/apps/stage/.prettierignore @@ -0,0 +1 @@ +*.md \ No newline at end of file diff --git a/apps/stage/Dockerfile b/apps/stage/Dockerfile new file mode 100644 index 00000000..bfc4f542 --- /dev/null +++ b/apps/stage/Dockerfile @@ -0,0 +1,40 @@ +FROM node:lts-alpine + +ARG ASSET_PREFIX +ENV ASSET_PREFIX=$ASSET_PREFIX + +ENV APP_UID=9999 +ENV APP_GID=9999 + +# Install dependencies and modify user/group +RUN apk --no-cache add shadow +RUN groupmod -g $APP_GID node +RUN usermod -u $APP_UID -g $APP_GID node + +# Create and set permissions for /usr/src +RUN mkdir -p /usr/src +RUN chown -R node:node /usr/src + +# Switch to node user +USER node +WORKDIR /usr/src + +# First copy just the package files +COPY --chown=node:node package*.json ./ + +# Install dependencies with plain npm install first to ensure package-lock.json exists +RUN npm install + +# Then copy the rest of the code +COPY --chown=node:node . . + +# Set up volume +VOLUME [ "/usr/src/public/static/dms_user_assets" ] + +# Clean and rebuild with ci +RUN npm cache clean --force +RUN npm ci +RUN NEXT_TELEMETRY_DISABLED=1 npm run build + +EXPOSE 3000 +CMD [ "npm", "start" ] \ No newline at end of file diff --git a/apps/stage/Dockerfile.local b/apps/stage/Dockerfile.local new file mode 100644 index 00000000..21318682 --- /dev/null +++ b/apps/stage/Dockerfile.local @@ -0,0 +1,40 @@ +FROM node:lts-alpine + +ARG ASSET_PREFIX +ENV ASSET_PREFIX=$ASSET_PREFIX + +ENV APP_UID=9999 +ENV APP_GID=9999 + +# Install dependencies and modify user/group +RUN apk --no-cache add shadow +RUN groupmod -g $APP_GID node +RUN usermod -u $APP_UID -g $APP_GID node + +# Create and set permissions for /usr/src +RUN mkdir -p /usr/src +RUN chown -R node:node /usr/src + +# Switch to node user +USER node +WORKDIR /usr/src + +# Copy the entire stage directory content +COPY --chown=node:node stage/package*.json ./ + +# Install dependencies +RUN npm install + +# Copy remaining files +COPY --chown=node:node stage/ . + +# Set up volume +VOLUME [ "/usr/src/public/static/dms_user_assets" ] + +# Clean and rebuild with ci +RUN npm cache clean --force +RUN npm ci +RUN NEXT_TELEMETRY_DISABLED=1 npm run build + +EXPOSE 3000 +CMD [ "npm", "start" ] \ No newline at end of file diff --git a/apps/stage/Jenkinsfile b/apps/stage/Jenkinsfile new file mode 100644 index 00000000..83e36eb2 --- /dev/null +++ b/apps/stage/Jenkinsfile @@ -0,0 +1,2 @@ +@Library(value='jenkins-pipeline-library@master', changelog=false) _ +pipelineOVERTUREStage() diff --git a/apps/stage/LICENSE b/apps/stage/LICENSE new file mode 100644 index 00000000..0ad25db4 --- /dev/null +++ b/apps/stage/LICENSE @@ -0,0 +1,661 @@ + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU Affero General Public License is a free, copyleft license for +software and other kinds of works, specifically designed to ensure +cooperation with the community in the case of network server software. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +our General Public Licenses are intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + Developers that use our General Public Licenses protect your rights +with two steps: (1) assert copyright on the software, and (2) offer +you this License which gives you legal permission to copy, distribute +and/or modify the software. + + A secondary benefit of defending all users' freedom is that +improvements made in alternate versions of the program, if they +receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and +encouraged by the resulting cooperation. However, in the case of +software used on network servers, this result may fail to come about. +The GNU General Public License permits making a modified version and +letting the public access it on a server without ever releasing its +source code to the public. + + The GNU Affero General Public License is designed specifically to +ensure that, in such cases, the modified source code becomes available +to the community. It requires the operator of a network server to +provide the source code of the modified version running there to the +users of that server. Therefore, public use of a modified version, on +a publicly accessible server, gives the public access to the source +code of the modified version. + + An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is +a different license, not a version of the Affero GPL, but Affero has +released a new version of the Affero GPL which permits relicensing under +this license. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU Affero General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the +Program, your modified version must prominently offer all users +interacting with it remotely through a computer network (if your version +supports such interaction) an opportunity to receive the Corresponding +Source of your version by providing access to the Corresponding Source +from a network server at no charge, through some standard or customary +means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 +of the GNU General Public License that is incorporated pursuant to the +following paragraph. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the work with which it is combined will remain governed by version +3 of the GNU General Public License. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU Affero General Public License from time to time. Such new versions +will be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU Affero General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU Affero General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU Affero General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU AGPL, see +. diff --git a/apps/stage/README.md b/apps/stage/README.md new file mode 100644 index 00000000..1c5205fe --- /dev/null +++ b/apps/stage/README.md @@ -0,0 +1,101 @@ +# Stage - UI + +
+arranger-logo +
+ +Stage is a React-based user interface designed to prop up browser-accessible data portals. + +Stage is a [Next.js](https://nextjs.org/) project bootstrapped with [create-next-app](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). + +For more information about Stage, see our [official Stage user documentation](https://www.docs.overture.bio/documentation/stage/) + + + +
+ +>
+> +>
+> +> Stage is part of the [Overture](https://www.overture.bio/) research software ecosystem. See our [related products](#related-products) for more information on how Overture is helping organize data and enable discovery. + + + +
+ +## Features + +- URL parameterization support +- Extensible layout, with primary and secondary menus +- Reusable UI components +- Theme customization + +## Getting Started + +1. Install the dependencies + +```shell + npm ci +``` + +2. Run the development server + +```shell + npm run dev +``` + +Once running, Stage is available from your [http://localhost:3000](http://localhost:3000) + +You can edit the UI by modifying `pages/index.js`. The UI will auto-update as you edit. + +**Note:** This app was tested using Node v16+. We recommend using this version if you encounter any issues. + +### Troubleshooting Note: + +Stage requires NPM v^8.3.0, to ensure all dependencies get installed correctly + +```bash +# If you need to update your NPM version first, use the following command: + npm i -g npm +``` + +## Learn More + +To learn more about Next.js, take a look at the following resources: + +- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. +- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. +- [The Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! + + +## Support & Contributions + +- Filing an [issue](https://github.com/overture-stack/stage/issues) +- Making a [contribution](https://github.com/overture-stack/.github/blob/master/CONTRIBUTING.md) +- Connect with us on [Slack](https://join.slack.com/t/overture-bio/shared_invite/zt-21tdumtdh-9fP1TFeLepK4~Lc377rOYw) +- Add or Upvote a [feature request](https://github.com/overture-stack/stage/issues/new?assignees=&labels=&projects=&template=Feature_Requests.md) + +## Related Products + +
+ Overture overview +
+ +Overture is an ecosystem of research software tools, each with narrow responsibilities, designed to reduce redundant programming efforts and enable developers and data scientists to build reliable systems that organize and share big data. + +See the links below for additional information on our other research software tools: + +
+ +| Software | Description | +| ------------------------------------------------------ | ------------------------------------------------------------------------------------------------- | +| [Score](https://github.com/overture-stack/score) | Transfer data to and from any cloud-based storage system | +| [Song](https://github.com/overture-stack/song) | Catalog and manage metadata associated to file data spread across cloud storage systems | +| [Maestro](https://github.com/overture-stack/maestro) | Organizing your distributed data into a centralized Elasticsearch index | +| [Arranger](https://github.com/overture-stack/arranger) | A search API with reusable UI components that build into configurable and functional data portals | +| [Stage](https://github.com/overture-stack/stage) | A simple web browser UI | + +## Acknowledgements + +Overture is supported by grant #U24CA253529 from the National Cancer Institute at the US National Institutes of Health, and additional funding from Genome Canada, the Canada Foundation for Innovation, the Canadian Institutes of Health Research, Canarie, and the Ontario Institute for Cancer Research. diff --git a/apps/stage/additional.d.ts b/apps/stage/additional.d.ts new file mode 100644 index 00000000..3b83822d --- /dev/null +++ b/apps/stage/additional.d.ts @@ -0,0 +1,3 @@ +declare module 'url-join'; +declare module 'js-cookie'; +declare module 'jsonwebtoken'; diff --git a/apps/stage/babel.config.js b/apps/stage/babel.config.js new file mode 100644 index 00000000..99f90b7b --- /dev/null +++ b/apps/stage/babel.config.js @@ -0,0 +1,16 @@ +module.exports = { + plugins: ['@emotion/babel-plugin'], + presets: [ + [ + 'next/babel', + { + 'preset-react': { + development: process.env.BABEL_ENV === 'development', + runtime: 'automatic', + importSource: '@emotion/react', + }, + }, + ], + '@babel/preset-typescript', + ], +}; diff --git a/apps/stage/canarie-logo.png b/apps/stage/canarie-logo.png new file mode 100644 index 00000000..1cbcfd68 Binary files /dev/null and b/apps/stage/canarie-logo.png differ diff --git a/apps/stage/components/Button.tsx b/apps/stage/components/Button.tsx new file mode 100644 index 00000000..a812de97 --- /dev/null +++ b/apps/stage/components/Button.tsx @@ -0,0 +1,125 @@ +import React, { ReactNode, ReactNodeArray } from 'react'; +import { css } from '@emotion/react'; +import styled from '@emotion/styled'; + +import defaultTheme from './theme'; +import { Spinner } from './theme/icons'; + +export const UnStyledButton = styled('button')` + background: transparent; + border: none; + cursor: pointer; + display: inline-flex; + justify-content: center; + align-items: center; + padding: 0; + position: relative; + width: fit-content; +`; + +export const ButtonElement = styled(UnStyledButton)` + ${({ theme }: { theme?: typeof defaultTheme }) => css` + color: ${theme?.colors.white}; + background-color: ${theme?.colors.primary}; + ${theme?.typography.subheading2}; + line-height: 24px; + border-radius: 0px; + border: 1px solid ${theme?.colors.primary}; + box-sizing: border-box; + padding: 6px 15px; + &:hover { + background-color: ${theme?.colors.primary_dark}; + } + &:disabled, + &:disabled:hover { + background-color: ${theme?.colors.grey_4}; + cursor: not-allowed; + color: ${theme?.colors.white}; + border: 1px solid ${theme?.colors.grey_4}; + } + `} +`; + +interface ButtonProps { + children?: ReactNode | ReactNodeArray; + disabled?: boolean; + onClick?: ( + e: React.SyntheticEvent, + ) => any | ((e: React.SyntheticEvent) => Promise); + isAsync?: boolean; + className?: string; + isLoading?: boolean; + title?: string; +} + +const Button = React.forwardRef((props, ref) => { + const { + children, + onClick = () => {}, + disabled = false, + isAsync = false, + className, + isLoading: controlledLoadingState, + title, + } = props; + + const [isLoading, setLoading] = React.useState(false); + + /** + * controlledLoadingState will allows consumer to control the loading state. + * Else, that is set by the component internally + */ + const shouldShowLoading = !!controlledLoadingState || (isLoading && isAsync); + + const onClickFn = async (event: React.SyntheticEvent) => { + setLoading(true); + await onClick(event); + setLoading(false); + }; + + return ( + + + {children} + + + {isAsync && ( + + + + )} + + ); +}); + +Button.displayName = 'Button'; + +export const TransparentButton = styled(ButtonElement)` + background: none; + border: none; + justify-content: flex-start; + text-align: left; + + &:focus, + &:hover { + background: none; + } +`; + +export default Button; \ No newline at end of file diff --git a/apps/stage/components/ClientError.tsx b/apps/stage/components/ClientError.tsx new file mode 100644 index 00000000..ac363160 --- /dev/null +++ b/apps/stage/components/ClientError.tsx @@ -0,0 +1,35 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import React from 'react'; +import PlatformAdminContact from './PlatformAdminContact'; +import { ErrorPageLayout } from './PageLayout'; + +const ClientError = () => { + return ( + + An unknown error has occurred. If the problem persists, contact the for + help. + + ); +}; + +export default ClientError; diff --git a/apps/stage/components/ErrorNotification.tsx b/apps/stage/components/ErrorNotification.tsx new file mode 100644 index 00000000..0ef6d4b5 --- /dev/null +++ b/apps/stage/components/ErrorNotification.tsx @@ -0,0 +1,180 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css, useTheme } from '@emotion/react'; +import styled from '@emotion/styled'; +import React from 'react'; +import IconButton from './IconButton'; + +import DismissIcon from './theme/icons/dismiss'; + +type ErrorSize = 'lg' | 'md' | 'sm'; + +const ERROR_SIZES = { + LG: 'lg' as ErrorSize, + MD: 'md' as ErrorSize, + SM: 'sm' as ErrorSize, +}; + +const getContainerStyles = (size: ErrorSize) => + ({ + [ERROR_SIZES.LG]: ` + padding: 1rem 2rem; + line-height: 24px; + `, + [ERROR_SIZES.MD]: ` + padding: 1rem; + line-height: 22px; + `, + [ERROR_SIZES.SM]: ` + padding: 0.5rem; + line-height: 18px; + display: flex; + align-items: center; + `, + }[size]); + +const ErrorContentContainer = styled('div')<{ size: ErrorSize }>` + ${({ theme, size }) => css` + border: 1px solid ${theme.colors.error_2}; + border-radius: 5px; + ${theme.shadow.default}; + ${theme.typography.subheading}; + font-weight: normal; + background-color: ${theme.colors.error_1}; + color: ${theme.colors.accent_dark}; + ${getContainerStyles(size)}; + max-width: 600px; + `} +`; + +// Title styles +const getTitleStyle = (size: ErrorSize) => + ({ + [ERROR_SIZES.LG]: ` + margin: 0.5rem 0 1rem; + font-size: 18px; + line-height: 24px; + `, + [ERROR_SIZES.MD]: ` + margin: 0rem; + padding-bottom: 0.4rem; + font-size: 16px; + line-height: 18px; + `, + [ERROR_SIZES.SM]: ` + margin: 0rem, + line-height: 16px; + `, + }[size]); + +const ErrorTitle = styled('h1')` + ${({ size }: { size: ErrorSize }) => css` + display: flex; + align-items: center; + ${getTitleStyle(size)} + `} +`; + +const ErrorNotification = ({ + children, + className, + title, + size, + onDismiss, + dismissible = false, + ...props +}: { + children: React.ReactNode; + className?: string; + title?: string; + size: ErrorSize; + styles?: string; + onDismiss?: Function; + dismissible?: boolean; +}) => { + const theme = useTheme(); + + return ( +
+ + {title ? ( +
+ + {title} + {dismissible && ( + + (onDismiss ? onDismiss() : () => null)} + Icon={DismissIcon} + height={10} + width={10} + fill={theme.colors.error_dark} + /> + + )} + + {children} +
+ ) : ( +
+
+ {children} +
+ {dismissible && ( + (onDismiss ? onDismiss() : () => null)} + Icon={DismissIcon} + height={10} + width={10} + fill={theme.colors.error_dark} + /> + )} +
+ )} +
+
+ ); +}; + +export default ErrorNotification; diff --git a/apps/stage/components/Footer.tsx b/apps/stage/components/Footer.tsx new file mode 100644 index 00000000..b19f1772 --- /dev/null +++ b/apps/stage/components/Footer.tsx @@ -0,0 +1,81 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css } from '@emotion/react'; +import { getConfig } from '../global/config'; +import { HELP_URL } from '../global/utils/constants'; +import StyledLink from './Link'; +import defaultTheme from './theme'; +import { OvertureLogoWithText } from './theme/icons'; + +const Footer = () => { + const { NEXT_PUBLIC_UI_VERSION } = getConfig(); + + return ( +
css` + height: ${theme.dimensions.footer.height}px; + background-color: ${theme.colors.white}; + border-top: 1px solid ${theme.colors.grey_3}; + display: flex; + justify-content: flex-end; + align-items: center; + padding: 0 18px; + ${theme.shadow.default}; + z-index: 10; + position: fixed; + bottom: 0px; + left: 0px; + right: 0px; + `} + > + css` + ${theme.typography.subheading2}; + padding-right: 13px; + `} + href={HELP_URL} + target="_blank" + > + Help + + + css` + color: ${theme.colors.accent_dark}; + ${theme.typography.subheading2} + line-height: 24px; + font-weight: normal; + padding-right: 10px; + padding-left: 5px; + ` + } + > + {NEXT_PUBLIC_UI_VERSION && `UI v${NEXT_PUBLIC_UI_VERSION}`} powered by + + + + +
+ ); +}; + +export default Footer; diff --git a/apps/stage/components/Head.tsx b/apps/stage/components/Head.tsx new file mode 100644 index 00000000..6ef21881 --- /dev/null +++ b/apps/stage/components/Head.tsx @@ -0,0 +1,32 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import NextHead from 'next/head'; + +const PageHead = ({ subtitle }: { subtitle?: string }) => { + return ( + + Overture{subtitle ? ` - ${subtitle}` : ''} + + ); +}; + +export default PageHead; diff --git a/apps/stage/components/HeroBanner.tsx b/apps/stage/components/HeroBanner.tsx new file mode 100644 index 00000000..66a0adb5 --- /dev/null +++ b/apps/stage/components/HeroBanner.tsx @@ -0,0 +1,167 @@ +// components/HeroBanner.tsx +import { css, useTheme } from '@emotion/react'; +import Link from 'next/link'; +import { ReactElement, ReactNode } from 'react'; + +// Define the breadcrumb item interface +export interface BreadcrumbItem { + label: string; + href?: string; +} + +// Define the component props interface +export interface HeroBannerProps { + title: string | ReactNode; // Updated to accept ReactNode + description?: string | ReactNode; // Updated to accept ReactNode + breadcrumbs?: BreadcrumbItem[]; + backgroundColor?: string; + textColor?: string; + height?: number; + fixed?: boolean; +} + +const HeroBanner = ({ + title, + description, + breadcrumbs = [], + backgroundColor, + textColor = '#ffffff', + height = 120, + fixed = true, +}: HeroBannerProps): ReactElement => { + const theme = useTheme(); + + const bgColor = backgroundColor || theme.colors.primary; + + return ( +
+
+ {breadcrumbs.length > 0 && ( +
+ {breadcrumbs.map((crumb, index) => ( + {crumb.href ? {crumb.label} : crumb.label} + ))} +
+ )} +

+ {title} +

+ {description && ( +

+ {description} +

+ )} +
+
+ ); +}; + +export default HeroBanner; diff --git a/apps/stage/components/IconButton.tsx b/apps/stage/components/IconButton.tsx new file mode 100644 index 00000000..d49243cc --- /dev/null +++ b/apps/stage/components/IconButton.tsx @@ -0,0 +1,50 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css } from '@emotion/react'; +import { IconProps } from './theme/icons/types'; + +const IconButton = ({ + Icon, + fill, + height, + width, + onClick = () => {}, +}: { + Icon: React.ComponentType; + fill: string; + height: number; + width: number; + onClick: React.MouseEventHandler; +}) => { + return ( + + + + ); +}; + +export default IconButton; diff --git a/apps/stage/components/Link.tsx b/apps/stage/components/Link.tsx new file mode 100644 index 00000000..1062d828 --- /dev/null +++ b/apps/stage/components/Link.tsx @@ -0,0 +1,68 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css } from '@emotion/react'; +import styled from '@emotion/styled'; +import Link from 'next/link'; + +import getInternalLink from '../global/utils/getInternalLink'; +import defaultTheme from './theme'; + +const StyledLink = styled('a')` + ${({ theme }: { theme: typeof defaultTheme }) => css` + color: ${theme.colors.secondary_accessible}; + ${theme.typography.regular}; + line-height: 24px; + &:hover { + color: ${theme.colors.accent}; + } + `} +`; + +export const StyledLinkAsButton = styled(StyledLink)` + ${({ theme }: { theme: typeof defaultTheme }) => css` + color: ${theme.colors.white}; + background-color: ${theme.colors.primary}; + ${theme.typography.subheading2}; + line-height: 24px; + border-radius: 5px; + border: 1px solid ${theme.colors.accent}; + padding: 6px 15px; + display: flex; + justify-content: center; + align-items: center; + cursor: pointer; + position: relative; + text-decoration: none; + &:hover { + color: ${theme.colors.white}; + background-color: ${theme.colors.primary_dark}; + } + `} +`; + +export const InternalLink = ({ children, path }: { children: React.ReactNode; path: string }) => ( + + {children} + +); + +export default StyledLink; diff --git a/apps/stage/components/Loader.tsx b/apps/stage/components/Loader.tsx new file mode 100644 index 00000000..a4388320 --- /dev/null +++ b/apps/stage/components/Loader.tsx @@ -0,0 +1,49 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css } from '@emotion/react'; + +// TODO: this is a placeholder Loader +const Loader = () => { + return ( +
css` + border: 10px solid ${theme.colors.grey_3}; + border-top: 10px solid ${theme.colors.secondary_dark}; + border-radius: 50%; + width: 60px; + height: 60px; + animation: spin 2s linear infinite; + + @keyframes spin { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } + } + `} + /> + ); +}; + +export default Loader; diff --git a/apps/stage/components/NavBar/DataTablesDropdown.tsx b/apps/stage/components/NavBar/DataTablesDropdown.tsx new file mode 100644 index 00000000..f8c62b35 --- /dev/null +++ b/apps/stage/components/NavBar/DataTablesDropdown.tsx @@ -0,0 +1,53 @@ +// components/NavBar/DataTablesDropdown.tsx +import cx from 'classnames'; +import { useRouter } from 'next/router'; +import { useEffect, useState } from 'react'; +import { INTERNAL_PATHS } from '../../global/utils/constants'; +import { DataTableInfo } from '../../global/utils/dataTablesDiscovery'; +import { InternalLink } from '../Link'; +import Dropdown from './Dropdown'; +import { linkStyles, StyledListLink } from './styles'; + +const DataTablesDropdown = () => { + const router = useRouter(); + const [dataTables, setDataTables] = useState([]); + const [loading, setLoading] = useState(true); + + useEffect(() => { + // Fetch data tables from API + fetch('/api/data-tables') + .then((response) => response.json()) + .then((data) => { + setDataTables(data); + setLoading(false); + }) + .catch((error) => { + console.error('Error fetching data tables:', error); + setLoading(false); + }); + }, []); + + if (loading) { + return null; // Or a loading indicator + } + + // If no data tables, return null + if (dataTables.length === 0) { + return null; + } + + // Generate dropdown items + const dropdownItems = dataTables.map((table) => ( + + {table.title} + + )); + + // Fix: Convert table paths to INTERNAL_PATHS type using type assertion + // This assumes that your table paths are compatible with your INTERNAL_PATHS enum + const tablePaths = dataTables.map((table) => table.path as unknown as INTERNAL_PATHS); + + return ; +}; + +export default DataTablesDropdown; diff --git a/apps/stage/components/NavBar/DocumentationDropdown.tsx b/apps/stage/components/NavBar/DocumentationDropdown.tsx new file mode 100644 index 00000000..cc636fc5 --- /dev/null +++ b/apps/stage/components/NavBar/DocumentationDropdown.tsx @@ -0,0 +1,103 @@ +// components/NavBar/DocumentationDropdown.tsx +import cx from 'classnames'; +import { useRouter } from 'next/router'; +import { useEffect, useState } from 'react'; +import { INTERNAL_PATHS } from '../../global/utils/constants'; +import { InternalLink } from '../Link'; +import Dropdown from './Dropdown'; +import { linkStyles, StyledListLink } from './styles'; + +interface DocSection { + title: string; + id: string; + order: number; +} + +const DocumentationDropdown = () => { + const router = useRouter(); + const [docSections, setDocSections] = useState([]); + const [loading, setLoading] = useState(true); + + useEffect(() => { + fetch('/api/docs') + .then((response) => response.json()) + .then(async (files) => { + const sectionsPromises = files.map(async (filename: string) => { + try { + const contentResponse = await fetch(`/docs/${filename}`); + if (!contentResponse.ok) throw new Error(`Failed to load ${filename}`); + + const content = await contentResponse.text(); + return { + title: extractTitle(content), + id: createSlug(filename), + order: extractOrder(filename), + }; + } catch (error) { + console.error(`Error processing file ${filename}:`, error); + return null; + } + }); + + const sections = (await Promise.all(sectionsPromises)) + .filter((section): section is DocSection => section !== null) + .sort((a, b) => a.order - b.order); + + setDocSections(sections); + setLoading(false); + }) + .catch((error) => { + console.error('Error fetching documentation:', error); + setLoading(false); + }); + }, []); + + if (loading) { + return null; // Or a loading indicator + } + + // If no documentation sections, return null + if (docSections.length === 0) { + return null; + } + + // Generate dropdown items + const dropdownItems = docSections.map((section) => ( + + + {section.title} + + + )); + + // Generate paths for active state tracking + const docPaths = docSections.map((section) => `${INTERNAL_PATHS.DOCUMENTATION}/${section.id}` as INTERNAL_PATHS); + + return ; +}; + +// Helper functions +function extractTitle(content: string): string { + const titleMatch = content.match(/^#\s+(.+?)(?:\s+\{#.+\})?$/m); + return titleMatch ? titleMatch[1].trim() : 'Untitled Section'; +} + +function createSlug(filename: string): string { + return filename + .replace(/^\d+[-_]?/, '') + .replace(/\.md$/, '') + .toLowerCase() + .replace(/\s+/g, '-') + .replace(/[^\w-]/g, ''); +} + +function extractOrder(filename: string): number { + const match = filename.match(/^(\d+)/); + return match ? parseInt(match[1], 10) : 999; +} + +export default DocumentationDropdown; diff --git a/apps/stage/components/NavBar/Dropdown.tsx b/apps/stage/components/NavBar/Dropdown.tsx new file mode 100644 index 00000000..9437aafe --- /dev/null +++ b/apps/stage/components/NavBar/Dropdown.tsx @@ -0,0 +1,165 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css, useTheme } from '@emotion/react'; +import cx from 'classnames'; +import { MouseEventHandler, ReactElement, ReactNode, SyntheticEvent, useEffect, useRef, useState } from 'react'; + +import defaultTheme from '../theme'; + +import { useRouter } from 'next/router'; +import { INTERNAL_PATHS } from '../../global/utils/constants'; +import { TransparentButton } from '../Button'; + +const Dropdown = ({ + children, + className, + data, + disabled, + label = '', + onClick, + title, + urls = [], +}: { + children?: ReactNode | ReactNode[]; + className?: string; + data: any[]; + disabled?: boolean; + label?: string; + onClick?: (event?: SyntheticEvent) => any; + title?: string; + urls?: INTERNAL_PATHS[]; +}): ReactElement => { + const [open, setOpen] = useState(false); + const theme: typeof defaultTheme = useTheme(); + const node: any = useRef(); + const router = useRouter(); + + const hasData = data?.length > 0; + const internalUrlIsActive = urls.includes(router.asPath as INTERNAL_PATHS); + + const handleClickOnButton = async (event?: SyntheticEvent) => { + await new Promise((resolve) => resolve(open || onClick?.(event))); + setOpen(!open); + }; + + const handleClickOnItem: MouseEventHandler = (event) => { + event.stopPropagation(); + handleClickOnButton(); + }; + + const handleClickOutside = (event: MouseEvent) => { + if (node?.current?.contains(event.target)) { + return; + } + setOpen(false); + }; + + useEffect(() => { + if (open) { + document.addEventListener('mousedown', handleClickOutside); + } else { + document.removeEventListener('mousedown', handleClickOutside); + } + + return () => { + document.removeEventListener('mousedown', handleClickOutside); + }; + }, [open]); + + useEffect(() => { + (disabled || !hasData) && setOpen(false); + }, [disabled, hasData]); + + return ( + span { + display: flex; + position: relative; + } + `} + disabled={disabled || !hasData} + onClick={handleClickOnButton} + ref={node} + title={title} + > + {children || label} + +
+ + {open && ( +
    + {data + .filter((x) => x) + .map((dataItem: ReactNode, index) => ( +
  • + {dataItem} +
  • + ))} +
+ )} + + ); +}; + +export default Dropdown; diff --git a/apps/stage/components/NavBar/NavBar.tsx b/apps/stage/components/NavBar/NavBar.tsx new file mode 100644 index 00000000..fdc15383 --- /dev/null +++ b/apps/stage/components/NavBar/NavBar.tsx @@ -0,0 +1,207 @@ +// components/NavBar/NavBar.tsx +import { css, useTheme } from '@emotion/react'; +import cx from 'classnames'; +import { useRouter } from 'next/router'; +import { createRef, ReactElement } from 'react'; + +import { getConfig } from '../../global/config'; +import useAuthContext from '../../global/hooks/useAuthContext'; +import { + INTERNAL_PATHS, + LECTERN_SWAGGER, + LOGIN_PATH, + LYRIC_SWAGGER, + SCORE_SWAGGER, + SONG_SWAGGER, + USER_PATH, +} from '../../global/utils/constants'; +import { InternalLink, StyledLinkAsButton } from '../Link'; +import defaultTheme from '../theme'; +import UserDropdown from '../UserDropdown'; + +import labIcon from '@/public/images/navbar-logo.png'; +import DataTablesDropdown from './DataTablesDropdown'; +import DocumentationDropdown from './DocumentationDropdown'; +import Dropdown from './Dropdown'; +import { linkStyles, StyledListLink } from './styles'; + +export const navBarRef = createRef(); + +const NavBar = (): ReactElement => { + const router = useRouter(); + const theme: typeof defaultTheme = useTheme(); + const { user } = useAuthContext(); + const { NEXT_PUBLIC_AUTH_PROVIDER, NEXT_PUBLIC_LAB_NAME } = getConfig(); + + const activeLinkStyle = ` + background-color: ${theme.colors.grey_2}; + color: ${theme.colors.accent2_dark}; + `; + + return ( +
+ +
+
+ + + + Lyric API + , + + Lectern API + , + + + Song API + + , + + + Score API + + , + ]} + label="APIs" + /> +
+ + {/* Auth Section */} + {NEXT_PUBLIC_AUTH_PROVIDER && ( +
+ {user ? ( +
css` + width: 195px; + height: ${theme.dimensions.navbar.height}px; + position: relative; + display: flex; + ${router.pathname === USER_PATH ? activeLinkStyle : ''} + &:hover { + background-color: ${theme.colors.grey_2}; + } + `} + > + +
+ ) : ( +
+ + css` + width: 70px; + ${theme.typography.button}; + line-height: 20px; + `} + > + Log in + + +
+ )} +
+ )} +
+
+ ); +}; + +export default NavBar; diff --git a/apps/stage/components/NavBar/styles.tsx b/apps/stage/components/NavBar/styles.tsx new file mode 100644 index 00000000..9e48e728 --- /dev/null +++ b/apps/stage/components/NavBar/styles.tsx @@ -0,0 +1,101 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css, SerializedStyles } from '@emotion/react'; +import styled from '@emotion/styled'; +import defaultTheme from '../theme'; + +export const linkStyles = (theme?: typeof defaultTheme): SerializedStyles => css` + align-items: center; + border-bottom: 4px solid transparent; + box-sizing: border-box; + color: ${theme?.colors.black}; + cursor: pointer; + display: flex; + flex: 0; + font-weight: bold; + height: 100%; + justify-content: center; + + text-decoration: none; + white-space: nowrap; + width: fit-content; + font-size: 14px; + + svg path { + fill: ${theme?.colors.black}; + } + + &.active, + &:hover { + color: ${theme?.colors.primary_dark}; + background-color: ${theme?.colors.grey_1}; + + svg path { + fill: ${theme?.colors.primary_dark}; + } + } +`; + +export const newBadgeStyle = (theme?: typeof defaultTheme): SerializedStyles => css` + background: ${theme?.colors.warning}; + color: ${theme?.colors.primary_dark}; + font-size: 10px; + line-height: 1; + text-transform: uppercase; + border-radius: 0px; + padding: 2px 4px; + font-weight: normal; + margin-top: -12px; + margin-left: 4px; +`; + +export const StyledLink = styled.a` + ${({ theme }: { theme?: typeof defaultTheme }) => linkStyles(theme)} +`; + +export const StyledListLink = styled.a<{ theme?: typeof defaultTheme }>` + ${({ theme }) => css` + align-items: center; + background-color: ${theme?.colors.white}; + border: 1px solid ${theme?.colors.grey_2}; + box-sizing: border-box; + color: ${theme?.colors.black}; + cursor: pointer; + display: flex; + font-size: 16px; + height: 40px; + outline: none; + padding: 6px 12px; + text-decoration: none; + width: 100%; + + &:hover { + background-color: ${theme?.colors.grey_1}; + } + + &:active { + background-color: ${theme?.colors.grey_2}; + color: ${theme?.colors.accent}; + cursor: default; + } + `} +`; diff --git a/apps/stage/components/PageLayout.tsx b/apps/stage/components/PageLayout.tsx new file mode 100644 index 00000000..e863d32b --- /dev/null +++ b/apps/stage/components/PageLayout.tsx @@ -0,0 +1,70 @@ +// PageLayout.tsx - Updated component with width consistency fixes +import { css } from '@emotion/react'; +import { ReactNode } from 'react'; + +import ErrorNotification from './ErrorNotification'; +import Footer from './Footer'; +import PageHead from './Head'; +import NavBar from './NavBar/NavBar'; + +const PageLayout = ({ children, subtitle }: { children: ReactNode; subtitle?: string }) => { + return ( + <> + +
css` + display: flex; + flex-direction: column; + min-height: 100vh; + ${theme.typography.regular} + color: ${theme.colors.black}; + width: 100%; + max-width: 100%; + overflow-x: hidden; + padding-top: ${theme.dimensions.navbar.height}px; + `} + > + +
+ {children} +
+
+
+ + ); +}; + +export const ErrorPageLayout = ({ + children, + subtitle, + errorTitle, +}: { + children: ReactNode; + subtitle: string; + errorTitle: string; +}) => { + return ( + + + {children} + + + ); +}; +export default PageLayout; diff --git a/apps/stage/components/PlatformAdminContact.tsx b/apps/stage/components/PlatformAdminContact.tsx new file mode 100644 index 00000000..3464c62b --- /dev/null +++ b/apps/stage/components/PlatformAdminContact.tsx @@ -0,0 +1,43 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import styled from '@emotion/styled'; +import { getConfig } from '../global/config'; +import StyledLink from './Link'; + +const Span = styled('span')` + line-height: 24px; +`; + +const PlatformAdminContact = () => { + const { NEXT_PUBLIC_ADMIN_EMAIL } = getConfig(); + const Component = NEXT_PUBLIC_ADMIN_EMAIL ? StyledLink : Span; + return platform administrator; +}; + +export const GenericHelpMessage = () => ( + + If the problem persists, please contact the for help troubleshooting + the issue. + +); + +export default PlatformAdminContact; diff --git a/apps/stage/components/Root.tsx b/apps/stage/components/Root.tsx new file mode 100644 index 00000000..9e510416 --- /dev/null +++ b/apps/stage/components/Root.tsx @@ -0,0 +1,70 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import React from 'react'; +import { ThemeProvider } from '@emotion/react'; +import { AuthProvider } from '../global/hooks/useAuthContext'; +import { PageContext } from '../global/hooks/usePageContext'; +import { ClientSideGetInitialPropsContext } from '../global/utils/pages/types'; + +import defaultTheme from './theme'; + +const Root = ({ + children, + pageContext, + session, +}: { + children: React.ReactElement; + pageContext: ClientSideGetInitialPropsContext; + session: any; +}) => { + return ( + <> + + + + + {children} + + + + ); +}; + +export default Root; diff --git a/apps/stage/components/SystemAlerts/helper.tsx b/apps/stage/components/SystemAlerts/helper.tsx new file mode 100644 index 00000000..0b28c0d7 --- /dev/null +++ b/apps/stage/components/SystemAlerts/helper.tsx @@ -0,0 +1,157 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css } from '@emotion/react'; +import React, { ReactElement } from 'react'; +import defaultTheme from '../theme'; +import DismissIcon from '../theme/icons/dismiss'; +import Error from '../theme/icons/error'; +import Info from '../theme/icons/info'; + +export type AlertLevel = 'error' | 'warning' | 'info'; + +export type AlertDef = { + level: AlertLevel; + title: string; + message?: string; + dismissable: boolean; + id: string; +}; + +export const isAlertLevel = (level: any): level is AlertLevel => { + return level === 'error' || level === 'warning' || level === 'info'; +}; + +export const isAlertDef = (obj: any): obj is AlertDef => { + return obj?.id && obj?.title && obj?.dismissable !== undefined && isAlertLevel(obj?.level); +}; + +export const isAlertDefs = (obj: any): obj is AlertDef[] => { + return Array.isArray(obj) && obj.every(isAlertDef); +}; + +type AlertVariant = { + backgroundColor: string; + icon: ReactElement; + textColor: string; +}; + +type SystemAlertProps = { + alert: AlertDef; + onClose: () => void; +}; + +const ALERT_VARIANTS: Record = { + error: { + backgroundColor: defaultTheme.colors.error_1, + icon: , + textColor: defaultTheme.colors.black, + }, + warning: { + backgroundColor: defaultTheme.colors.warning_1, + icon: , + textColor: defaultTheme.colors.black, + }, + info: { + backgroundColor: defaultTheme.colors.secondary_2, + icon: , + textColor: defaultTheme.colors.black, + }, +}; + +export const SystemAlert: React.FC = ({ alert, onClose }) => { + function createMarkup(msg: string) { + return { __html: msg }; + } + + const { backgroundColor, textColor, icon } = ALERT_VARIANTS[alert.level]; + + return ( +
+
+
+ {icon} +
+
+
+ {alert.title} +
+ {alert.message && ( +
+ )} +
+
+ + {alert.dismissable && ( +
+ +
+ )} +
+ ); +}; diff --git a/apps/stage/components/SystemAlerts/index.tsx b/apps/stage/components/SystemAlerts/index.tsx new file mode 100644 index 00000000..db9d7969 --- /dev/null +++ b/apps/stage/components/SystemAlerts/index.tsx @@ -0,0 +1,82 @@ +import { css } from '@emotion/react'; +import React, { useEffect, useState } from 'react'; +import { AlertDef, isAlertDefs, SystemAlert } from './helper'; + +type SystemAlertsProps = { + alerts?: AlertDef[]; // alerts prop is optional + resetOnRefresh?: boolean; // Reset dismissed alerts on refresh +}; + +const SystemAlerts: React.FC = ({ alerts, resetOnRefresh = false }) => { + const [dismissedAlertIds, setDismissedAlertIds] = useState([]); + + // Safely parse the environment variable + const getAlertsFromEnv = (): AlertDef[] => { + try { + // Read from NEXT_PUBLIC_SYSTEM_ALERTS environment variable + const envAlerts = process.env.NEXT_PUBLIC_SYSTEM_ALERTS; + + if (typeof envAlerts === 'string' && envAlerts.trim() !== '') { + const parsed = JSON.parse(envAlerts); + if (isAlertDefs(parsed)) { + return parsed; + } else { + console.warn('System alerts in environment variable are not in the expected format', parsed); + } + } + } catch (error) { + console.error('Error parsing system alerts from environment variable:', error); + } + return []; + }; + + // Determine the final alerts to display - prioritize props over environment variables + const finalAlerts: AlertDef[] = alerts || getAlertsFromEnv(); + + useEffect(() => { + if (resetOnRefresh) { + localStorage.removeItem('SYSTEM_ALERTS_DISMISSED_IDS'); + setDismissedAlertIds([]); // Reset the state + } else { + try { + const storedDismissedIds = JSON.parse(localStorage.getItem('SYSTEM_ALERTS_DISMISSED_IDS') || '[]'); + setDismissedAlertIds(Array.isArray(storedDismissedIds) ? storedDismissedIds : []); + } catch (error) { + console.error('Error parsing dismissed alert IDs from localStorage:', error); + setDismissedAlertIds([]); + } + } + }, [resetOnRefresh]); + + const handleClose = (id: string) => { + const updatedDismissedIds = [...dismissedAlertIds, id]; + setDismissedAlertIds(updatedDismissedIds); + localStorage.setItem('SYSTEM_ALERTS_DISMISSED_IDS', JSON.stringify(updatedDismissedIds)); + }; + + // Filter out dismissed alerts + const displayAlerts = finalAlerts.filter((alert: AlertDef) => !dismissedAlertIds.includes(alert.id)); + + if (displayAlerts.length === 0) { + return null; + } + + return ( +
+ {displayAlerts.map((alert) => ( + handleClose(alert.id)} /> + ))} +
+ ); +}; + +export default SystemAlerts; diff --git a/apps/stage/components/UserDropdown.tsx b/apps/stage/components/UserDropdown.tsx new file mode 100644 index 00000000..be5ab428 --- /dev/null +++ b/apps/stage/components/UserDropdown.tsx @@ -0,0 +1,207 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css, useTheme } from '@emotion/react'; +import styled from '@emotion/styled'; +import { signOut } from 'next-auth/react'; +import { useEffect, useRef, useState } from 'react'; + +import { getConfig } from '@/global/config'; +import { useRouter } from 'next/router'; +import useAuthContext from '../global/hooks/useAuthContext'; +import { UserWithId } from '../global/types/types'; +import { AUTH_PROVIDER, USER_PATH } from '../global/utils/constants'; +import { InternalLink as Link } from './Link'; +import { Avatar, ChevronDown } from './theme/icons'; + +const getDisplayName = (user?: UserWithId) => { + const greeting = 'Hello'; + if (user) { + if (user.firstName) { + return `${greeting}, ${user.firstName}`; + } else if (user.lastName) { + return `${greeting}, ${user.lastName}`; + } else if (user.email) { + return `${greeting}, ${user.email}`; + } + } + return greeting; +}; + +const CurrentUser = () => { + const { user } = useAuthContext(); + return ( +
+ + {getDisplayName(user)} + +
+ ); +}; + +const StyledListLink = styled('a')` + ${({ theme }) => css` + text-decoration: none; + height: 40px; + display: flex; + align-items: center; + padding: 6px 12px; + color: ${theme.colors.black}; + background-color: ${theme.colors.white}; + outline: none; + font-size: 16px; + cursor: pointer; + width: 100%; + + &:hover { + background-color: ${theme.colors.grey_1}; + } + + &:not(:last-child) { + border-bottom: 1px solid ${theme.colors.grey_3}; + } + `} +`; + +const UserDropdown = () => { + const [open, setOpen] = useState(false); + const node: any = useRef(); + const router = useRouter(); + const theme = useTheme(); + const { NEXT_PUBLIC_AUTH_PROVIDER } = getConfig(); + + const handleClickOutside = (e: any) => { + if (node.current.contains(e.target)) { + return; + } + setOpen(false); + }; + + useEffect(() => { + if (open) { + document.addEventListener('mousedown', handleClickOutside); + } else { + document.removeEventListener('mousedown', handleClickOutside); + } + + return () => { + document.removeEventListener('mousedown', handleClickOutside); + }; + }, [open]); + + const fillColor = router.pathname === USER_PATH ? theme.colors.accent2_dark : theme.colors.accent_dark; + + const handleLogout = () => { + if (NEXT_PUBLIC_AUTH_PROVIDER === AUTH_PROVIDER.KEYCLOAK) { + signOut(); + } + }; + + return ( +
setOpen(!open)} + > + + + + {open ? ( + + ) : ( + + )} + {open && ( +
    +
  • + + Profile & Token + +
  • +
  • + Logout +
  • +
+ )} +
+ ); +}; + +export default UserDropdown; diff --git a/apps/stage/components/inactiveDataTables/dataTableFive/Facets.tsx b/apps/stage/components/inactiveDataTables/dataTableFive/Facets.tsx new file mode 100644 index 00000000..1091db41 --- /dev/null +++ b/apps/stage/components/inactiveDataTables/dataTableFive/Facets.tsx @@ -0,0 +1,240 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +import { StageThemeInterface } from '@/components/theme'; +import { getConfig } from '@/global/config'; +import { css, useTheme } from '@emotion/react'; +import { Aggregations, QuickSearch, useArrangerTheme } from '@overture-stack/arranger-components'; +import { UseThemeContextProps } from '@overture-stack/arranger-components/dist/types'; +import { ReactElement } from 'react'; + +const getAggregationsStyles = (theme: StageThemeInterface): UseThemeContextProps => ({ + callerName: 'Data-Table-1-Facets', + components: { + Aggregations: { + ActionIcon: { + fill: theme.colors.secondary, + }, + AggsGroup: { + collapsedBackground: theme.colors.grey_2, + css: css` + .title { + ${theme.typography.subheading2} + line-height: 20px; + } + // Leaving these toggle-button styles untouch as I haven't been able to test making changes + .toggle-button { + ${theme.typography.data}; + padding: 2px 5px 8px 5px; + margin-left: 5px; + .toggle-button-option { + border: 1px solid ${theme.colors.grey_5}; + &:nth-of-type(2) { + border-left: 0px; + border-right: 0px; + } + } + .toggle-button-option .bucket-count { + ${theme.typography.label2} + display: inline-block; + background-color: ${theme.colors.grey_3}; + padding: 0 3px; + border-radius: 3px; + } + .toggle-button-option.active { + background-color: ${theme.colors.secondary_light}; + .bucket-count { + background-color: ${theme.colors.secondary_2}; + } + } + .toggle-button-option.disabled { + background-color: ${theme.colors.grey_2}; + color: ${theme.colors.grey_6}; + } + } + `, + groupDividerColor: theme.colors.grey_3, + headerBackground: theme.colors.white, + headerDividerColor: theme.colors.grey_2, + headerFontColor: theme.colors.accent_dark, + }, + BucketCount: { + background: `rgba(${theme.colors.accent_light_rgb}, 0.45)`, + fontSize: '0.75rem', + }, + FilterInput: { + css: css` + border-radius: 5px; + border: 1px solid ${theme.colors.secondary}; + margin: 6px 5px 7px 0; + &.focused { + box-shadow: inset 0 0 2px 1px ${theme.colors.accent}; + } + & input { + ${theme.typography.data} + &::placeholder { + color: ${theme.colors.black}; + } + } + input[type='text' i] { + margin-left: 5px; + margin-top: 2px; + } + `, + }, + MoreOrLessButton: { + css: css` + ${theme.typography.label2}; + &::before { + padding-top: 3px; + margin-right: 3px; + } + &.more::before { + content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='11' viewBox='0 0 11 11'%3E%3Cpath fill='%2304518C' fill-rule='evenodd' d='M7.637 6.029H6.034v1.613c0 .291-.24.53-.534.53-.294 0-.534-.239-.534-.53V6.03H3.363c-.294 0-.534-.238-.534-.529 0-.29.24-.529.534-.529h1.603V3.358c0-.291.24-.53.534-.53.294 0 .534.239.534.53V4.97h1.603c.294 0 .534.238.534.529 0 .29-.24.529-.534.529M5.5 0C2.462 0 0 2.462 0 5.5S2.462 11 5.5 11 11 8.538 11 5.5 8.538 0 5.5 0'/%3E%3C/svg%3E%0A"); + } + &.less::before { + content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='11' viewBox='0 0 20 20'%3E%3Cpath fill='%2304518c' fill-rule='evenodd' d='M13.81 10.952H6.19c-.523 0-.952-.428-.952-.952s.429-.952.952-.952h7.62c.523 0 .952.428.952.952s-.429.952-.952.952M10 0C4.476 0 0 4.476 0 10s4.476 10 10 10 10-4.476 10-10S15.524 0 10 0'/%3E%3C/svg%3E%0A"); + } + `, + fontColor: theme.colors.primary, + }, + RangeAgg: { + css: css` + &[data-fieldName='analysis.host.host_age'] .unit-wrapper { + display: none; + } + `, + RangeLabel: { + borderRadius: '0.2rem', + fontWeight: 'bold !important', + css: css` + ${theme.typography.label2} + background-color: ${theme.colors.grey_3}; + &:last-of-type, + &:nth-of-type(4) { + background-color: ${theme.colors.white}; + color: ${theme.colors.grey_6}; + } + `, + padding: '0 0.2rem', + }, + // slider is the button that you drag to select values + RangeSlider: { + borderColor: theme.colors.grey_5, + css: theme.shadow.default, + disabledBackground: theme.colors.grey_3, + }, + // the band upon which the sliders move + RangeTrack: { + disabledInBackground: theme.colors.grey_4, + disabledOutBackground: theme.colors.grey_3, + inBackground: theme.colors.primary_dark, + outBackground: theme.colors.grey_4, + }, + }, + TreeJointIcon: { + fill: theme.colors.primary_dark, + size: 8, + transition: 'all 0s', + }, + }, + QuickSearch: { + fieldNames: 'donors.specimens.submitter_specimen_id', + headerTitle: 'Specimen Collector Sample ID', + placeholder: 'e.g. AB-12345', + // components + DropDownItems: { + css: css` + border: 1px solid ${theme.colors.secondary}; + border-radius: 5px; + `, + entityLogo: { + enabled: false, + }, + resultKeyText: { + css: css` + margin-left: 20px; + font-weight: bold; + `, + }, + resultValue: { + css: css` + margin-left: 20px; + `, + }, + }, + QuickSearchWrapper: { + css: css` + .title { + ${theme.typography.subheading2} + line-height: 20px; + } + `, + }, + TreeJointIcon: { + fill: theme.colors.primary_dark, + size: 8, + transition: 'all 0s', + }, + PinnedValues: { + background: theme.colors.primary_dark, + css: css` + ${theme.typography.label} + &::after { + content: url(data:image/svg+xml,%3Csvg%20width%3D%228%22%20height%3D%228%22%20stroke%3D%22white%22%20stroke-width%3D%222%22%3E%0A%20%20%3Cline%20x1%3D%220%22%20y1%3D%220%22%20x2%3D%228%22%20y2%3D%228%22%20/%3E%0A%20%20%3Cline%20x1%3D%228%22%20y1%3D%220%22%20x2%3D%220%22%20y2%3D%228%22%20/%3E%0A%3C/svg%3E); + margin: 0 0 0 0.5rem; + } + `, + fontColor: theme.colors.white, + hoverBackground: theme.colors.primary, + margin: '0.1rem', + padding: '0 0.5rem', + }, + }, + }, +}); +const Facets = (): ReactElement => { + const { NEXT_PUBLIC_ENABLE_DATATABLE_5_QUICKSEARCH } = getConfig(); + const theme = useTheme(); + useArrangerTheme(getAggregationsStyles(theme)); + return ( +
+

+ Filters +

+ {NEXT_PUBLIC_ENABLE_DATATABLE_5_QUICKSEARCH && } + +
+ ); +}; +export default Facets; diff --git a/apps/stage/components/inactiveDataTables/dataTableFive/PageContent.tsx b/apps/stage/components/inactiveDataTables/dataTableFive/PageContent.tsx new file mode 100644 index 00000000..5b4e3268 --- /dev/null +++ b/apps/stage/components/inactiveDataTables/dataTableFive/PageContent.tsx @@ -0,0 +1,128 @@ +/* + * + * Copyright (c) 2024 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css, useTheme } from '@emotion/react'; +import { useArrangerData } from '@overture-stack/arranger-components'; +import { SQONType } from '@overture-stack/arranger-components/dist/DataContext/types.js'; +import stringify from 'fast-json-stable-stringify'; +import { isEqual } from 'lodash'; +import { useEffect, useMemo, useState } from 'react'; + +import useUrlParamState from '@/global/hooks/useUrlParamsState'; + +import Facets from './Facets'; +import QueryBar from './QueryBar'; +import RepoTable from './RepoTable'; + +const PageContent = () => { + const theme = useTheme(); + const [showSidebar, setShowSidebar] = useState(true); + const sidebarWidth = showSidebar ? theme.dimensions.facets.width : 0; + + // TODO: abstract this param handling into an Arranger integration. + const { sqon, setSQON } = useArrangerData({ callerName: 'DataTableOne-PageContent' }); + const [firstRender, setFirstRender] = useState(true); + const [currentFilters, setCurrentFilters] = useUrlParamState('filters', null, { + prepare: (v) => v.replace('"field"', '"fieldName"'), + deSerialize: (v) => { + return v ? JSON.parse(v) : null; + }, + serialize: (v) => (v ? stringify(v) : ''), + }); + + useEffect(() => { + if (firstRender) { + currentFilters && setSQON(currentFilters); + setFirstRender(false); + } + }, [currentFilters, firstRender, setSQON]); + + useEffect(() => { + firstRender || isEqual(sqon, currentFilters) || setCurrentFilters(sqon); + }, [currentFilters, firstRender, setCurrentFilters, sqon]); + + return useMemo( + () => ( +
+
+ {/* WIP button to hide/show the sidebar + */} + + +
+
+ + +
+
+
+
+ ), + [], + ); +}; + +export default PageContent; diff --git a/apps/stage/components/inactiveDataTables/dataTableFive/QueryBar.tsx b/apps/stage/components/inactiveDataTables/dataTableFive/QueryBar.tsx new file mode 100644 index 00000000..4520e3dc --- /dev/null +++ b/apps/stage/components/inactiveDataTables/dataTableFive/QueryBar.tsx @@ -0,0 +1,117 @@ +/* + * + * Copyright (c) 2024 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +import { StageThemeInterface } from '@/components/theme'; +import { css, useTheme } from '@emotion/react'; +import { SQONViewer, useArrangerTheme } from '@overture-stack/arranger-components'; +import { UseThemeContextProps } from '@overture-stack/arranger-components/dist/types'; +import { Row } from 'react-grid-system'; +const getThemeCustomisations = (theme: StageThemeInterface): UseThemeContextProps => ({ + callerName: 'DataSetOne-QueryBar', + components: { + SQONViewer: { + EmptyMessage: { + arrowColor: theme.colors.primary_dark, + }, + SQONBubble: { + borderRadius: '8px', + fontSize: '13px', + fontWeight: 300, + height: '1.6rem', + letterSpacing: '0.2px', + }, + SQONClear: { + label: 'Reset', + borderColor: theme.colors.grey_5, + borderRadius: '5px', + background: theme.colors.primary_dark, + cursor: 'pointer', + fontColor: theme.colors.white, + fontSize: '0.88rem', + fontWeight: 600, + hoverBackground: theme.colors.primary, + padding: '0 12px', + }, + SQONFieldName: { + fontWeight: 'normal', + textTransform: 'uppercase', + }, + SQONGroup: { + fontColor: theme.colors.grey_6, + margin: '0.1rem 0 0', + }, + SQONLessOrMore: { + background: theme.colors.primary_light, + css: css` + ${theme.typography.label}; + `, + fontColor: theme.colors.white, + hoverBackground: theme.colors.primary, + lineHeight: '1.4rem !important', + margin: '0 0.4rem 0 0', + padding: '0 0.4rem', + textTransform: 'uppercase', + }, + SQONValue: { + background: theme.colors.primary_dark, + css: css` + margin-left: 0; + ${theme.typography.label} + &::after { + content: url(data:image/svg+xml,%3Csvg%20width%3D%228%22%20height%3D%228%22%20stroke%3D%22white%22%20stroke-width%3D%222%22%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%3E%0A%20%20%3Cline%20x1%3D%220%22%20y1%3D%220%22%20x2%3D%228%22%20y2%3D%228%22%20/%3E%0A%20%20%3Cline%20x1%3D%228%22%20y1%3D%220%22%20x2%3D%220%22%20y2%3D%228%22%20/%3E%0A%3C/svg%3E); + margin: 0 0 0 0.5rem; + } + `, + fontColor: theme.colors.white, + hoverBackground: theme.colors.primary, + margin: '0.1rem 0.4rem', + padding: '0 0.5rem', + }, + SQONValueGroup: { + css: css` + &:last-of-type { + margin-left: 0; + } + `, + fontSize: '1.4rem', + margin: '-0.2rem 0.4rem 0', + }, + }, + }, +}); +const QueryBar = () => { + const theme = useTheme(); + useArrangerTheme(getThemeCustomisations(theme)); + return ( + css` + min-height: 48px; + margin: 10px 0; + background-color: ${theme.colors.white}; + border-radius: 5px; + ${theme.shadow.default}; + `} + > + + + ); +}; +export default QueryBar; diff --git a/apps/stage/components/inactiveDataTables/dataTableFive/RepoTable/helper.ts b/apps/stage/components/inactiveDataTables/dataTableFive/RepoTable/helper.ts new file mode 100644 index 00000000..689967d1 --- /dev/null +++ b/apps/stage/components/inactiveDataTables/dataTableFive/RepoTable/helper.ts @@ -0,0 +1,88 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import createArrangerFetcher from '@/components/utils/arrangerFetcher'; +import { INTERNAL_API_PROXY } from '@/global/utils/constants'; +import { SQONType } from '@overture-stack/arranger-components/dist/DataContext/types'; +import SQON from '@overture-stack/sqon-builder'; +import { isEmpty } from 'lodash'; + +export const arrangerFetcher = createArrangerFetcher({ + ARRANGER_API: INTERNAL_API_PROXY.DATATABLE_5_ARRANGER, +}); + +const saveSetMutation = `mutation ($sqon: JSON!) { + saveSet( + sqon: $sqon, + type: file, + path: "name" + ) { + setId + } +}`; + +export const saveSet = (sqon: SQONType): Promise => { + return arrangerFetcher({ + body: { + query: saveSetMutation, + variables: { sqon }, + }, + }) + .then( + ({ + data: { + saveSet: { setId }, + }, + }) => { + return setId; + }, + ) + .catch((err: Error) => { + console.warn(err); + return Promise.reject(err); + }); +}; + +// Type guard to check if SQON is not null +function isSQON(sqon: SQONType | null): sqon is SQONType { + return sqon !== null && !isEmpty(sqon); +} + +export function buildSqonWithObjectIds(currentSqon: SQONType, objectIds: string[]): SQONType { + // Create object ID SQON only if we have IDs + let objectsSqon: SQONType | null = null; + if (objectIds.length > 0) { + const builder = SQON.in('object_id', objectIds); + objectsSqon = builder.toValue() as unknown as SQONType; + } + + // If both SQONs are valid, combine them + if (isSQON(currentSqon) && isSQON(objectsSqon)) { + const sqonArray = [currentSqon, objectsSqon].map((sqon) => sqon as any); + const builder = SQON.and(sqonArray); + return builder.toValue() as unknown as SQONType; + } + + // Return whichever SQON is valid, or null if neither is + if (isSQON(currentSqon)) return currentSqon; + if (isSQON(objectsSqon)) return objectsSqon; + return null; +} diff --git a/apps/stage/components/inactiveDataTables/dataTableFive/RepoTable/index.tsx b/apps/stage/components/inactiveDataTables/dataTableFive/RepoTable/index.tsx new file mode 100644 index 00000000..5d40d89e --- /dev/null +++ b/apps/stage/components/inactiveDataTables/dataTableFive/RepoTable/index.tsx @@ -0,0 +1,193 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css, useTheme } from '@emotion/react'; +import { + Pagination, + Table, + TableContextProvider, + Toolbar, + useArrangerTheme, +} from '@overture-stack/arranger-components'; +import { CustomExporterInput } from '@overture-stack/arranger-components/dist/Table/DownloadButton/types'; +import { UseThemeContextProps } from '@overture-stack/arranger-components/dist/ThemeContext/types'; +import { useMemo } from 'react'; +import urlJoin from 'url-join'; + +import { StageThemeInterface } from '@/components/theme'; +import { Download } from '@/components/theme/icons'; +import { INTERNAL_API_PROXY } from '@/global/utils/constants'; + +const getTableConfigs = ({ + apiHost, + customExporters, + theme, +}: { + apiHost: string; + customExporters?: CustomExporterInput; + theme: StageThemeInterface; +}): UseThemeContextProps => ({ + callerName: 'RepoTable', + components: { + Table: { + // functionality + hideLoader: true, + + // appearance + background: theme.colors.white, + borderColor: theme.colors.grey_5, // Updated from grey_3 to grey_5 for more contrast + css: css` + ${theme.shadow.default} + `, + + // Child components + columnTypes: { + all: { + cellValue: ({ getValue }) => { + const value = getValue(); + return ['', null, 'null', 'NA', undefined, 'undefined'].includes(value) ? ( + + -- + + ) : ( + value + ); + }, + }, + }, + CountDisplay: { + fontColor: 'inherit', + }, + DownloadButton: { + customExporters, + exportSelectedRowsField: 'submission_metadata.submitter_id', + downloadUrl: urlJoin(apiHost, 'download'), + label: () => ( + <> + path { + fill: ${theme.colors.grey_5}; + } + `} + />{' '} + Download + + ), + ListWrapper: { + width: '11rem', + }, + }, + DropDown: { + arrowColor: '#151c3d', + arrowTransition: 'all 0s', + background: theme.colors.white, + borderColor: theme.colors.grey_5, + css: css` + ${theme.typography.subheading2} + line-height: 1.3rem; + `, + fontColor: theme.colors.accent_dark, + disabledFontColor: theme.colors.grey_5, + hoverBackground: theme.colors.secondary_light, + + ListWrapper: { + background: theme.colors.white, + css: css` + ${theme.shadow.default} + `, + fontColor: theme.colors.black, + fontSize: '0.7rem', + hoverBackground: theme.colors.secondary_light, + }, + }, + HeaderRow: { + borderColor: theme.colors.grey_5, // Updated from grey_3 to grey_5 for more contrast + css: css` + ${theme.typography.data} + `, + fontColor: theme.colors.accent_dark, + fontSize: '13px', + fontWeight: 'bold', + lineHeight: '1.7rem', + }, + MaxRowsSelector: { + fontColor: 'inherit', + }, + Row: { + css: css` + &:nth-of-type(2n-1) { + background-color: ${theme.colors.grey_1}; + } + `, + hoverBackground: theme.colors.grey_highlight, + lineHeight: '1.5rem', + selectedBackground: theme.colors.accent_highlight, + verticalBorderColor: theme.colors.grey_5, // Updated from grey_3 to grey_5 for more contrast + }, + TableWrapper: { + margin: '0.5rem 0', + }, + }, + }, +}); + +const RepoTable = () => { + const theme = useTheme(); + const today = new Date().toISOString().slice(0, 10).replace(/-/g, ''); + const customExporters = [ + { label: 'Download', fileName: `dataset-2-data-export.${today}.tsv` }, // exports a TSV with what is displayed on the table (columns selected, etc.) + ]; + + useArrangerTheme(getTableConfigs({ apiHost: INTERNAL_API_PROXY.DATATABLE_5_ARRANGER, customExporters, theme })); + + return useMemo( + () => ( + <> +
+ + + + + + + + ), + [], + ); +}; + +export default RepoTable; diff --git a/apps/stage/components/inactiveDataTables/dataTableFive/getConfigError.tsx b/apps/stage/components/inactiveDataTables/dataTableFive/getConfigError.tsx new file mode 100644 index 00000000..9fba3a56 --- /dev/null +++ b/apps/stage/components/inactiveDataTables/dataTableFive/getConfigError.tsx @@ -0,0 +1,125 @@ +/* + * + * Copyright (c) 2024 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +import StyledLink from '@/components/Link'; +import { GenericHelpMessage } from '@/components/PlatformAdminContact'; +import { Checkmark, Warning } from '@/components/theme/icons'; +import { getConfig } from '@/global/config'; +import { css, useTheme } from '@emotion/react'; +import { ReactNode } from 'react'; +const ArrangerAdminUILink = () => { + const { NEXT_PUBLIC_ARRANGER_DATATABLE_5_ADMIN_UI } = getConfig(); + return ( + + Arranger Admin UI + + ); +}; +const ListItem = ({ Icon, value, fieldName }: { Icon?: ReactNode; value: string; fieldName: string }) => { + const theme = useTheme(); + return ( +
  • + {Icon || } + + {fieldName}:{' '} + + {value} + + +
  • + ); +}; +const WarningListItem = ({ fieldName }: { fieldName: string }) => ( + } fieldName={fieldName} value={'Missing'} /> +); +const getConfigError = ({ + hasConfig, + documentType, + index, +}: { + hasConfig: boolean; + documentType: string; + index: string; +}) => + index && documentType ? ( + !hasConfig && ( + + No active configurations for the DMS portal were found. Please make sure the index and GraphQL document type + specified in the DMS{' '} + + config.yaml + {' '} + file during installation have been created in the . + + ) + ) : ( + + One or more of the following values required by the DMS portal do not exist. Please make sure the values are + specified in the DMS{' '} + + config.yaml + {' '} + file during installation and have been used to create your project in the .{' '} + +
      + {[ + { fieldName: 'GraphQL Document type', value: documentType }, + { fieldName: 'Elasticsearch index', value: index }, + ].map(({ fieldName, value }) => { + return value ? ( + + ) : ( + + ); + })} +
    +
    + ); +export default getConfigError; diff --git a/apps/stage/components/inactiveDataTables/dataTableFive/index.tsx b/apps/stage/components/inactiveDataTables/dataTableFive/index.tsx new file mode 100644 index 00000000..fa3966ab --- /dev/null +++ b/apps/stage/components/inactiveDataTables/dataTableFive/index.tsx @@ -0,0 +1,175 @@ +/* + * + * Copyright (c) 2024 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css, useTheme } from '@emotion/react'; +import { ArrangerDataProvider } from '@overture-stack/arranger-components'; +import { ReactElement, useEffect, useState } from 'react'; + +import ErrorNotification from '@/components/ErrorNotification'; +import Loader from '@/components/Loader'; +import PageLayout from '@/components/PageLayout'; +import sleep from '@/components/utils/sleep'; +import { getConfig } from '@/global/config'; +import { RepoFiltersType } from '@/global/types/sqon'; + +import getConfigError from './getConfigError'; +import PageContent from './PageContent'; +import { arrangerFetcher } from './RepoTable/helper'; + +export interface PageContentProps { + sqon: RepoFiltersType; + selectedTableRows: string[]; + setSelectedTableRows: (ids: []) => void; + index: string; + api: ({ + endpoint, + body, + headers, + method, + }: { + endpoint: string; + body: string; + headers: any; + method: string; + }) => Promise; + setSQON: (sqon: RepoFiltersType) => void; + fetchData?: () => Promise; +} + +const { + NEXT_PUBLIC_ARRANGER_DATATABLE_5_API, + NEXT_PUBLIC_ARRANGER_DATATABLE_5_DOCUMENT_TYPE, + NEXT_PUBLIC_ARRANGER_DATATABLE_5_INDEX, +} = getConfig(); + +const configsQuery = ` + query ($documentType: String!, $index: String!) { + hasValidConfig (documentType: $documentType, index: $index) + } +`; + +const DataSetOneRepositoryPage = (): ReactElement => { + const theme = useTheme(); + const [arrangerHasConfig, setArrangerHasConfig] = useState(false); + const [loadingArrangerConfig, setLoadingArrangerConfig] = useState(true); + + useEffect(() => { + arrangerFetcher({ + endpoint: 'graphql/hasValidConfig', + body: JSON.stringify({ + variables: { + documentType: NEXT_PUBLIC_ARRANGER_DATATABLE_5_DOCUMENT_TYPE, + index: NEXT_PUBLIC_ARRANGER_DATATABLE_5_INDEX, + }, + query: configsQuery, + }), + }) + .then(async ({ data } = {}) => { + if (data?.hasValidConfig) { + await setArrangerHasConfig(data.hasValidConfig); + // 1s delay so loader doesn't flicker on and off too quickly + await sleep(1000); + + return setLoadingArrangerConfig(false); + } + + throw new Error('Could not validate Arranger Dataset1 server configuration!'); + }) + .catch(async (err) => { + console.warn(err); + // same as above comment + await sleep(1000); + setLoadingArrangerConfig(false); + }); + }, []); + + const ConfigError = getConfigError({ + hasConfig: arrangerHasConfig, + index: NEXT_PUBLIC_ARRANGER_DATATABLE_5_INDEX, + documentType: NEXT_PUBLIC_ARRANGER_DATATABLE_5_DOCUMENT_TYPE, + }); + + return ( + + {loadingArrangerConfig ? ( +
    + +
    + ) : ConfigError ? ( +
    +
    + + {ConfigError} + +
    +
    + ) : ( + + + + )} +
    + ); +}; + +export default DataSetOneRepositoryPage; diff --git a/apps/stage/components/inactiveDataTables/dataTableFour/Facets.tsx b/apps/stage/components/inactiveDataTables/dataTableFour/Facets.tsx new file mode 100644 index 00000000..07528f19 --- /dev/null +++ b/apps/stage/components/inactiveDataTables/dataTableFour/Facets.tsx @@ -0,0 +1,240 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +import { StageThemeInterface } from '@/components/theme'; +import { getConfig } from '@/global/config'; +import { css, useTheme } from '@emotion/react'; +import { Aggregations, QuickSearch, useArrangerTheme } from '@overture-stack/arranger-components'; +import { UseThemeContextProps } from '@overture-stack/arranger-components/dist/types'; +import { ReactElement } from 'react'; + +const getAggregationsStyles = (theme: StageThemeInterface): UseThemeContextProps => ({ + callerName: 'Data-Table-1-Facets', + components: { + Aggregations: { + ActionIcon: { + fill: theme.colors.secondary, + }, + AggsGroup: { + collapsedBackground: theme.colors.grey_2, + css: css` + .title { + ${theme.typography.subheading2} + line-height: 20px; + } + // Leaving these toggle-button styles untouch as I haven't been able to test making changes + .toggle-button { + ${theme.typography.data}; + padding: 2px 5px 8px 5px; + margin-left: 5px; + .toggle-button-option { + border: 1px solid ${theme.colors.grey_5}; + &:nth-of-type(2) { + border-left: 0px; + border-right: 0px; + } + } + .toggle-button-option .bucket-count { + ${theme.typography.label2} + display: inline-block; + background-color: ${theme.colors.grey_3}; + padding: 0 3px; + border-radius: 3px; + } + .toggle-button-option.active { + background-color: ${theme.colors.secondary_light}; + .bucket-count { + background-color: ${theme.colors.secondary_2}; + } + } + .toggle-button-option.disabled { + background-color: ${theme.colors.grey_2}; + color: ${theme.colors.grey_6}; + } + } + `, + groupDividerColor: theme.colors.grey_3, + headerBackground: theme.colors.white, + headerDividerColor: theme.colors.grey_2, + headerFontColor: theme.colors.accent_dark, + }, + BucketCount: { + background: `rgba(${theme.colors.accent_light_rgb}, 0.45)`, + fontSize: '0.75rem', + }, + FilterInput: { + css: css` + border-radius: 5px; + border: 1px solid ${theme.colors.secondary}; + margin: 6px 5px 7px 0; + &.focused { + box-shadow: inset 0 0 2px 1px ${theme.colors.accent}; + } + & input { + ${theme.typography.data} + &::placeholder { + color: ${theme.colors.black}; + } + } + input[type='text' i] { + margin-left: 5px; + margin-top: 2px; + } + `, + }, + MoreOrLessButton: { + css: css` + ${theme.typography.label2}; + &::before { + padding-top: 3px; + margin-right: 3px; + } + &.more::before { + content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='11' viewBox='0 0 11 11'%3E%3Cpath fill='%2304518C' fill-rule='evenodd' d='M7.637 6.029H6.034v1.613c0 .291-.24.53-.534.53-.294 0-.534-.239-.534-.53V6.03H3.363c-.294 0-.534-.238-.534-.529 0-.29.24-.529.534-.529h1.603V3.358c0-.291.24-.53.534-.53.294 0 .534.239.534.53V4.97h1.603c.294 0 .534.238.534.529 0 .29-.24.529-.534.529M5.5 0C2.462 0 0 2.462 0 5.5S2.462 11 5.5 11 11 8.538 11 5.5 8.538 0 5.5 0'/%3E%3C/svg%3E%0A"); + } + &.less::before { + content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='11' viewBox='0 0 20 20'%3E%3Cpath fill='%2304518c' fill-rule='evenodd' d='M13.81 10.952H6.19c-.523 0-.952-.428-.952-.952s.429-.952.952-.952h7.62c.523 0 .952.428.952.952s-.429.952-.952.952M10 0C4.476 0 0 4.476 0 10s4.476 10 10 10 10-4.476 10-10S15.524 0 10 0'/%3E%3C/svg%3E%0A"); + } + `, + fontColor: theme.colors.primary, + }, + RangeAgg: { + css: css` + &[data-fieldName='analysis.host.host_age'] .unit-wrapper { + display: none; + } + `, + RangeLabel: { + borderRadius: '0.2rem', + fontWeight: 'bold !important', + css: css` + ${theme.typography.label2} + background-color: ${theme.colors.grey_3}; + &:last-of-type, + &:nth-of-type(4) { + background-color: ${theme.colors.white}; + color: ${theme.colors.grey_6}; + } + `, + padding: '0 0.2rem', + }, + // slider is the button that you drag to select values + RangeSlider: { + borderColor: theme.colors.grey_5, + css: theme.shadow.default, + disabledBackground: theme.colors.grey_3, + }, + // the band upon which the sliders move + RangeTrack: { + disabledInBackground: theme.colors.grey_4, + disabledOutBackground: theme.colors.grey_3, + inBackground: theme.colors.primary_dark, + outBackground: theme.colors.grey_4, + }, + }, + TreeJointIcon: { + fill: theme.colors.primary_dark, + size: 8, + transition: 'all 0s', + }, + }, + QuickSearch: { + fieldNames: 'donors.specimens.submitter_specimen_id', + headerTitle: 'Specimen Collector Sample ID', + placeholder: 'e.g. AB-12345', + // components + DropDownItems: { + css: css` + border: 1px solid ${theme.colors.secondary}; + border-radius: 5px; + `, + entityLogo: { + enabled: false, + }, + resultKeyText: { + css: css` + margin-left: 20px; + font-weight: bold; + `, + }, + resultValue: { + css: css` + margin-left: 20px; + `, + }, + }, + QuickSearchWrapper: { + css: css` + .title { + ${theme.typography.subheading2} + line-height: 20px; + } + `, + }, + TreeJointIcon: { + fill: theme.colors.primary_dark, + size: 8, + transition: 'all 0s', + }, + PinnedValues: { + background: theme.colors.primary_dark, + css: css` + ${theme.typography.label} + &::after { + content: url(data:image/svg+xml,%3Csvg%20width%3D%228%22%20height%3D%228%22%20stroke%3D%22white%22%20stroke-width%3D%222%22%3E%0A%20%20%3Cline%20x1%3D%220%22%20y1%3D%220%22%20x2%3D%228%22%20y2%3D%228%22%20/%3E%0A%20%20%3Cline%20x1%3D%228%22%20y1%3D%220%22%20x2%3D%220%22%20y2%3D%228%22%20/%3E%0A%3C/svg%3E); + margin: 0 0 0 0.5rem; + } + `, + fontColor: theme.colors.white, + hoverBackground: theme.colors.primary, + margin: '0.1rem', + padding: '0 0.5rem', + }, + }, + }, +}); +const Facets = (): ReactElement => { + const { NEXT_PUBLIC_ENABLE_DATATABLE_4_QUICKSEARCH } = getConfig(); + const theme = useTheme(); + useArrangerTheme(getAggregationsStyles(theme)); + return ( +
    +

    + Filters +

    + {NEXT_PUBLIC_ENABLE_DATATABLE_4_QUICKSEARCH && } + +
    + ); +}; +export default Facets; diff --git a/apps/stage/components/inactiveDataTables/dataTableFour/PageContent.tsx b/apps/stage/components/inactiveDataTables/dataTableFour/PageContent.tsx new file mode 100644 index 00000000..5b4e3268 --- /dev/null +++ b/apps/stage/components/inactiveDataTables/dataTableFour/PageContent.tsx @@ -0,0 +1,128 @@ +/* + * + * Copyright (c) 2024 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css, useTheme } from '@emotion/react'; +import { useArrangerData } from '@overture-stack/arranger-components'; +import { SQONType } from '@overture-stack/arranger-components/dist/DataContext/types.js'; +import stringify from 'fast-json-stable-stringify'; +import { isEqual } from 'lodash'; +import { useEffect, useMemo, useState } from 'react'; + +import useUrlParamState from '@/global/hooks/useUrlParamsState'; + +import Facets from './Facets'; +import QueryBar from './QueryBar'; +import RepoTable from './RepoTable'; + +const PageContent = () => { + const theme = useTheme(); + const [showSidebar, setShowSidebar] = useState(true); + const sidebarWidth = showSidebar ? theme.dimensions.facets.width : 0; + + // TODO: abstract this param handling into an Arranger integration. + const { sqon, setSQON } = useArrangerData({ callerName: 'DataTableOne-PageContent' }); + const [firstRender, setFirstRender] = useState(true); + const [currentFilters, setCurrentFilters] = useUrlParamState('filters', null, { + prepare: (v) => v.replace('"field"', '"fieldName"'), + deSerialize: (v) => { + return v ? JSON.parse(v) : null; + }, + serialize: (v) => (v ? stringify(v) : ''), + }); + + useEffect(() => { + if (firstRender) { + currentFilters && setSQON(currentFilters); + setFirstRender(false); + } + }, [currentFilters, firstRender, setSQON]); + + useEffect(() => { + firstRender || isEqual(sqon, currentFilters) || setCurrentFilters(sqon); + }, [currentFilters, firstRender, setCurrentFilters, sqon]); + + return useMemo( + () => ( +
    +
    + {/* WIP button to hide/show the sidebar + */} + + +
    +
    + + +
    +
    +
    +
    + ), + [], + ); +}; + +export default PageContent; diff --git a/apps/stage/components/inactiveDataTables/dataTableFour/QueryBar.tsx b/apps/stage/components/inactiveDataTables/dataTableFour/QueryBar.tsx new file mode 100644 index 00000000..4520e3dc --- /dev/null +++ b/apps/stage/components/inactiveDataTables/dataTableFour/QueryBar.tsx @@ -0,0 +1,117 @@ +/* + * + * Copyright (c) 2024 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +import { StageThemeInterface } from '@/components/theme'; +import { css, useTheme } from '@emotion/react'; +import { SQONViewer, useArrangerTheme } from '@overture-stack/arranger-components'; +import { UseThemeContextProps } from '@overture-stack/arranger-components/dist/types'; +import { Row } from 'react-grid-system'; +const getThemeCustomisations = (theme: StageThemeInterface): UseThemeContextProps => ({ + callerName: 'DataSetOne-QueryBar', + components: { + SQONViewer: { + EmptyMessage: { + arrowColor: theme.colors.primary_dark, + }, + SQONBubble: { + borderRadius: '8px', + fontSize: '13px', + fontWeight: 300, + height: '1.6rem', + letterSpacing: '0.2px', + }, + SQONClear: { + label: 'Reset', + borderColor: theme.colors.grey_5, + borderRadius: '5px', + background: theme.colors.primary_dark, + cursor: 'pointer', + fontColor: theme.colors.white, + fontSize: '0.88rem', + fontWeight: 600, + hoverBackground: theme.colors.primary, + padding: '0 12px', + }, + SQONFieldName: { + fontWeight: 'normal', + textTransform: 'uppercase', + }, + SQONGroup: { + fontColor: theme.colors.grey_6, + margin: '0.1rem 0 0', + }, + SQONLessOrMore: { + background: theme.colors.primary_light, + css: css` + ${theme.typography.label}; + `, + fontColor: theme.colors.white, + hoverBackground: theme.colors.primary, + lineHeight: '1.4rem !important', + margin: '0 0.4rem 0 0', + padding: '0 0.4rem', + textTransform: 'uppercase', + }, + SQONValue: { + background: theme.colors.primary_dark, + css: css` + margin-left: 0; + ${theme.typography.label} + &::after { + content: url(data:image/svg+xml,%3Csvg%20width%3D%228%22%20height%3D%228%22%20stroke%3D%22white%22%20stroke-width%3D%222%22%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%3E%0A%20%20%3Cline%20x1%3D%220%22%20y1%3D%220%22%20x2%3D%228%22%20y2%3D%228%22%20/%3E%0A%20%20%3Cline%20x1%3D%228%22%20y1%3D%220%22%20x2%3D%220%22%20y2%3D%228%22%20/%3E%0A%3C/svg%3E); + margin: 0 0 0 0.5rem; + } + `, + fontColor: theme.colors.white, + hoverBackground: theme.colors.primary, + margin: '0.1rem 0.4rem', + padding: '0 0.5rem', + }, + SQONValueGroup: { + css: css` + &:last-of-type { + margin-left: 0; + } + `, + fontSize: '1.4rem', + margin: '-0.2rem 0.4rem 0', + }, + }, + }, +}); +const QueryBar = () => { + const theme = useTheme(); + useArrangerTheme(getThemeCustomisations(theme)); + return ( + css` + min-height: 48px; + margin: 10px 0; + background-color: ${theme.colors.white}; + border-radius: 5px; + ${theme.shadow.default}; + `} + > + + + ); +}; +export default QueryBar; diff --git a/apps/stage/components/inactiveDataTables/dataTableFour/RepoTable/helper.ts b/apps/stage/components/inactiveDataTables/dataTableFour/RepoTable/helper.ts new file mode 100644 index 00000000..19bec8a8 --- /dev/null +++ b/apps/stage/components/inactiveDataTables/dataTableFour/RepoTable/helper.ts @@ -0,0 +1,88 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import createArrangerFetcher from '@/components/utils/arrangerFetcher'; +import { INTERNAL_API_PROXY } from '@/global/utils/constants'; +import { SQONType } from '@overture-stack/arranger-components/dist/DataContext/types'; +import SQON from '@overture-stack/sqon-builder'; +import { isEmpty } from 'lodash'; + +export const arrangerFetcher = createArrangerFetcher({ + ARRANGER_API: INTERNAL_API_PROXY.DATATABLE_4_ARRANGER, +}); + +const saveSetMutation = `mutation ($sqon: JSON!) { + saveSet( + sqon: $sqon, + type: file, + path: "name" + ) { + setId + } +}`; + +export const saveSet = (sqon: SQONType): Promise => { + return arrangerFetcher({ + body: { + query: saveSetMutation, + variables: { sqon }, + }, + }) + .then( + ({ + data: { + saveSet: { setId }, + }, + }) => { + return setId; + }, + ) + .catch((err: Error) => { + console.warn(err); + return Promise.reject(err); + }); +}; + +// Type guard to check if SQON is not null +function isSQON(sqon: SQONType | null): sqon is SQONType { + return sqon !== null && !isEmpty(sqon); +} + +export function buildSqonWithObjectIds(currentSqon: SQONType, objectIds: string[]): SQONType { + // Create object ID SQON only if we have IDs + let objectsSqon: SQONType | null = null; + if (objectIds.length > 0) { + const builder = SQON.in('object_id', objectIds); + objectsSqon = builder.toValue() as unknown as SQONType; + } + + // If both SQONs are valid, combine them + if (isSQON(currentSqon) && isSQON(objectsSqon)) { + const sqonArray = [currentSqon, objectsSqon].map((sqon) => sqon as any); + const builder = SQON.and(sqonArray); + return builder.toValue() as unknown as SQONType; + } + + // Return whichever SQON is valid, or null if neither is + if (isSQON(currentSqon)) return currentSqon; + if (isSQON(objectsSqon)) return objectsSqon; + return null; +} diff --git a/apps/stage/components/inactiveDataTables/dataTableFour/RepoTable/index.tsx b/apps/stage/components/inactiveDataTables/dataTableFour/RepoTable/index.tsx new file mode 100644 index 00000000..a977b606 --- /dev/null +++ b/apps/stage/components/inactiveDataTables/dataTableFour/RepoTable/index.tsx @@ -0,0 +1,193 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css, useTheme } from '@emotion/react'; +import { + Pagination, + Table, + TableContextProvider, + Toolbar, + useArrangerTheme, +} from '@overture-stack/arranger-components'; +import { CustomExporterInput } from '@overture-stack/arranger-components/dist/Table/DownloadButton/types'; +import { UseThemeContextProps } from '@overture-stack/arranger-components/dist/ThemeContext/types'; +import { useMemo } from 'react'; +import urlJoin from 'url-join'; + +import { StageThemeInterface } from '@/components/theme'; +import { Download } from '@/components/theme/icons'; +import { INTERNAL_API_PROXY } from '@/global/utils/constants'; + +const getTableConfigs = ({ + apiHost, + customExporters, + theme, +}: { + apiHost: string; + customExporters?: CustomExporterInput; + theme: StageThemeInterface; +}): UseThemeContextProps => ({ + callerName: 'RepoTable', + components: { + Table: { + // functionality + hideLoader: true, + + // appearance + background: theme.colors.white, + borderColor: theme.colors.grey_5, // Updated from grey_3 to grey_5 for more contrast + css: css` + ${theme.shadow.default} + `, + + // Child components + columnTypes: { + all: { + cellValue: ({ getValue }) => { + const value = getValue(); + return ['', null, 'null', 'NA', undefined, 'undefined'].includes(value) ? ( + + -- + + ) : ( + value + ); + }, + }, + }, + CountDisplay: { + fontColor: 'inherit', + }, + DownloadButton: { + customExporters, + exportSelectedRowsField: 'submission_metadata.submitter_id', + downloadUrl: urlJoin(apiHost, 'download'), + label: () => ( + <> + path { + fill: ${theme.colors.grey_5}; + } + `} + />{' '} + Download + + ), + ListWrapper: { + width: '11rem', + }, + }, + DropDown: { + arrowColor: '#151c3d', + arrowTransition: 'all 0s', + background: theme.colors.white, + borderColor: theme.colors.grey_5, + css: css` + ${theme.typography.subheading2} + line-height: 1.3rem; + `, + fontColor: theme.colors.accent_dark, + disabledFontColor: theme.colors.grey_5, + hoverBackground: theme.colors.secondary_light, + + ListWrapper: { + background: theme.colors.white, + css: css` + ${theme.shadow.default} + `, + fontColor: theme.colors.black, + fontSize: '0.7rem', + hoverBackground: theme.colors.secondary_light, + }, + }, + HeaderRow: { + borderColor: theme.colors.grey_5, // Updated from grey_3 to grey_5 for more contrast + css: css` + ${theme.typography.data} + `, + fontColor: theme.colors.accent_dark, + fontSize: '13px', + fontWeight: 'bold', + lineHeight: '1.7rem', + }, + MaxRowsSelector: { + fontColor: 'inherit', + }, + Row: { + css: css` + &:nth-of-type(2n-1) { + background-color: ${theme.colors.grey_1}; + } + `, + hoverBackground: theme.colors.grey_highlight, + lineHeight: '1.5rem', + selectedBackground: theme.colors.accent_highlight, + verticalBorderColor: theme.colors.grey_5, // Updated from grey_3 to grey_5 for more contrast + }, + TableWrapper: { + margin: '0.5rem 0', + }, + }, + }, +}); + +const RepoTable = () => { + const theme = useTheme(); + const today = new Date().toISOString().slice(0, 10).replace(/-/g, ''); + const customExporters = [ + { label: 'Download', fileName: `dataset-2-data-export.${today}.tsv` }, // exports a TSV with what is displayed on the table (columns selected, etc.) + ]; + + useArrangerTheme(getTableConfigs({ apiHost: INTERNAL_API_PROXY.DATATABLE_4_ARRANGER, customExporters, theme })); + + return useMemo( + () => ( + <> +
    + + +
    + + + + + ), + [], + ); +}; + +export default RepoTable; diff --git a/apps/stage/components/inactiveDataTables/dataTableFour/getConfigError.tsx b/apps/stage/components/inactiveDataTables/dataTableFour/getConfigError.tsx new file mode 100644 index 00000000..9e576bd7 --- /dev/null +++ b/apps/stage/components/inactiveDataTables/dataTableFour/getConfigError.tsx @@ -0,0 +1,125 @@ +/* + * + * Copyright (c) 2024 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +import StyledLink from '@/components/Link'; +import { GenericHelpMessage } from '@/components/PlatformAdminContact'; +import { Checkmark, Warning } from '@/components/theme/icons'; +import { getConfig } from '@/global/config'; +import { css, useTheme } from '@emotion/react'; +import { ReactNode } from 'react'; +const ArrangerAdminUILink = () => { + const { NEXT_PUBLIC_ARRANGER_DATATABLE_4_ADMIN_UI } = getConfig(); + return ( + + Arranger Admin UI + + ); +}; +const ListItem = ({ Icon, value, fieldName }: { Icon?: ReactNode; value: string; fieldName: string }) => { + const theme = useTheme(); + return ( +
  • + {Icon || } + + {fieldName}:{' '} + + {value} + + +
  • + ); +}; +const WarningListItem = ({ fieldName }: { fieldName: string }) => ( + } fieldName={fieldName} value={'Missing'} /> +); +const getConfigError = ({ + hasConfig, + documentType, + index, +}: { + hasConfig: boolean; + documentType: string; + index: string; +}) => + index && documentType ? ( + !hasConfig && ( + + No active configurations for the DMS portal were found. Please make sure the index and GraphQL document type + specified in the DMS{' '} + + config.yaml + {' '} + file during installation have been created in the . + + ) + ) : ( + + One or more of the following values required by the DMS portal do not exist. Please make sure the values are + specified in the DMS{' '} + + config.yaml + {' '} + file during installation and have been used to create your project in the .{' '} + +
      + {[ + { fieldName: 'GraphQL Document type', value: documentType }, + { fieldName: 'Elasticsearch index', value: index }, + ].map(({ fieldName, value }) => { + return value ? ( + + ) : ( + + ); + })} +
    +
    + ); +export default getConfigError; diff --git a/apps/stage/components/inactiveDataTables/dataTableFour/index.tsx b/apps/stage/components/inactiveDataTables/dataTableFour/index.tsx new file mode 100644 index 00000000..7a5795d9 --- /dev/null +++ b/apps/stage/components/inactiveDataTables/dataTableFour/index.tsx @@ -0,0 +1,175 @@ +/* + * + * Copyright (c) 2024 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css, useTheme } from '@emotion/react'; +import { ArrangerDataProvider } from '@overture-stack/arranger-components'; +import { ReactElement, useEffect, useState } from 'react'; + +import ErrorNotification from '@/components/ErrorNotification'; +import Loader from '@/components/Loader'; +import PageLayout from '@/components/PageLayout'; +import sleep from '@/components/utils/sleep'; +import { getConfig } from '@/global/config'; +import { RepoFiltersType } from '@/global/types/sqon'; + +import getConfigError from './getConfigError'; +import PageContent from './PageContent'; +import { arrangerFetcher } from './RepoTable/helper'; + +export interface PageContentProps { + sqon: RepoFiltersType; + selectedTableRows: string[]; + setSelectedTableRows: (ids: []) => void; + index: string; + api: ({ + endpoint, + body, + headers, + method, + }: { + endpoint: string; + body: string; + headers: any; + method: string; + }) => Promise; + setSQON: (sqon: RepoFiltersType) => void; + fetchData?: () => Promise; +} + +const { + NEXT_PUBLIC_ARRANGER_DATATABLE_4_API, + NEXT_PUBLIC_ARRANGER_DATATABLE_4_DOCUMENT_TYPE, + NEXT_PUBLIC_ARRANGER_DATATABLE_4_INDEX, +} = getConfig(); + +const configsQuery = ` + query ($documentType: String!, $index: String!) { + hasValidConfig (documentType: $documentType, index: $index) + } +`; + +const DataSetOneRepositoryPage = (): ReactElement => { + const theme = useTheme(); + const [arrangerHasConfig, setArrangerHasConfig] = useState(false); + const [loadingArrangerConfig, setLoadingArrangerConfig] = useState(true); + + useEffect(() => { + arrangerFetcher({ + endpoint: 'graphql/hasValidConfig', + body: JSON.stringify({ + variables: { + documentType: NEXT_PUBLIC_ARRANGER_DATATABLE_4_DOCUMENT_TYPE, + index: NEXT_PUBLIC_ARRANGER_DATATABLE_4_INDEX, + }, + query: configsQuery, + }), + }) + .then(async ({ data } = {}) => { + if (data?.hasValidConfig) { + await setArrangerHasConfig(data.hasValidConfig); + // 1s delay so loader doesn't flicker on and off too quickly + await sleep(1000); + + return setLoadingArrangerConfig(false); + } + + throw new Error('Could not validate Arranger Dataset1 server configuration!'); + }) + .catch(async (err) => { + console.warn(err); + // same as above comment + await sleep(1000); + setLoadingArrangerConfig(false); + }); + }, []); + + const ConfigError = getConfigError({ + hasConfig: arrangerHasConfig, + index: NEXT_PUBLIC_ARRANGER_DATATABLE_4_INDEX, + documentType: NEXT_PUBLIC_ARRANGER_DATATABLE_4_DOCUMENT_TYPE, + }); + + return ( + + {loadingArrangerConfig ? ( +
    + +
    + ) : ConfigError ? ( +
    +
    + + {ConfigError} + +
    +
    + ) : ( + + + + )} +
    + ); +}; + +export default DataSetOneRepositoryPage; diff --git a/apps/stage/components/inactiveDataTables/dataTableThree/Facets.tsx b/apps/stage/components/inactiveDataTables/dataTableThree/Facets.tsx new file mode 100644 index 00000000..8f2eb06f --- /dev/null +++ b/apps/stage/components/inactiveDataTables/dataTableThree/Facets.tsx @@ -0,0 +1,240 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +import { StageThemeInterface } from '@/components/theme'; +import { getConfig } from '@/global/config'; +import { css, useTheme } from '@emotion/react'; +import { Aggregations, QuickSearch, useArrangerTheme } from '@overture-stack/arranger-components'; +import { UseThemeContextProps } from '@overture-stack/arranger-components/dist/types'; +import { ReactElement } from 'react'; + +const getAggregationsStyles = (theme: StageThemeInterface): UseThemeContextProps => ({ + callerName: 'Data-Table-1-Facets', + components: { + Aggregations: { + ActionIcon: { + fill: theme.colors.secondary, + }, + AggsGroup: { + collapsedBackground: theme.colors.grey_2, + css: css` + .title { + ${theme.typography.subheading2} + line-height: 20px; + } + // Leaving these toggle-button styles untouch as I haven't been able to test making changes + .toggle-button { + ${theme.typography.data}; + padding: 2px 5px 8px 5px; + margin-left: 5px; + .toggle-button-option { + border: 1px solid ${theme.colors.grey_5}; + &:nth-of-type(2) { + border-left: 0px; + border-right: 0px; + } + } + .toggle-button-option .bucket-count { + ${theme.typography.label2} + display: inline-block; + background-color: ${theme.colors.grey_3}; + padding: 0 3px; + border-radius: 3px; + } + .toggle-button-option.active { + background-color: ${theme.colors.secondary_light}; + .bucket-count { + background-color: ${theme.colors.secondary_2}; + } + } + .toggle-button-option.disabled { + background-color: ${theme.colors.grey_2}; + color: ${theme.colors.grey_6}; + } + } + `, + groupDividerColor: theme.colors.grey_3, + headerBackground: theme.colors.white, + headerDividerColor: theme.colors.grey_2, + headerFontColor: theme.colors.accent_dark, + }, + BucketCount: { + background: `rgba(${theme.colors.accent_light_rgb}, 0.45)`, + fontSize: '0.75rem', + }, + FilterInput: { + css: css` + border-radius: 5px; + border: 1px solid ${theme.colors.secondary}; + margin: 6px 5px 7px 0; + &.focused { + box-shadow: inset 0 0 2px 1px ${theme.colors.accent}; + } + & input { + ${theme.typography.data} + &::placeholder { + color: ${theme.colors.black}; + } + } + input[type='text' i] { + margin-left: 5px; + margin-top: 2px; + } + `, + }, + MoreOrLessButton: { + css: css` + ${theme.typography.label2}; + &::before { + padding-top: 3px; + margin-right: 3px; + } + &.more::before { + content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='11' viewBox='0 0 11 11'%3E%3Cpath fill='%2304518C' fill-rule='evenodd' d='M7.637 6.029H6.034v1.613c0 .291-.24.53-.534.53-.294 0-.534-.239-.534-.53V6.03H3.363c-.294 0-.534-.238-.534-.529 0-.29.24-.529.534-.529h1.603V3.358c0-.291.24-.53.534-.53.294 0 .534.239.534.53V4.97h1.603c.294 0 .534.238.534.529 0 .29-.24.529-.534.529M5.5 0C2.462 0 0 2.462 0 5.5S2.462 11 5.5 11 11 8.538 11 5.5 8.538 0 5.5 0'/%3E%3C/svg%3E%0A"); + } + &.less::before { + content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='11' viewBox='0 0 20 20'%3E%3Cpath fill='%2304518c' fill-rule='evenodd' d='M13.81 10.952H6.19c-.523 0-.952-.428-.952-.952s.429-.952.952-.952h7.62c.523 0 .952.428.952.952s-.429.952-.952.952M10 0C4.476 0 0 4.476 0 10s4.476 10 10 10 10-4.476 10-10S15.524 0 10 0'/%3E%3C/svg%3E%0A"); + } + `, + fontColor: theme.colors.primary, + }, + RangeAgg: { + css: css` + &[data-fieldName='analysis.host.host_age'] .unit-wrapper { + display: none; + } + `, + RangeLabel: { + borderRadius: '0.2rem', + fontWeight: 'bold !important', + css: css` + ${theme.typography.label2} + background-color: ${theme.colors.grey_3}; + &:last-of-type, + &:nth-of-type(4) { + background-color: ${theme.colors.white}; + color: ${theme.colors.grey_6}; + } + `, + padding: '0 0.2rem', + }, + // slider is the button that you drag to select values + RangeSlider: { + borderColor: theme.colors.grey_5, + css: theme.shadow.default, + disabledBackground: theme.colors.grey_3, + }, + // the band upon which the sliders move + RangeTrack: { + disabledInBackground: theme.colors.grey_4, + disabledOutBackground: theme.colors.grey_3, + inBackground: theme.colors.primary_dark, + outBackground: theme.colors.grey_4, + }, + }, + TreeJointIcon: { + fill: theme.colors.primary_dark, + size: 8, + transition: 'all 0s', + }, + }, + QuickSearch: { + fieldNames: 'donors.specimens.submitter_specimen_id', + headerTitle: 'Specimen Collector Sample ID', + placeholder: 'e.g. AB-12345', + // components + DropDownItems: { + css: css` + border: 1px solid ${theme.colors.secondary}; + border-radius: 5px; + `, + entityLogo: { + enabled: false, + }, + resultKeyText: { + css: css` + margin-left: 20px; + font-weight: bold; + `, + }, + resultValue: { + css: css` + margin-left: 20px; + `, + }, + }, + QuickSearchWrapper: { + css: css` + .title { + ${theme.typography.subheading2} + line-height: 20px; + } + `, + }, + TreeJointIcon: { + fill: theme.colors.primary_dark, + size: 8, + transition: 'all 0s', + }, + PinnedValues: { + background: theme.colors.primary_dark, + css: css` + ${theme.typography.label} + &::after { + content: url(data:image/svg+xml,%3Csvg%20width%3D%228%22%20height%3D%228%22%20stroke%3D%22white%22%20stroke-width%3D%222%22%3E%0A%20%20%3Cline%20x1%3D%220%22%20y1%3D%220%22%20x2%3D%228%22%20y2%3D%228%22%20/%3E%0A%20%20%3Cline%20x1%3D%228%22%20y1%3D%220%22%20x2%3D%220%22%20y2%3D%228%22%20/%3E%0A%3C/svg%3E); + margin: 0 0 0 0.5rem; + } + `, + fontColor: theme.colors.white, + hoverBackground: theme.colors.primary, + margin: '0.1rem', + padding: '0 0.5rem', + }, + }, + }, +}); +const Facets = (): ReactElement => { + const { NEXT_PUBLIC_ENABLE_DATATABLE_3_QUICKSEARCH } = getConfig(); + const theme = useTheme(); + useArrangerTheme(getAggregationsStyles(theme)); + return ( +
    +

    + Filters +

    + {NEXT_PUBLIC_ENABLE_DATATABLE_3_QUICKSEARCH && } + +
    + ); +}; +export default Facets; diff --git a/apps/stage/components/inactiveDataTables/dataTableThree/PageContent.tsx b/apps/stage/components/inactiveDataTables/dataTableThree/PageContent.tsx new file mode 100644 index 00000000..44d9d38b --- /dev/null +++ b/apps/stage/components/inactiveDataTables/dataTableThree/PageContent.tsx @@ -0,0 +1,128 @@ +/* + * + * Copyright (c) 2024 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css, useTheme } from '@emotion/react'; +import { useArrangerData } from '@overture-stack/arranger-components'; +import { SQONType } from '@overture-stack/arranger-components/dist/DataContext/types.js'; +import stringify from 'fast-json-stable-stringify'; +import { isEqual } from 'lodash'; +import { useEffect, useMemo, useState } from 'react'; + +import useUrlParamState from '@/global/hooks/useUrlParamsState'; + +import Facets from './Facets'; +import QueryBar from './QueryBar'; +import RepoTable from './RepoTable'; + +const PageContent = () => { + const theme = useTheme(); + const [showSidebar, setShowSidebar] = useState(true); + const sidebarWidth = showSidebar ? theme.dimensions.facets.width : 0; + + // TODO: abstract this param handling into an Arranger integration. + const { sqon, setSQON } = useArrangerData({ callerName: 'DataTableTwo-PageContent' }); + const [firstRender, setFirstRender] = useState(true); + const [currentFilters, setCurrentFilters] = useUrlParamState('filters', null, { + prepare: (v) => v.replace('"field"', '"fieldName"'), + deSerialize: (v) => { + return v ? JSON.parse(v) : null; + }, + serialize: (v) => (v ? stringify(v) : ''), + }); + + useEffect(() => { + if (firstRender) { + currentFilters && setSQON(currentFilters); + setFirstRender(false); + } + }, [currentFilters, firstRender, setSQON]); + + useEffect(() => { + firstRender || isEqual(sqon, currentFilters) || setCurrentFilters(sqon); + }, [currentFilters, firstRender, setCurrentFilters, sqon]); + + return useMemo( + () => ( +
    +
    + {/* WIP button to hide/show the sidebar + */} + + +
    +
    + + +
    +
    +
    +
    + ), + [], + ); +}; + +export default PageContent; diff --git a/apps/stage/components/inactiveDataTables/dataTableThree/QueryBar.tsx b/apps/stage/components/inactiveDataTables/dataTableThree/QueryBar.tsx new file mode 100644 index 00000000..4520e3dc --- /dev/null +++ b/apps/stage/components/inactiveDataTables/dataTableThree/QueryBar.tsx @@ -0,0 +1,117 @@ +/* + * + * Copyright (c) 2024 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +import { StageThemeInterface } from '@/components/theme'; +import { css, useTheme } from '@emotion/react'; +import { SQONViewer, useArrangerTheme } from '@overture-stack/arranger-components'; +import { UseThemeContextProps } from '@overture-stack/arranger-components/dist/types'; +import { Row } from 'react-grid-system'; +const getThemeCustomisations = (theme: StageThemeInterface): UseThemeContextProps => ({ + callerName: 'DataSetOne-QueryBar', + components: { + SQONViewer: { + EmptyMessage: { + arrowColor: theme.colors.primary_dark, + }, + SQONBubble: { + borderRadius: '8px', + fontSize: '13px', + fontWeight: 300, + height: '1.6rem', + letterSpacing: '0.2px', + }, + SQONClear: { + label: 'Reset', + borderColor: theme.colors.grey_5, + borderRadius: '5px', + background: theme.colors.primary_dark, + cursor: 'pointer', + fontColor: theme.colors.white, + fontSize: '0.88rem', + fontWeight: 600, + hoverBackground: theme.colors.primary, + padding: '0 12px', + }, + SQONFieldName: { + fontWeight: 'normal', + textTransform: 'uppercase', + }, + SQONGroup: { + fontColor: theme.colors.grey_6, + margin: '0.1rem 0 0', + }, + SQONLessOrMore: { + background: theme.colors.primary_light, + css: css` + ${theme.typography.label}; + `, + fontColor: theme.colors.white, + hoverBackground: theme.colors.primary, + lineHeight: '1.4rem !important', + margin: '0 0.4rem 0 0', + padding: '0 0.4rem', + textTransform: 'uppercase', + }, + SQONValue: { + background: theme.colors.primary_dark, + css: css` + margin-left: 0; + ${theme.typography.label} + &::after { + content: url(data:image/svg+xml,%3Csvg%20width%3D%228%22%20height%3D%228%22%20stroke%3D%22white%22%20stroke-width%3D%222%22%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%3E%0A%20%20%3Cline%20x1%3D%220%22%20y1%3D%220%22%20x2%3D%228%22%20y2%3D%228%22%20/%3E%0A%20%20%3Cline%20x1%3D%228%22%20y1%3D%220%22%20x2%3D%220%22%20y2%3D%228%22%20/%3E%0A%3C/svg%3E); + margin: 0 0 0 0.5rem; + } + `, + fontColor: theme.colors.white, + hoverBackground: theme.colors.primary, + margin: '0.1rem 0.4rem', + padding: '0 0.5rem', + }, + SQONValueGroup: { + css: css` + &:last-of-type { + margin-left: 0; + } + `, + fontSize: '1.4rem', + margin: '-0.2rem 0.4rem 0', + }, + }, + }, +}); +const QueryBar = () => { + const theme = useTheme(); + useArrangerTheme(getThemeCustomisations(theme)); + return ( + css` + min-height: 48px; + margin: 10px 0; + background-color: ${theme.colors.white}; + border-radius: 5px; + ${theme.shadow.default}; + `} + > + + + ); +}; +export default QueryBar; diff --git a/apps/stage/components/inactiveDataTables/dataTableThree/RepoTable/helper.ts b/apps/stage/components/inactiveDataTables/dataTableThree/RepoTable/helper.ts new file mode 100644 index 00000000..3045440a --- /dev/null +++ b/apps/stage/components/inactiveDataTables/dataTableThree/RepoTable/helper.ts @@ -0,0 +1,88 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import createArrangerFetcher from '@/components/utils/arrangerFetcher'; +import { INTERNAL_API_PROXY } from '@/global/utils/constants'; +import { SQONType } from '@overture-stack/arranger-components/dist/DataContext/types'; +import SQON from '@overture-stack/sqon-builder'; +import { isEmpty } from 'lodash'; + +export const arrangerFetcher = createArrangerFetcher({ + ARRANGER_API: INTERNAL_API_PROXY.DATATABLE_3_ARRANGER, +}); + +const saveSetMutation = `mutation ($sqon: JSON!) { + saveSet( + sqon: $sqon, + type: file, + path: "name" + ) { + setId + } +}`; + +export const saveSet = (sqon: SQONType): Promise => { + return arrangerFetcher({ + body: { + query: saveSetMutation, + variables: { sqon }, + }, + }) + .then( + ({ + data: { + saveSet: { setId }, + }, + }) => { + return setId; + }, + ) + .catch((err: Error) => { + console.warn(err); + return Promise.reject(err); + }); +}; + +// Type guard to check if SQON is not null +function isSQON(sqon: SQONType | null): sqon is SQONType { + return sqon !== null && !isEmpty(sqon); +} + +export function buildSqonWithObjectIds(currentSqon: SQONType, objectIds: string[]): SQONType { + // Create object ID SQON only if we have IDs + let objectsSqon: SQONType | null = null; + if (objectIds.length > 0) { + const builder = SQON.in('object_id', objectIds); + objectsSqon = builder.toValue() as unknown as SQONType; + } + + // If both SQONs are valid, combine them + if (isSQON(currentSqon) && isSQON(objectsSqon)) { + const sqonArray = [currentSqon, objectsSqon].map((sqon) => sqon as any); + const builder = SQON.and(sqonArray); + return builder.toValue() as unknown as SQONType; + } + + // Return whichever SQON is valid, or null if neither is + if (isSQON(currentSqon)) return currentSqon; + if (isSQON(objectsSqon)) return objectsSqon; + return null; +} diff --git a/apps/stage/components/inactiveDataTables/dataTableThree/RepoTable/index.tsx b/apps/stage/components/inactiveDataTables/dataTableThree/RepoTable/index.tsx new file mode 100644 index 00000000..020841cd --- /dev/null +++ b/apps/stage/components/inactiveDataTables/dataTableThree/RepoTable/index.tsx @@ -0,0 +1,193 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css, useTheme } from '@emotion/react'; +import { + Pagination, + Table, + TableContextProvider, + Toolbar, + useArrangerTheme, +} from '@overture-stack/arranger-components'; +import { CustomExporterInput } from '@overture-stack/arranger-components/dist/Table/DownloadButton/types'; +import { UseThemeContextProps } from '@overture-stack/arranger-components/dist/ThemeContext/types'; +import { useMemo } from 'react'; +import urlJoin from 'url-join'; + +import { StageThemeInterface } from '@/components/theme'; +import { Download } from '@/components/theme/icons'; +import { INTERNAL_API_PROXY } from '@/global/utils/constants'; + +const getTableConfigs = ({ + apiHost, + customExporters, + theme, +}: { + apiHost: string; + customExporters?: CustomExporterInput; + theme: StageThemeInterface; +}): UseThemeContextProps => ({ + callerName: 'RepoTable', + components: { + Table: { + // functionality + hideLoader: true, + + // appearance + background: theme.colors.white, + borderColor: theme.colors.grey_5, // Updated from grey_3 to grey_5 for more contrast + css: css` + ${theme.shadow.default} + `, + + // Child components + columnTypes: { + all: { + cellValue: ({ getValue }) => { + const value = getValue(); + return ['', null, 'null', 'NA', undefined, 'undefined'].includes(value) ? ( + + -- + + ) : ( + value + ); + }, + }, + }, + CountDisplay: { + fontColor: 'inherit', + }, + DownloadButton: { + customExporters, + exportSelectedRowsField: 'submission_metadata.submitter_id', + downloadUrl: urlJoin(apiHost, 'download'), + label: () => ( + <> + path { + fill: ${theme.colors.grey_5}; + } + `} + />{' '} + Download + + ), + ListWrapper: { + width: '11rem', + }, + }, + DropDown: { + arrowColor: '#151c3d', + arrowTransition: 'all 0s', + background: theme.colors.white, + borderColor: theme.colors.grey_5, + css: css` + ${theme.typography.subheading2} + line-height: 1.3rem; + `, + fontColor: theme.colors.accent_dark, + disabledFontColor: theme.colors.grey_5, + hoverBackground: theme.colors.secondary_light, + + ListWrapper: { + background: theme.colors.white, + css: css` + ${theme.shadow.default} + `, + fontColor: theme.colors.black, + fontSize: '0.7rem', + hoverBackground: theme.colors.secondary_light, + }, + }, + HeaderRow: { + borderColor: theme.colors.grey_5, // Updated from grey_3 to grey_5 for more contrast + css: css` + ${theme.typography.data} + `, + fontColor: theme.colors.accent_dark, + fontSize: '13px', + fontWeight: 'bold', + lineHeight: '1.7rem', + }, + MaxRowsSelector: { + fontColor: 'inherit', + }, + Row: { + css: css` + &:nth-of-type(2n-1) { + background-color: ${theme.colors.grey_1}; + } + `, + hoverBackground: theme.colors.grey_highlight, + lineHeight: '1.5rem', + selectedBackground: theme.colors.accent_highlight, + verticalBorderColor: theme.colors.grey_5, // Updated from grey_3 to grey_5 for more contrast + }, + TableWrapper: { + margin: '0.5rem 0', + }, + }, + }, +}); + +const RepoTable = () => { + const theme = useTheme(); + const today = new Date().toISOString().slice(0, 10).replace(/-/g, ''); + const customExporters = [ + { label: 'Download', fileName: `dataset-2-data-export.${today}.tsv` }, // exports a TSV with what is displayed on the table (columns selected, etc.) + ]; + + useArrangerTheme(getTableConfigs({ apiHost: INTERNAL_API_PROXY.DATATABLE_3_ARRANGER, customExporters, theme })); + + return useMemo( + () => ( + <> +
    + + +
    + + + + + ), + [], + ); +}; + +export default RepoTable; diff --git a/apps/stage/components/inactiveDataTables/dataTableThree/getConfigError.tsx b/apps/stage/components/inactiveDataTables/dataTableThree/getConfigError.tsx new file mode 100644 index 00000000..56bb9c04 --- /dev/null +++ b/apps/stage/components/inactiveDataTables/dataTableThree/getConfigError.tsx @@ -0,0 +1,155 @@ +/* + * + * Copyright (c) 2024 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +import StyledLink from '@/components/Link'; +import { GenericHelpMessage } from '@/components/PlatformAdminContact'; +import { Checkmark } from '@/components/theme/icons'; +import { getConfig } from '@/global/config'; +import { css, useTheme } from '@emotion/react'; +import { ReactNode } from 'react'; + +const ArrangerAdminUILink = () => { + const { NEXT_PUBLIC_ARRANGER_DATATABLE_1_ADMIN_UI } = getConfig(); + return ( + + Arranger Admin UI + + ); +}; + +const ListItem = ({ Icon, value, fieldName }: { Icon?: ReactNode; value: string; fieldName: string }) => { + const theme = useTheme(); + return ( +
  • + {Icon || } + + {fieldName}:{' '} + + {value} + + +
  • + ); +}; + +// Modified WarningListItem to not use the Warning icon +const WarningListItem = ({ fieldName }: { fieldName: string }) => { + const theme = useTheme(); + return ( +
  • + + {fieldName}:{' '} + + Missing + + +
  • + ); +}; + +const getConfigError = ({ + hasConfig, + documentType, + index, +}: { + hasConfig: boolean; + documentType: string; + index: string; +}) => + index && documentType ? ( + !hasConfig && ( + + No active configurations for the DMS portal were found. Please make sure the index and GraphQL document type + specified in the DMS{' '} + + config.yaml + {' '} + file during installation have been created in the . + + ) + ) : ( + + One or more of the following values required by the DMS portal do not exist. Please make sure the values are + specified in the DMS{' '} + + config.yaml + {' '} + file during installation and have been used to create your project in the .{' '} + +
      + {[ + { fieldName: 'GraphQL Document type', value: documentType }, + { fieldName: 'Elasticsearch index', value: index }, + ].map(({ fieldName, value }) => { + return value ? ( + + ) : ( + + ); + })} +
    +
    + ); + +export default getConfigError; diff --git a/apps/stage/components/inactiveDataTables/dataTableThree/index.tsx b/apps/stage/components/inactiveDataTables/dataTableThree/index.tsx new file mode 100644 index 00000000..c7a960dc --- /dev/null +++ b/apps/stage/components/inactiveDataTables/dataTableThree/index.tsx @@ -0,0 +1,175 @@ +/* + * + * Copyright (c) 2024 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css, useTheme } from '@emotion/react'; +import { ArrangerDataProvider } from '@overture-stack/arranger-components'; +import { ReactElement, useEffect, useState } from 'react'; + +import ErrorNotification from '@/components/ErrorNotification'; +import Loader from '@/components/Loader'; +import PageLayout from '@/components/PageLayout'; +import sleep from '@/components/utils/sleep'; +import { getConfig } from '@/global/config'; +import { RepoFiltersType } from '@/global/types/sqon'; + +import getConfigError from './getConfigError'; +import PageContent from './PageContent'; +import { arrangerFetcher } from './RepoTable/helper'; + +export interface PageContentProps { + sqon: RepoFiltersType; + selectedTableRows: string[]; + setSelectedTableRows: (ids: []) => void; + index: string; + api: ({ + endpoint, + body, + headers, + method, + }: { + endpoint: string; + body: string; + headers: any; + method: string; + }) => Promise; + setSQON: (sqon: RepoFiltersType) => void; + fetchData?: () => Promise; +} + +const { + NEXT_PUBLIC_ARRANGER_DATATABLE_3_API, + NEXT_PUBLIC_ARRANGER_DATATABLE_3_DOCUMENT_TYPE, + NEXT_PUBLIC_ARRANGER_DATATABLE_3_INDEX, +} = getConfig(); + +const configsQuery = ` + query ($documentType: String!, $index: String!) { + hasValidConfig (documentType: $documentType, index: $index) + } +`; + +const DataSetTwoRepositoryPage = (): ReactElement => { + const theme = useTheme(); + const [arrangerHasConfig, setArrangerHasConfig] = useState(false); + const [loadingArrangerConfig, setLoadingArrangerConfig] = useState(true); + + useEffect(() => { + arrangerFetcher({ + endpoint: 'graphql/hasValidConfig', + body: JSON.stringify({ + variables: { + documentType: NEXT_PUBLIC_ARRANGER_DATATABLE_3_DOCUMENT_TYPE, + index: NEXT_PUBLIC_ARRANGER_DATATABLE_3_INDEX, + }, + query: configsQuery, + }), + }) + .then(async ({ data } = {}) => { + if (data?.hasValidConfig) { + await setArrangerHasConfig(data.hasValidConfig); + // 1s delay so loader doesn't flicker on and off too quickly + await sleep(1000); + + return setLoadingArrangerConfig(false); + } + + throw new Error('Could not validate Arranger Dataset2 server configuration!'); + }) + .catch(async (err) => { + console.warn(err); + // same as above comment + await sleep(1000); + setLoadingArrangerConfig(false); + }); + }, []); + + const ConfigError = getConfigError({ + hasConfig: arrangerHasConfig, + index: NEXT_PUBLIC_ARRANGER_DATATABLE_3_INDEX, + documentType: NEXT_PUBLIC_ARRANGER_DATATABLE_3_DOCUMENT_TYPE, + }); + + return ( + + {loadingArrangerConfig ? ( +
    + +
    + ) : ConfigError ? ( +
    +
    + + {ConfigError} + +
    +
    + ) : ( + + + + )} +
    + ); +}; + +export default DataSetTwoRepositoryPage; diff --git a/apps/stage/components/pages/403.tsx b/apps/stage/components/pages/403.tsx new file mode 100644 index 00000000..83a1fabb --- /dev/null +++ b/apps/stage/components/pages/403.tsx @@ -0,0 +1,84 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { EMAIL_SETTING_URL } from '../../global/utils/constants'; +import providerMap from '../../global/utils/providerTypeMap'; +import StyledLink from '../Link'; +import { ErrorPageLayout } from '../PageLayout'; +import { ProviderType } from '../../global/types/types'; +import PlatformAdminContact from '../PlatformAdminContact'; + +enum EgoLoginError { + NO_PRIMARY_EMAIL = 'no_primary_email', + ACCESS_DENIED = 'access_denied', +} + +const errorSubtitles: { [k in EgoLoginError]: string } = { + no_primary_email: 'No Primary Email Found', + access_denied: 'Unable to log in', +}; + +const isValidProviderType = (providerType: ProviderType) => Object.values(ProviderType).includes(providerType); + +const Error403 = ({ query }: { query: { error_type: EgoLoginError; provider_type?: string } }) => { + const { error_type: errorType, provider_type: providerType } = query; + const providerTypeDisplayName = isValidProviderType(providerType as ProviderType) + ? providerMap[providerType as ProviderType].displayName + : 'identity provider'; + + switch (errorType) { + case EgoLoginError.NO_PRIMARY_EMAIL: + return ( + + No primary email could be found on your {providerTypeDisplayName} profile. An email is required to log in to + the Data Explorer. Make sure an email exists on your {providerTypeDisplayName} profile and that it is + accessible by external parties (i.e. not private). See{' '} + + here + {' '} + for instructions on how to do this. + + ); + case EgoLoginError.ACCESS_DENIED: + return ( + + You have denied the DMS access to your {providerTypeDisplayName} profile or cancelled your log in attempt. + Please try again and approve access for {providerTypeDisplayName}, or log in with a different provider for + which you would prefer to allow access. + + ); + default: + return ( + + You do not have permission to access the requested page. Please check that you have entered the correct URL. + If the problem persists, contact the for help. + + ); + } +}; + +export default Error403; diff --git a/apps/stage/components/pages/404.tsx b/apps/stage/components/pages/404.tsx new file mode 100644 index 00000000..4618f83b --- /dev/null +++ b/apps/stage/components/pages/404.tsx @@ -0,0 +1,35 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import React from 'react'; +import PlatformAdminContact from '../PlatformAdminContact'; +import { ErrorPageLayout } from '../PageLayout'; + +const Error404 = () => { + return ( + + The page you requested could not be found. Please check that you have entered the correct URL. + If the problem persists, contact the for help. + + ); +}; + +export default Error404; diff --git a/apps/stage/components/pages/500.tsx b/apps/stage/components/pages/500.tsx new file mode 100644 index 00000000..b480650e --- /dev/null +++ b/apps/stage/components/pages/500.tsx @@ -0,0 +1,34 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import PlatformAdminContact from '../PlatformAdminContact'; +import { ErrorPageLayout } from '../PageLayout'; + +const Error500 = () => { + return ( + + The page you requested could not be accessed due to a server error. If the problem persists, + please contact the for help. + + ); +}; + +export default Error500; diff --git a/apps/stage/components/pages/activeDataTables/dataTableOne/Facets.tsx b/apps/stage/components/pages/activeDataTables/dataTableOne/Facets.tsx new file mode 100644 index 00000000..690e8d47 --- /dev/null +++ b/apps/stage/components/pages/activeDataTables/dataTableOne/Facets.tsx @@ -0,0 +1,240 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +import { StageThemeInterface } from '@/components/theme'; +import { getConfig } from '@/global/config'; +import { css, useTheme } from '@emotion/react'; +import { Aggregations, QuickSearch, useArrangerTheme } from '@overture-stack/arranger-components'; +import { UseThemeContextProps } from '@overture-stack/arranger-components/dist/types'; +import { ReactElement } from 'react'; + +const getAggregationsStyles = (theme: StageThemeInterface): UseThemeContextProps => ({ + callerName: 'Data-Table-1-Facets', + components: { + Aggregations: { + ActionIcon: { + fill: theme.colors.secondary, + }, + AggsGroup: { + collapsedBackground: theme.colors.grey_2, + css: css` + .title { + ${theme.typography.subheading2} + line-height: 20px; + } + // Leaving these toggle-button styles untouch as I haven't been able to test making changes + .toggle-button { + ${theme.typography.data}; + padding: 2px 5px 8px 5px; + margin-left: 5px; + .toggle-button-option { + border: 1px solid ${theme.colors.grey_5}; + &:nth-of-type(2) { + border-left: 0px; + border-right: 0px; + } + } + .toggle-button-option .bucket-count { + ${theme.typography.label2} + display: inline-block; + background-color: ${theme.colors.grey_3}; + padding: 0 3px; + border-radius: 3px; + } + .toggle-button-option.active { + background-color: ${theme.colors.secondary_light}; + .bucket-count { + background-color: ${theme.colors.secondary_2}; + } + } + .toggle-button-option.disabled { + background-color: ${theme.colors.grey_2}; + color: ${theme.colors.grey_6}; + } + } + `, + groupDividerColor: theme.colors.grey_3, + headerBackground: theme.colors.white, + headerDividerColor: theme.colors.grey_2, + headerFontColor: theme.colors.accent_dark, + }, + BucketCount: { + background: `rgba(${theme.colors.accent_light_rgb}, 0.45)`, + fontSize: '0.75rem', + }, + FilterInput: { + css: css` + border-radius: 5px; + border: 1px solid ${theme.colors.secondary}; + margin: 6px 5px 7px 0; + &.focused { + box-shadow: inset 0 0 2px 1px ${theme.colors.accent}; + } + & input { + ${theme.typography.data} + &::placeholder { + color: ${theme.colors.black}; + } + } + input[type='text' i] { + margin-left: 5px; + margin-top: 2px; + } + `, + }, + MoreOrLessButton: { + css: css` + ${theme.typography.label2}; + &::before { + padding-top: 3px; + margin-right: 3px; + } + &.more::before { + content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='11' viewBox='0 0 11 11'%3E%3Cpath fill='%2304518C' fill-rule='evenodd' d='M7.637 6.029H6.034v1.613c0 .291-.24.53-.534.53-.294 0-.534-.239-.534-.53V6.03H3.363c-.294 0-.534-.238-.534-.529 0-.29.24-.529.534-.529h1.603V3.358c0-.291.24-.53.534-.53.294 0 .534.239.534.53V4.97h1.603c.294 0 .534.238.534.529 0 .29-.24.529-.534.529M5.5 0C2.462 0 0 2.462 0 5.5S2.462 11 5.5 11 11 8.538 11 5.5 8.538 0 5.5 0'/%3E%3C/svg%3E%0A"); + } + &.less::before { + content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='11' viewBox='0 0 20 20'%3E%3Cpath fill='%2304518c' fill-rule='evenodd' d='M13.81 10.952H6.19c-.523 0-.952-.428-.952-.952s.429-.952.952-.952h7.62c.523 0 .952.428.952.952s-.429.952-.952.952M10 0C4.476 0 0 4.476 0 10s4.476 10 10 10 10-4.476 10-10S15.524 0 10 0'/%3E%3C/svg%3E%0A"); + } + `, + fontColor: theme.colors.primary, + }, + RangeAgg: { + css: css` + &[data-fieldName='analysis.host.host_age'] .unit-wrapper { + display: none; + } + `, + RangeLabel: { + borderRadius: '0.2rem', + fontWeight: 'bold !important', + css: css` + ${theme.typography.label2} + background-color: ${theme.colors.grey_3}; + &:last-of-type, + &:nth-of-type(4) { + background-color: ${theme.colors.white}; + color: ${theme.colors.grey_6}; + } + `, + padding: '0 0.2rem', + }, + // slider is the button that you drag to select values + RangeSlider: { + borderColor: theme.colors.grey_5, + css: theme.shadow.default, + disabledBackground: theme.colors.grey_3, + }, + // the band upon which the sliders move + RangeTrack: { + disabledInBackground: theme.colors.grey_4, + disabledOutBackground: theme.colors.grey_3, + inBackground: theme.colors.primary_dark, + outBackground: theme.colors.grey_4, + }, + }, + TreeJointIcon: { + fill: theme.colors.primary_dark, + size: 8, + transition: 'all 0s', + }, + }, + QuickSearch: { + fieldNames: 'donors.specimens.submitter_specimen_id', + headerTitle: 'Specimen Collector Sample ID', + placeholder: 'e.g. AB-12345', + // components + DropDownItems: { + css: css` + border: 1px solid ${theme.colors.secondary}; + border-radius: 5px; + `, + entityLogo: { + enabled: false, + }, + resultKeyText: { + css: css` + margin-left: 20px; + font-weight: bold; + `, + }, + resultValue: { + css: css` + margin-left: 20px; + `, + }, + }, + QuickSearchWrapper: { + css: css` + .title { + ${theme.typography.subheading2} + line-height: 20px; + } + `, + }, + TreeJointIcon: { + fill: theme.colors.primary_dark, + size: 8, + transition: 'all 0s', + }, + PinnedValues: { + background: theme.colors.primary_dark, + css: css` + ${theme.typography.label} + &::after { + content: url(data:image/svg+xml,%3Csvg%20width%3D%228%22%20height%3D%228%22%20stroke%3D%22white%22%20stroke-width%3D%222%22%3E%0A%20%20%3Cline%20x1%3D%220%22%20y1%3D%220%22%20x2%3D%228%22%20y2%3D%228%22%20/%3E%0A%20%20%3Cline%20x1%3D%228%22%20y1%3D%220%22%20x2%3D%220%22%20y2%3D%228%22%20/%3E%0A%3C/svg%3E); + margin: 0 0 0 0.5rem; + } + `, + fontColor: theme.colors.white, + hoverBackground: theme.colors.primary, + margin: '0.1rem', + padding: '0 0.5rem', + }, + }, + }, +}); +const Facets = (): ReactElement => { + const { NEXT_PUBLIC_ENABLE_DATATABLE_1_QUICKSEARCH } = getConfig(); + const theme = useTheme(); + useArrangerTheme(getAggregationsStyles(theme)); + return ( +
    +

    + Filters +

    + {NEXT_PUBLIC_ENABLE_DATATABLE_1_QUICKSEARCH && } + +
    + ); +}; +export default Facets; diff --git a/apps/stage/components/pages/activeDataTables/dataTableOne/PageContent.tsx b/apps/stage/components/pages/activeDataTables/dataTableOne/PageContent.tsx new file mode 100644 index 00000000..5b4e3268 --- /dev/null +++ b/apps/stage/components/pages/activeDataTables/dataTableOne/PageContent.tsx @@ -0,0 +1,128 @@ +/* + * + * Copyright (c) 2024 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css, useTheme } from '@emotion/react'; +import { useArrangerData } from '@overture-stack/arranger-components'; +import { SQONType } from '@overture-stack/arranger-components/dist/DataContext/types.js'; +import stringify from 'fast-json-stable-stringify'; +import { isEqual } from 'lodash'; +import { useEffect, useMemo, useState } from 'react'; + +import useUrlParamState from '@/global/hooks/useUrlParamsState'; + +import Facets from './Facets'; +import QueryBar from './QueryBar'; +import RepoTable from './RepoTable'; + +const PageContent = () => { + const theme = useTheme(); + const [showSidebar, setShowSidebar] = useState(true); + const sidebarWidth = showSidebar ? theme.dimensions.facets.width : 0; + + // TODO: abstract this param handling into an Arranger integration. + const { sqon, setSQON } = useArrangerData({ callerName: 'DataTableOne-PageContent' }); + const [firstRender, setFirstRender] = useState(true); + const [currentFilters, setCurrentFilters] = useUrlParamState('filters', null, { + prepare: (v) => v.replace('"field"', '"fieldName"'), + deSerialize: (v) => { + return v ? JSON.parse(v) : null; + }, + serialize: (v) => (v ? stringify(v) : ''), + }); + + useEffect(() => { + if (firstRender) { + currentFilters && setSQON(currentFilters); + setFirstRender(false); + } + }, [currentFilters, firstRender, setSQON]); + + useEffect(() => { + firstRender || isEqual(sqon, currentFilters) || setCurrentFilters(sqon); + }, [currentFilters, firstRender, setCurrentFilters, sqon]); + + return useMemo( + () => ( +
    +
    + {/* WIP button to hide/show the sidebar + */} + + +
    +
    + + +
    +
    +
    +
    + ), + [], + ); +}; + +export default PageContent; diff --git a/apps/stage/components/pages/activeDataTables/dataTableOne/QueryBar.tsx b/apps/stage/components/pages/activeDataTables/dataTableOne/QueryBar.tsx new file mode 100644 index 00000000..4520e3dc --- /dev/null +++ b/apps/stage/components/pages/activeDataTables/dataTableOne/QueryBar.tsx @@ -0,0 +1,117 @@ +/* + * + * Copyright (c) 2024 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +import { StageThemeInterface } from '@/components/theme'; +import { css, useTheme } from '@emotion/react'; +import { SQONViewer, useArrangerTheme } from '@overture-stack/arranger-components'; +import { UseThemeContextProps } from '@overture-stack/arranger-components/dist/types'; +import { Row } from 'react-grid-system'; +const getThemeCustomisations = (theme: StageThemeInterface): UseThemeContextProps => ({ + callerName: 'DataSetOne-QueryBar', + components: { + SQONViewer: { + EmptyMessage: { + arrowColor: theme.colors.primary_dark, + }, + SQONBubble: { + borderRadius: '8px', + fontSize: '13px', + fontWeight: 300, + height: '1.6rem', + letterSpacing: '0.2px', + }, + SQONClear: { + label: 'Reset', + borderColor: theme.colors.grey_5, + borderRadius: '5px', + background: theme.colors.primary_dark, + cursor: 'pointer', + fontColor: theme.colors.white, + fontSize: '0.88rem', + fontWeight: 600, + hoverBackground: theme.colors.primary, + padding: '0 12px', + }, + SQONFieldName: { + fontWeight: 'normal', + textTransform: 'uppercase', + }, + SQONGroup: { + fontColor: theme.colors.grey_6, + margin: '0.1rem 0 0', + }, + SQONLessOrMore: { + background: theme.colors.primary_light, + css: css` + ${theme.typography.label}; + `, + fontColor: theme.colors.white, + hoverBackground: theme.colors.primary, + lineHeight: '1.4rem !important', + margin: '0 0.4rem 0 0', + padding: '0 0.4rem', + textTransform: 'uppercase', + }, + SQONValue: { + background: theme.colors.primary_dark, + css: css` + margin-left: 0; + ${theme.typography.label} + &::after { + content: url(data:image/svg+xml,%3Csvg%20width%3D%228%22%20height%3D%228%22%20stroke%3D%22white%22%20stroke-width%3D%222%22%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%3E%0A%20%20%3Cline%20x1%3D%220%22%20y1%3D%220%22%20x2%3D%228%22%20y2%3D%228%22%20/%3E%0A%20%20%3Cline%20x1%3D%228%22%20y1%3D%220%22%20x2%3D%220%22%20y2%3D%228%22%20/%3E%0A%3C/svg%3E); + margin: 0 0 0 0.5rem; + } + `, + fontColor: theme.colors.white, + hoverBackground: theme.colors.primary, + margin: '0.1rem 0.4rem', + padding: '0 0.5rem', + }, + SQONValueGroup: { + css: css` + &:last-of-type { + margin-left: 0; + } + `, + fontSize: '1.4rem', + margin: '-0.2rem 0.4rem 0', + }, + }, + }, +}); +const QueryBar = () => { + const theme = useTheme(); + useArrangerTheme(getThemeCustomisations(theme)); + return ( + css` + min-height: 48px; + margin: 10px 0; + background-color: ${theme.colors.white}; + border-radius: 5px; + ${theme.shadow.default}; + `} + > + + + ); +}; +export default QueryBar; diff --git a/apps/stage/components/pages/activeDataTables/dataTableOne/RepoTable/helper.ts b/apps/stage/components/pages/activeDataTables/dataTableOne/RepoTable/helper.ts new file mode 100644 index 00000000..39c682c1 --- /dev/null +++ b/apps/stage/components/pages/activeDataTables/dataTableOne/RepoTable/helper.ts @@ -0,0 +1,88 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import createArrangerFetcher from '@/components/utils/arrangerFetcher'; +import { INTERNAL_API_PROXY } from '@/global/utils/constants'; +import { SQONType } from '@overture-stack/arranger-components/dist/DataContext/types'; +import SQON from '@overture-stack/sqon-builder'; +import { isEmpty } from 'lodash'; + +export const arrangerFetcher = createArrangerFetcher({ + ARRANGER_API: INTERNAL_API_PROXY.DATATABLE_1_ARRANGER, +}); + +const saveSetMutation = `mutation ($sqon: JSON!) { + saveSet( + sqon: $sqon, + type: file, + path: "name" + ) { + setId + } +}`; + +export const saveSet = (sqon: SQONType): Promise => { + return arrangerFetcher({ + body: { + query: saveSetMutation, + variables: { sqon }, + }, + }) + .then( + ({ + data: { + saveSet: { setId }, + }, + }) => { + return setId; + }, + ) + .catch((err: Error) => { + console.warn(err); + return Promise.reject(err); + }); +}; + +// Type guard to check if SQON is not null +function isSQON(sqon: SQONType | null): sqon is SQONType { + return sqon !== null && !isEmpty(sqon); +} + +export function buildSqonWithObjectIds(currentSqon: SQONType, objectIds: string[]): SQONType { + // Create object ID SQON only if we have IDs + let objectsSqon: SQONType | null = null; + if (objectIds.length > 0) { + const builder = SQON.in('object_id', objectIds); + objectsSqon = builder.toValue() as unknown as SQONType; + } + + // If both SQONs are valid, combine them + if (isSQON(currentSqon) && isSQON(objectsSqon)) { + const sqonArray = [currentSqon, objectsSqon].map((sqon) => sqon as any); + const builder = SQON.and(sqonArray); + return builder.toValue() as unknown as SQONType; + } + + // Return whichever SQON is valid, or null if neither is + if (isSQON(currentSqon)) return currentSqon; + if (isSQON(objectsSqon)) return objectsSqon; + return null; +} diff --git a/apps/stage/components/pages/activeDataTables/dataTableOne/RepoTable/index.tsx b/apps/stage/components/pages/activeDataTables/dataTableOne/RepoTable/index.tsx new file mode 100644 index 00000000..773b2c41 --- /dev/null +++ b/apps/stage/components/pages/activeDataTables/dataTableOne/RepoTable/index.tsx @@ -0,0 +1,193 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING INs + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css, useTheme } from '@emotion/react'; +import { + Pagination, + Table, + TableContextProvider, + Toolbar, + useArrangerTheme, +} from '@overture-stack/arranger-components'; +import { CustomExporterInput } from '@overture-stack/arranger-components/dist/Table/DownloadButton/types'; +import { UseThemeContextProps } from '@overture-stack/arranger-components/dist/ThemeContext/types'; +import { useMemo } from 'react'; +import urlJoin from 'url-join'; + +import { StageThemeInterface } from '@/components/theme'; +import { Download } from '@/components/theme/icons'; +import { INTERNAL_API_PROXY } from '@/global/utils/constants'; + +const getTableConfigs = ({ + apiHost, + customExporters, + theme, +}: { + apiHost: string; + customExporters?: CustomExporterInput; + theme: StageThemeInterface; +}): UseThemeContextProps => ({ + callerName: 'RepoTable', + components: { + Table: { + // functionality + hideLoader: true, + + // appearance + background: theme.colors.white, + borderColor: theme.colors.grey_5, // Updated from grey_3 to grey_5 for more contrast + css: css` + ${theme.shadow.default} + `, + + // Child components + columnTypes: { + all: { + cellValue: ({ getValue }) => { + const value = getValue(); + return ['', null, 'null', 'NA', undefined, 'undefined'].includes(value) ? ( + + -- + + ) : ( + value + ); + }, + }, + }, + CountDisplay: { + fontColor: 'inherit', + }, + DownloadButton: { + customExporters, + exportSelectedRowsField: 'submission_metadata.submitter_id', + downloadUrl: urlJoin(apiHost, 'download'), + label: () => ( + <> + path { + fill: ${theme.colors.grey_5}; + } + `} + />{' '} + Download + + ), + ListWrapper: { + width: '11rem', + }, + }, + DropDown: { + arrowColor: '#151c3d', + arrowTransition: 'all 0s', + background: theme.colors.white, + borderColor: theme.colors.grey_5, + css: css` + ${theme.typography.subheading2} + line-height: 1.3rem; + `, + fontColor: theme.colors.accent_dark, + disabledFontColor: theme.colors.grey_5, + hoverBackground: theme.colors.secondary_light, + + ListWrapper: { + background: theme.colors.white, + css: css` + ${theme.shadow.default} + `, + fontColor: theme.colors.black, + fontSize: '0.7rem', + hoverBackground: theme.colors.secondary_light, + }, + }, + HeaderRow: { + borderColor: theme.colors.grey_5, // Updated from grey_3 to grey_5 for more contrast + css: css` + ${theme.typography.data} + `, + fontColor: theme.colors.accent_dark, + fontSize: '13px', + fontWeight: 'bold', + lineHeight: '1.7rem', + }, + MaxRowsSelector: { + fontColor: 'inherit', + }, + Row: { + css: css` + &:nth-of-type(2n-1) { + background-color: ${theme.colors.grey_1}; + } + `, + hoverBackground: theme.colors.grey_highlight, + lineHeight: '1.5rem', + selectedBackground: theme.colors.accent_highlight, + verticalBorderColor: theme.colors.grey_5, // Updated from grey_3 to grey_5 for more contrast + }, + TableWrapper: { + margin: '0.5rem 0', + }, + }, + }, +}); + +const RepoTable = () => { + const theme = useTheme(); + const today = new Date().toISOString().slice(0, 10).replace(/-/g, ''); + const customExporters = [ + { label: 'Download', fileName: `dataset-2-data-export.${today}.tsv` }, // exports a TSV with what is displayed on the table (columns selected, etc.) + ]; + + useArrangerTheme(getTableConfigs({ apiHost: INTERNAL_API_PROXY.DATATABLE_1_ARRANGER, customExporters, theme })); + + return useMemo( + () => ( + <> +
    + + +
    + + + + + ), + [], + ); +}; + +export default RepoTable; diff --git a/apps/stage/components/pages/activeDataTables/dataTableOne/getConfigError.tsx b/apps/stage/components/pages/activeDataTables/dataTableOne/getConfigError.tsx new file mode 100644 index 00000000..1f8912ff --- /dev/null +++ b/apps/stage/components/pages/activeDataTables/dataTableOne/getConfigError.tsx @@ -0,0 +1,125 @@ +/* + * + * Copyright (c) 2024 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +import StyledLink from '@/components/Link'; +import { GenericHelpMessage } from '@/components/PlatformAdminContact'; +import { Checkmark, Warning } from '@/components/theme/icons'; +import { getConfig } from '@/global/config'; +import { css, useTheme } from '@emotion/react'; +import { ReactNode } from 'react'; +const ArrangerAdminUILink = () => { + const { NEXT_PUBLIC_ARRANGER_DATATABLE_1_ADMIN_UI } = getConfig(); + return ( + + Arranger Admin UI + + ); +}; +const ListItem = ({ Icon, value, fieldName }: { Icon?: ReactNode; value: string; fieldName: string }) => { + const theme = useTheme(); + return ( +
  • + {Icon || } + + {fieldName}:{' '} + + {value} + + +
  • + ); +}; +const WarningListItem = ({ fieldName }: { fieldName: string }) => ( + } fieldName={fieldName} value={'Missing'} /> +); +const getConfigError = ({ + hasConfig, + documentType, + index, +}: { + hasConfig: boolean; + documentType: string; + index: string; +}) => + index && documentType ? ( + !hasConfig && ( + + No active configurations for the DMS portal were found. Please make sure the index and GraphQL document type + specified in the DMS{' '} + + config.yaml + {' '} + file during installation have been created in the . + + ) + ) : ( + + One or more of the following values required by the DMS portal do not exist. Please make sure the values are + specified in the DMS{' '} + + config.yaml + {' '} + file during installation and have been used to create your project in the .{' '} + +
      + {[ + { fieldName: 'GraphQL Document type', value: documentType }, + { fieldName: 'Elasticsearch index', value: index }, + ].map(({ fieldName, value }) => { + return value ? ( + + ) : ( + + ); + })} +
    +
    + ); +export default getConfigError; diff --git a/apps/stage/components/pages/activeDataTables/dataTableOne/index.tsx b/apps/stage/components/pages/activeDataTables/dataTableOne/index.tsx new file mode 100644 index 00000000..88d46020 --- /dev/null +++ b/apps/stage/components/pages/activeDataTables/dataTableOne/index.tsx @@ -0,0 +1,175 @@ +/* + * + * Copyright (c) 2024 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css, useTheme } from '@emotion/react'; +import { ArrangerDataProvider } from '@overture-stack/arranger-components'; +import { ReactElement, useEffect, useState } from 'react'; + +import ErrorNotification from '@/components/ErrorNotification'; +import Loader from '@/components/Loader'; +import PageLayout from '@/components/PageLayout'; +import sleep from '@/components/utils/sleep'; +import { getConfig } from '@/global/config'; +import { RepoFiltersType } from '@/global/types/sqon'; + +import getConfigError from './getConfigError'; +import PageContent from './PageContent'; +import { arrangerFetcher } from './RepoTable/helper'; + +export interface PageContentProps { + sqon: RepoFiltersType; + selectedTableRows: string[]; + setSelectedTableRows: (ids: []) => void; + index: string; + api: ({ + endpoint, + body, + headers, + method, + }: { + endpoint: string; + body: string; + headers: any; + method: string; + }) => Promise; + setSQON: (sqon: RepoFiltersType) => void; + fetchData?: () => Promise; +} + +const { + NEXT_PUBLIC_ARRANGER_DATATABLE_1_API, + NEXT_PUBLIC_ARRANGER_DATATABLE_1_DOCUMENT_TYPE, + NEXT_PUBLIC_ARRANGER_DATATABLE_1_INDEX, +} = getConfig(); + +const configsQuery = ` + query ($documentType: String!, $index: String!) { + hasValidConfig (documentType: $documentType, index: $index) + } +`; + +const DataSetOneRepositoryPage = (): ReactElement => { + const theme = useTheme(); + const [arrangerHasConfig, setArrangerHasConfig] = useState(false); + const [loadingArrangerConfig, setLoadingArrangerConfig] = useState(true); + + useEffect(() => { + arrangerFetcher({ + endpoint: 'graphql/hasValidConfig', + body: JSON.stringify({ + variables: { + documentType: NEXT_PUBLIC_ARRANGER_DATATABLE_1_DOCUMENT_TYPE, + index: NEXT_PUBLIC_ARRANGER_DATATABLE_1_INDEX, + }, + query: configsQuery, + }), + }) + .then(async ({ data } = {}) => { + if (data?.hasValidConfig) { + await setArrangerHasConfig(data.hasValidConfig); + // 1s delay so loader doesn't flicker on and off too quickly + await sleep(1000); + + return setLoadingArrangerConfig(false); + } + + throw new Error('Could not validate Arranger Dataset1 server configuration!'); + }) + .catch(async (err) => { + console.warn(err); + // same as above comment + await sleep(1000); + setLoadingArrangerConfig(false); + }); + }, []); + + const ConfigError = getConfigError({ + hasConfig: arrangerHasConfig, + index: NEXT_PUBLIC_ARRANGER_DATATABLE_1_INDEX, + documentType: NEXT_PUBLIC_ARRANGER_DATATABLE_1_DOCUMENT_TYPE, + }); + + return ( + + {loadingArrangerConfig ? ( +
    + +
    + ) : ConfigError ? ( +
    +
    + + {ConfigError} + +
    +
    + ) : ( + + + + )} +
    + ); +}; + +export default DataSetOneRepositoryPage; diff --git a/apps/stage/components/pages/activeDataTables/dataTableTwo/Facets.tsx b/apps/stage/components/pages/activeDataTables/dataTableTwo/Facets.tsx new file mode 100644 index 00000000..7b9f970d --- /dev/null +++ b/apps/stage/components/pages/activeDataTables/dataTableTwo/Facets.tsx @@ -0,0 +1,240 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +import { StageThemeInterface } from '@/components/theme'; +import { getConfig } from '@/global/config'; +import { css, useTheme } from '@emotion/react'; +import { Aggregations, QuickSearch, useArrangerTheme } from '@overture-stack/arranger-components'; +import { UseThemeContextProps } from '@overture-stack/arranger-components/dist/types'; +import { ReactElement } from 'react'; + +const getAggregationsStyles = (theme: StageThemeInterface): UseThemeContextProps => ({ + callerName: 'Data-Table-1-Facets', + components: { + Aggregations: { + ActionIcon: { + fill: theme.colors.secondary, + }, + AggsGroup: { + collapsedBackground: theme.colors.grey_2, + css: css` + .title { + ${theme.typography.subheading2} + line-height: 20px; + } + // Leaving these toggle-button styles untouch as I haven't been able to test making changes + .toggle-button { + ${theme.typography.data}; + padding: 2px 5px 8px 5px; + margin-left: 5px; + .toggle-button-option { + border: 1px solid ${theme.colors.grey_5}; + &:nth-of-type(2) { + border-left: 0px; + border-right: 0px; + } + } + .toggle-button-option .bucket-count { + ${theme.typography.label2} + display: inline-block; + background-color: ${theme.colors.grey_3}; + padding: 0 3px; + border-radius: 3px; + } + .toggle-button-option.active { + background-color: ${theme.colors.secondary_light}; + .bucket-count { + background-color: ${theme.colors.secondary_2}; + } + } + .toggle-button-option.disabled { + background-color: ${theme.colors.grey_2}; + color: ${theme.colors.grey_6}; + } + } + `, + groupDividerColor: theme.colors.grey_3, + headerBackground: theme.colors.white, + headerDividerColor: theme.colors.grey_2, + headerFontColor: theme.colors.accent_dark, + }, + BucketCount: { + background: `rgba(${theme.colors.accent_light_rgb}, 0.45)`, + fontSize: '0.75rem', + }, + FilterInput: { + css: css` + border-radius: 5px; + border: 1px solid ${theme.colors.secondary}; + margin: 6px 5px 7px 0; + &.focused { + box-shadow: inset 0 0 2px 1px ${theme.colors.accent}; + } + & input { + ${theme.typography.data} + &::placeholder { + color: ${theme.colors.black}; + } + } + input[type='text' i] { + margin-left: 5px; + margin-top: 2px; + } + `, + }, + MoreOrLessButton: { + css: css` + ${theme.typography.label2}; + &::before { + padding-top: 3px; + margin-right: 3px; + } + &.more::before { + content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='11' viewBox='0 0 11 11'%3E%3Cpath fill='%2304518C' fill-rule='evenodd' d='M7.637 6.029H6.034v1.613c0 .291-.24.53-.534.53-.294 0-.534-.239-.534-.53V6.03H3.363c-.294 0-.534-.238-.534-.529 0-.29.24-.529.534-.529h1.603V3.358c0-.291.24-.53.534-.53.294 0 .534.239.534.53V4.97h1.603c.294 0 .534.238.534.529 0 .29-.24.529-.534.529M5.5 0C2.462 0 0 2.462 0 5.5S2.462 11 5.5 11 11 8.538 11 5.5 8.538 0 5.5 0'/%3E%3C/svg%3E%0A"); + } + &.less::before { + content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='11' viewBox='0 0 20 20'%3E%3Cpath fill='%2304518c' fill-rule='evenodd' d='M13.81 10.952H6.19c-.523 0-.952-.428-.952-.952s.429-.952.952-.952h7.62c.523 0 .952.428.952.952s-.429.952-.952.952M10 0C4.476 0 0 4.476 0 10s4.476 10 10 10 10-4.476 10-10S15.524 0 10 0'/%3E%3C/svg%3E%0A"); + } + `, + fontColor: theme.colors.primary, + }, + RangeAgg: { + css: css` + &[data-fieldName='analysis.host.host_age'] .unit-wrapper { + display: none; + } + `, + RangeLabel: { + borderRadius: '0.2rem', + fontWeight: 'bold !important', + css: css` + ${theme.typography.label2} + background-color: ${theme.colors.grey_3}; + &:last-of-type, + &:nth-of-type(4) { + background-color: ${theme.colors.white}; + color: ${theme.colors.grey_6}; + } + `, + padding: '0 0.2rem', + }, + // slider is the button that you drag to select values + RangeSlider: { + borderColor: theme.colors.grey_5, + css: theme.shadow.default, + disabledBackground: theme.colors.grey_3, + }, + // the band upon which the sliders move + RangeTrack: { + disabledInBackground: theme.colors.grey_4, + disabledOutBackground: theme.colors.grey_3, + inBackground: theme.colors.primary_dark, + outBackground: theme.colors.grey_4, + }, + }, + TreeJointIcon: { + fill: theme.colors.primary_dark, + size: 8, + transition: 'all 0s', + }, + }, + QuickSearch: { + fieldNames: 'donors.specimens.submitter_specimen_id', + headerTitle: 'Specimen Collector Sample ID', + placeholder: 'e.g. AB-12345', + // components + DropDownItems: { + css: css` + border: 1px solid ${theme.colors.secondary}; + border-radius: 5px; + `, + entityLogo: { + enabled: false, + }, + resultKeyText: { + css: css` + margin-left: 20px; + font-weight: bold; + `, + }, + resultValue: { + css: css` + margin-left: 20px; + `, + }, + }, + QuickSearchWrapper: { + css: css` + .title { + ${theme.typography.subheading2} + line-height: 20px; + } + `, + }, + TreeJointIcon: { + fill: theme.colors.primary_dark, + size: 8, + transition: 'all 0s', + }, + PinnedValues: { + background: theme.colors.primary_dark, + css: css` + ${theme.typography.label} + &::after { + content: url(data:image/svg+xml,%3Csvg%20width%3D%228%22%20height%3D%228%22%20stroke%3D%22white%22%20stroke-width%3D%222%22%3E%0A%20%20%3Cline%20x1%3D%220%22%20y1%3D%220%22%20x2%3D%228%22%20y2%3D%228%22%20/%3E%0A%20%20%3Cline%20x1%3D%228%22%20y1%3D%220%22%20x2%3D%220%22%20y2%3D%228%22%20/%3E%0A%3C/svg%3E); + margin: 0 0 0 0.5rem; + } + `, + fontColor: theme.colors.white, + hoverBackground: theme.colors.primary, + margin: '0.1rem', + padding: '0 0.5rem', + }, + }, + }, +}); +const Facets = (): ReactElement => { + const { NEXT_PUBLIC_ENABLE_DATATABLE_2_QUICKSEARCH } = getConfig(); + const theme = useTheme(); + useArrangerTheme(getAggregationsStyles(theme)); + return ( +
    +

    + Filters +

    + {NEXT_PUBLIC_ENABLE_DATATABLE_2_QUICKSEARCH && } + +
    + ); +}; +export default Facets; diff --git a/apps/stage/components/pages/activeDataTables/dataTableTwo/PageContent.tsx b/apps/stage/components/pages/activeDataTables/dataTableTwo/PageContent.tsx new file mode 100644 index 00000000..44d9d38b --- /dev/null +++ b/apps/stage/components/pages/activeDataTables/dataTableTwo/PageContent.tsx @@ -0,0 +1,128 @@ +/* + * + * Copyright (c) 2024 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css, useTheme } from '@emotion/react'; +import { useArrangerData } from '@overture-stack/arranger-components'; +import { SQONType } from '@overture-stack/arranger-components/dist/DataContext/types.js'; +import stringify from 'fast-json-stable-stringify'; +import { isEqual } from 'lodash'; +import { useEffect, useMemo, useState } from 'react'; + +import useUrlParamState from '@/global/hooks/useUrlParamsState'; + +import Facets from './Facets'; +import QueryBar from './QueryBar'; +import RepoTable from './RepoTable'; + +const PageContent = () => { + const theme = useTheme(); + const [showSidebar, setShowSidebar] = useState(true); + const sidebarWidth = showSidebar ? theme.dimensions.facets.width : 0; + + // TODO: abstract this param handling into an Arranger integration. + const { sqon, setSQON } = useArrangerData({ callerName: 'DataTableTwo-PageContent' }); + const [firstRender, setFirstRender] = useState(true); + const [currentFilters, setCurrentFilters] = useUrlParamState('filters', null, { + prepare: (v) => v.replace('"field"', '"fieldName"'), + deSerialize: (v) => { + return v ? JSON.parse(v) : null; + }, + serialize: (v) => (v ? stringify(v) : ''), + }); + + useEffect(() => { + if (firstRender) { + currentFilters && setSQON(currentFilters); + setFirstRender(false); + } + }, [currentFilters, firstRender, setSQON]); + + useEffect(() => { + firstRender || isEqual(sqon, currentFilters) || setCurrentFilters(sqon); + }, [currentFilters, firstRender, setCurrentFilters, sqon]); + + return useMemo( + () => ( +
    +
    + {/* WIP button to hide/show the sidebar + */} + + +
    +
    + + +
    +
    +
    +
    + ), + [], + ); +}; + +export default PageContent; diff --git a/apps/stage/components/pages/activeDataTables/dataTableTwo/QueryBar.tsx b/apps/stage/components/pages/activeDataTables/dataTableTwo/QueryBar.tsx new file mode 100644 index 00000000..4520e3dc --- /dev/null +++ b/apps/stage/components/pages/activeDataTables/dataTableTwo/QueryBar.tsx @@ -0,0 +1,117 @@ +/* + * + * Copyright (c) 2024 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +import { StageThemeInterface } from '@/components/theme'; +import { css, useTheme } from '@emotion/react'; +import { SQONViewer, useArrangerTheme } from '@overture-stack/arranger-components'; +import { UseThemeContextProps } from '@overture-stack/arranger-components/dist/types'; +import { Row } from 'react-grid-system'; +const getThemeCustomisations = (theme: StageThemeInterface): UseThemeContextProps => ({ + callerName: 'DataSetOne-QueryBar', + components: { + SQONViewer: { + EmptyMessage: { + arrowColor: theme.colors.primary_dark, + }, + SQONBubble: { + borderRadius: '8px', + fontSize: '13px', + fontWeight: 300, + height: '1.6rem', + letterSpacing: '0.2px', + }, + SQONClear: { + label: 'Reset', + borderColor: theme.colors.grey_5, + borderRadius: '5px', + background: theme.colors.primary_dark, + cursor: 'pointer', + fontColor: theme.colors.white, + fontSize: '0.88rem', + fontWeight: 600, + hoverBackground: theme.colors.primary, + padding: '0 12px', + }, + SQONFieldName: { + fontWeight: 'normal', + textTransform: 'uppercase', + }, + SQONGroup: { + fontColor: theme.colors.grey_6, + margin: '0.1rem 0 0', + }, + SQONLessOrMore: { + background: theme.colors.primary_light, + css: css` + ${theme.typography.label}; + `, + fontColor: theme.colors.white, + hoverBackground: theme.colors.primary, + lineHeight: '1.4rem !important', + margin: '0 0.4rem 0 0', + padding: '0 0.4rem', + textTransform: 'uppercase', + }, + SQONValue: { + background: theme.colors.primary_dark, + css: css` + margin-left: 0; + ${theme.typography.label} + &::after { + content: url(data:image/svg+xml,%3Csvg%20width%3D%228%22%20height%3D%228%22%20stroke%3D%22white%22%20stroke-width%3D%222%22%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%3E%0A%20%20%3Cline%20x1%3D%220%22%20y1%3D%220%22%20x2%3D%228%22%20y2%3D%228%22%20/%3E%0A%20%20%3Cline%20x1%3D%228%22%20y1%3D%220%22%20x2%3D%220%22%20y2%3D%228%22%20/%3E%0A%3C/svg%3E); + margin: 0 0 0 0.5rem; + } + `, + fontColor: theme.colors.white, + hoverBackground: theme.colors.primary, + margin: '0.1rem 0.4rem', + padding: '0 0.5rem', + }, + SQONValueGroup: { + css: css` + &:last-of-type { + margin-left: 0; + } + `, + fontSize: '1.4rem', + margin: '-0.2rem 0.4rem 0', + }, + }, + }, +}); +const QueryBar = () => { + const theme = useTheme(); + useArrangerTheme(getThemeCustomisations(theme)); + return ( + css` + min-height: 48px; + margin: 10px 0; + background-color: ${theme.colors.white}; + border-radius: 5px; + ${theme.shadow.default}; + `} + > + + + ); +}; +export default QueryBar; diff --git a/apps/stage/components/pages/activeDataTables/dataTableTwo/RepoTable/helper.ts b/apps/stage/components/pages/activeDataTables/dataTableTwo/RepoTable/helper.ts new file mode 100644 index 00000000..7920377a --- /dev/null +++ b/apps/stage/components/pages/activeDataTables/dataTableTwo/RepoTable/helper.ts @@ -0,0 +1,88 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import createArrangerFetcher from '@/components/utils/arrangerFetcher'; +import { INTERNAL_API_PROXY } from '@/global/utils/constants'; +import { SQONType } from '@overture-stack/arranger-components/dist/DataContext/types'; +import SQON from '@overture-stack/sqon-builder'; +import { isEmpty } from 'lodash'; + +export const arrangerFetcher = createArrangerFetcher({ + ARRANGER_API: INTERNAL_API_PROXY.DATATABLE_2_ARRANGER, +}); + +const saveSetMutation = `mutation ($sqon: JSON!) { + saveSet( + sqon: $sqon, + type: file, + path: "name" + ) { + setId + } +}`; + +export const saveSet = (sqon: SQONType): Promise => { + return arrangerFetcher({ + body: { + query: saveSetMutation, + variables: { sqon }, + }, + }) + .then( + ({ + data: { + saveSet: { setId }, + }, + }) => { + return setId; + }, + ) + .catch((err: Error) => { + console.warn(err); + return Promise.reject(err); + }); +}; + +// Type guard to check if SQON is not null +function isSQON(sqon: SQONType | null): sqon is SQONType { + return sqon !== null && !isEmpty(sqon); +} + +export function buildSqonWithObjectIds(currentSqon: SQONType, objectIds: string[]): SQONType { + // Create object ID SQON only if we have IDs + let objectsSqon: SQONType | null = null; + if (objectIds.length > 0) { + const builder = SQON.in('object_id', objectIds); + objectsSqon = builder.toValue() as unknown as SQONType; + } + + // If both SQONs are valid, combine them + if (isSQON(currentSqon) && isSQON(objectsSqon)) { + const sqonArray = [currentSqon, objectsSqon].map((sqon) => sqon as any); + const builder = SQON.and(sqonArray); + return builder.toValue() as unknown as SQONType; + } + + // Return whichever SQON is valid, or null if neither is + if (isSQON(currentSqon)) return currentSqon; + if (isSQON(objectsSqon)) return objectsSqon; + return null; +} diff --git a/apps/stage/components/pages/activeDataTables/dataTableTwo/RepoTable/index.tsx b/apps/stage/components/pages/activeDataTables/dataTableTwo/RepoTable/index.tsx new file mode 100644 index 00000000..7ea42d67 --- /dev/null +++ b/apps/stage/components/pages/activeDataTables/dataTableTwo/RepoTable/index.tsx @@ -0,0 +1,193 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css, useTheme } from '@emotion/react'; +import { + Pagination, + Table, + TableContextProvider, + Toolbar, + useArrangerTheme, +} from '@overture-stack/arranger-components'; +import { CustomExporterInput } from '@overture-stack/arranger-components/dist/Table/DownloadButton/types'; +import { UseThemeContextProps } from '@overture-stack/arranger-components/dist/ThemeContext/types'; +import { useMemo } from 'react'; +import urlJoin from 'url-join'; + +import { StageThemeInterface } from '@/components/theme'; +import { Download } from '@/components/theme/icons'; +import { INTERNAL_API_PROXY } from '@/global/utils/constants'; + +const getTableConfigs = ({ + apiHost, + customExporters, + theme, +}: { + apiHost: string; + customExporters?: CustomExporterInput; + theme: StageThemeInterface; +}): UseThemeContextProps => ({ + callerName: 'RepoTable', + components: { + Table: { + // functionality + hideLoader: true, + + // appearance + background: theme.colors.white, + borderColor: theme.colors.grey_5, // Updated from grey_3 to grey_5 for more contrast + css: css` + ${theme.shadow.default} + `, + + // Child components + columnTypes: { + all: { + cellValue: ({ getValue }) => { + const value = getValue(); + return ['', null, 'null', 'NA', undefined, 'undefined'].includes(value) ? ( + + -- + + ) : ( + value + ); + }, + }, + }, + CountDisplay: { + fontColor: 'inherit', + }, + DownloadButton: { + customExporters, + exportSelectedRowsField: 'submission_metadata.submitter_id', + downloadUrl: urlJoin(apiHost, 'download'), + label: () => ( + <> + path { + fill: ${theme.colors.grey_5}; + } + `} + />{' '} + Download + + ), + ListWrapper: { + width: '11rem', + }, + }, + DropDown: { + arrowColor: '#151c3d', + arrowTransition: 'all 0s', + background: theme.colors.white, + borderColor: theme.colors.grey_5, + css: css` + ${theme.typography.subheading2} + line-height: 1.3rem; + `, + fontColor: theme.colors.accent_dark, + disabledFontColor: theme.colors.grey_5, + hoverBackground: theme.colors.secondary_light, + + ListWrapper: { + background: theme.colors.white, + css: css` + ${theme.shadow.default} + `, + fontColor: theme.colors.black, + fontSize: '0.7rem', + hoverBackground: theme.colors.secondary_light, + }, + }, + HeaderRow: { + borderColor: theme.colors.grey_5, // Updated from grey_3 to grey_5 for more contrast + css: css` + ${theme.typography.data} + `, + fontColor: theme.colors.accent_dark, + fontSize: '13px', + fontWeight: 'bold', + lineHeight: '1.7rem', + }, + MaxRowsSelector: { + fontColor: 'inherit', + }, + Row: { + css: css` + &:nth-of-type(2n-1) { + background-color: ${theme.colors.grey_1}; + } + `, + hoverBackground: theme.colors.grey_highlight, + lineHeight: '1.5rem', + selectedBackground: theme.colors.accent_highlight, + verticalBorderColor: theme.colors.grey_5, // Updated from grey_3 to grey_5 for more contrast + }, + TableWrapper: { + margin: '0.5rem 0', + }, + }, + }, +}); + +const RepoTable = () => { + const theme = useTheme(); + const today = new Date().toISOString().slice(0, 10).replace(/-/g, ''); + const customExporters = [ + { label: 'Download', fileName: `dataset-2-data-export.${today}.tsv` }, // exports a TSV with what is displayed on the table (columns selected, etc.) + ]; + + useArrangerTheme(getTableConfigs({ apiHost: INTERNAL_API_PROXY.DATATABLE_2_ARRANGER, customExporters, theme })); + + return useMemo( + () => ( + <> +
    + + +
    + + + + + ), + [], + ); +}; + +export default RepoTable; diff --git a/apps/stage/components/pages/activeDataTables/dataTableTwo/getConfigError.tsx b/apps/stage/components/pages/activeDataTables/dataTableTwo/getConfigError.tsx new file mode 100644 index 00000000..56bb9c04 --- /dev/null +++ b/apps/stage/components/pages/activeDataTables/dataTableTwo/getConfigError.tsx @@ -0,0 +1,155 @@ +/* + * + * Copyright (c) 2024 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +import StyledLink from '@/components/Link'; +import { GenericHelpMessage } from '@/components/PlatformAdminContact'; +import { Checkmark } from '@/components/theme/icons'; +import { getConfig } from '@/global/config'; +import { css, useTheme } from '@emotion/react'; +import { ReactNode } from 'react'; + +const ArrangerAdminUILink = () => { + const { NEXT_PUBLIC_ARRANGER_DATATABLE_1_ADMIN_UI } = getConfig(); + return ( + + Arranger Admin UI + + ); +}; + +const ListItem = ({ Icon, value, fieldName }: { Icon?: ReactNode; value: string; fieldName: string }) => { + const theme = useTheme(); + return ( +
  • + {Icon || } + + {fieldName}:{' '} + + {value} + + +
  • + ); +}; + +// Modified WarningListItem to not use the Warning icon +const WarningListItem = ({ fieldName }: { fieldName: string }) => { + const theme = useTheme(); + return ( +
  • + + {fieldName}:{' '} + + Missing + + +
  • + ); +}; + +const getConfigError = ({ + hasConfig, + documentType, + index, +}: { + hasConfig: boolean; + documentType: string; + index: string; +}) => + index && documentType ? ( + !hasConfig && ( + + No active configurations for the DMS portal were found. Please make sure the index and GraphQL document type + specified in the DMS{' '} + + config.yaml + {' '} + file during installation have been created in the . + + ) + ) : ( + + One or more of the following values required by the DMS portal do not exist. Please make sure the values are + specified in the DMS{' '} + + config.yaml + {' '} + file during installation and have been used to create your project in the .{' '} + +
      + {[ + { fieldName: 'GraphQL Document type', value: documentType }, + { fieldName: 'Elasticsearch index', value: index }, + ].map(({ fieldName, value }) => { + return value ? ( + + ) : ( + + ); + })} +
    +
    + ); + +export default getConfigError; diff --git a/apps/stage/components/pages/activeDataTables/dataTableTwo/index.tsx b/apps/stage/components/pages/activeDataTables/dataTableTwo/index.tsx new file mode 100644 index 00000000..2fd0d0d9 --- /dev/null +++ b/apps/stage/components/pages/activeDataTables/dataTableTwo/index.tsx @@ -0,0 +1,175 @@ +/* + * + * Copyright (c) 2024 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css, useTheme } from '@emotion/react'; +import { ArrangerDataProvider } from '@overture-stack/arranger-components'; +import { ReactElement, useEffect, useState } from 'react'; + +import ErrorNotification from '@/components/ErrorNotification'; +import Loader from '@/components/Loader'; +import PageLayout from '@/components/PageLayout'; +import sleep from '@/components/utils/sleep'; +import { getConfig } from '@/global/config'; +import { RepoFiltersType } from '@/global/types/sqon'; + +import getConfigError from './getConfigError'; +import PageContent from './PageContent'; +import { arrangerFetcher } from './RepoTable/helper'; + +export interface PageContentProps { + sqon: RepoFiltersType; + selectedTableRows: string[]; + setSelectedTableRows: (ids: []) => void; + index: string; + api: ({ + endpoint, + body, + headers, + method, + }: { + endpoint: string; + body: string; + headers: any; + method: string; + }) => Promise; + setSQON: (sqon: RepoFiltersType) => void; + fetchData?: () => Promise; +} + +const { + NEXT_PUBLIC_ARRANGER_DATATABLE_2_API, + NEXT_PUBLIC_ARRANGER_DATATABLE_2_DOCUMENT_TYPE, + NEXT_PUBLIC_ARRANGER_DATATABLE_2_INDEX, +} = getConfig(); + +const configsQuery = ` + query ($documentType: String!, $index: String!) { + hasValidConfig (documentType: $documentType, index: $index) + } +`; + +const DataSetTwoRepositoryPage = (): ReactElement => { + const theme = useTheme(); + const [arrangerHasConfig, setArrangerHasConfig] = useState(false); + const [loadingArrangerConfig, setLoadingArrangerConfig] = useState(true); + + useEffect(() => { + arrangerFetcher({ + endpoint: 'graphql/hasValidConfig', + body: JSON.stringify({ + variables: { + documentType: NEXT_PUBLIC_ARRANGER_DATATABLE_2_DOCUMENT_TYPE, + index: NEXT_PUBLIC_ARRANGER_DATATABLE_2_INDEX, + }, + query: configsQuery, + }), + }) + .then(async ({ data } = {}) => { + if (data?.hasValidConfig) { + await setArrangerHasConfig(data.hasValidConfig); + // 1s delay so loader doesn't flicker on and off too quickly + await sleep(1000); + + return setLoadingArrangerConfig(false); + } + + throw new Error('Could not validate Arranger Dataset2 server configuration!'); + }) + .catch(async (err) => { + console.warn(err); + // same as above comment + await sleep(1000); + setLoadingArrangerConfig(false); + }); + }, []); + + const ConfigError = getConfigError({ + hasConfig: arrangerHasConfig, + index: NEXT_PUBLIC_ARRANGER_DATATABLE_2_INDEX, + documentType: NEXT_PUBLIC_ARRANGER_DATATABLE_2_DOCUMENT_TYPE, + }); + + return ( + + {loadingArrangerConfig ? ( +
    + +
    + ) : ConfigError ? ( +
    +
    + + {ConfigError} + +
    +
    + ) : ( + + + + )} +
    + ); +}; + +export default DataSetTwoRepositoryPage; diff --git a/apps/stage/components/pages/documentation/DocContainer/DocsContainer.tsx b/apps/stage/components/pages/documentation/DocContainer/DocsContainer.tsx new file mode 100644 index 00000000..c3520d18 --- /dev/null +++ b/apps/stage/components/pages/documentation/DocContainer/DocsContainer.tsx @@ -0,0 +1,482 @@ +// DocsContainer/DocsContainer.tsx +/** @jsxImportSource @emotion/react */ +import { marked } from 'marked'; +import { useCallback, useEffect, useRef, useState } from 'react'; +import styles from './styles'; +import { Section } from './types'; +import { extractHeadings, extractOrder, extractTitle, generateId, renderMarkdown } from './utils/markdown'; +import { updateActiveHash } from './utils/navigation'; + +// Add props interface with heroHeight +interface DocsContainerProps { + heroHeight?: number; +} + +const DocsContainer = ({ heroHeight = 160 }: DocsContainerProps) => { + const [sections, setSections] = useState([]); + const [activeHash, setActiveHash] = useState(''); + const [activeTocItem, setActiveTocItem] = useState(''); + const [isClient, setIsClient] = useState(false); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + const [sidebarOpen, setSidebarOpen] = useState(false); + const [tocOpen, setTocOpen] = useState(false); + const [headings, setHeadings] = useState<{ id: string; text: string; level: number }[]>([]); + const [currentSection, setCurrentSection] = useState
    (null); + + const sidebarRef = useRef(null); + const mainRef = useRef(null); + const tocRef = useRef(null); + + useEffect(() => { + // Handle sidebar overlay scrolling + const handleSidebarToggle = (isOpen: boolean) => { + if (isOpen) { + document.body.style.overflow = 'hidden'; + } else { + document.body.style.overflow = ''; + } + }; + + // Update whenever sidebar state changes + handleSidebarToggle(sidebarOpen); + + return () => { + document.body.style.overflow = ''; + }; + }, [sidebarOpen]); + + // Set up marked with error handling + useEffect(() => { + marked.setOptions({ + breaks: true, + gfm: true, + }); + }, []); + + // Load markdown files + useEffect(() => { + const loadMarkdownFiles = async () => { + setLoading(true); + try { + // Fetch the list of markdown files + const response = await fetch('/api/docs'); + + if (!response.ok) { + throw new Error(`Failed to fetch documentation list: ${response.statusText}`); + } + + const files = await response.json(); + + if (!files || files.length === 0) { + setError('No documentation files found.'); + setLoading(false); + return; + } + + // Process each markdown file + const sectionsPromises = files.map(async (filename: string) => { + try { + const response = await fetch(`/docs/${filename}`); + + if (!response.ok) { + throw new Error(`Failed to load ${filename}: ${response.statusText}`); + } + + const content = await response.text(); + const title = extractTitle(content); + + return { + title, + markdownPath: `/docs/${filename}`, + content, + order: extractOrder(filename), + id: generateId(title), + }; + } catch (error) { + console.error(`Error loading markdown for ${filename}:`, error); + return null; + } + }); + + const loadedSections = (await Promise.all(sectionsPromises)) + .filter((section): section is Section => section !== null) + .sort((a, b) => a.order - b.order); + + setSections(loadedSections); + + // Set current section based on hash or default to first section + if (window.location.hash) { + const sectionId = window.location.hash.substring(1); + const section = loadedSections.find((s) => s.id === sectionId); + if (section) { + setCurrentSection(section); + // Extract headings from the current section + setHeadings(extractHeadings(section.content || '')); + } + } else if (loadedSections.length > 0) { + setCurrentSection(loadedSections[0]); + // Extract headings from the first section + setHeadings(extractHeadings(loadedSections[0].content || '')); + } + } catch (error) { + console.error('Error loading markdown files:', error); + setError(`Failed to load documentation: ${error instanceof Error ? error.message : 'Unknown error'}`); + } finally { + setLoading(false); + } + }; + + loadMarkdownFiles(); + }, []); + + // Client-side navigation and scroll effects + useEffect(() => { + setIsClient(true); + setActiveHash(window.location.hash); + + const handleHashChange = () => { + updateActiveHash(setActiveHash); + setSidebarOpen(false); + + // Update current section based on hash + const sectionId = window.location.hash.substring(1); + const section = sections.find((s) => s.id === sectionId); + if (section) { + setCurrentSection(section); + // Extract headings from the current section + setHeadings(extractHeadings(section.content || '')); + } + }; + + const handleScroll = () => { + // Check which heading is currently in view + const headingElements = document.querySelectorAll('h1, h2, h3, h4, h5, h6'); + const scrollPosition = window.scrollY + 100; // Add offset for better UX + + let currentHeading = ''; + + headingElements.forEach((element) => { + const { top } = element.getBoundingClientRect(); + const position = window.scrollY + top; + + if (position <= scrollPosition) { + const id = element.id; + if (id) { + currentHeading = id; + } + } + }); + + if (currentHeading) { + setActiveTocItem(currentHeading); + } + }; + + window.addEventListener('hashchange', handleHashChange); + window.addEventListener('scroll', handleScroll); + + // Initial scroll check + setTimeout(handleScroll, 100); + + return () => { + window.removeEventListener('hashchange', handleHashChange); + window.removeEventListener('scroll', handleScroll); + }; + }, [sections]); + + // Safe markdown rendering function + const safeMdRender = useCallback((content: string) => renderMarkdown(content, marked), []); + + // Handle click outside of sidebar to close it + useEffect(() => { + const handleClickOutside = (event: MouseEvent) => { + if (sidebarRef.current && !sidebarRef.current.contains(event.target as Node) && sidebarOpen) { + setSidebarOpen(false); + } + + if (tocRef.current && !tocRef.current.contains(event.target as Node) && tocOpen) { + setTocOpen(false); + } + }; + + document.addEventListener('mousedown', handleClickOutside); + + return () => { + document.removeEventListener('mousedown', handleClickOutside); + }; + }, [sidebarOpen, tocOpen]); + + // Get previous and next sections + const getPrevSection = () => { + if (!currentSection) return null; + const currentIndex = sections.findIndex((s) => s.id === currentSection.id); + return currentIndex > 0 ? sections[currentIndex - 1] : null; + }; + + const getNextSection = () => { + if (!currentSection) return null; + const currentIndex = sections.findIndex((s) => s.id === currentSection.id); + return currentIndex < sections.length - 1 ? sections[currentIndex + 1] : null; + }; + + const prevSection = getPrevSection(); + const nextSection = getNextSection(); + // Determine if we should use mobile styles + const [isMobile, setIsMobile] = useState(false); + + useEffect(() => { + const checkIfMobile = () => { + setIsMobile(window.innerWidth < 768); + }; + + checkIfMobile(); + window.addEventListener('resize', checkIfMobile); + return () => window.removeEventListener('resize', checkIfMobile); + }, []); + + return ( +
    +
    setSidebarOpen(false)} + /> + + + + + +
    +
    + {loading ? ( +
    +
    +
    + ) : error ? ( +
    +

    Error Loading Documentation

    +

    {error}

    +
    + ) : sections.length === 0 ? ( +
    +

    No Documentation Available

    +

    Documentation is currently being prepared. Please check back later.

    +
    + ) : ( + <> + {currentSection && ( +
    + + Home + + + Documentation + + {currentSection.title} +
    + )} + + {sections.map((section) => ( + + ))} + + )} +
    + + {!loading && !error && headings.length > 0 && ( + <> +
    +
    + On This Page + +
    + +
    + +
    +
    + + + +
    +

    On This Page

    + +
    + + )} +
    +
    + ); +}; + +export default DocsContainer; diff --git a/apps/stage/components/pages/documentation/DocContainer/Sidebar.tsx b/apps/stage/components/pages/documentation/DocContainer/Sidebar.tsx new file mode 100644 index 00000000..03c51ac5 --- /dev/null +++ b/apps/stage/components/pages/documentation/DocContainer/Sidebar.tsx @@ -0,0 +1,218 @@ +// components/documentation/Sidebar.tsx +import { css } from '@emotion/react'; +import Link from 'next/link'; +import { useRouter } from 'next/router'; +import { useEffect, useState } from 'react'; +import theme from './theme'; +import { SidebarSection } from './types'; + +interface SidebarProps { + sections: SidebarSection[]; + isOpen?: boolean; // For mobile toggle + onClose?: () => void; // For mobile close button + headerHeight?: number; // Total height of navbar + hero +} + +const Sidebar: React.FC = ({ sections, isOpen = false, onClose, headerHeight = 210 }) => { + const router = useRouter(); + const currentSlug = router.query.slug as string; + const [isMobile, setIsMobile] = useState(false); + + // Check if we're on mobile + useEffect(() => { + const checkIfMobile = () => { + const mqList = window.matchMedia(`(max-width: ${theme.breakpoints.md.replace('px', '')}px)`); + setIsMobile(mqList.matches); + }; + + checkIfMobile(); + window.addEventListener('resize', checkIfMobile); + return () => window.removeEventListener('resize', checkIfMobile); + }, []); + + return ( + + ); +}; + +export default Sidebar; diff --git a/apps/stage/components/pages/documentation/DocContainer/index.tsx b/apps/stage/components/pages/documentation/DocContainer/index.tsx new file mode 100644 index 00000000..e44383a4 --- /dev/null +++ b/apps/stage/components/pages/documentation/DocContainer/index.tsx @@ -0,0 +1,2 @@ +import DocsContainer from './DocsContainer'; +export default DocsContainer; diff --git a/apps/stage/components/pages/documentation/DocContainer/layout.tsx b/apps/stage/components/pages/documentation/DocContainer/layout.tsx new file mode 100644 index 00000000..3376421d --- /dev/null +++ b/apps/stage/components/pages/documentation/DocContainer/layout.tsx @@ -0,0 +1,157 @@ +// components/documentation/Layout.tsx +import { css } from '@emotion/react'; +import { useEffect, useState } from 'react'; +import Sidebar from './Sidebar'; +import theme from './theme'; +import { SidebarSection } from './types'; + +interface LayoutProps { + children: React.ReactNode; + sections: SidebarSection[]; +} + +const Layout: React.FC = ({ children, sections }) => { + const [sidebarOpen, setSidebarOpen] = useState(false); + const [isMobile, setIsMobile] = useState(false); + + // Check if we're on mobile for responsive behavior + useEffect(() => { + const checkIfMobile = () => { + const mqList = window.matchMedia(`(max-width: ${theme.breakpoints.md.replace('px', '')}px)`); + setIsMobile(mqList.matches); + }; + + checkIfMobile(); + window.addEventListener('resize', checkIfMobile); + return () => window.removeEventListener('resize', checkIfMobile); + }, []); + + // Handle body overflow when sidebar is open on mobile + useEffect(() => { + if (isMobile) { + if (sidebarOpen) { + document.body.style.overflow = 'hidden'; + } else { + document.body.style.overflow = ''; + } + } + + return () => { + document.body.style.overflow = ''; + }; + }, [sidebarOpen, isMobile]); + + return ( +
    + {/* Sidebar for desktop */} + setSidebarOpen(false)} /> + + {/* Main content area */} +
    + {children} +
    + + {/* Mobile sidebar toggle button */} + + + {/* Mobile sidebar overlay */} + {isMobile && ( +
    setSidebarOpen(false)} + aria-hidden="true" + /> + )} +
    + ); +}; + +export default Layout; diff --git a/apps/stage/components/pages/documentation/DocContainer/styles.ts b/apps/stage/components/pages/documentation/DocContainer/styles.ts new file mode 100644 index 00000000..e5ad75ed --- /dev/null +++ b/apps/stage/components/pages/documentation/DocContainer/styles.ts @@ -0,0 +1,901 @@ +import { css } from '@emotion/react'; +import theme from './theme'; + +const styles = { + container: css` + display: flex; + width: 100%; + height: 100%; + position: relative; + overflow: hidden; + `, + + contentWrapper: css` + display: flex; + width: 100%; + max-width: 100%; + position: relative; + margin: 0; + padding: 0; + min-height: 100vh; + + @media (max-width: ${theme.breakpoints.md}) { + flex-direction: column; + } + `, + + sidebar: css` + width: 280px; + min-width: 280px; + background: ${theme.colors.sidebar}; + border-right: 1px solid ${theme.colors.border}; + position: fixed; + left: 0; + overflow-y: auto; + padding-bottom: 2rem; + z-index: 10; + flex-shrink: 0; + align-self: flex-start; + + /* Scrollbar styling */ + scrollbar-width: thin; + scrollbar-color: ${theme.colors.primary} ${theme.colors.sidebar}; + + &::-webkit-scrollbar { + width: 6px; + } + + &::-webkit-scrollbar-track { + background: ${theme.colors.sidebar}; + } + + &::-webkit-scrollbar-thumb { + background-color: ${theme.colors.primary}80; + border-radius: 6px; + } + + /* Tablet-specific adjustments */ + @media (min-width: ${theme.breakpoints.md}) and (max-width: ${theme.breakpoints.lg}) { + width: 240px; + min-width: 240px; + } + + /* Mobile adjustments */ + @media (max-width: ${theme.breakpoints.md}) { + position: fixed; + top: 0; + left: 0; + bottom: 0; + transform: translateX(-100%); + width: 85%; + max-width: 300px; + height: 100vh; + box-shadow: 0 0 15px rgba(0, 0, 0, 0.1); + padding-top: 1rem; + transition: transform 0.3s ease; + + &.active { + transform: translateX(0); + } + } + `, + + sidebarToggle: css` + display: none; + position: fixed; + bottom: 20px; + right: 20px; + background: ${theme.colors.primary}; + color: white; + width: 50px; + height: 50px; + border-radius: 50%; + border: none; + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); + z-index: 1001; + cursor: pointer; + align-items: center; + justify-content: center; + transition: ${theme.transitions.standard}; + + &:hover { + background: #09638a; + } + + svg { + width: 24px; + height: 24px; + } + + @media (max-width: ${theme.breakpoints.md}) { + display: flex; + } + `, + + sidebarOverlay: css` + display: none; + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.5); + z-index: 999; + opacity: 0; + transition: opacity 0.3s ease; + + &.active { + opacity: 1; + } + + @media (max-width: ${theme.breakpoints.md}) { + &.visible { + display: block; + } + } + `, + + sidebarHeader: css` + padding: 0 1.5rem 1rem; + font-weight: 600; + font-size: 0.875rem; + text-transform: uppercase; + letter-spacing: 0.05em; + color: ${theme.colors.textSecondary}; + display: flex; + justify-content: space-between; + align-items: center; + + .close-button { + display: none; + background: transparent; + border: none; + color: ${theme.colors.textSecondary}; + cursor: pointer; + padding: 5px; + + &:hover { + color: ${theme.colors.primary}; + } + + svg { + width: 20px; + height: 20px; + } + } + + @media (max-width: ${theme.breakpoints.md}) { + .close-button { + display: block; + } + } + `, + + nav: css` + li { + margin: 0.5rem 0; + } + + a { + display: block; + padding: 0.75rem 1rem; + color: ${theme.colors.primary_green}; + text-decoration: none; + font-size: 0.875rem; + border-radius: 0.375rem; + transition: ${theme.transitions.standard}; + border-left: 2px solid transparent; + + &:hover { + color: ${theme.colors.primary}; + background: ${theme.colors.hover}; + } + + &.active { + color: ${theme.colors.primary}; + background: ${theme.colors.hover}; + font-weight: 500; + border-left-color: ${theme.colors.primary}; + } + } + + @media (max-width: ${theme.breakpoints.md}) { + li { + margin: 0.25rem 0; + } + + a { + padding: 0.75rem 0.75rem; + } + } + `, + + main: css` + flex: 1; + padding: 1.5rem 2.5rem 3rem; + width: calc(100% - 280px); + margin-left: 280px; + box-sizing: border-box; + margin-top: 120px; + + /* Tablet adjustments */ + @media (min-width: ${theme.breakpoints.md}) and (max-width: ${theme.breakpoints.lg}) { + width: calc(100% - 240px); + margin-left: 240px; + padding: 1.5rem 1.5rem 3rem; + } + + /* Mobile adjustments */ + @media (max-width: ${theme.breakpoints.md}) { + width: 100%; + margin-left: 0; + padding: 1.5rem 1rem 3rem; + } + `, + + content: css` + max-width: ${theme.maxWidth}; + margin: 0 auto; + font-size: 1rem; + line-height: 1.25; + color: ${theme.colors.text}; + overflow-wrap: break-word; + word-wrap: break-word; + word-break: break-word; + hyphens: auto; + + /* Tablet-specific content adjustments */ + @media (min-width: ${theme.breakpoints.md}) and (max-width: ${theme.breakpoints.lg}) { + padding-right: 1rem; + max-width: 100%; + width: 100%; + } + + h1:first-of-type { + visibility: hidden; + height: 0; + margin: 0; + margin-top: -30px; + padding: 0; + line-height: 0; + font-size: 0; + border: none; + } + + h1 { + font-size: 32px; + font-weight: 900; + line-height: 60px; + margin-bottom: 20px; + border-bottom: 2px solid ${theme.colors.border}; + padding-bottom: 0.75rem; + margin-top: 0; + + /* Tablet-specific heading size */ + @media (min-width: ${theme.breakpoints.md}) and (max-width: ${theme.breakpoints.lg}) { + font-size: 1.9rem; + padding-bottom: 0.5rem; + } + + @media (max-width: ${theme.breakpoints.md}) { + font-size: 1.75rem; + } + + @media (max-width: ${theme.breakpoints.sm}) { + font-size: 1.5rem; + } + } + + h2 { + font-size: 28px; + font-weight: 900; + line-height: 40px; + margin-bottom: 20px; + border-bottom: 1px solid ${theme.colors.border}; + padding-bottom: 0.5rem; + + /* Tablet-specific heading size */ + @media (min-width: ${theme.breakpoints.md}) and (max-width: ${theme.breakpoints.lg}) { + font-size: 1.6rem; + } + + @media (max-width: ${theme.breakpoints.md}) { + font-size: 1.5rem; + } + + @media (max-width: ${theme.breakpoints.sm}) { + font-size: 1.35rem; + } + } + + h3 { + font-size: 24px; + font-weight: 900; + color: #000; + + @media (min-width: ${theme.breakpoints.md}) and (max-width: ${theme.breakpoints.lg}) { + font-size: 1.4rem; + } + + @media (max-width: ${theme.breakpoints.md}) { + font-size: 1.35rem; + } + + @media (max-width: ${theme.breakpoints.sm}) { + font-size: 1.25rem; + } + } + + h4 { + font-size: 20px; + margin-bottom: 20px; + + @media (min-width: ${theme.breakpoints.md}) and (max-width: ${theme.breakpoints.lg}) { + font-size: 1.2rem; + } + + @media (max-width: ${theme.breakpoints.md}) { + font-size: 1.15rem; + } + + @media (max-width: ${theme.breakpoints.sm}) { + font-size: 1.1rem; + } + } + + details { + background-color: ${theme.colors.primaryLight}50; + border: 1px solid ${theme.colors.border}; + border-radius: 0.5rem; + padding: 0.75rem 1.25rem; + margin: 1.5rem 0; + transition: all 0.3s ease-in-out; + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); + } + + details[open] { + padding-left: 1.25rem; + padding-bottom: 1rem; + transition-delay: 0.1s; + } + + /* Content transition */ + details > :not(summary) { + transform-origin: top left; + opacity: 0; + overflow: hidden; + transition: all 0.3s ease-out; + } + + details[open] > :not(summary) { + opacity: 1; + height: auto; + margin-top: 1rem; + padding-left: 1.75rem; + transition-delay: 0.15s; + } + + details[open] ul { + padding-left: 4rem; + margin-bottom: 0.5rem; + } + + details[open] pre { + margin-left: 25px; + width: 90%; + } + + details[open] code { + overflow-x: auto; + } + + summary { + cursor: pointer; + position: relative; + padding: 0.5rem 0; + font-weight: 600; + list-style: none; + outline: none; + color: ${theme.colors.primary}; + display: flex; + align-items: center; + user-select: none; + transition: color 0.2s ease; + } + + summary:hover { + color: ${theme.colors.primary_green}; + } + + summary::-webkit-details-marker { + display: none; + } + + summary::before { + content: ''; + border-width: 0.4rem; + border-style: solid; + border-color: transparent transparent transparent ${theme.colors.primary}; + position: relative; + display: inline-block; + margin-right: 0.75rem; + top: -1px; + transition: transform 0.25s ease; + } + + details[open] > summary::before { + transform: rotate(90deg); + } + + details code { + background-color: rgba(0, 0, 0, 0.05); + border-radius: 3px; + padding: 0.1em 0.3em; + } + + p { + line-height: 1.5; + font-size: 18px; + font-weight: 400; + } + + ul, + ol { + margin: 1.25rem 0; + max-width: 100%; + overflow-wrap: break-word; + font-size: 16px; + padding-left: 2rem; + + @media (max-width: ${theme.breakpoints.sm}) { + padding-left: 1.25rem; + } + } + + li { + line-height: 1.5rem; + } + + a { + color: ${theme.colors.primary_green}; + font-weight: 900; + text-decoration: none; + border-bottom: 1px solid transparent; + transition: ${theme.transitions.standard}; + word-break: break-word; + overflow-wrap: break-word; + + &:hover { + border-bottom-color: ${theme.colors.primary}; + } + } + + blockquote { + margin: 2rem 0; + padding: 1.25rem 1.75rem; + border-left: 4px solid ${theme.colors.primary}; + background: ${theme.colors.hover}; + border-radius: 0.5rem; + + @media (max-width: ${theme.breakpoints.sm}) { + padding: 1rem 1.25rem; + margin: 1.5rem 0; + } + + p { + margin: 0; + font-style: italic; + } + } + + table { + width: 100%; + margin: 2rem 0; + border-collapse: collapse; + border-spacing: 0; + font-size: 0.9375rem; + border: 1px solid ${theme.colors.border}; + border-radius: 0.5rem; + overflow: hidden; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); + table-layout: fixed; + max-width: 100%; + display: table; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + + @media (max-width: ${theme.breakpoints.md}) { + margin: 1.5rem 0; + font-size: 0.875rem; + border-radius: 0.375rem; + } + + th, + td { + width: 50%; + } + + thead { + background: ${theme.colors.sidebar}; + border-bottom: 2px solid ${theme.colors.border}; + } + + th { + padding: 1rem 1.25rem; + text-align: left; + font-weight: 600; + color: ${theme.colors.textSecondary}; + text-transform: uppercase; + letter-spacing: 0.05em; + border-bottom: 2px solid ${theme.colors.border}; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + + @media (max-width: ${theme.breakpoints.sm}) { + padding: 0.875rem 1rem; + font-size: 0.8125rem; + } + } + + td { + padding: 1rem 1.25rem; + text-align: left; + border-bottom: 1px solid ${theme.colors.border}; + vertical-align: middle; + transition: background-color 0.2s ease; + word-wrap: break-word; + overflow: hidden; + text-overflow: ellipsis; + + @media (max-width: ${theme.breakpoints.sm}) { + padding: 0.875rem 1rem; + } + } + + tbody tr:nth-of-type(even) { + background-color: ${theme.colors.primaryLight}20; + } + + tbody tr:hover { + background-color: ${theme.colors.primaryLight}40; + } + + tbody tr:last-child td { + border-bottom: none; + } + + @media (max-width: ${theme.breakpoints.sm}) { + font-size: 0.8125rem; + } + } + + table::-webkit-scrollbar { + height: 8px; + } + + table::-webkit-scrollbar-track { + background: ${theme.colors.sidebar}; + } + + table::-webkit-scrollbar-thumb { + background-color: ${theme.colors.primary}80; + border-radius: 4px; + } + + pre, + code { + font-family: ${theme.fonts.mono}; + background: ${theme.colors.primaryLight}50; + border-radius: 0.5rem; + font-size: 0.9375rem; + line-height: 2; + overflow-x: auto; + + @media (max-width: ${theme.breakpoints.md}) { + font-size: 0.875rem; + } + } + + pre { + padding: 1rem; + border: 1px solid ${theme.colors.border}; + margin: 1rem 0; + box-shadow: ${theme.boxShadow}; + max-width: 100%; + + @media (max-width: ${theme.breakpoints.sm}) { + padding: 1rem; + margin: 1.25rem 0; + } + + code { + background: none; + padding: 0; + } + } + + code { + padding: 0.2rem 0.4rem; + border-radius: 0.25rem; + word-break: normal; + } + + img { + display: block; + max-width: 98%; + height: auto; + margin: 2rem auto; + border-radius: 8px; + box-shadow: ${theme.boxShadow}; + border: 10px solid transparent; + + @media (max-width: ${theme.breakpoints.md}) { + margin: 1.5rem auto; + } + } + + strong { + font-weight: 900; + color: #000; + letter-spacing: -0.02em; + } + `, + + loadingContainer: css` + display: flex; + justify-content: center; + align-items: center; + height: 300px; + width: 100%; + `, + + loader: css` + border: 4px solid ${theme.colors.border}; + border-top: 4px solid ${theme.colors.primary}; + border-radius: 50%; + width: 40px; + height: 40px; + animation: spin 1s linear infinite; + + @keyframes spin { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } + } + `, + + errorContainer: css` + padding: 1.5rem; + margin: 1.5rem 0; + background-color: #fff5f5; + border-left: 4px solid ${theme.colors.error}; + border-radius: 0.5rem; + color: ${theme.colors.error}; + `, + + noContent: css` + text-align: center; + padding: 3rem 1.5rem; + color: ${theme.colors.textSecondary}; + + @media (max-width: ${theme.breakpoints.md}) { + padding: 2rem 1rem; + } + `, + + toc: css` + display: none; + position: fixed; + overflow-y: auto; + padding-left: 2rem; + width: 240px; + font-size: 0.875rem; + scrollbar-width: thin; + scrollbar-color: ${theme.colors.primary} ${theme.colors.background}; + + @media (min-width: 1200px) { + display: block; + } + + h4 { + font-size: 0.875rem; + text-transform: uppercase; + letter-spacing: 0.05em; + color: ${theme.colors.textSecondary}; + margin: 0 0 1rem; + font-weight: 900; + } + + ul { + list-style: none; + padding: 0; + margin: 0; + } + + li { + margin-bottom: 0.5rem; + padding-left: 1rem; + border-left: 2px solid ${theme.colors.border}; + } + + li.active { + border-left: 2px solid ${theme.colors.primary}; + } + + a { + color: ${theme.colors.textSecondary}; + text-decoration: none; + display: block; + padding: 0.25rem 0; + font-size: 0.8125rem; + transition: ${theme.transitions.standard}; + + &:hover, + &.active { + color: ${theme.colors.primary}; + } + } + `, + + tableOfContentsToggle: css` + display: none; + position: fixed; + bottom: 20px; + right: 80px; + background: ${theme.colors.primary}; + color: white; + width: 50px; + height: 50px; + border-radius: 50%; + border: none; + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); + z-index: 1001; + cursor: pointer; + align-items: center; + justify-content: center; + transition: ${theme.transitions.standard}; + + &:hover { + background: #09638a; + } + + svg { + width: 24px; + height: 24px; + } + + @media (min-width: ${theme.breakpoints.md}) and (max-width: 1200px) { + display: flex; + } + `, + + tocSidebar: css` + display: none; + position: fixed; + top: 0; + right: 0; + width: 85%; + max-width: 300px; + height: 100vh; + background: ${theme.colors.background}; + border-left: 1px solid ${theme.colors.border}; + z-index: 1000; + padding: 1rem; + transform: translateX(100%); + transition: transform 0.3s ease-in-out; + overflow-y: auto; + + &.active { + transform: translateX(0); + } + + @media (min-width: ${theme.breakpoints.md}) and (max-width: 1200px) { + display: block; + } + `, + + breadcrumbs: css` + display: flex; + flex-wrap: wrap; + margin-bottom: 1rem; + font-size: 0.875rem; + color: ${theme.colors.textSecondary}; + + a { + color: ${theme.colors.textSecondary}; + text-decoration: none; + transition: ${theme.transitions.standard}; + + &:hover { + color: ${theme.colors.primary}; + } + } + + span { + display: inline-flex; + align-items: center; + + &:not(:last-child)::after { + content: '/'; + padding: 0 0.5rem; + color: ${theme.colors.border}; + } + } + `, + + docHeader: css` + margin-bottom: 2rem; + width: 100%; + max-width: 100%; + + @media (max-width: ${theme.breakpoints.md}) { + margin-bottom: 1.5rem; + } + `, + + docFooter: css` + display: flex; + flex-wrap: wrap; + justify-content: space-between; + margin-top: 3rem; + margin-bottom: 3rem; + padding-top: 1.5rem; + + a { + display: flex; + align-items: center; + color: ${theme.colors.primary_green}; + text-decoration: none; + transition: ${theme.transitions.standard}; + padding: 0.5rem; + border-radius: 0.25rem; + border-bottom: none; + + &:hover { + background: ${theme.colors.hover}; + border-bottom: none; + text-decoration: none; + } + + svg { + width: 20px; + height: 20px; + } + } + + .prev-link svg { + margin-right: 0.5rem; + } + + .next-link svg { + margin-left: 0.5rem; + } + + @media (max-width: ${theme.breakpoints.sm}) { + flex-direction: column; + gap: 1rem; + } + `, + + sectionNav: css` + display: flex; + width: 100%; + justify-content: space-between; + + .prev-link { + flex: 0 0 auto; + } + + .next-link { + flex: 0 0 auto; + margin-left: auto; + text-align: right; + } + `, +}; + +export default styles; diff --git a/apps/stage/components/pages/documentation/DocContainer/theme.ts b/apps/stage/components/pages/documentation/DocContainer/theme.ts new file mode 100644 index 00000000..74301191 --- /dev/null +++ b/apps/stage/components/pages/documentation/DocContainer/theme.ts @@ -0,0 +1,78 @@ +// DocsContainer/theme.ts +const theme = { + colors: { + background: '#ffffff', + sidebar: '#f5f6f7', + primary: '#0B75A2', + primaryLight: '#e8f4f8', + primary_green: '#00A88F', + text: '#2d3748', + textSecondary: '#4a5568', + border: '#e2e8f0', + hover: 'rgba(0, 168, 143, 0.08)', + codeBackground: '#f7fafc', + error: '#e53e3e', + hero: '#0B75A2', + white: '#ffffff', + }, + fonts: { + base: 'system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell, Noto Sans, sans-serif', + mono: 'SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace', + heading: 'system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell, Noto Sans, sans-serif', + }, + maxWidth: '125ch', + breakpoints: { + xs: '480px', + sm: '640px', + md: '768px', + lg: '1024px', + xl: '1280px', + xxl: '1536px', + }, + transitions: { + standard: 'all 0.2s ease-in-out', + fast: 'all 0.1s ease-in-out', + slow: 'all 0.3s ease-in-out', + }, + boxShadow: '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)', + boxShadowMd: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)', + boxShadowLg: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)', + zIndices: { + base: 0, + content: 1, + header: 10, + sidebar: 20, + overlay: 30, + modal: 40, + tooltip: 50, + }, + spacing: { + 0: '0', + 1: '0.25rem', // 4px + 2: '0.5rem', // 8px + 3: '0.75rem', // 12px + 4: '1rem', // 16px + 5: '1.25rem', // 20px + 6: '1.5rem', // 24px + 8: '2rem', // 32px + 10: '2.5rem', // 40px + 12: '3rem', // 48px + 16: '4rem', // 64px + 20: '5rem', // 80px + 24: '6rem', // 96px + 32: '8rem', // 128px + }, + borderRadius: { + none: '0', + sm: '0.125rem', // 2px + default: '0.25rem', // 4px + md: '0.375rem', // 6px + lg: '0.5rem', // 8px + xl: '0.75rem', // 12px + '2xl': '1rem', // 16px + '3xl': '1.5rem', // 24px + full: '9999px', + }, +}; + +export default theme; diff --git a/apps/stage/components/pages/documentation/DocContainer/types.ts b/apps/stage/components/pages/documentation/DocContainer/types.ts new file mode 100644 index 00000000..88fda4e1 --- /dev/null +++ b/apps/stage/components/pages/documentation/DocContainer/types.ts @@ -0,0 +1,14 @@ +// types/documentation.ts +export interface Section { + title: string; + markdownPath: string; + content?: string; + order: number; + id: string; // Make id non-optional and always a string +} + +// Type for sidebar sections +export interface SidebarSection { + title: string; + id: string; +} diff --git a/apps/stage/components/pages/documentation/DocContainer/utils/markdown.ts b/apps/stage/components/pages/documentation/DocContainer/utils/markdown.ts new file mode 100644 index 00000000..217e52d9 --- /dev/null +++ b/apps/stage/components/pages/documentation/DocContainer/utils/markdown.ts @@ -0,0 +1,111 @@ +// DocsContainer/utils/markdown.ts + +/** + * Extracts the title from markdown content + */ +export function extractTitle(content: string): string { + const titleMatch = content.match(/^#\s+(.+?)(?:\s+\{#.+\})?$/m); + return titleMatch ? titleMatch[1].trim() : 'Untitled Section'; +} + +/** + * Extracts the order from a filename + */ +export function extractOrder(filename: string): number { + const match = filename.match(/^(\d+)/); + return match ? parseInt(match[1], 10) : 999; +} + +/** + * Generates a section ID from a title + */ +export function generateId(title: string): string { + return title + .toLowerCase() + .replace(/\s+/g, '-') + .replace(/[^\w-]/g, ''); +} + +/** + * Renders markdown safely and properly handles heading IDs + */ +export function renderMarkdown(content: string = '', marked: any): { __html: string } { + try { + // Process the content to add IDs to headings properly + const processedContent = processHeadings(content); + + // Render the markdown + const renderedHTML = marked(processedContent); + + // Clean up any remaining {#id} patterns that might be visible + const cleanedHTML = renderedHTML.replace(/\s*\{#[\w-]+\}/g, ''); + + return { __html: cleanedHTML }; + } catch (error) { + console.error('Error rendering markdown:', error); + return { __html: '

    Error rendering content

    ' }; + } +} + +/** + * Process headings to add IDs without showing {#id} in the output + */ +function processHeadings(content: string): string { + // First remove any existing heading IDs in the format {#id} + const cleanedContent = content.replace(/(\s*\{#[\w-]+\})/g, ''); + + // Then add back IDs in a way that works with marked + return cleanedContent.replace(/^(#{1,6})\s+(.+)$/gm, (match, hashes, title) => { + const id = generateId(title.trim()); + return `${hashes} ${title} `; + }); +} + +/** + * Extracts headings from markdown content for table of contents + */ +export function extractHeadings(content: string): { id: string; text: string; level: number }[] { + const headings: { id: string; text: string; level: number }[] = []; + // Match headings without the {#id} part or with it + const headingRegex = /^(#{1,6})\s+(.+?)(?:\s+\{#([\w-]+)\})?$/gm; + + let match; + while ((match = headingRegex.exec(content)) !== null) { + const level = match[1].length; + const text = match[2].trim(); + // Use explicit ID if provided, otherwise generate one + const explicitId = match[3]; + const id = explicitId || generateId(text); + + // Skip h1 as it's usually the title + if (level > 1) { + headings.push({ id, text, level }); + } + } + + return headings; +} + +/** + * Extracts the first paragraph from markdown content for summaries + */ +export function extractSummary(content: string, maxLength: number = 160): string { + // Remove the title and any ID tags + const contentWithoutTitle = content.replace(/^#\s+.+?(?:\s+\{#.+\})?$/m, '').trim(); + + // Find the first paragraph + const paragraphMatch = contentWithoutTitle.match(/^(?!#)(.+?)(\n\n|$)/s); + + if (paragraphMatch) { + const summary = paragraphMatch[1].replace(/\n/g, ' ').trim(); + + // Truncate if too long + if (summary.length > maxLength) { + return summary.substring(0, maxLength) + '...'; + } + + return summary; + } + + return ''; +} diff --git a/apps/stage/components/pages/documentation/DocContainer/utils/navigation.ts b/apps/stage/components/pages/documentation/DocContainer/utils/navigation.ts new file mode 100644 index 00000000..02431bf8 --- /dev/null +++ b/apps/stage/components/pages/documentation/DocContainer/utils/navigation.ts @@ -0,0 +1,7 @@ +// DocsContainer/utils/navigation.ts +/** + * Updates the active hash in the state + */ +export function updateActiveHash(setActiveHash: (hash: string) => void): void { + setActiveHash(window.location.hash); +} diff --git a/apps/stage/components/pages/documentation/PageContent.tsx b/apps/stage/components/pages/documentation/PageContent.tsx new file mode 100644 index 00000000..8f3f2451 --- /dev/null +++ b/apps/stage/components/pages/documentation/PageContent.tsx @@ -0,0 +1,36 @@ +// components/pages/documentation/PageContent.tsx +import { css } from '@emotion/react'; +import { ReactElement } from 'react'; +import DocsContainer from './DocContainer'; +import theme from './DocContainer/theme'; + +const PageContent = (): ReactElement => { + return ( +
    +
    + +
    +
    + ); +}; + +export default PageContent; diff --git a/apps/stage/components/pages/documentation/index.tsx b/apps/stage/components/pages/documentation/index.tsx new file mode 100644 index 00000000..19183961 --- /dev/null +++ b/apps/stage/components/pages/documentation/index.tsx @@ -0,0 +1,12 @@ +// components/pages/documentation/index.tsx +import { ReactElement } from 'react'; +import PageLayout from '../../PageLayout'; +import PageContent from './PageContent'; + +const Documentation = (): ReactElement => ( + + + +); + +export default Documentation; diff --git a/apps/stage/components/pages/home/HomeAcknowledgements.tsx b/apps/stage/components/pages/home/HomeAcknowledgements.tsx new file mode 100644 index 00000000..d6ca669a --- /dev/null +++ b/apps/stage/components/pages/home/HomeAcknowledgements.tsx @@ -0,0 +1,79 @@ +import { css, useTheme } from '@emotion/react'; +import { ReactElement } from 'react'; + +const HomeAcknowledgements = (): ReactElement => { + const theme = useTheme(); + + return ( +
    +
    +
    +

    + Acknowledgements +

    +

    + The OICR Genome Informatics group built this portal using Overture, their open-source software suite that + helps researchers organize, share, and explore their datasets. +

    +
    + + Learn More + +
    +
    + ); +}; + +export default HomeAcknowledgements; diff --git a/apps/stage/components/pages/home/HomeContent.tsx b/apps/stage/components/pages/home/HomeContent.tsx new file mode 100644 index 00000000..f36cc861 --- /dev/null +++ b/apps/stage/components/pages/home/HomeContent.tsx @@ -0,0 +1,26 @@ +import HeroBanner from '@/components/HeroBanner'; +import { css } from '@emotion/react'; +import { ReactElement } from 'react'; +import defaultTheme from '../../theme'; +import HomeNavigation from './HomeNavigation'; + +const HomeContent = (): ReactElement => { + return ( +
    + + +
    + ); +}; + +export default HomeContent; diff --git a/apps/stage/components/pages/home/HomeHero.tsx b/apps/stage/components/pages/home/HomeHero.tsx new file mode 100644 index 00000000..6b8bb244 --- /dev/null +++ b/apps/stage/components/pages/home/HomeHero.tsx @@ -0,0 +1,52 @@ +import { css } from '@emotion/react'; +import { ReactElement } from 'react'; +import defaultTheme from '../../theme'; + +const HomeHero = (): ReactElement => { + return ( +
    +
    +

    + Home{' '} +

    +

    + Incrementally build your Overture data platform with Prelude. +

    +
    +
    + ); +}; + +export default HomeHero; diff --git a/apps/stage/components/pages/home/HomeNavigation.tsx b/apps/stage/components/pages/home/HomeNavigation.tsx new file mode 100644 index 00000000..a1407f51 --- /dev/null +++ b/apps/stage/components/pages/home/HomeNavigation.tsx @@ -0,0 +1,326 @@ +// components/pages/home/HomeNavigation.tsx +import { css, useTheme } from '@emotion/react'; +import { ReactElement, useEffect, useState } from 'react'; +import { INTERNAL_PATHS } from '../../../global/utils/constants'; +import { DataTableInfo } from '../../../global/utils/dataTablesDiscovery'; +import HomeAcknowledgements from './HomeAcknowledgements'; + +interface CardItem { + title: string; + link: string; + description: string; + subItems?: { title: string; link: string; external?: boolean }[]; + external?: boolean; + isDynamic?: boolean; +} + +interface SectionItem { + title: string; + id: string; + order: number; +} + +const HomeNavigation = (): ReactElement => { + const theme = useTheme(); + const [openDropdown, setOpenDropdown] = useState(null); + const [docSections, setDocSections] = useState([]); + const [dataTables, setDataTables] = useState([]); + const [homeCards, setHomeCards] = useState([ + { + title: 'Explore the Data', + link: '#', + description: 'Browse and interact with datasets', + subItems: [], // Will be populated dynamically with data tables + }, + { + title: 'Documentation & Guides', + link: INTERNAL_PATHS.DOCUMENTATION, + description: 'Phased guides covering Prelude usage', + isDynamic: true, + }, + { + title: 'Find Support', + link: 'https://docs.overture.bio/community/support', + description: 'Connect with our community and get help', + external: true, + }, + { + title: 'Community Resources', + link: '#', + description: 'Additional Overture resources', + subItems: [ + { title: 'Overture Docs', link: 'https://docs.overture.bio/', external: true }, + { title: 'Overture.bio', link: 'https://overture.bio/', external: true }, + { title: 'Overture-Stack GitHub', link: 'https://github.com/overture-stack', external: true }, + ], + }, + ]); + + // Load data tables from API + useEffect(() => { + fetch('/api/data-tables') + .then((response) => response.json()) + .then((data) => { + setDataTables(data); + + // Update the Explore the Data card with data tables + setHomeCards((prevCards) => + prevCards.map((card) => + card.title === 'Explore the Data' + ? { + ...card, + subItems: data.map((table: DataTableInfo) => ({ + title: table.title, + link: table.path, + })), + } + : card, + ), + ); + }) + .catch((error) => { + console.error('Error fetching data tables:', error); + }); + }, []); + + // Load documentation sections + useEffect(() => { + const fetchDocs = async () => { + try { + const response = await fetch('/api/docs'); + if (!response.ok) throw new Error('Failed to fetch documentation list'); + + const files = await response.json(); + const sectionsPromises = files.map(async (filename: string) => { + try { + const contentResponse = await fetch(`/docs/${filename}`); + if (!contentResponse.ok) throw new Error(`Failed to load ${filename}`); + + const content = await contentResponse.text(); + return { + title: extractTitle(content), + id: createSlug(filename), + order: extractOrder(filename), + }; + } catch (error) { + console.error(`Error processing file ${filename}:`, error); + return null; + } + }); + + const sections = (await Promise.all(sectionsPromises)) + .filter((section): section is SectionItem => section !== null) + .sort((a, b) => a.order - b.order); + + setDocSections(sections); + setHomeCards((prevCards) => + prevCards.map((card) => + card.isDynamic + ? { + ...card, + subItems: sections.map((section) => ({ + title: section.title, + link: `${INTERNAL_PATHS.DOCUMENTATION}/${section.id}`, + })), + } + : card, + ), + ); + } catch (error) { + console.error('Error fetching documentation:', error); + } + }; + + fetchDocs(); + }, []); + + const handleCardClick = (card: CardItem, index: number, e: React.MouseEvent) => { + if (card.subItems && card.subItems.length > 0) { + e.preventDefault(); + setOpenDropdown(openDropdown === index ? null : index); + } else if (card.external) { + window.open(card.link, '_blank', 'noopener,noreferrer'); + } else { + e.preventDefault(); + window.location.href = card.link; + } + }; + + const handleSubItemClick = (subItem: { title: string; link: string; external?: boolean }, e: React.MouseEvent) => { + e.preventDefault(); + if (subItem.external) { + window.open(subItem.link, '_blank', 'noopener,noreferrer'); + } else { + window.location.href = subItem.link; + } + }; + + // CSS styles + const styles = { + container: css` + width: 95%; + margin: 0 auto; + padding: 24px 16px 48px; + @media (max-width: 1280px) { + width: 92%; + } + `, + grid: css` + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 20px; + @media (max-width: 1024px) { + grid-template-columns: 1fr 1fr; + } + @media (max-width: 768px) { + grid-template-columns: 1fr; + } + `, + card: css` + cursor: pointer; + transition: transform 0.25s ease, box-shadow 0.25s ease; + &:hover { + transform: translateY(-1px); + } + `, + cardContainer: css` + background-color: ${theme.colors.white}; + border-radius: 8px; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + border: 1px solid ${theme.colors.grey_3}; + transition: box-shadow 0.25s ease; + &:hover { + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15); + } + `, + cardContent: css` + padding: 18px; + `, + cardHeader: css` + display: flex; + justify-content: space-between; + align-items: center; + `, + cardTitle: css` + font-size: 1.125rem; + font-weight: 600; + color: ${theme.colors.primary}; + margin: 0 0 4px 0; + `, + cardDescription: css` + font-size: 0.875rem; + color: ${theme.colors.grey_6}; + margin: 4px 0; + `, + dropdownButton: css` + background: none; + border: none; + cursor: pointer; + transition: transform 0.2s ease; + padding: 4px; + `, + dropdownContent: css` + border-top: 1px solid ${theme.colors.grey_3}; + padding: 12px; + max-height: 260px; + overflow-y: auto; + `, + dropdownItem: css` + display: block; + padding: 8px 0; + color: ${theme.colors.grey_6}; + text-decoration: none; + font-size: 0.875rem; + transition: color 0.2s ease; + cursor: pointer; + &:hover { + color: ${theme.colors.secondary}; + } + &:not(:last-child) { + border-bottom: 1px solid ${theme.colors.grey_3}; + } + `, + acknowledgements: css` + margin-top: 20px; + `, + emptySubItems: css` + padding: 12px; + color: ${theme.colors.grey_5}; + font-style: italic; + text-align: center; + `, + }; + + return ( +
    +
    + {homeCards.map((card, index) => ( +
    handleCardClick(card, index, e)}> +
    +
    +
    +

    {card.title}

    + {card.subItems && card.subItems.length > 0 && ( + + )} +
    +

    {card.description}

    +
    + {card.subItems && openDropdown === index && ( +
    + {card.subItems.length > 0 ? ( + card.subItems.map((subItem, subIndex) => ( +
    handleSubItemClick(subItem, e)} css={styles.dropdownItem}> + {subItem.title} +
    + )) + ) : ( +
    No items available
    + )} +
    + )} +
    +
    + ))} +
    + +
    + +
    +
    + ); +}; + +// Helper functions +function extractTitle(content: string): string { + const titleMatch = content.match(/^#\s+(.+?)(?:\s+\{#.+\})?$/m); + return titleMatch ? titleMatch[1].trim() : 'Untitled Section'; +} + +function createSlug(filename: string): string { + return filename + .replace(/^\d+[-_]?/, '') + .replace(/\.md$/, '') + .toLowerCase() + .replace(/\s+/g, '-') + .replace(/[^\w-]/g, ''); +} + +function extractOrder(filename: string): number { + const match = filename.match(/^(\d+)/); + return match ? parseInt(match[1], 10) : 999; +} + +export default HomeNavigation; diff --git a/apps/stage/components/pages/home/index.tsx b/apps/stage/components/pages/home/index.tsx new file mode 100644 index 00000000..c64e7f64 --- /dev/null +++ b/apps/stage/components/pages/home/index.tsx @@ -0,0 +1,11 @@ +import { ReactElement } from 'react'; +import PageLayout from '../../PageLayout'; +import HomeContent from './HomeContent'; + +const Home = (): ReactElement => ( + + + +); + +export default Home; diff --git a/apps/stage/components/pages/login/index.tsx b/apps/stage/components/pages/login/index.tsx new file mode 100644 index 00000000..052ec069 --- /dev/null +++ b/apps/stage/components/pages/login/index.tsx @@ -0,0 +1,231 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css } from '@emotion/react'; +import { signIn } from 'next-auth/react'; + +import PageLayout from '../../PageLayout'; + +import { getConfig } from '../../../global/config'; +import { IconProps } from '../../theme/icons/types'; + +import { AUTH_PROVIDER, USER_PATH } from '@/global/utils/constants'; +import { trim } from 'lodash'; +import { usePageQuery } from '../../../global/hooks/usePageContext'; +import { ProviderType } from '../../../global/types/types'; +import providerMap, { ProviderDetail } from '../../../global/utils/providerTypeMap'; +import ErrorNotification from '../../ErrorNotification'; + +const LoginButton = ({ Icon, title, path }: { Icon: React.ComponentType; title: string; path: string }) => { + const { NEXT_PUBLIC_AUTH_PROVIDER } = getConfig(); + + const disabled = true; + // const disabled = !path; + + const handleLogin = () => { + if (NEXT_PUBLIC_AUTH_PROVIDER === AUTH_PROVIDER.KEYCLOAK) { + signIn(AUTH_PROVIDER.KEYCLOAK, { callbackUrl: USER_PATH }); + } else { + return false; + } + }; + + return ( + +
    css` + display: flex; + width: 225px; + height: 42px; + border-radius: 5px; + border: 1px solid ${theme.colors.accent}; + cursor: ${disabled ? 'not-allowed' : 'pointer'}; + opacity: ${disabled ? 0.4 : 1}; + &:hover { + border: 1px solid ${theme.colors.accent_dark}; + } + `} + > + + + + + css` + display: flex; + flex: 4; + justify-content: center; + align-items: center; + background-color: ${theme.colors.accent}; + color: ${theme.colors.white}; + ${theme.typography.button} + border-radius: 0 3px 3px 0; + &:hover { + background-color: ${theme.colors.accent_dark}; + color: ${theme.colors.white}; + } + ` + } + > + {title} + +
    +
    + ); +}; + +const LoginPage = () => { + const query = usePageQuery(); + const { NEXT_PUBLIC_SSO_PROVIDERS, NEXT_PUBLIC_AUTH_PROVIDER } = getConfig(); + + const configuredProviders = NEXT_PUBLIC_SSO_PROVIDERS.length + ? NEXT_PUBLIC_SSO_PROVIDERS.split(',').map((p: string) => trim(p)) + : []; + // typing p arg as 'any' because typescript complains with 'string' + // check configured providers are valid ProviderTypes + const providers: ProviderDetail[] = configuredProviders + .filter((p: any) => Object.values(ProviderType).includes(p)) + .map((provider: string) => providerMap[provider as ProviderType]); + + return ( + +
    +
    + css` + display: flex; + flex: 3; + background-color: ${theme.colors.white}; + flex-direction: column; + justify-content: center; + padding-left: 5rem; + ` + } + > +

    + css` + ${theme.typography.heading} + font-size: 40px; + line-height: 0; + color: ${theme.colors.accent_dark}; + ` + } + > + Coming Soon +

    + {query.session_expired && ( +
    + + Your session has expired. Please log in again. + +
    + )} + {query.error && ( +
    + + Please try again. + +
    + )} + css` + display: block; + max-width: 475px; + ${theme.typography.heading} + color: ${theme.colors.accent_dark}; + margin: 10px 0; + font-weight: normal; + `} + > + Keycloak integration and setup will be included in Prelude version 2.0.0 + + {NEXT_PUBLIC_AUTH_PROVIDER === AUTH_PROVIDER.KEYCLOAK ? ( + + ) : ( +
    + + No identity providers have been configured. Please check you dms configuration file. + +
    + )} +
    +
    +
    css` + flex: 1; + background-color: ${theme.colors.primary}; + `} + /> +
    +
    + + ); +}; + +export default LoginPage; diff --git a/apps/stage/components/pages/molecular/Facets.tsx b/apps/stage/components/pages/molecular/Facets.tsx new file mode 100644 index 00000000..74cadbd3 --- /dev/null +++ b/apps/stage/components/pages/molecular/Facets.tsx @@ -0,0 +1,247 @@ +/* + * + * Copyright (c) 2024 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { StageThemeInterface } from '@/components/theme'; +import { getConfig } from '@/global/config'; +import { css, useTheme } from '@emotion/react'; +import { Aggregations, QuickSearch, useArrangerTheme } from '@overture-stack/arranger-components'; +import { UseThemeContextProps } from '@overture-stack/arranger-components/dist/types'; +import { ReactElement } from 'react'; + +const getAggregationsStyles = (theme: StageThemeInterface): UseThemeContextProps => ({ + callerName: 'Explorer-Facets', + components: { + Aggregations: { + ActionIcon: { + fill: theme.colors.secondary, + }, + AggsGroup: { + collapsedBackground: theme.colors.grey_2, + css: css` + .title { + ${theme.typography.subheading2} + line-height: 20px; + } + // Leaving these toggle-button styles untouch as I haven't been able to test making changes + .toggle-button { + ${theme.typography.data}; + padding: 2px 5px 8px 5px; + margin-left: 5px; + .toggle-button-option { + border: 1px solid ${theme.colors.grey_5}; + &:nth-of-type(2) { + border-left: 0px; + border-right: 0px; + } + } + .toggle-button-option .bucket-count { + ${theme.typography.label2} + display: inline-block; + background-color: ${theme.colors.grey_3}; + padding: 0 3px; + border-radius: 3px; + } + .toggle-button-option.active { + background-color: ${theme.colors.secondary_light}; + .bucket-count { + background-color: ${theme.colors.secondary_2}; + } + } + .toggle-button-option.disabled { + background-color: ${theme.colors.grey_2}; + color: ${theme.colors.grey_6}; + } + } + `, + groupDividerColor: theme.colors.grey_3, + headerBackground: theme.colors.white, + headerDividerColor: theme.colors.grey_2, + headerFontColor: theme.colors.accent_dark, + }, + BucketCount: { + background: `rgba(${theme.colors.accent_light_rgb}, 0.45)`, + fontSize: '0.75rem', + }, + FilterInput: { + css: css` + border-radius: 5px; + border: 1px solid ${theme.colors.secondary}; + margin: 6px 5px 7px 0; + &.focused { + box-shadow: inset 0 0 2px 1px ${theme.colors.accent}; + } + & input { + ${theme.typography.data} + &::placeholder { + color: ${theme.colors.black}; + } + } + input[type='text' i] { + margin-left: 5px; + margin-top: 2px; + } + `, + }, + MoreOrLessButton: { + css: css` + ${theme.typography.label2}; + &::before { + padding-top: 3px; + margin-right: 3px; + } + &.more::before { + content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='11' viewBox='0 0 11 11'%3E%3Cpath fill='%2304518C' fill-rule='evenodd' d='M7.637 6.029H6.034v1.613c0 .291-.24.53-.534.53-.294 0-.534-.239-.534-.53V6.03H3.363c-.294 0-.534-.238-.534-.529 0-.29.24-.529.534-.529h1.603V3.358c0-.291.24-.53.534-.53.294 0 .534.239.534.53V4.97h1.603c.294 0 .534.238.534.529 0 .29-.24.529-.534.529M5.5 0C2.462 0 0 2.462 0 5.5S2.462 11 5.5 11 11 8.538 11 5.5 8.538 0 5.5 0'/%3E%3C/svg%3E%0A"); + } + &.less::before { + content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='11' viewBox='0 0 20 20'%3E%3Cpath fill='%2304518c' fill-rule='evenodd' d='M13.81 10.952H6.19c-.523 0-.952-.428-.952-.952s.429-.952.952-.952h7.62c.523 0 .952.428.952.952s-.429.952-.952.952M10 0C4.476 0 0 4.476 0 10s4.476 10 10 10 10-4.476 10-10S15.524 0 10 0'/%3E%3C/svg%3E%0A"); + } + `, + fontColor: theme.colors.primary, + }, + RangeAgg: { + css: css` + &[data-fieldName='analysis.host.host_age'] .unit-wrapper { + display: none; + } + `, + RangeLabel: { + borderRadius: '0.2rem', + fontWeight: 'bold !important', + css: css` + ${theme.typography.label2} + background-color: ${theme.colors.grey_3}; + &:last-of-type, + &:nth-of-type(4) { + background-color: ${theme.colors.white}; + color: ${theme.colors.grey_6}; + } + `, + padding: '0 0.2rem', + }, + // slider is the button that you drag to select values + RangeSlider: { + borderColor: theme.colors.grey_5, + css: theme.shadow.default, + disabledBackground: theme.colors.grey_3, + }, + // the band upon which the sliders move + RangeTrack: { + disabledInBackground: theme.colors.grey_4, + disabledOutBackground: theme.colors.grey_3, + inBackground: theme.colors.primary_dark, + outBackground: theme.colors.grey_4, + }, + }, + TreeJointIcon: { + fill: theme.colors.primary_dark, + size: 8, + transition: 'all 0s', + }, + }, + QuickSearch: { + fieldNames: 'donors.specimens.submitter_specimen_id', + headerTitle: 'Specimen Collector Sample ID', + placeholder: 'e.g. AB-12345', + + // components + DropDownItems: { + css: css` + border: 1px solid ${theme.colors.secondary}; + border-radius: 5px; + `, + entityLogo: { + enabled: false, + }, + resultKeyText: { + css: css` + margin-left: 20px; + font-weight: bold; + `, + }, + resultValue: { + css: css` + margin-left: 20px; + `, + }, + }, + QuickSearchWrapper: { + css: css` + .title { + ${theme.typography.subheading2} + line-height: 20px; + } + `, + }, + TreeJointIcon: { + fill: theme.colors.primary_dark, + size: 8, + transition: 'all 0s', + }, + PinnedValues: { + background: theme.colors.primary_dark, + css: css` + ${theme.typography.label} + &::after { + content: url(data:image/svg+xml,%3Csvg%20width%3D%228%22%20height%3D%228%22%20stroke%3D%22white%22%20stroke-width%3D%222%22%3E%0A%20%20%3Cline%20x1%3D%220%22%20y1%3D%220%22%20x2%3D%228%22%20y2%3D%228%22%20/%3E%0A%20%20%3Cline%20x1%3D%228%22%20y1%3D%220%22%20x2%3D%220%22%20y2%3D%228%22%20/%3E%0A%3C/svg%3E); + margin: 0 0 0 0.5rem; + } + `, + fontColor: theme.colors.white, + hoverBackground: theme.colors.primary, + margin: '0.1rem', + padding: '0 0.5rem', + }, + }, + }, +}); + +const Facets = (): ReactElement => { + const { NEXT_PUBLIC_ENABLE_MOLECULAR_QUICKSEARCH } = getConfig(); + const theme = useTheme(); + useArrangerTheme(getAggregationsStyles(theme)); + + return ( +
    +

    + Filters +

    + + {NEXT_PUBLIC_ENABLE_MOLECULAR_QUICKSEARCH && } + + +
    + ); +}; + +export default Facets; diff --git a/apps/stage/components/pages/molecular/PageContent.tsx b/apps/stage/components/pages/molecular/PageContent.tsx new file mode 100644 index 00000000..cdc70850 --- /dev/null +++ b/apps/stage/components/pages/molecular/PageContent.tsx @@ -0,0 +1,128 @@ +/* + * + * Copyright (c) 2024 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { useEffect, useMemo, useState } from 'react'; +import { css, useTheme } from '@emotion/react'; +import { useArrangerData } from '@overture-stack/arranger-components'; +import { SQONType } from '@overture-stack/arranger-components/dist/DataContext/types'; +import stringify from 'fast-json-stable-stringify'; +import { isEqual } from 'lodash'; + +import useUrlParamState from '@/global/hooks/useUrlParamsState'; + +import Facets from './Facets'; +import RepoTable from './RepoTable'; +import QueryBar from './QueryBar'; + +const PageContent = () => { + const theme = useTheme(); + const [showSidebar, setShowSidebar] = useState(true); + const sidebarWidth = showSidebar ? theme.dimensions.facets.width : 0; + + // TODO: abstract this param handling into an Arranger integration. + const { sqon, setSQON } = useArrangerData({ callerName: 'Explorer-PageContent' }); + const [firstRender, setFirstRender] = useState(true); + const [currentFilters, setCurrentFilters] = useUrlParamState('filters', null, { + prepare: (v) => v.replace('"field"', '"fieldName"'), + deSerialize: (v) => { + return v ? JSON.parse(v) : null; + }, + serialize: (v) => (v ? stringify(v) : ''), + }); + + useEffect(() => { + if (firstRender) { + currentFilters && setSQON(currentFilters); + setFirstRender(false); + } + }, [currentFilters, firstRender, setSQON]); + + useEffect(() => { + firstRender || isEqual(sqon, currentFilters) || setCurrentFilters(sqon); + }, [currentFilters, firstRender, setCurrentFilters, sqon]); + + return useMemo( + () => ( +
    +
    + {/* WIP button to hide/show the sidebar + */} + + +
    +
    + + +
    +
    +
    +
    + ), + [], + ); +}; + +export default PageContent; diff --git a/apps/stage/components/pages/molecular/QueryBar.tsx b/apps/stage/components/pages/molecular/QueryBar.tsx new file mode 100644 index 00000000..e25e805e --- /dev/null +++ b/apps/stage/components/pages/molecular/QueryBar.tsx @@ -0,0 +1,124 @@ +/* + * + * Copyright (c) 2024 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css, useTheme } from '@emotion/react'; +import { SQONViewer, useArrangerTheme } from '@overture-stack/arranger-components'; +import { UseThemeContextProps } from '@overture-stack/arranger-components/dist/types'; +import { Row } from 'react-grid-system'; + +import { StageThemeInterface } from '@/components/theme'; + +const getThemeCustomisations = (theme: StageThemeInterface): UseThemeContextProps => ({ + callerName: 'Explorer-QueryBar', + components: { + SQONViewer: { + EmptyMessage: { + arrowColor: theme.colors.primary_dark, + }, + SQONBubble: { + borderRadius: '8px', + fontSize: '13px', + fontWeight: 300, + height: '1.6rem', + letterSpacing: '0.2px', + }, + SQONClear: { + label: 'Reset', + borderColor: theme.colors.grey_5, + borderRadius: '5px', + background: theme.colors.primary_dark, + cursor: 'pointer', + fontColor: theme.colors.white, + fontSize: '0.88rem', + fontWeight: 600, + hoverBackground: theme.colors.primary, + padding: '0 12px', + }, + SQONFieldName: { + fontWeight: 'normal', + textTransform: 'uppercase', + }, + SQONGroup: { + fontColor: theme.colors.grey_6, + margin: '0.1rem 0 0', + }, + SQONLessOrMore: { + background: theme.colors.primary_dark, + css: css` + ${theme.typography.label}; + `, + fontColor: theme.colors.white, + hoverBackground: theme.colors.primary, + lineHeight: '1.4rem !important', + margin: '0 0.4rem 0 0', + padding: '0 0.4rem', + textTransform: 'uppercase', + }, + SQONValue: { + background: theme.colors.primary_dark, + css: css` + margin-left: 0; + ${theme.typography.label} + + &::after { + content: url(data:image/svg+xml,%3Csvg%20width%3D%228%22%20height%3D%228%22%20stroke%3D%22white%22%20stroke-width%3D%222%22%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%3E%0A%20%20%3Cline%20x1%3D%220%22%20y1%3D%220%22%20x2%3D%228%22%20y2%3D%228%22%20/%3E%0A%20%20%3Cline%20x1%3D%228%22%20y1%3D%220%22%20x2%3D%220%22%20y2%3D%228%22%20/%3E%0A%3C/svg%3E); + margin: 0 0 0 0.5rem; + } + `, + fontColor: theme.colors.white, + hoverBackground: theme.colors.primary, + margin: '0.1rem 0.4rem', + padding: '0 0.5rem', + }, + SQONValueGroup: { + css: css` + &:last-of-type { + margin-left: 0; + } + `, + fontSize: '1.4rem', + margin: '-0.2rem 0.4rem 0', + }, + }, + }, +}); + +const QueryBar = () => { + const theme = useTheme(); + useArrangerTheme(getThemeCustomisations(theme)); + + return ( + css` + min-height: 48px; + margin: 10px 0; + background-color: ${theme.colors.white}; + border-radius: 5px; + ${theme.shadow.default}; + `} + > + + + ); +}; + +export default QueryBar; diff --git a/apps/stage/components/pages/molecular/RepoTable/helper.ts b/apps/stage/components/pages/molecular/RepoTable/helper.ts new file mode 100644 index 00000000..91ebc5ab --- /dev/null +++ b/apps/stage/components/pages/molecular/RepoTable/helper.ts @@ -0,0 +1,81 @@ +/* + * + * Copyright (c) 2024 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { SQONType } from '@overture-stack/arranger-components/dist/DataContext/types'; +import SQON from '@overture-stack/sqon-builder'; +import { isEmpty } from 'lodash'; + +import createArrangerFetcher from '@/components/utils/arrangerFetcher'; +import { INTERNAL_API_PROXY } from '@/global/utils/constants'; + +export const arrangerFetcher = createArrangerFetcher({ + ARRANGER_API: INTERNAL_API_PROXY.MOLECULAR_ARRANGER, +}); + +const saveSetMutation = `mutation ($sqon: JSON!) { + saveSet( + sqon: $sqon, + type: file, + path: "name" + ) { + setId + } +}`; + +export const saveSet = (sqon: SQONType): Promise => { + return arrangerFetcher({ + body: { + query: saveSetMutation, + variables: { sqon }, + }, + }) + .then( + ({ + data: { + saveSet: { setId }, + }, + }) => { + return setId; + }, + ) + .catch((err: any) => { + console.warn(err); + Promise.reject(err); + }) as Promise; +}; + +export function buildSqonWithObjectIds(currentSqon: SQONType, objectIds: string[]): SQONType { + const objectsSqon = objectIds && objectIds.length > 0 ? SQON.in('object_id', objectIds) : null; + + if (!isEmpty(currentSqon) && !isEmpty(objectsSqon)) { + return currentSqon.and(objectsSqon); + } + + if (isEmpty(currentSqon) && !isEmpty(objectsSqon)) { + return objectsSqon; + } + + if (!isEmpty(currentSqon) && isEmpty(objectsSqon)) { + return currentSqon; + } + + return null; +} diff --git a/apps/stage/components/pages/molecular/RepoTable/index.tsx b/apps/stage/components/pages/molecular/RepoTable/index.tsx new file mode 100644 index 00000000..53591d97 --- /dev/null +++ b/apps/stage/components/pages/molecular/RepoTable/index.tsx @@ -0,0 +1,229 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css, useTheme } from '@emotion/react'; +import { + Pagination, + Table, + TableContextProvider, + Toolbar, + useArrangerTheme, +} from '@overture-stack/arranger-components'; +import { CustomExporterInput } from '@overture-stack/arranger-components/dist/Table/DownloadButton/types'; +import { UseThemeContextProps } from '@overture-stack/arranger-components/dist/ThemeContext/types'; +import { useMemo } from 'react'; +import urlJoin from 'url-join'; + +import StyledLink from '@/components/Link'; +import { StageThemeInterface } from '@/components/theme'; +import { Download } from '@/components/theme/icons'; +import { getConfig } from '@/global/config'; +import { INTERNAL_API_PROXY } from '@/global/utils/constants'; + +const getTableConfigs = ({ + apiHost, + customExporters, + theme, +}: { + apiHost: string; + customExporters?: CustomExporterInput; + theme: StageThemeInterface; +}): UseThemeContextProps => ({ + callerName: 'RepoTable', + components: { + Table: { + // functionality + hideLoader: true, + + // appearance + background: theme.colors.white, + borderColor: theme.colors.grey_3, + css: css` + ${theme.shadow.default} + `, + + // Child components + columnTypes: { + all: { + cellValue: ({ getValue }) => { + const value = getValue(); + return ['', null, 'null', 'NA', undefined, 'undefined'].includes(value) ? ( + + -- + + ) : ( + value + ); + }, + }, + }, + CountDisplay: { + fontColor: 'inherit', + }, + DownloadButton: { + customExporters, + downloadUrl: urlJoin(apiHost, 'download'), + label: () => ( + <> + path { + fill: ${theme.colors.grey_5}; + } + `} + />{' '} + Download + + ), + ListWrapper: { + width: '11rem', + }, + }, + DropDown: { + arrowColor: '#151c3d', + arrowTransition: 'all 0s', + background: theme.colors.white, + borderColor: theme.colors.grey_5, + css: css` + ${theme.typography.subheading2} + line-height: 1.3rem; + `, + fontColor: theme.colors.accent_dark, + disabledFontColor: theme.colors.grey_5, + hoverBackground: theme.colors.secondary_light, + + ListWrapper: { + background: theme.colors.white, + css: css` + ${theme.shadow.default} + `, + fontColor: theme.colors.black, + fontSize: '0.7rem', + hoverBackground: theme.colors.secondary_light, + }, + }, + HeaderRow: { + borderColor: theme.colors.grey_3, + css: css` + ${theme.typography.data} + `, + fontColor: theme.colors.accent_dark, + fontSize: '13px', + fontWeight: 'bold', + lineHeight: '1.7rem', + }, + MaxRowsSelector: { + fontColor: 'inherit', + }, + Row: { + css: css` + &:nth-of-type(2n-1) { + background-color: ${theme.colors.grey_1}; + } + `, + hoverBackground: theme.colors.grey_highlight, + lineHeight: '1.5rem', + selectedBackground: 'pink', + verticalBorderColor: theme.colors.grey_3, + }, + TableWrapper: { + margin: '0.5rem 0', + }, + }, + }, +}); + +const RepoTable = () => { + const { NEXT_PUBLIC_ARRANGER_MANIFEST_COLUMNS } = getConfig(); + const theme = useTheme(); + + const today = new Date().toISOString().slice(0, 10).replace(/-/g, ''); + const manifestColumns = NEXT_PUBLIC_ARRANGER_MANIFEST_COLUMNS.split(',') + .filter((field) => field.trim()) // break it into arrays, and ensure there's no empty field names + .map((fieldName) => fieldName.replace(/['"]+/g, '').trim()); + const customExporters = [ + { label: 'File Table', fileName: `data-explorer-table-export.${today}.tsv` }, // exports a TSV with what is displayed on the table (columns selected, etc.) + { label: 'File Manifest', fileName: `score-manifest.${today}.tsv`, columns: manifestColumns }, // exports a TSV with the manifest columns + { + label: () => ( + + To download files using a file manifest, please follow these + + instructions + + . + + ), + }, + ]; + + useArrangerTheme(getTableConfigs({ apiHost: INTERNAL_API_PROXY.MOLECULAR_ARRANGER, customExporters, theme })); + + return useMemo( + () => ( + <> +
    + + +
    + + + + + ), + [], + ); +}; + +export default RepoTable; diff --git a/apps/stage/components/pages/molecular/getConfigError.tsx b/apps/stage/components/pages/molecular/getConfigError.tsx new file mode 100644 index 00000000..70510be2 --- /dev/null +++ b/apps/stage/components/pages/molecular/getConfigError.tsx @@ -0,0 +1,133 @@ +/* + * + * Copyright (c) 2024 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css, useTheme } from '@emotion/react'; +import { ReactNode } from 'react'; + +import StyledLink from '@/components/Link'; +import { GenericHelpMessage } from '@/components/PlatformAdminContact'; +import { Checkmark, Warning } from '@/components/theme/icons'; +import { getConfig } from '@/global/config'; + +const ArrangerAdminUILink = () => { + const { NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_ADMIN_UI } = getConfig(); + return ( + + Arranger Admin UI + + ); +}; + +const ListItem = ({ Icon, value, fieldName }: { Icon?: ReactNode; value: string; fieldName: string }) => { + const theme = useTheme(); + + return ( +
  • + {Icon || } + + {fieldName}:{' '} + + {value} + + +
  • + ); +}; + +const WarningListItem = ({ fieldName }: { fieldName: string }) => ( + } fieldName={fieldName} value={'Missing'} /> +); + +const getConfigError = ({ + hasConfig, + documentType, + index, +}: { + hasConfig: boolean; + documentType: string; + index: string; +}) => + index && documentType ? ( + !hasConfig && ( + + No active configurations for the DMS portal were found. Please make sure the index and GraphQL document type + specified in the DMS{' '} + + config.yaml + {' '} + file during installation have been created in the . + + ) + ) : ( + + One or more of the following values required by the DMS portal do not exist. Please make sure the values are + specified in the DMS{' '} + + config.yaml + {' '} + file during installation and have been used to create your project in the .{' '} + +
      + {[ + { fieldName: 'GraphQL Document type', value: documentType }, + { fieldName: 'Elasticsearch index', value: index }, + ].map(({ fieldName, value }) => { + return value ? ( + + ) : ( + + ); + })} +
    +
    + ); + +export default getConfigError; diff --git a/apps/stage/components/pages/molecular/index.tsx b/apps/stage/components/pages/molecular/index.tsx new file mode 100644 index 00000000..f9c59c8d --- /dev/null +++ b/apps/stage/components/pages/molecular/index.tsx @@ -0,0 +1,163 @@ +/* + * + * Copyright (c) 2024 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css, useTheme } from '@emotion/react'; +import { ArrangerDataProvider } from '@overture-stack/arranger-components'; +import { ReactElement, useEffect, useState } from 'react'; + +import ErrorNotification from '@/components/ErrorNotification'; +import Loader from '@/components/Loader'; +import PageLayout from '@/components/PageLayout'; +import sleep from '@/components/utils/sleep'; +import { getConfig } from '@/global/config'; +import { RepoFiltersType } from '@/global/types/sqon'; + +import getConfigError from './getConfigError'; +import PageContent from './PageContent'; +import { arrangerFetcher } from './RepoTable/helper'; + +export interface PageContentProps { + sqon: RepoFiltersType; + selectedTableRows: string[]; + setSelectedTableRows: (ids: []) => void; + index: string; + api: ({ + endpoint, + body, + headers, + method, + }: { + endpoint: string; + body: string; + headers: any; + method: string; + }) => Promise; + setSQON: (sqon: RepoFiltersType) => void; + fetchData?: () => Promise; +} + +const { + NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_API, + NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_DOCUMENT_TYPE, + NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_INDEX, +} = getConfig(); + +const configsQuery = ` + query ($documentType: String!, $index: String!) { + hasValidConfig (documentType: $documentType, index: $index) + } +`; + +const MolecularRepositoryPage = (): ReactElement => { + const theme = useTheme(); + const [arrangerHasConfig, setArrangerHasConfig] = useState(false); + const [loadingArrangerConfig, setLoadingArrangerConfig] = useState(true); + + useEffect(() => { + arrangerFetcher({ + endpoint: 'graphql/hasValidConfig', + body: JSON.stringify({ + variables: { + documentType: NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_DOCUMENT_TYPE, + index: NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_INDEX, + }, + query: configsQuery, + }), + }) + .then(async ({ data } = {}) => { + if (data?.hasValidConfig) { + await setArrangerHasConfig(data.hasValidConfig); + // 1s delay so loader doesn't flicker on and off too quickly + await sleep(1000); + + return setLoadingArrangerConfig(false); + } + + throw new Error('Could not validate Arranger server configuration!'); + }) + .catch(async (err) => { + console.warn(err); + // same as above comment + await sleep(1000); + setLoadingArrangerConfig(false); + }); + }, [NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_DOCUMENT_TYPE, NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_INDEX]); + + const ConfigError = getConfigError({ + hasConfig: arrangerHasConfig, + index: NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_INDEX, + documentType: NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_DOCUMENT_TYPE, + }); + + return ( + + {loadingArrangerConfig ? ( +
    + +
    + ) : ConfigError ? ( + + {ConfigError} + + ) : ( + + + + )} +
    + ); +}; + +export default MolecularRepositoryPage; diff --git a/apps/stage/components/pages/molecular/sqonTypes.ts b/apps/stage/components/pages/molecular/sqonTypes.ts new file mode 100644 index 00000000..66ad04a1 --- /dev/null +++ b/apps/stage/components/pages/molecular/sqonTypes.ts @@ -0,0 +1,66 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +export type ArrayFieldKeys = 'in' | 'is' | 'filter'; + +export type ScalarFieldKeys = '>=' | '<=' | '>' | '<'; + +export type CombinationKeys = 'and' | 'or' | 'not'; + +export type ArrayFieldValue = Array | string; +export type ScalarFieldValue = number; + +export interface FilterField { + fields: string[]; + value: ArrayFieldValue; +} + +export interface FilterFieldOperator { + op: ArrayFieldKeys; + content: FilterField; +} + +export interface ArrayField { + field: string; + value: ArrayFieldValue; +} + +export interface ScalarField { + field: string; + value: ScalarFieldValue; +} + +export interface ArrayFieldOperator { + op: ArrayFieldKeys; + content: ArrayField; +} + +export interface ScalarFieldOperator { + op: ScalarFieldKeys; + content: ScalarField; +} + +export type FieldOperator = ArrayFieldOperator | ScalarFieldOperator; + +export type RepoFiltersType = { + op: 'and'; + content: FieldOperator[]; +}; diff --git a/apps/stage/components/pages/swaggerDocs/Lectern.tsx b/apps/stage/components/pages/swaggerDocs/Lectern.tsx new file mode 100644 index 00000000..d4edb7b2 --- /dev/null +++ b/apps/stage/components/pages/swaggerDocs/Lectern.tsx @@ -0,0 +1,230 @@ +import { css } from '@emotion/react'; +import dynamic from 'next/dynamic'; +import { useEffect, useState } from 'react'; +import { SwaggerUIProps } from 'swagger-ui-react'; +import 'swagger-ui-react/swagger-ui.css'; +import PageLayout from '../../PageLayout'; + +const SwaggerUI = dynamic(() => import('swagger-ui-react'), { + ssr: false, +}); + +// Import Type from swagger-ui-react or use a more compatible interface +// Note: In swagger-ui, a Request object has a url property but it's not strictly typed +type SwaggerRequest = { + url: string; + [key: string]: any; +}; + +type SwaggerResponse = { + [key: string]: any; +}; + +const Lectern = () => { + const [swaggerSpec, setSwaggerSpec] = useState(null); + const [error, setError] = useState(null); + const [swaggerUrl, setSwaggerUrl] = useState(null); + + useEffect(() => { + const tryFetchSwaggerSpec = async () => { + // Try multiple possible paths for Swagger documentation + const possiblePaths = [ + '/api/lectern/api-docs', + '/api/lectern/swagger', + '/api/lectern/docs', + '/api/lectern/openapi', + '/api/lectern/v2/api-docs', + ]; + + // Try all paths until one works + for (const path of possiblePaths) { + try { + console.log(`Attempting to fetch Swagger spec from: ${path}`); + const response = await fetch(path); + + if (response.ok) { + console.log(`Success fetching from: ${path}`); + const data = await response.json(); + + // Modify the spec to use our proxy + const modifiedSpec = { + ...data, + servers: [ + { + url: '/api/lectern', + description: 'Lectern API (Proxied)', + }, + ], + // Ensure all paths start with our proxy path + paths: Object.entries(data.paths || {}).reduce( + (acc, [path, methods]) => ({ + ...acc, + [path.startsWith('/') ? path : `/${path}`]: methods, + }), + {}, + ), + }; + + setSwaggerSpec(modifiedSpec); + return; // Exit after successful fetch + } + } catch (err) { + console.log(`Failed to fetch from ${path}:`, err); + } + } + + // If we get here, none of the paths worked - fall back to direct URL mode + console.log('All fetch attempts failed, falling back to direct URL mode'); + setSwaggerUrl('/api/lectern/api-docs'); + + // Only set error if we're not using fallback URL mode + if (!swaggerUrl) { + setError('Failed to load API documentation. The Lectern service may not be available.'); + } + }; + + tryFetchSwaggerSpec(); + }, [swaggerUrl]); + + // Use type assertion to make TypeScript happy + const requestInterceptor = (req: any) => { + console.log('Intercepting request:', req.url); + + // Check if the URL is already absolute (starts with http:// or https://) + if (req.url.match(/^https?:\/\//)) { + // Extract the path portion of the URL (everything after the domain) + const urlObj = new URL(req.url); + const pathWithQuery = urlObj.pathname + urlObj.search; + + // Replace the URL with our proxy path + the extracted path + req.url = `/api/lectern${pathWithQuery.startsWith('/') ? '' : '/'}${pathWithQuery}`; + } + // For relative URLs, just prepend our proxy path if needed + else if (!req.url.startsWith('/api/lectern')) { + req.url = `/api/lectern${req.url.startsWith('/') ? '' : '/'}${req.url}`; + } + + console.log('Modified request:', req.url); + return req; + }; + + // Use type assertion to make TypeScript happy + const responseInterceptor = (res: any) => { + console.log('Response received:', res); + return res; + }; + + const swaggerConfig: SwaggerUIProps = swaggerSpec + ? { + // Use pre-fetched spec if available + spec: swaggerSpec, + docExpansion: 'none', + filter: true, + defaultModelExpandDepth: 1, + plugins: [], + presets: [], + layout: 'BaseLayout', + requestInterceptor, + responseInterceptor, + } + : { + // Fallback to URL mode + url: swaggerUrl || '/api/lectern/api-docs', + docExpansion: 'none', + filter: true, + defaultModelExpandDepth: 1, + plugins: [], + presets: [], + layout: 'BaseLayout', + requestInterceptor, + responseInterceptor, + }; + + if (error && !swaggerUrl) { + return ( + +
    +
    + {error} +
    + +
    +
    +
    +
    + ); + } + + if (!swaggerSpec && !swaggerUrl) { + return ( + +
    +
    Loading API documentation...
    +
    +
    + ); + } + + return ( + +
    + +
    +
    + ); +}; + +const containerStyle = css` + padding: 20px; + max-width: 1200px; + margin: 0 auto; + + h1 { + margin-bottom: 20px; + } + + .swagger-ui { + .info { + margin: 20px 0; + } + + .opblock { + margin: 0 0 15px; + } + } +`; + +const loadingStyle = css` + text-align: center; + padding: 2rem; + font-size: 1.2rem; + color: #666; +`; + +const errorStyle = css` + text-align: center; + padding: 2rem; + color: #dc3545; + font-size: 1.2rem; + background: #fff; + border-radius: 4px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); +`; + +export default Lectern; diff --git a/apps/stage/components/pages/swaggerDocs/Lyric.tsx b/apps/stage/components/pages/swaggerDocs/Lyric.tsx new file mode 100644 index 00000000..61c5b988 --- /dev/null +++ b/apps/stage/components/pages/swaggerDocs/Lyric.tsx @@ -0,0 +1,343 @@ +import { css } from '@emotion/react'; +import dynamic from 'next/dynamic'; +import { useEffect, useState } from 'react'; +import { SwaggerUIProps } from 'swagger-ui-react'; +import 'swagger-ui-react/swagger-ui.css'; +import PageLayout from '../../PageLayout'; + +const SwaggerUI = dynamic(() => import('swagger-ui-react'), { + ssr: false, +}); + +const Lyric = () => { + const [swaggerSpec, setSwaggerSpec] = useState(null); + const [error, setError] = useState(null); + const [swaggerUrl, setSwaggerUrl] = useState(null); + const [debugInfo, setDebugInfo] = useState([]); + const [showDebug, setShowDebug] = useState(false); + + const addDebugInfo = (info: string) => { + console.log('Debug:', info); + setDebugInfo((prev) => [...prev, info]); + }; + + useEffect(() => { + const tryFetchSwaggerSpec = async () => { + // Try multiple possible paths for Swagger documentation + const possiblePaths = [ + '/api/lyric/api-docs', + '/api/lyric/swagger', + '/api/lyric/docs', + '/api/lyric/openapi', + '/api/lyric/v2/api-docs', + ]; + + addDebugInfo(`Starting fetch attempts at ${new Date().toISOString()}`); + + // Try all paths until one works + for (const path of possiblePaths) { + try { + addDebugInfo(`Attempting to fetch from: ${path}`); + const response = await fetch(path); + + addDebugInfo(`Response from ${path}: status ${response.status}`); + + if (response.ok) { + addDebugInfo(`Success fetching from: ${path}`); + const data = await response.json(); + addDebugInfo(`Parsed JSON data successfully`); + + // Modify the spec to use our proxy + const modifiedSpec = { + ...data, + servers: [ + { + url: '/api/lyric', + description: 'Lyric API (Proxied)', + }, + ], + // Ensure all paths start with our proxy path + paths: Object.entries(data.paths || {}).reduce( + (acc, [path, methods]) => ({ + ...acc, + [path.startsWith('/') ? path : `/${path}`]: methods, + }), + {}, + ), + }; + + setSwaggerSpec(modifiedSpec); + return; // Exit after successful fetch + } + } catch (err) { + addDebugInfo(`Error fetching from ${path}: ${err instanceof Error ? err.message : String(err)}`); + } + } + + // If we get here, none of the paths worked + addDebugInfo('All fetch attempts failed, falling back to direct URL mode'); + setSwaggerUrl('/api/lyric/api-docs'); + + // Only set error if we're not using fallback URL mode + if (!swaggerUrl) { + setError('Failed to load API documentation. The Lyric service may not be available.'); + } + }; + + tryFetchSwaggerSpec(); + }, [swaggerUrl]); + + // Use type 'any' to avoid TypeScript errors with swagger-ui-react types + const requestInterceptor = (req: any) => { + console.log('Intercepting request:', req.url); + addDebugInfo(`Intercepting request: ${req.url}`); + + // Check if the URL is already absolute (starts with http:// or https://) + if (req.url.match(/^https?:\/\//)) { + // Extract the path portion of the URL (everything after the domain) + const urlObj = new URL(req.url); + const pathWithQuery = urlObj.pathname + urlObj.search; + + // Replace the URL with our proxy path + the extracted path + req.url = `/api/lyric${pathWithQuery.startsWith('/') ? '' : '/'}${pathWithQuery}`; + } + // For relative URLs, just prepend our proxy path if needed + else if (!req.url.startsWith('/api/lyric')) { + req.url = `/api/lyric${req.url.startsWith('/') ? '' : '/'}${req.url}`; + } + + addDebugInfo(`Modified request to: ${req.url}`); + return req; + }; + + // Use type 'any' to avoid TypeScript errors with swagger-ui-react types + const responseInterceptor = (res: any) => { + console.log('Response received:', res); + + // Add response info to debug log if possible + try { + if (res && res.status) { + addDebugInfo(`Response received: status ${res.status}`); + } else { + addDebugInfo(`Response received (no status available)`); + } + } catch (e) { + addDebugInfo(`Error logging response: ${e instanceof Error ? e.message : String(e)}`); + } + + return res; + }; + + const swaggerConfig: SwaggerUIProps = swaggerSpec + ? { + // Use pre-fetched spec if available + spec: swaggerSpec, + docExpansion: 'none', + filter: true, + defaultModelExpandDepth: 1, + plugins: [], + presets: [], + layout: 'BaseLayout', + requestInterceptor, + responseInterceptor, + } + : { + // Fallback to URL mode + url: swaggerUrl || '/api/lyric/api-docs', + docExpansion: 'none', + filter: true, + defaultModelExpandDepth: 1, + plugins: [], + presets: [], + layout: 'BaseLayout', + requestInterceptor, + responseInterceptor, + }; + + if (error && !swaggerUrl) { + return ( + +
    +
    + {error} +
    + + +
    +
    + + {showDebug && ( +
    +

    Debug Information:

    +

    Lyric service should be running at http://localhost:3030 (check env config)

    +

    + To access Swagger directly, try:{' '} + + http://localhost:3030/api-docs + +

    +
    + +
    + {debugInfo.map((info, index) => ( +
    + {info} +
    + ))} +
    +
    + )} +
    +
    + ); + } + + if (!swaggerSpec && !swaggerUrl) { + return ( + +
    +
    Loading API documentation...
    +
    +
    + ); + } + + return ( + +
    +
    + +
    + + {showDebug && ( +
    +

    Debug Information:

    +
    + {debugInfo.map((info, index) => ( +
    + {info} +
    + ))} +
    +
    + )} + + +
    +
    + ); +}; + +const containerStyle = css` + padding: 20px; + max-width: 1200px; + margin: 0 auto; + + h1 { + margin-bottom: 20px; + } + + .swagger-ui { + .info { + margin: 20px 0; + } + + .opblock { + margin: 0 0 15px; + } + } +`; + +const loadingStyle = css` + text-align: center; + padding: 2rem; + font-size: 1.2rem; + color: #666; +`; + +const errorStyle = css` + text-align: center; + padding: 2rem; + color: #dc3545; + font-size: 1.2rem; + background: #fff; + border-radius: 4px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + margin-bottom: 20px; +`; + +const debugStyle = css` + margin-top: 20px; + margin-bottom: 20px; + padding: 15px; + background: #f9f9f9; + border: 1px solid #ddd; + border-radius: 4px; +`; + +export default Lyric; diff --git a/apps/stage/components/pages/swaggerDocs/Score.tsx b/apps/stage/components/pages/swaggerDocs/Score.tsx new file mode 100644 index 00000000..9626d43d --- /dev/null +++ b/apps/stage/components/pages/swaggerDocs/Score.tsx @@ -0,0 +1,160 @@ +import { css } from '@emotion/react'; +import dynamic from 'next/dynamic'; +import { useEffect, useState } from 'react'; +import { SwaggerUIProps } from 'swagger-ui-react'; +import 'swagger-ui-react/swagger-ui.css'; +import PageLayout from '../../PageLayout'; + +const SwaggerUI = dynamic(() => import('swagger-ui-react'), { + ssr: false, +}); + +const Score = () => { + const [swaggerSpec, setSwaggerSpec] = useState(null); + const [error, setError] = useState(null); + + useEffect(() => { + const fetchSwaggerSpec = async () => { + try { + // Try to fetch directly from Score service first + const response = await fetch('/api/score/v2/api-docs'); + + console.log('Response status:', response.status); + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + + const data = await response.json(); + console.log('Received Swagger spec:', data); + + // Modify the spec to use our proxy + const modifiedSpec = { + ...data, + servers: [ + { + url: '/api/score', + description: 'Score API (Proxied)', + }, + ], + // Ensure all paths start with our proxy path + paths: Object.entries(data.paths).reduce( + (acc, [path, methods]) => ({ + ...acc, + [path.startsWith('/') ? path : `/${path}`]: methods, + }), + {}, + ), + }; + + setSwaggerSpec(modifiedSpec); + } catch (err) { + console.error('Failed to fetch Swagger spec:', err); + setError('Failed to load API documentation. Please try again later.'); + } + }; + + fetchSwaggerSpec(); + }, []); + + const swaggerConfig: SwaggerUIProps = { + spec: swaggerSpec, + docExpansion: 'none', + filter: true, + defaultModelExpandDepth: 1, + plugins: [], + presets: [], + layout: 'BaseLayout', + requestInterceptor: (req) => { + console.log('Intercepting request:', req.url); + + // Check if the URL is already absolute (starts with http:// or https://) + if (req.url.match(/^https?:\/\//)) { + // Extract the path portion of the URL (everything after the domain) + const urlObj = new URL(req.url); + const pathWithQuery = urlObj.pathname + urlObj.search; + + // Replace the URL with our proxy path + the extracted path + req.url = `/api/score${pathWithQuery.startsWith('/') ? '' : '/'}${pathWithQuery}`; + } + // For relative URLs, just prepend our proxy path if needed + else if (!req.url.startsWith('/api/score')) { + req.url = `/api/score${req.url.startsWith('/') ? '' : '/'}${req.url}`; + } + + console.log('Modified request:', req.url); + return req; + }, + responseInterceptor: (res) => { + console.log('Response received:', res); + return res; + }, + }; + + if (error) { + return ( + +
    +
    {error}
    +
    +
    + ); + } + + if (!swaggerSpec) { + return ( + +
    +
    Loading API documentation...
    +
    +
    + ); + } + + return ( + +
    + +
    +
    + ); +}; + +const containerStyle = css` + padding: 20px; + width: 90%; + margin: 0 auto; + + h1 { + margin-bottom: 20px; + } + + .swagger-ui { + .info { + margin: 20px 0; + } + + .opblock { + margin: 0 0 15px; + } + } +`; + +const loadingStyle = css` + text-align: center; + padding: 2rem; + font-size: 1.2rem; + color: #666; +`; + +const errorStyle = css` + text-align: center; + padding: 2rem; + color: #dc3545; + font-size: 1.2rem; + background: #fff; + border-radius: 4px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); +`; + +export default Score; diff --git a/apps/stage/components/pages/swaggerDocs/Song.tsx b/apps/stage/components/pages/swaggerDocs/Song.tsx new file mode 100644 index 00000000..f8e72b28 --- /dev/null +++ b/apps/stage/components/pages/swaggerDocs/Song.tsx @@ -0,0 +1,162 @@ +import { css } from '@emotion/react'; +import dynamic from 'next/dynamic'; +import { useEffect, useState } from 'react'; +import { SwaggerUIProps } from 'swagger-ui-react'; +import 'swagger-ui-react/swagger-ui.css'; +import PageLayout from '../../PageLayout'; + +const SwaggerUI = dynamic(() => import('swagger-ui-react'), { + ssr: false, +}); + +const Song = () => { + const [swaggerSpec, setSwaggerSpec] = useState(null); + const [error, setError] = useState(null); + + useEffect(() => { + const fetchSwaggerSpec = async () => { + try { + // Try to fetch directly from Song service first + const response = await fetch('/api/song/v2/api-docs'); + + console.log('Response status:', response.status); + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + + const data = await response.json(); + console.log('Received Swagger spec:', data); + + // Modify the spec to use our proxy + const modifiedSpec = { + ...data, + servers: [ + { + url: '/api/song', + description: 'Song API (Proxied)', + }, + ], + // Ensure all paths start with our proxy path + paths: Object.entries(data.paths).reduce( + (acc, [path, methods]) => ({ + ...acc, + [path.startsWith('/') ? path : `/${path}`]: methods, + }), + {}, + ), + }; + + setSwaggerSpec(modifiedSpec); + } catch (err) { + console.error('Failed to fetch Swagger spec:', err); + setError('Failed to load API documentation. Please try again later.'); + } + }; + + fetchSwaggerSpec(); + }, []); + + const swaggerConfig: SwaggerUIProps = { + spec: swaggerSpec, + docExpansion: 'none', + filter: true, + defaultModelExpandDepth: 1, + plugins: [], + presets: [], + layout: 'BaseLayout', + // Example for Song.tsx - Apply similar changes to all Swagger components + + requestInterceptor: (req) => { + console.log('Intercepting request:', req.url); + + // Check if the URL is already absolute (starts with http:// or https://) + if (req.url.match(/^https?:\/\//)) { + // Extract the path portion of the URL (everything after the domain) + const urlObj = new URL(req.url); + const pathWithQuery = urlObj.pathname + urlObj.search; + + // Replace the URL with our proxy path + the extracted path + req.url = `/api/song${pathWithQuery.startsWith('/') ? '' : '/'}${pathWithQuery}`; + } + // For relative URLs, just prepend our proxy path if needed + else if (!req.url.startsWith('/api/song')) { + req.url = `/api/song${req.url.startsWith('/') ? '' : '/'}${req.url}`; + } + + console.log('Modified request:', req.url); + return req; + }, + responseInterceptor: (res) => { + console.log('Response received:', res); + return res; + }, + }; + + if (error) { + return ( + +
    +
    {error}
    +
    +
    + ); + } + + if (!swaggerSpec) { + return ( + +
    +
    Loading API documentation...
    +
    +
    + ); + } + + return ( + +
    + +
    +
    + ); +}; + +const containerStyle = css` + padding: 20px; + width: 90%; + margin: 0 auto; + + h1 { + margin-bottom: 20px; + } + + .swagger-ui { + .info { + margin: 20px 0; + } + + .opblock { + margin: 0 0 15px; + } + } +`; + +const loadingStyle = css` + text-align: center; + padding: 2rem; + font-size: 1.2rem; + color: #666; +`; + +const errorStyle = css` + text-align: center; + padding: 2rem; + color: #dc3545; + font-size: 1.2rem; + background: #fff; + border-radius: 4px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); +`; + +export default Song; diff --git a/apps/stage/components/pages/user/ApiTokenInfo.tsx b/apps/stage/components/pages/user/ApiTokenInfo.tsx new file mode 100644 index 00000000..a285d00b --- /dev/null +++ b/apps/stage/components/pages/user/ApiTokenInfo.tsx @@ -0,0 +1,555 @@ +/* + * Copyright (c) 2024 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import { css, Global, useTheme } from '@emotion/react'; +import styled from '@emotion/styled'; +import { has, isEmpty, orderBy } from 'lodash'; +import React, { FunctionComponent, ReactNode, useEffect, useState } from 'react'; +import { Tooltip, TooltipProps } from 'react-tippy'; + +import useAuthContext from '../../../global/hooks/useAuthContext'; +import { getDayValue, parseExpiry } from '../../../global/utils/apiToken'; +import { INTERNAL_API_PROXY } from '../../../global/utils/constants'; + +import Button from '../../Button'; +import ErrorNotification from '../../ErrorNotification'; +import StyledLink from '../../Link'; +import { Checkmark } from '../../theme/icons'; + +import { permissionBodyParams, scopesFromPermissions } from '@/global/utils/keycloakUtils'; +import urlJoin from 'url-join'; +import PlatformAdminContact, { GenericHelpMessage } from '../../PlatformAdminContact'; +import sleep from '../../utils/sleep'; + +export enum AccessLevel { + READ = 'READ', + WRITE = 'WRITE', + DENY = 'DENY', + ADMIN = 'ADMIN', +} + +export interface ScopeObj { + policy: string; + accessLevel: AccessLevel; +} + +const parseScope = (scope: string): ScopeObj => { + const [policy, accessLevel] = scope.split('.'); + return { + policy, + accessLevel: accessLevel as AccessLevel, + }; +}; + +interface ApiToken { + expiryDate: string; + isRevoked: boolean; + issueDate: string; + name?: string; + scope: string[]; +} + +interface CustomTooltipProps extends TooltipProps { + children: ReactNode; +} + +const CustomTooltip: FunctionComponent = (props) => React.cloneElement(, { ...props }); + +const TooltipContainer = styled('div')` + ${({ theme }) => css` + ${theme.typography.label}; + background: ${theme.colors.grey_6}; + border-radius: 2px; + padding: 2px 4px; + color: white; + font-weight: normal; + margin-bottom: 10%; + &:before { + content: ''; + display: block; + position: absolute; + width: 0; + height: 0; + border: 5px solid transparent; + pointer-events: none; + right: 50%; + top: 79%; + border-top-color: ${theme.colors.grey_6}; + border-right: 5px solid transparent; + border-left: 5px solid transparent; + margin-right: -5px; + } + `} +`; + +enum ApiTokenErrorType { + SCOPES_ERROR = 'scopes_error', + GENERATE_TOKEN_ERROR = 'generate_token_error', + REVOKE_TOKEN_ERROR = 'revoke_token_error', + FETCH_TOKENS_ERROR = 'fetch_tokens_error', + NO_VALID_PERMISSIONS_ERROR = 'no_valid_permissions_error', +} + +type ErrorResponse = { + type: ApiTokenErrorType; + statusCode?: number; +}; + +const WithGenericHelpMessage = ({ requestError }: { requestError: string }) => { + return ( + + {requestError} + + + ); +}; + +const getErrorMessage = ({ type, statusCode }: ErrorResponse) => { + switch (type) { + case ApiTokenErrorType.SCOPES_ERROR: + return ( + + ); + case ApiTokenErrorType.GENERATE_TOKEN_ERROR: + return ( + + ); + case ApiTokenErrorType.REVOKE_TOKEN_ERROR: + return ( + + ); + case ApiTokenErrorType.FETCH_TOKENS_ERROR: + return ( + + ); + case ApiTokenErrorType.NO_VALID_PERMISSIONS_ERROR: + return ( + + You do not have permissions to generate an API token. Your permissions may have changed recently. Please + contact the to gain the correct permissions. + + ); + default: + return ; + } +}; + +const ApiTokenInfo = () => { + const { user } = useAuthContext(); + const [existingApiToken, setExistingApiToken] = useState(null); + const [isCopyingToken, setIsCopyingToken] = React.useState(false); + const [copySuccess, setCopySuccess] = React.useState(false); + const [requestError, setRequestError] = React.useState(null); + const theme = useTheme(); + + const apiKeyEndpoint = INTERNAL_API_PROXY.PROTECTED_KEYCLOAK_APIKEY_ENDPOINT; + + const getUserScopes = async (userId: string) => { + return fetch(urlJoin(INTERNAL_API_PROXY.PROTECTED_KEYCLOAK_TOKEN_ENDPOINT), { + method: 'POST', + body: permissionBodyParams(), + }) + .then((res) => { + if (res.status !== 200) { + setRequestError({ type: ApiTokenErrorType.SCOPES_ERROR, statusCode: res.status }); + throw new Error(`${res.status}: ${ApiTokenErrorType.SCOPES_ERROR}`); + } + return res.json(); + }) + .then((permissions) => scopesFromPermissions(permissions)) + .catch((err: Error) => { + console.warn(err); + return err; + }); + }; + + const generateApiToken = async () => { + if (user) { + const scopesResult = await getUserScopes(user?.id); + + // prevent api token request if scopes request fails + if (!Array.isArray(scopesResult)) { + return; + } + + const filteredScopes = scopesResult + .map((s: string) => parseScope(s)) + .filter((s: ScopeObj) => s.accessLevel !== AccessLevel.DENY); + + if (filteredScopes.length) { + const scopeParams = filteredScopes.map((f: ScopeObj) => `${f.policy}.${f.accessLevel}`); + + const searchParam = new URLSearchParams({ user_id: user.id }); + scopeParams.map((param) => searchParam.append('scopes', encodeURIComponent(param))); + + const fullUrlApiKeyService = urlJoin(apiKeyEndpoint, `?${searchParam}`); + + return fetch(fullUrlApiKeyService, { method: 'POST' }) + .then((res) => { + if (res.status !== 200) { + setRequestError({ + type: ApiTokenErrorType.GENERATE_TOKEN_ERROR, + statusCode: res.status, + }); + throw new Error(`${res.status}: ${ApiTokenErrorType.GENERATE_TOKEN_ERROR}`); + } + return res.json(); + }) + .then((newApiToken: ApiToken) => { + setExistingApiToken(newApiToken); + setRequestError(null); + }) + .catch((err: Error) => { + console.warn(err.message); + return err; + }); + } else { + setRequestError({ type: ApiTokenErrorType.NO_VALID_PERMISSIONS_ERROR }); + } + } + }; + + const revokeApiToken = async () => { + return ( + existingApiToken && + fetch(urlJoin(apiKeyEndpoint, `?apiKey=${existingApiToken.name}`), { + method: 'DELETE', + }) + .then((res) => { + if (res.status !== 200) { + setRequestError({ type: ApiTokenErrorType.REVOKE_TOKEN_ERROR, statusCode: res.status }); + throw new Error(`${res.status}: ${ApiTokenErrorType.REVOKE_TOKEN_ERROR}`); + } + setExistingApiToken(null); + setRequestError(null); + }) + .catch((err: Error) => { + console.warn(err); + }) + ); + }; + + const copyApiToken = (text: string) => { + setIsCopyingToken(true); + navigator.clipboard + .writeText(text) + .then(async () => { + await setIsCopyingToken(false); + await setCopySuccess(true); + await sleep(); + setCopySuccess(false); + }) + .catch((err) => { + console.warn('Failed to copy token! ', err); + setIsCopyingToken(false); + }); + }; + + const parsedExpiry: number = existingApiToken ? parseExpiry(existingApiToken?.expiryDate) : 0; + const tokenIsExpired: boolean = has(existingApiToken, 'expiryDate') && parsedExpiry <= 0; + + const displayToken = (token: ApiToken | null) => { + if (!token) { + return 'You have no API token...'; + } else if (token.name) { + return token.name; + } else { + return 'API token encrypted'; + } + }; + + useEffect(() => { + if (user) { + const searchParam = new URLSearchParams({ + sort: 'isRevoked', + sortOrder: 'ASC', + user_id: user.id, + limit: '1000', + }); + + fetch(urlJoin(apiKeyEndpoint, `?${searchParam}`), { method: 'GET' }) + .then((res) => { + if (res.status !== 200) { + setRequestError({ type: ApiTokenErrorType.FETCH_TOKENS_ERROR, statusCode: res.status }); + throw new Error(`${res.status}: ${ApiTokenErrorType.FETCH_TOKENS_ERROR}`); + } + return res.json(); + }) + .then((json) => { + setRequestError(null); + const unrevokedTokens = json.resultSet.filter((r: ApiToken) => !r.isRevoked); + const unrevokedTokensSortedByExpiry = orderBy(unrevokedTokens, 'expiryDate', ['desc']); + const activeToken = unrevokedTokensSortedByExpiry.find((r: ApiToken) => { + const expiry = parseExpiry(r.expiryDate) || 0; + return expiry > 0; + }); + const tokenToDisplay = activeToken || unrevokedTokensSortedByExpiry[0]; + if (tokenToDisplay) { + setExistingApiToken(tokenToDisplay); + } else { + setExistingApiToken(null); + } + }) + .catch((err: Error) => { + console.warn('Error: ' + err.message); + }); + } + }, []); + + const userEffectiveScopes = (user?.scope || []) + .map((s) => parseScope(s)) + .filter((s: ScopeObj) => { + return s.accessLevel !== AccessLevel.DENY; + }); + + const userHasScopes = userEffectiveScopes.length > 0; + + return ( +
    +

    + API Token +

    +
      +
    1. Your API token is used to download controlled access data.
    2. +
    3. + Your API token is associated with your user credentials and should NEVER be shared with + anyone. +
    4. +
    5. When you generate a new token, all previous tokens become invalid.
    6. +
    7. Expired and revoked tokens also become invalid.
    8. +
    +
    + {!userHasScopes && ( + + You do not have permissions to generate an API token. Please contact the to gain + the correct permissions. + + )} +
    + {requestError?.type && ( +
    + setRequestError(null)} + > + + {getErrorMessage(requestError)} + + +
    + )} +
    + + +
    +
    +
    + {existingApiToken && ( +
    + {tokenIsExpired ? 'Expired' : getDayValue(parsedExpiry)} +
    + )} + + {displayToken(existingApiToken)} + +
    + <> + + + Copied! + + } + position="top" + > + + + +
    +
    + + For more information, please read the instructions on how to download data. + +
    +
    + ); +}; + +export default ApiTokenInfo; diff --git a/apps/stage/components/pages/user/AuthenticatedBadge.tsx b/apps/stage/components/pages/user/AuthenticatedBadge.tsx new file mode 100644 index 00000000..2a54bea4 --- /dev/null +++ b/apps/stage/components/pages/user/AuthenticatedBadge.tsx @@ -0,0 +1,72 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css, useTheme } from '@emotion/react'; + +import defaultTheme from '../../theme'; +import { Checkmark } from '../../theme/icons'; +import { ProviderType } from '../../../global/types/types'; +import providerMap from '../../../global/utils/providerTypeMap'; + +const AuthenticatedBadge = ({ provider }: { provider: ProviderType }) => { + const IconComponent = providerMap[provider].icon; + const theme: typeof defaultTheme = useTheme(); + return ( +
    + css` + width: 235px; + max-height: 30px; + border: 1px solid ${theme.colors.grey_5}; + border-radius: 5px; + background-color: ${theme.colors.white}; + ${theme.typography.data}; + display: flex; + justify-content: space-between; + align-items: center; + padding: 2px 7px 0; + ` + } + > + + css` + border-right: 1px solid ${theme.colors.grey_5}; + padding: 0 10px 0 0; + ` + } + > + {IconComponent && } + + css` + ${theme.typography.data}; + color: ${theme.colors.accent_dark}; + `} + > + Authenticated with {providerMap[provider].displayName} + + +
    + ); +}; + +export default AuthenticatedBadge; diff --git a/apps/stage/components/pages/user/index.tsx b/apps/stage/components/pages/user/index.tsx new file mode 100644 index 00000000..7ab5b0c1 --- /dev/null +++ b/apps/stage/components/pages/user/index.tsx @@ -0,0 +1,118 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css } from '@emotion/react'; +import styled from '@emotion/styled'; + +import PageLayout from '../../PageLayout'; +import { OvertureUser } from '../../theme/icons'; +import defaultTheme from '../../theme'; +import useAuthContext from '../../../global/hooks/useAuthContext'; +import AuthenticatedBadge from './AuthenticatedBadge'; +import ApiTokenInfo from './ApiTokenInfo'; + +const StyledPageLayout = styled(PageLayout)` + ${({ theme }: { theme: typeof defaultTheme }) => + css` + background-color: ${theme.colors.white}; + `} +`; + +const FlexDiv = styled('div')` + display: flex; +`; + +const UserInfoContainer = styled(FlexDiv)` + ${({ theme }: { theme: typeof defaultTheme }) => css` + flex-direction: row; + justify-content: space-between; + width: 800px; + margin-top: 1.5rem; + margin-bottom: 0.5rem; + padding-bottom: 2.5rem; + border-bottom: 1px solid ${theme.colors.grey_3}; + `} +`; + +const UserTitle = styled('h1')` + ${({ theme }: { theme: typeof defaultTheme }) => css` + ${theme.typography.regular}; + font-size: 30px; + line-height: 36px; + color: ${theme.colors.accent_dark}; + margin-bottom: 0.5rem; + margin-top: 0.1rem; + `} +`; + +const UserEmail = styled('div')` + ${({ theme }: { theme: typeof defaultTheme }) => css` + ${theme.typography.subheading}; + color: ${theme.colors.accent_dark}; + font-weight: normal; + padding-left: 0.2rem; + `} +`; + +const UserComponent = () => { + const { user } = useAuthContext(); + return ( + + + {user && ( + + + + +
    + {`${user.firstName} ${user.lastName}`} + {user.email || ''} +
    +
    + +
    + +
    + )} +
    +
    + ); +}; + +export default UserComponent; diff --git a/apps/stage/components/theme/colors.ts b/apps/stage/components/theme/colors.ts new file mode 100644 index 00000000..d732abcc --- /dev/null +++ b/apps/stage/components/theme/colors.ts @@ -0,0 +1,292 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +const base = { + white: '#fff', + black: '#282A35', + red: '#9E005D', +}; + +const grey = { + grey_1: '#F2F5F8', + grey_2: '#F2F3F5', + grey_3: '#AEAFB3', + grey_4: '#9BB9D1', + grey_5: '#5E6068', + grey_6: '#282A35', + grey_highlight: '#DFDFE1', +}; + +const primary = { + primary: '#113052', + primary_dark: '#0A1F35', + primary_darker: '#06131F', + primary_light: '#1A4270', + primary_lighter: '#265A97', + primary_lightest: '#3373BF', + primary_pale: '#DAE2EC', + primary_palest: '#EDF1F5', +}; + +// Blue shades from the Secondary palette +const secondary = { + secondary: '#0B75A2', + secondary_dark: '#109ED9', + secondary_light: '#4BC6F0', + secondary_lighter: '#66CEF2', + secondary_lightest: '#AEE5F8', + secondary_pale: '#D2F1FB', + secondary_palest: '#EDF9FD', + + // Legacy names for backward compatibility + secondary_accessible: '#0B75A2', // Using the main secondary color + secondary_1: '#AEE5F8', // Matching secondary_lightest + secondary_2: '#4BC6F0', // Matching secondary_light + secondary_black: '#282A35', // Using the black color +}; + +// Dark blue shades from the Accent 1 palette +const accent1 = { + accent1_dark: '#00305D', + accent1_medium: '#04518C', + accent1_light: '#4F85AE', + accent1_lighter: '#9BB9D1', + accent1_lightest: '#C0D3E2', + accent1_pale: '#E5EDF3', +}; + +// Purple/Pink shades from the Accent 2 palette +const accent2 = { + accent2_dark: '#9E005D', + accent2_medium: '#B74A89', + accent2_light: '#C772A3', + accent2_lighter: '#E2B7D0', + accent2_lightest: '#EDD2E1', + accent2_pale: '#F7ECF3', +}; + +// Yellow/Gold shades from the Accent 3 palette +const accent3 = { + accent3_dark: '#CFD509', + accent3_medium: '#D9DE3A', + accent3_light: '#E4E775', + accent3_lighter: '#F0F2B0', + accent3_lightest: '#F5F7CE', + accent3_pale: '#FBFBEB', +}; + +// Legacy accent properties for backward compatibility +const accent = { + accent: '#0B75A2', // Using the main secondary color + accent_dark: '#00305D', // Using accent1_dark + accent_light: '#C0D3E2', // Using accent1_lightest + accent_light_rgb: '192, 211, 226', // RGB version of accent1_lightest + accent_1: '#E5EDF3', // Using accent1_pale + accent_highlight: '#4F85AE40', // Semi-transparent version of accent1_light +}; + +// Grayscale colors +const grayscale = { + grayscale_dark: '#282A35', + grayscale_medium: '#5E6068', + grayscale_light: '#AEAFB3', + grayscale_lighter: '#DFDFE1', + grayscale_lightest: '#F2F3F5', + grayscale_pale: '#F2F5F8', +}; + +// Gradient colors +const gradients = { + gradient_start: '#45A0D4', + gradient_end: '#6EC9D0', + gradient: 'linear-gradient(90deg, #45A0D4 0%, #6EC9D0 100%)', +}; + +// Success, error, warning states +const success = { + success: '#00A88F', + success_dark: '#00896F', + success_light: '#E6F7F4', +}; + +const error = { + error: '#9E005D', + error_dark: '#7D0049', + error_light: '#F7E6EF', + + // Legacy error names for backward compatibility + error_1: '#F7E6EF', // Using error_light + error_2: '#EDD2E1', // Using accent2_lightest +}; + +const warning = { + warning: '#CFD509', + warning_dark: '#A9AD07', + warning_light: '#F9FAE6', + + // Legacy warning name for backward compatibility + warning_1: '#F9FAE6', // Using warning_light +}; + +export default { + ...base, + ...grey, + ...grayscale, + ...primary, + ...secondary, + ...accent1, + ...accent2, + ...accent3, + ...accent, // Include legacy accent properties + ...gradients, + ...success, + ...error, + ...warning, +}; + +// Clean update for future + +// const home = { +// hero: '#0B75A2', +// main: '#F2F5F8', +// button: '#00A88F', +// highlight: '#109ED9', +// }; + +// const base = { +// white: '#fff', +// black: '#282A35', +// red: '#9E005D', +// }; + +// const grey = { +// grey_1: '#F2F5F8', +// grey_2: '#F2F3F5', +// grey_3: '#AEAFB3', +// grey_4: '#9BB9D1', +// grey_5: '#5E6068', +// grey_6: '#282A35', +// grey_highlight: '#DFDFE1', +// }; + +// // Teal/Green shades from the Primary palette +// const primary = { +// primary: '#00A88F', +// primary_dark: '#00C4A7', +// primary_light: '#00DDBE', +// primary_lighter: '#40E6CF', +// primary_lightest: '#99F1E5', +// primary_pale: '#CCF8F2', +// primary_palest: '#E5FBF8', +// }; + +// // Blue shades from the Secondary palette +// const secondary = { +// secondary: '#0B75A2', +// secondary_dark: '#109ED9', +// secondary_light: '#4BC6F0', +// secondary_lighter: '#66CEF2', +// secondary_lightest: '#AEE5F8', +// secondary_pale: '#D2F1FB', +// secondary_palest: '#EDF9FD', +// }; + +// // Dark blue shades from the Accent 1 palette +// const accent1 = { +// accent1_dark: '#00305D', +// accent1_medium: '#04518C', +// accent1_light: '#4F85AE', +// accent1_lighter: '#9BB9D1', +// accent1_lightest: '#C0D3E2', +// accent1_pale: '#E5EDF3', +// }; + +// // Purple/Pink shades from the Accent 2 palette +// const accent2 = { +// accent2_dark: '#9E005D', +// accent2_medium: '#B74A89', +// accent2_light: '#C772A3', +// accent2_lighter: '#E2B7D0', +// accent2_lightest: '#EDD2E1', +// accent2_pale: '#F7ECF3', +// }; + +// // Yellow/Gold shades from the Accent 3 palette +// const accent3 = { +// accent3_dark: '#CFD509', +// accent3_medium: '#D9DE3A', +// accent3_light: '#E4E775', +// accent3_lighter: '#F0F2B0', +// accent3_lightest: '#F5F7CE', +// accent3_pale: '#FBFBEB', +// }; + +// // Grayscale colors +// const grayscale = { +// grayscale_dark: '#282A35', +// grayscale_medium: '#5E6068', +// grayscale_light: '#AEAFB3', +// grayscale_lighter: '#DFDFE1', +// grayscale_lightest: '#F2F3F5', +// grayscale_pale: '#F2F5F8', +// }; + +// // Gradient colors +// const gradients = { +// gradient_start: '#45A0D4', +// gradient_end: '#6EC9D0', +// gradient: 'linear-gradient(90deg, #45A0D4 0%, #6EC9D0 100%)', +// }; + +// // Success, error, warning states +// const success = { +// success: '#00A88F', +// success_dark: '#00896F', +// success_light: '#E6F7F4', +// }; + +// const error = { +// error: '#9E005D', +// error_dark: '#7D0049', +// error_light: '#F7E6EF', +// }; + +// const warning = { +// warning: '#CFD509', +// warning_dark: '#A9AD07', +// warning_light: '#F9FAE6', +// }; + +// export default { +// ...base, +// ...grey, +// ...grayscale, +// ...primary, +// ...secondary, +// ...accent1, +// ...accent2, +// ...accent3, +// ...gradients, +// ...success, +// ...error, +// ...warning, +// ...home, +// }; diff --git a/apps/stage/components/theme/components.ts b/apps/stage/components/theme/components.ts new file mode 100644 index 00000000..22dc45c0 --- /dev/null +++ b/apps/stage/components/theme/components.ts @@ -0,0 +1,33 @@ +/* + * + * Copyright (c) 2023 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import colors from '@/components/theme/colors'; + +type Colors = typeof colors; + +const components = (colors: Colors) => ({ + Input: { + borderColor: colors.secondary, + boxShadow: `inset 0 0 4px 0 ${colors.accent}`, + }, +}); + +export default components; diff --git a/apps/stage/components/theme/dimensions.ts b/apps/stage/components/theme/dimensions.ts new file mode 100644 index 00000000..d0f7fc4e --- /dev/null +++ b/apps/stage/components/theme/dimensions.ts @@ -0,0 +1,37 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +const dimensions = { + navbar: { + height: 50, + }, + footer: { + height: 47, + }, + facets: { + width: 250, + }, + labIcon: { + width: 30, + }, +}; + +export default dimensions; diff --git a/apps/stage/components/theme/emotion.d.ts b/apps/stage/components/theme/emotion.d.ts new file mode 100644 index 00000000..f4323628 --- /dev/null +++ b/apps/stage/components/theme/emotion.d.ts @@ -0,0 +1,6 @@ +import '@emotion/react'; +import { StageThemeInterface } from '.'; + +declare module '@emotion/react' { + export interface Theme extends StageThemeInterface {} +} diff --git a/apps/stage/components/theme/icons/avatar.tsx b/apps/stage/components/theme/icons/avatar.tsx new file mode 100644 index 00000000..7f102708 --- /dev/null +++ b/apps/stage/components/theme/icons/avatar.tsx @@ -0,0 +1,51 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css } from '@emotion/react'; + +import { IconProps } from './types'; + +const Avatar = ({ fill, height, width, style }: IconProps) => { + return ( + + + + + + + ); +}; + +export default Avatar; diff --git a/apps/stage/components/theme/icons/checkmark.tsx b/apps/stage/components/theme/icons/checkmark.tsx new file mode 100644 index 00000000..f1496e81 --- /dev/null +++ b/apps/stage/components/theme/icons/checkmark.tsx @@ -0,0 +1,49 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css } from '@emotion/react'; + +import { IconProps } from './types'; + +const Checkmark = ({ fill, height, width, style }: IconProps) => { + return ( + + + + + + + ); +}; + +export default Checkmark; diff --git a/apps/stage/components/theme/icons/chevron_down.tsx b/apps/stage/components/theme/icons/chevron_down.tsx new file mode 100644 index 00000000..94570799 --- /dev/null +++ b/apps/stage/components/theme/icons/chevron_down.tsx @@ -0,0 +1,45 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css } from '@emotion/react'; + +import { IconProps } from './types'; + +const ChevronDown = ({ fill, width, height, style }: IconProps) => { + return ( + + + + ); +}; + +export default ChevronDown; diff --git a/apps/stage/components/theme/icons/dismiss.tsx b/apps/stage/components/theme/icons/dismiss.tsx new file mode 100644 index 00000000..c10b8461 --- /dev/null +++ b/apps/stage/components/theme/icons/dismiss.tsx @@ -0,0 +1,47 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css } from '@emotion/react'; +import theme from '..'; +import { IconProps } from './types'; + +const Dismiss = ({ height, width, style, fill }: IconProps) => { + return ( + + + + ); +}; + +export default Dismiss; diff --git a/apps/stage/components/theme/icons/download.tsx b/apps/stage/components/theme/icons/download.tsx new file mode 100644 index 00000000..c10a9ae3 --- /dev/null +++ b/apps/stage/components/theme/icons/download.tsx @@ -0,0 +1,45 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css } from '@emotion/react'; + +import { IconProps } from './types'; + +const Download = ({ fill, size = 12, style }: IconProps) => { + return ( + + + + ); +}; + +export default Download; diff --git a/apps/stage/components/theme/icons/error.tsx b/apps/stage/components/theme/icons/error.tsx new file mode 100644 index 00000000..8e6526c7 --- /dev/null +++ b/apps/stage/components/theme/icons/error.tsx @@ -0,0 +1,57 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css } from '@emotion/react'; +import { ReactElement } from 'react'; + +import theme from '../'; +import { IconProps } from './types'; + +const Error = ({ fill = theme.colors.red, size = 26, style }: IconProps): ReactElement => { + return ( + + + + + + + + + ); +}; + +export default Error; diff --git a/apps/stage/components/theme/icons/facebook.tsx b/apps/stage/components/theme/icons/facebook.tsx new file mode 100644 index 00000000..52f5c48d --- /dev/null +++ b/apps/stage/components/theme/icons/facebook.tsx @@ -0,0 +1,63 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css } from '@emotion/react'; + +import { IconProps } from './types'; + +const FacebookLogo = ({ width, height, style }: IconProps) => ( + + + + + + + + + + + + + + + + + + + + + +); + +export default FacebookLogo; diff --git a/apps/stage/components/theme/icons/github.tsx b/apps/stage/components/theme/icons/github.tsx new file mode 100644 index 00000000..e61660f4 --- /dev/null +++ b/apps/stage/components/theme/icons/github.tsx @@ -0,0 +1,63 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css } from '@emotion/react'; + +import { IconProps } from './types'; + +const GitHubLogo = ({ width, height, style }: IconProps) => ( + + + + + + + + + + + + + + + + + + + + + +); + +export default GitHubLogo; diff --git a/apps/stage/components/theme/icons/google.tsx b/apps/stage/components/theme/icons/google.tsx new file mode 100644 index 00000000..79cf73f8 --- /dev/null +++ b/apps/stage/components/theme/icons/google.tsx @@ -0,0 +1,89 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css, SerializedStyles } from '@emotion/react'; + +const GoogleLogo = ({ + width, + height, + style, +}: { + width: number; + height: number; + style?: SerializedStyles; +}) => { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; + +export default GoogleLogo; diff --git a/apps/stage/components/theme/icons/illustration.tsx b/apps/stage/components/theme/icons/illustration.tsx new file mode 100644 index 00000000..4e33779b --- /dev/null +++ b/apps/stage/components/theme/icons/illustration.tsx @@ -0,0 +1,454 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css } from '@emotion/react'; + +const Illustration = ({ width, height, style }: any) => { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; + +export default Illustration; diff --git a/apps/stage/components/theme/icons/index.tsx b/apps/stage/components/theme/icons/index.tsx new file mode 100644 index 00000000..fa8c5795 --- /dev/null +++ b/apps/stage/components/theme/icons/index.tsx @@ -0,0 +1,58 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import GoogleLogo from './google'; +import FacebookLogo from './facebook'; +import GitHubLogo from './github'; +import LinkedInLogo from './linkedin'; +import OrcidLogo from './orcid'; +import KeycloakLogo from './keycloak'; +import Illustration from './illustration'; +import Avatar from './avatar'; +import ChevronDown from './chevron_down'; +import Download from './download'; +import OvertureLogo from './overture_logo'; +import OvertureLogoWithText from './overture_logo_with_text'; +import OvertureUser from './overture_user'; +import Checkmark from './checkmark'; +import Spinner from './spinner'; +import Error from './error'; +import Warning from './warning'; + +export { + GoogleLogo, + FacebookLogo, + GitHubLogo, + LinkedInLogo, + OrcidLogo, + KeycloakLogo, + Illustration, + Avatar, + ChevronDown, + Download, + OvertureLogo, + OvertureLogoWithText, + OvertureUser, + Checkmark, + Spinner, + Error, + Warning, +}; diff --git a/apps/stage/components/theme/icons/info.tsx b/apps/stage/components/theme/icons/info.tsx new file mode 100644 index 00000000..43f0e0bc --- /dev/null +++ b/apps/stage/components/theme/icons/info.tsx @@ -0,0 +1,53 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css } from '@emotion/react'; +import { ReactElement } from 'react'; + +import theme from '../'; +import { IconProps } from './types'; + +const Info = ({ fill = theme.colors.error_dark, size = 16, style }: IconProps): ReactElement => { + return ( + + + + + + + + + ); +}; + +export default Info; diff --git a/apps/stage/components/theme/icons/keycloak.tsx b/apps/stage/components/theme/icons/keycloak.tsx new file mode 100644 index 00000000..601edfd4 --- /dev/null +++ b/apps/stage/components/theme/icons/keycloak.tsx @@ -0,0 +1,746 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css } from '@emotion/react'; +import { SerializedStyles } from '@emotion/react'; + +const KeycloakLogo = ({ + width, + height, + style, +}: { + width: number; + height: number; + style?: SerializedStyles; +}) => { + return ( + + + + + + + + + + + keycloak_deliverables + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; + +export default KeycloakLogo; diff --git a/apps/stage/components/theme/icons/linkedin.tsx b/apps/stage/components/theme/icons/linkedin.tsx new file mode 100644 index 00000000..31adb3d8 --- /dev/null +++ b/apps/stage/components/theme/icons/linkedin.tsx @@ -0,0 +1,63 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css } from '@emotion/react'; + +import { IconProps } from './types'; + +const LinkedInLogo = ({ width, height, style }: IconProps) => ( + + + + + + + + + + + + + + + + + + + + + +); + +export default LinkedInLogo; diff --git a/apps/stage/components/theme/icons/orcid.tsx b/apps/stage/components/theme/icons/orcid.tsx new file mode 100644 index 00000000..377feb40 --- /dev/null +++ b/apps/stage/components/theme/icons/orcid.tsx @@ -0,0 +1,72 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css } from '@emotion/react'; + +import { IconProps } from './types'; + +const OrcidLogo = ({ width, height, style }: IconProps) => ( + + + + + + + + + + + + + + + + + + + + + + + + + + +); + +export default OrcidLogo; diff --git a/apps/stage/components/theme/icons/overture_logo.tsx b/apps/stage/components/theme/icons/overture_logo.tsx new file mode 100644 index 00000000..a6985fcd --- /dev/null +++ b/apps/stage/components/theme/icons/overture_logo.tsx @@ -0,0 +1,87 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css } from '@emotion/react'; + +import { IconProps } from './types'; + +const OvertureLogo = ({ height, style }: IconProps) => { + return ( + + + + + + + + + + + + + + + + + + + + + + ); +}; + +export default OvertureLogo; diff --git a/apps/stage/components/theme/icons/overture_logo_with_text.tsx b/apps/stage/components/theme/icons/overture_logo_with_text.tsx new file mode 100644 index 00000000..58c1c033 --- /dev/null +++ b/apps/stage/components/theme/icons/overture_logo_with_text.tsx @@ -0,0 +1,105 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css } from '@emotion/react'; + +import { IconProps } from './types'; + +const OvertureLogoWithText = ({ width, height, style }: IconProps) => { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; + +export default OvertureLogoWithText; diff --git a/apps/stage/components/theme/icons/overture_user.tsx b/apps/stage/components/theme/icons/overture_user.tsx new file mode 100644 index 00000000..346531ba --- /dev/null +++ b/apps/stage/components/theme/icons/overture_user.tsx @@ -0,0 +1,117 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css } from '@emotion/react'; + +import { IconProps } from './types'; + +const OvertureUser = ({ height, width, style }: IconProps) => { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; + +export default OvertureUser; diff --git a/apps/stage/components/theme/icons/spinner.tsx b/apps/stage/components/theme/icons/spinner.tsx new file mode 100644 index 00000000..320695f9 --- /dev/null +++ b/apps/stage/components/theme/icons/spinner.tsx @@ -0,0 +1,52 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css, keyframes } from '@emotion/react'; +import { IconProps } from './types'; + +// Animation +const spin = keyframes` + 100% { + transform: rotate(360deg); + } +`; + +const Spinner = ({ fill, height, width }: IconProps) => { + return ( + + + + ); +}; + +export default Spinner; diff --git a/apps/stage/components/theme/icons/types.ts b/apps/stage/components/theme/icons/types.ts new file mode 100644 index 00000000..b85bd1ab --- /dev/null +++ b/apps/stage/components/theme/icons/types.ts @@ -0,0 +1,30 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { SerializedStyles } from '@emotion/react'; + +export type IconProps = { + fill?: string; + height?: number; + size?: number; + style?: SerializedStyles; + width?: number; +}; diff --git a/apps/stage/components/theme/icons/warning.tsx b/apps/stage/components/theme/icons/warning.tsx new file mode 100644 index 00000000..567c9cb4 --- /dev/null +++ b/apps/stage/components/theme/icons/warning.tsx @@ -0,0 +1,50 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css } from '@emotion/react'; +import theme from '..'; +import { IconProps } from './types'; + +const Warning = ({ height, width, style, fill = theme.colors.error_dark, size = 16 }: IconProps) => { + // Use size if height and width are not provided + const finalHeight = height || size; + const finalWidth = width || size; + + return ( + + + + ); +}; + +export default Warning; diff --git a/apps/stage/components/theme/index.ts b/apps/stage/components/theme/index.ts new file mode 100644 index 00000000..5bbb457d --- /dev/null +++ b/apps/stage/components/theme/index.ts @@ -0,0 +1,37 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import colors from './colors'; +import components from './components'; +import typography from './typography'; +import shadow from './shadow'; +import dimensions from './dimensions'; + +const defaultTheme = { + colors, + typography, + shadow, + dimensions, + components: components(colors), +}; + +export default defaultTheme; +export type StageThemeInterface = typeof defaultTheme; diff --git a/apps/stage/components/theme/shadow.ts b/apps/stage/components/theme/shadow.ts new file mode 100644 index 00000000..664ceeae --- /dev/null +++ b/apps/stage/components/theme/shadow.ts @@ -0,0 +1,33 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +const defaultShadow = ` + box-shadow: 0 1px 6px 0 rgba(0, 0, 0, 0.1), 0 1px 5px 0 rgba(0, 0, 0, 0.08); +`; + +const rightShadow = ` + box-shadow: 3px 0 5px -2px rgba(0, 0, 0, 0.1), 3px 0 5px -2px rgba(0, 0, 0, 0.08); +`; + +export default { + default: defaultShadow, + right: rightShadow, +}; diff --git a/apps/stage/components/theme/typography.ts b/apps/stage/components/theme/typography.ts new file mode 100644 index 00000000..a76ad99a --- /dev/null +++ b/apps/stage/components/theme/typography.ts @@ -0,0 +1,117 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { css } from '@emotion/react'; + +const baseFont = css` + font-family: 'Lato', sans-serif; +`; + +const regular = css` + ${baseFont} + font-size: inherit; + font-weight: inherit; + font-style: inherit; + font-stretch: inherit; + line-height: inherit; + letter-spacing: inherit; +`; + +const button = css` + ${baseFont} + font-size: 16px; + font-weight: bold; + font-style: normal; + font-stretch: normal; + line-height: 18px; + letter-spacing: normal; +`; + +const heading = css` + ${baseFont} + font-size: 18px; + font-weight: bold; + font-style: normal; + font-stretch: normal; + line-height: 30px; + letter-spacing: normal; +`; + +const subheading = css` + ${baseFont} + font-size: 16px; + font-weight: bold; + font-style: normal; + font-stretch: normal; + line-height: 24px; + letter-spacing: normal; +`; + +const subheading2 = css` + ${baseFont} + font-size: 14px; + font-weight: bold; + font-style: normal; + font-stretch: normal; + line-height: 16px; + letter-spacing: normal; +`; + +const label = css` + ${baseFont} + font-size: 12px; + font-weight: bold; + font-style: normal; + font-stretch: normal; + line-height: 16px; + letter-spacing: normal; +`; + +const label2 = css` + ${baseFont} + font-size: 10px; + font-weight: normal; + font-style: normal; + font-stretch: normal; + line-height: 14px; + letter-spacing: normal; +`; + +const data = css` + ${baseFont} + font-size: 13px; + font-weight: normal; + font-style: normal; + font-stretch: normal; + line-height: 16px; + letter-spacing: normal; +`; + +export default { + regular, + heading, + subheading, + subheading2, + label, + label2, + data, + button, +}; diff --git a/apps/stage/components/utils/ajax.ts b/apps/stage/components/utils/ajax.ts new file mode 100644 index 00000000..d6604b0d --- /dev/null +++ b/apps/stage/components/utils/ajax.ts @@ -0,0 +1,46 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/*************** +Arranger does not work with fetch lib right out of the box, so using this implementation from +https://github.com/IHCC-cohorts/ihcc-ui/blob/develop/src/pages/cohortRepo/arrangerFetcher/ajax.ts +for now + ***************/ + +import axios from 'axios'; + +const ajax = axios.create(); + +ajax.interceptors.request.use( + (config) => { + // set Authorization headers on a per request basis + // setting headers on axios get/put/post or common seems to be shared accross all axios instances + config.headers = { + ...config.headers, + }; + return config; + }, + (err) => { + return Promise.reject(err); + }, +); + +export default ajax; diff --git a/apps/stage/components/utils/arrangerFetcher.ts b/apps/stage/components/utils/arrangerFetcher.ts new file mode 100644 index 00000000..49606610 --- /dev/null +++ b/apps/stage/components/utils/arrangerFetcher.ts @@ -0,0 +1,66 @@ +/* + * + * Copyright (c) 2024 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import urlJoin from 'url-join'; +import ajax from './ajax'; + +const createArrangerFetcher = ({ + ARRANGER_API = 'http://noUrlProvided', + onError = (err: any) => Promise.reject(err), + defaultHeaders = {}, +} = {}) => { + const cache = new Map(); + + return async (args: { + body?: Record | string | null; + endpoint?: string; + endpointTag?: string; + headers?: Record; + }) => { + const key = JSON.stringify(args); + + if (cache.has(key)) return cache.get(key); + // TODO: max cache size + + const { body = {}, endpoint = '/graphql', endpointTag = '', headers = {} } = args; + const uri = urlJoin(ARRANGER_API, endpoint, endpointTag); + const response = await ajax + .post(uri, body, { + headers: { + 'Content-Type': 'application/json', + ...(defaultHeaders || {}), + ...headers, + }, + }) + .then((response: { data: any }) => { + return response.data; + }) + .catch((err: { response: any }) => { + return onError(err); + }); + + cache.set(key, response); + + return response; + }; +}; + +export default createArrangerFetcher; diff --git a/apps/stage/components/utils/sleep.ts b/apps/stage/components/utils/sleep.ts new file mode 100644 index 00000000..c627a81d --- /dev/null +++ b/apps/stage/components/utils/sleep.ts @@ -0,0 +1,29 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +const sleep = (time: number = 2000) => + new Promise((resolve) => { + setTimeout(() => { + resolve(''); + }, time); + }); + +export default sleep; diff --git a/apps/stage/global/config.ts b/apps/stage/global/config.ts new file mode 100644 index 00000000..9320f838 --- /dev/null +++ b/apps/stage/global/config.ts @@ -0,0 +1,264 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import getNextConfig from 'next/config'; + +type Config = { + NEXT_PUBLIC_ADMIN_EMAIL: string; + NEXT_PUBLIC_APP_COMMIT: string; + NEXT_PUBLIC_APP_VERSION: string; + NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_API: string; + NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_ADMIN_UI: string; + NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_DOCUMENT_TYPE: string; + NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_INDEX: string; + NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_MANIFEST_COLUMNS: string; + NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_CARDINALITY_PRECISION_THRESHOLD: number; + NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_MAX_BUCKET_COUNTS: number; + + // DATATABLE 1 + NEXT_PUBLIC_ARRANGER_DATATABLE_1_API: string; + NEXT_PUBLIC_ARRANGER_DATATABLE_1_ADMIN_UI: string; + NEXT_PUBLIC_ARRANGER_DATATABLE_1_DOCUMENT_TYPE: string; + NEXT_PUBLIC_ARRANGER_DATATABLE_1_INDEX: string; + NEXT_PUBLIC_ARRANGER_DATATABLE_1_MANIFEST_COLUMNS: string; + NEXT_PUBLIC_ARRANGER_DATATABLE_1_CARDINALITY_PRECISION_THRESHOLD: number; + NEXT_PUBLIC_ARRANGER_DATATABLE_1_MAX_BUCKET_COUNTS: number; + + // DATATABLE 2 + NEXT_PUBLIC_ARRANGER_DATATABLE_2_API: string; + NEXT_PUBLIC_ARRANGER_DATATABLE_2_ADMIN_UI: string; + NEXT_PUBLIC_ARRANGER_DATATABLE_2_DOCUMENT_TYPE: string; + NEXT_PUBLIC_ARRANGER_DATATABLE_2_INDEX: string; + NEXT_PUBLIC_ARRANGER_DATATABLE_2_MANIFEST_COLUMNS: string; + NEXT_PUBLIC_ARRANGER_DATATABLE_2_CARDINALITY_PRECISION_THRESHOLD: number; + NEXT_PUBLIC_ARRANGER_DATATABLE_2_MAX_BUCKET_COUNTS: number; + + // DATATABLE 3 + NEXT_PUBLIC_ARRANGER_DATATABLE_3_API: string; + NEXT_PUBLIC_ARRANGER_DATATABLE_3_ADMIN_UI: string; + NEXT_PUBLIC_ARRANGER_DATATABLE_3_DOCUMENT_TYPE: string; + NEXT_PUBLIC_ARRANGER_DATATABLE_3_INDEX: string; + NEXT_PUBLIC_ARRANGER_DATATABLE_3_MANIFEST_COLUMNS: string; + NEXT_PUBLIC_ARRANGER_DATATABLE_3_CARDINALITY_PRECISION_THRESHOLD: number; + NEXT_PUBLIC_ARRANGER_DATATABLE_3_MAX_BUCKET_COUNTS: number; + + // DATATABLE 4 + NEXT_PUBLIC_ARRANGER_DATATABLE_4_API: string; + NEXT_PUBLIC_ARRANGER_DATATABLE_4_ADMIN_UI: string; + NEXT_PUBLIC_ARRANGER_DATATABLE_4_DOCUMENT_TYPE: string; + NEXT_PUBLIC_ARRANGER_DATATABLE_4_INDEX: string; + NEXT_PUBLIC_ARRANGER_DATATABLE_4_MANIFEST_COLUMNS: string; + NEXT_PUBLIC_ARRANGER_DATATABLE_4_CARDINALITY_PRECISION_THRESHOLD: number; + NEXT_PUBLIC_ARRANGER_DATATABLE_4_MAX_BUCKET_COUNTS: number; + + // DATATABLE 5 + NEXT_PUBLIC_ARRANGER_DATATABLE_5_API: string; + NEXT_PUBLIC_ARRANGER_DATATABLE_5_ADMIN_UI: string; + NEXT_PUBLIC_ARRANGER_DATATABLE_5_DOCUMENT_TYPE: string; + NEXT_PUBLIC_ARRANGER_DATATABLE_5_INDEX: string; + NEXT_PUBLIC_ARRANGER_DATATABLE_5_MANIFEST_COLUMNS: string; + NEXT_PUBLIC_ARRANGER_DATATABLE_5_CARDINALITY_PRECISION_THRESHOLD: number; + NEXT_PUBLIC_ARRANGER_DATATABLE_5_MAX_BUCKET_COUNTS: number; + + // External APIs + NEXT_PUBLIC_SONG_API: string; + NEXT_PUBLIC_SCORE_API: string; + NEXT_PUBLIC_LYRIC_API: string; + NEXT_PUBLIC_LECTERN_API: string; + + NEXT_PUBLIC_BASE_PATH: string; + NEXT_PUBLIC_CHANGELOG_START_SECONDS: number; + NEXT_PUBLIC_DOWNLOAD_ALL_URL: string; + NEXT_PUBLIC_GOOGLE_ANALYTICS_ID: string; + NEXT_PUBLIC_KEYCLOAK: string; + NEXT_PUBLIC_LAB_NAME: string; + NEXT_PUBLIC_LOGO_FILENAME: string; + ACCESSTOKEN_ENCRYPTION_SECRET: string; + KEYCLOAK_CLIENT_SECRET: string; + NEXT_PUBLIC_ARRANGER_API: string; + NEXT_PUBLIC_ARRANGER_DOCUMENT_TYPE: string; + NEXT_PUBLIC_ARRANGER_INDEX: string; + NEXT_PUBLIC_ARRANGER_MANIFEST_COLUMNS: string; + + // Keycloak + NEXT_PUBLIC_AUTH_PROVIDER: string; + NEXT_PUBLIC_KEYCLOAK_CLIENT_ID: string; + NEXT_PUBLIC_KEYCLOAK_HOST: string; + NEXT_PUBLIC_KEYCLOAK_PERMISSION_AUDIENCE: string; + NEXT_PUBLIC_KEYCLOAK_REALM: string; + NEXT_PUBLIC_UI_VERSION: string; + SESSION_ENCRYPTION_SECRET: string; + // NEXT_PUBLIC_PORTAL_API_URL: string; + NEXT_PUBLIC_SSO_PROVIDERS: string; + // NEXT_PUBLIC_STUDIES_SVC_URL: string; + // NEXT_PUBLIC_SYSTEM_ALERTS: string; + // Optional features/functionalities + NEXT_PUBLIC_DEBUG: boolean; + NEXT_PUBLIC_ENABLE_DOWNLOADS: boolean; + NEXT_PUBLIC_ENABLE_LOGIN: boolean; + NEXT_PUBLIC_ENABLE_MOLECULAR_QUICKSEARCH: boolean; + NEXT_PUBLIC_ENABLE_DATATABLE_1_QUICKSEARCH: boolean; + NEXT_PUBLIC_ENABLE_DATATABLE_2_QUICKSEARCH: boolean; + NEXT_PUBLIC_ENABLE_DATATABLE_3_QUICKSEARCH: boolean; + NEXT_PUBLIC_ENABLE_DATATABLE_4_QUICKSEARCH: boolean; + NEXT_PUBLIC_ENABLE_DATATABLE_5_QUICKSEARCH: boolean; + // NEXT_PUBLIC_ENABLE_REGISTRATION: boolean; + //Banners + NEXT_PUBLIC_SYSTEM_ALERTS: string; +}; + +export const getConfig = (): Config => { + const publicConfig: { [k: string]: string } = getNextConfig()?.publicRuntimeConfig || {}; + + return { + ACCESSTOKEN_ENCRYPTION_SECRET: process.env.ACCESSTOKEN_ENCRYPTION_SECRET || 'super_secret', + NEXT_PUBLIC_ADMIN_EMAIL: publicConfig.NEXT_PUBLIC_ADMIN_EMAIL, + NEXT_PUBLIC_APP_COMMIT: publicConfig.NEXT_PUBLIC_APP_COMMIT || '', + NEXT_PUBLIC_APP_VERSION: publicConfig.NEXT_PUBLIC_APP_VERSION || '', + + // Added missing Arranger base config + NEXT_PUBLIC_ARRANGER_API: publicConfig.NEXT_PUBLIC_ARRANGER_API || 'http://localhost:5050', + NEXT_PUBLIC_ARRANGER_DOCUMENT_TYPE: publicConfig.NEXT_PUBLIC_ARRANGER_DOCUMENT_TYPE || '', + NEXT_PUBLIC_ARRANGER_INDEX: publicConfig.NEXT_PUBLIC_ARRANGER_INDEX || '', + NEXT_PUBLIC_ARRANGER_MANIFEST_COLUMNS: publicConfig.NEXT_PUBLIC_ARRANGER_MANIFEST_COLUMNS || '', + + // DataSet_1 Arranger + NEXT_PUBLIC_ARRANGER_DATATABLE_1_API: publicConfig.NEXT_PUBLIC_ARRANGER_DATATABLE_1_API || '', + NEXT_PUBLIC_ARRANGER_DATATABLE_1_DOCUMENT_TYPE: publicConfig.NEXT_PUBLIC_ARRANGER_DATATABLE_1_DOCUMENT_TYPE || '', + NEXT_PUBLIC_ARRANGER_DATATABLE_1_ADMIN_UI: publicConfig.NEXT_PUBLIC_ARRANGER_DATATABLE_1_ADMIN_UI || '', + NEXT_PUBLIC_ARRANGER_DATATABLE_1_INDEX: publicConfig.NEXT_PUBLIC_ARRANGER_DATATABLE_1_INDEX || '', + NEXT_PUBLIC_ARRANGER_DATATABLE_1_MANIFEST_COLUMNS: + publicConfig.NEXT_PUBLIC_ARRANGER_DATATABLE_1_MANIFEST_COLUMNS || '', + NEXT_PUBLIC_ARRANGER_DATATABLE_1_CARDINALITY_PRECISION_THRESHOLD: + Number(publicConfig.NEXT_PUBLIC_ARRANGER_DATATABLE_1_CARDINALITY_PRECISION_THRESHOLD) || 3000, + NEXT_PUBLIC_ARRANGER_DATATABLE_1_MAX_BUCKET_COUNTS: + Number(publicConfig.NEXT_PUBLIC_ARRANGER_DATATABLE_1_MAX_BUCKET_COUNTS) || 50000, + + // DataSet_2 Arranger + NEXT_PUBLIC_ARRANGER_DATATABLE_2_API: publicConfig.NEXT_PUBLIC_ARRANGER_DATATABLE_2_API || '', + NEXT_PUBLIC_ARRANGER_DATATABLE_2_DOCUMENT_TYPE: publicConfig.NEXT_PUBLIC_ARRANGER_DATATABLE_2_DOCUMENT_TYPE || '', + NEXT_PUBLIC_ARRANGER_DATATABLE_2_ADMIN_UI: publicConfig.NEXT_PUBLIC_ARRANGER_DATATABLE_2_ADMIN_UI || '', + NEXT_PUBLIC_ARRANGER_DATATABLE_2_INDEX: publicConfig.NEXT_PUBLIC_ARRANGER_DATATABLE_2_INDEX || '', + NEXT_PUBLIC_ARRANGER_DATATABLE_2_MANIFEST_COLUMNS: + publicConfig.NEXT_PUBLIC_ARRANGER_DATATABLE_2_MANIFEST_COLUMNS || '', + NEXT_PUBLIC_ARRANGER_DATATABLE_2_CARDINALITY_PRECISION_THRESHOLD: + Number(publicConfig.NEXT_PUBLIC_ARRANGER_DATATABLE_2_CARDINALITY_PRECISION_THRESHOLD) || 3000, + NEXT_PUBLIC_ARRANGER_DATATABLE_2_MAX_BUCKET_COUNTS: + Number(publicConfig.NEXT_PUBLIC_ARRANGER_DATATABLE_2_MAX_BUCKET_COUNTS) || 50000, + + // DataSet_3 Arranger + NEXT_PUBLIC_ARRANGER_DATATABLE_3_API: publicConfig.NEXT_PUBLIC_ARRANGER_DATATABLE_3_API || '', + NEXT_PUBLIC_ARRANGER_DATATABLE_3_DOCUMENT_TYPE: publicConfig.NEXT_PUBLIC_ARRANGER_DATATABLE_3_DOCUMENT_TYPE || '', + NEXT_PUBLIC_ARRANGER_DATATABLE_3_ADMIN_UI: publicConfig.NEXT_PUBLIC_ARRANGER_DATATABLE_3_ADMIN_UI || '', + NEXT_PUBLIC_ARRANGER_DATATABLE_3_INDEX: publicConfig.NEXT_PUBLIC_ARRANGER_DATATABLE_3_INDEX || '', + NEXT_PUBLIC_ARRANGER_DATATABLE_3_MANIFEST_COLUMNS: + publicConfig.NEXT_PUBLIC_ARRANGER_DATATABLE_3_MANIFEST_COLUMNS || '', + NEXT_PUBLIC_ARRANGER_DATATABLE_3_CARDINALITY_PRECISION_THRESHOLD: + Number(publicConfig.NEXT_PUBLIC_ARRANGER_DATATABLE_3_CARDINALITY_PRECISION_THRESHOLD) || 3000, + NEXT_PUBLIC_ARRANGER_DATATABLE_3_MAX_BUCKET_COUNTS: + Number(publicConfig.NEXT_PUBLIC_ARRANGER_DATATABLE_3_MAX_BUCKET_COUNTS) || 50000, + + // DataSet_4 Arranger + NEXT_PUBLIC_ARRANGER_DATATABLE_4_API: publicConfig.NEXT_PUBLIC_ARRANGER_DATATABLE_4_API || '', + NEXT_PUBLIC_ARRANGER_DATATABLE_4_DOCUMENT_TYPE: publicConfig.NEXT_PUBLIC_ARRANGER_DATATABLE_4_DOCUMENT_TYPE || '', + NEXT_PUBLIC_ARRANGER_DATATABLE_4_ADMIN_UI: publicConfig.NEXT_PUBLIC_ARRANGER_DATATABLE_4_ADMIN_UI || '', + NEXT_PUBLIC_ARRANGER_DATATABLE_4_INDEX: publicConfig.NEXT_PUBLIC_ARRANGER_DATATABLE_4_INDEX || '', + NEXT_PUBLIC_ARRANGER_DATATABLE_4_MANIFEST_COLUMNS: + publicConfig.NEXT_PUBLIC_ARRANGER_DATATABLE_4_MANIFEST_COLUMNS || '', + NEXT_PUBLIC_ARRANGER_DATATABLE_4_CARDINALITY_PRECISION_THRESHOLD: + Number(publicConfig.NEXT_PUBLIC_ARRANGER_DATATABLE_4_CARDINALITY_PRECISION_THRESHOLD) || 3000, + NEXT_PUBLIC_ARRANGER_DATATABLE_4_MAX_BUCKET_COUNTS: + Number(publicConfig.NEXT_PUBLIC_ARRANGER_DATATABLE_4_MAX_BUCKET_COUNTS) || 50000, + + // DataSet_5 Arranger + NEXT_PUBLIC_ARRANGER_DATATABLE_5_API: publicConfig.NEXT_PUBLIC_ARRANGER_DATATABLE_5_API || '', + NEXT_PUBLIC_ARRANGER_DATATABLE_5_DOCUMENT_TYPE: publicConfig.NEXT_PUBLIC_ARRANGER_DATATABLE_5_DOCUMENT_TYPE || '', + NEXT_PUBLIC_ARRANGER_DATATABLE_5_ADMIN_UI: publicConfig.NEXT_PUBLIC_ARRANGER_DATATABLE_5_ADMIN_UI || '', + NEXT_PUBLIC_ARRANGER_DATATABLE_5_INDEX: publicConfig.NEXT_PUBLIC_ARRANGER_DATATABLE_5_INDEX || '', + NEXT_PUBLIC_ARRANGER_DATATABLE_5_MANIFEST_COLUMNS: + publicConfig.NEXT_PUBLIC_ARRANGER_DATATABLE_5_MANIFEST_COLUMNS || '', + NEXT_PUBLIC_ARRANGER_DATATABLE_5_CARDINALITY_PRECISION_THRESHOLD: + Number(publicConfig.NEXT_PUBLIC_ARRANGER_DATATABLE_5_CARDINALITY_PRECISION_THRESHOLD) || 3000, + NEXT_PUBLIC_ARRANGER_DATATABLE_5_MAX_BUCKET_COUNTS: + Number(publicConfig.NEXT_PUBLIC_ARRANGER_DATATABLE_5_MAX_BUCKET_COUNTS) || 50000, + + // MOLECULAR Arranger + NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_API: publicConfig.NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_API || '', + NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_ADMIN_UI: publicConfig.NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_ADMIN_UI || '', + NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_DOCUMENT_TYPE: + publicConfig.NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_DOCUMENT_TYPE || '', + NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_INDEX: publicConfig.NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_INDEX || '', + NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_MANIFEST_COLUMNS: + publicConfig.NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_MANIFEST_COLUMNS || '', + NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_CARDINALITY_PRECISION_THRESHOLD: + Number(publicConfig.NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_CARDINALITY_PRECISION_THRESHOLD) || 3000, + NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_MAX_BUCKET_COUNTS: + Number(publicConfig.NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_MAX_BUCKET_COUNTS) || 50000, + + // Swagger Docs + NEXT_PUBLIC_SONG_API: publicConfig.NEXT_PUBLIC_SONG_API || 'http://localhost:8080', + NEXT_PUBLIC_SCORE_API: publicConfig.NEXT_PUBLIC_SCORE_API || 'http://localhost:8087', + NEXT_PUBLIC_LYRIC_API: publicConfig.NEXT_PUBLIC_SONG_API || 'http://localhost:3030', + NEXT_PUBLIC_LECTERN_API: publicConfig.NEXT_PUBLIC_SCORE_API || 'http://localhost:3031', + + // Auth + NEXT_PUBLIC_AUTH_PROVIDER: (publicConfig.NEXT_PUBLIC_AUTH_PROVIDER || '').toLowerCase(), + NEXT_PUBLIC_SSO_PROVIDERS: publicConfig.NEXT_PUBLIC_SSO_PROVIDERS || '', + + // Keycloak + NEXT_PUBLIC_KEYCLOAK: publicConfig.NEXT_PUBLIC_KEYCLOAK || '', + NEXT_PUBLIC_KEYCLOAK_CLIENT_ID: publicConfig.NEXT_PUBLIC_KEYCLOAK_CLIENT_ID || '', + KEYCLOAK_CLIENT_SECRET: process.env.KEYCLOAK_CLIENT_SECRET || '', + NEXT_PUBLIC_KEYCLOAK_HOST: publicConfig.NEXT_PUBLIC_KEYCLOAK_HOST || '', + NEXT_PUBLIC_KEYCLOAK_PERMISSION_AUDIENCE: publicConfig.NEXT_PUBLIC_KEYCLOAK_PERMISSION_AUDIENCE || '', + NEXT_PUBLIC_KEYCLOAK_REALM: publicConfig.NEXT_PUBLIC_KEYCLOAK_REALM || '', + + // Base configuration + NEXT_PUBLIC_BASE_PATH: publicConfig.NEXT_PUBLIC_BASE_PATH || '/', + NEXT_PUBLIC_CHANGELOG_START_SECONDS: Number(publicConfig.NEXT_PUBLIC_CHANGELOG_START_SECONDS) || 0, + NEXT_PUBLIC_DEBUG: (publicConfig.NEXT_PUBLIC_DEBUG || '').toLowerCase() === 'true', + NEXT_PUBLIC_DOWNLOAD_ALL_URL: publicConfig.NEXT_PUBLIC_DOWNLOAD_ALL_URL || '', + NEXT_PUBLIC_GOOGLE_ANALYTICS_ID: publicConfig.NEXT_PUBLIC_GOOGLE_ANALYTICS_ID || '', + NEXT_PUBLIC_LAB_NAME: publicConfig.NEXT_PUBLIC_LAB_NAME || 'Overture Stage UI', + NEXT_PUBLIC_LOGO_FILENAME: publicConfig.NEXT_PUBLIC_LOGO_FILENAME || '', + NEXT_PUBLIC_UI_VERSION: publicConfig.NEXT_PUBLIC_UI_VERSION || '', + SESSION_ENCRYPTION_SECRET: process.env.SESSION_ENCRYPTION_SECRET || '', + + // Banners + NEXT_PUBLIC_SYSTEM_ALERTS: publicConfig.NEXT_PUBLIC_SYSTEM_ALERTS || '[]', + + // Feature flags + NEXT_PUBLIC_ENABLE_MOLECULAR_QUICKSEARCH: + (publicConfig.NEXT_PUBLIC_ENABLE_MOLECULAR_QUICKSEARCH || '').toLowerCase() === 'true', + NEXT_PUBLIC_ENABLE_DATATABLE_1_QUICKSEARCH: + (publicConfig.NEXT_PUBLIC_ENABLE_DATATABLE_1_QUICKSEARCH || '').toLowerCase() === 'true', + NEXT_PUBLIC_ENABLE_DATATABLE_2_QUICKSEARCH: + (publicConfig.NEXT_PUBLIC_ENABLE_DATATABLE_2_QUICKSEARCH || '').toLowerCase() === 'true', + NEXT_PUBLIC_ENABLE_DATATABLE_3_QUICKSEARCH: + (publicConfig.NEXT_PUBLIC_ENABLE_DATATABLE_3_QUICKSEARCH || '').toLowerCase() === 'true', + NEXT_PUBLIC_ENABLE_DATATABLE_4_QUICKSEARCH: + (publicConfig.NEXT_PUBLIC_ENABLE_DATATABLE_4_QUICKSEARCH || '').toLowerCase() === 'true', + NEXT_PUBLIC_ENABLE_DATATABLE_5_QUICKSEARCH: + (publicConfig.NEXT_PUBLIC_ENABLE_DATATABLE_5_QUICKSEARCH || '').toLowerCase() === 'true', + NEXT_PUBLIC_ENABLE_DOWNLOADS: (publicConfig.NEXT_PUBLIC_ENABLE_DOWNLOADS || '').toLowerCase() === 'true', + NEXT_PUBLIC_ENABLE_LOGIN: (publicConfig.NEXT_PUBLIC_ENABLE_LOGIN || '').toLowerCase() === 'true', + }; +}; diff --git a/apps/stage/global/hooks/useAuthContext.tsx b/apps/stage/global/hooks/useAuthContext.tsx new file mode 100644 index 00000000..e3d9ad80 --- /dev/null +++ b/apps/stage/global/hooks/useAuthContext.tsx @@ -0,0 +1,72 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import React, { createContext, useEffect, useState } from 'react'; + +import { getConfig } from '../config'; +import { ProviderType, UserStatus, UserType, UserWithId } from '../types/types'; +import { AUTH_PROVIDER } from '../utils/constants'; + +type T_AuthContext = { + user?: UserWithId; +}; + +const AuthContext = createContext({ + user: undefined, +}); + +if (process.env.NODE_ENV === 'development') { + AuthContext.displayName = 'AuthContext'; +} + +export const AuthProvider = ({ children, session }: { children: React.ReactElement; session: any }) => { + const { NEXT_PUBLIC_AUTH_PROVIDER } = getConfig(); + const [user, setUser] = useState(); + + useEffect(() => { + if (NEXT_PUBLIC_AUTH_PROVIDER === AUTH_PROVIDER.KEYCLOAK && session?.account) { + const newUser: UserWithId = { + id: session?.user?.id, + email: session?.user?.email, + type: UserType.USER, + status: UserStatus.APPROVED, + firstName: session?.user?.firstName, + lastName: session?.user?.lastName, + createdAt: 0, + lastLogin: 0, + providerType: ProviderType.KEYCLOAK, + providerSubjectId: '', + scope: session?.scopes, + }; + setUser(newUser); + } + }, [session]); + + const authData = { + user, + }; + + return {children}; +}; + +export default function useAuthContext() { + return React.useContext(AuthContext); +} diff --git a/apps/stage/global/hooks/usePageContext.tsx b/apps/stage/global/hooks/usePageContext.tsx new file mode 100644 index 00000000..dc32d32f --- /dev/null +++ b/apps/stage/global/hooks/usePageContext.tsx @@ -0,0 +1,43 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import React from 'react'; +import { ClientSideGetInitialPropsContext } from '../utils/pages/types'; + +export const PageContext = React.createContext({ + pathname: '', + query: {}, + asPath: '', +}); + +if (process.env.NODE_ENV === 'development') { + PageContext.displayName = 'PageContext'; +} + +export default function usePageContext(): ClientSideGetInitialPropsContext { + const pageContext = React.useContext(PageContext); + return pageContext; +} + +export const usePageQuery = () => { + const { query } = usePageContext(); + return query as T; +}; diff --git a/apps/stage/global/hooks/useUrlParamsState.tsx b/apps/stage/global/hooks/useUrlParamsState.tsx new file mode 100644 index 00000000..bad1785d --- /dev/null +++ b/apps/stage/global/hooks/useUrlParamsState.tsx @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2024 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import { useEffect, useState } from 'react'; +import { useRouter } from 'next/router'; +import { isEqual } from 'lodash'; + +const entriesToObj = (entriesArr: [string, string][], cb = (val: string, param: string) => val) => + entriesArr.length + ? entriesArr.reduce( + (acc: any, [param, val]: [string, string]) => ({ + ...acc, + [param]: cb(val, param), + }), + {}, + ) + : {}; + +export const getParamsObj = ( + queryString: string | URLSearchParams = '', +): Record => { + const currentQueryEntries = [...new URLSearchParams(queryString).entries()]; + + return entriesToObj(currentQueryEntries); +}; + +const getSanitizedValue = (v: string): null | undefined | string => (v ? v : null); + +const noopFn = (v: any) => v; + +export const useUrlParamsState = ( + key: string, + initialValue: T, + { + prepare = noopFn, + pushNavigation = false, + serialize = noopFn, + deSerialize = noopFn, + }: { + prepare?: (val: string) => string; + pushNavigation?: boolean; + serialize: (val: T) => string; + deSerialize: (val: string | null | undefined) => T; + }, +) => { + const router = useRouter(); + const [pathName, queryParams] = router.asPath.split('?'); + const [previousQuery, setPreviousQuery] = useState>(); + const currentQuery = getParamsObj(queryParams); + + const hasQueryParams = !!queryParams; + const previousValue = !hasQueryParams && previousQuery; + + useEffect(() => { + const query = { + ...(initialValue && { [key]: serialize(initialValue) }), + ...currentQuery, + }; + + const preparedQuery = entriesToObj(Object.entries(query), (val, param) => + param === key ? prepare(val) : val, + ); + + setPreviousQuery(query); + + const urlParams = new window.URLSearchParams(previousValue ? previousValue : query).toString(); + const newPath = urlParams ? `${pathName}?${urlParams}` : pathName; + + if (previousValue || !isEqual(query, preparedQuery)) { + router.replace(router.pathname, newPath); + } + }, [router.asPath]); + + const setUrlState = (value: T) => { + const newParams = new window.URLSearchParams({ + ...currentQuery, + [key]: serialize(value), + }); + + const newPath = `${pathName}?${newParams.toString()}`; + + if (pushNavigation) { + router.push(router.pathname, newPath); + } else { + router.replace(router.pathname, newPath); + } + }; + + const deserializeValue = (v: string) => { + const sanitized = getSanitizedValue(v); + return deSerialize(sanitized); + }; + + return [ + previousValue ? deserializeValue(previousValue[key]) : deserializeValue(currentQuery[key]), + setUrlState, + ] as [T, typeof setUrlState]; +}; + +export default useUrlParamsState; diff --git a/apps/stage/global/next-auth.d.ts b/apps/stage/global/next-auth.d.ts new file mode 100644 index 00000000..d74608c7 --- /dev/null +++ b/apps/stage/global/next-auth.d.ts @@ -0,0 +1,23 @@ +import NextAuth from 'next-auth'; + +declare module 'next-auth' { + /** + * Returned by `useSession`, `getSession` and received as a prop on the `SessionProvider` React Context + */ + interface Session { + user: { + sub: string; + name: string; + email: string; + firstName: string; + lastName: string; + emailVerified: string; + }; + expires: string; + account: { + provider: string; + accessToken: string; + }; + scopes: string[]; + } +} diff --git a/apps/stage/global/types/sqon.ts b/apps/stage/global/types/sqon.ts new file mode 100644 index 00000000..175dd984 --- /dev/null +++ b/apps/stage/global/types/sqon.ts @@ -0,0 +1,66 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +export type ArrayFieldKeys = 'in' | 'is' | 'filter'; + +export type ScalarFieldKeys = '>=' | '<=' | '>' | '<'; + +export type CombinationKeys = 'and' | 'or' | 'not'; + +export type ArrayFieldValue = Array | string; +export type ScalarFieldValue = number; + +export interface FilterField { + fieldNames: string[]; + value: ArrayFieldValue; +} + +export interface FilterFieldOperator { + op: ArrayFieldKeys; + content: FilterField; +} + +export interface ArrayField { + fieldName: string; + value: ArrayFieldValue; +} + +export interface ScalarField { + fieldName: string; + value: ScalarFieldValue; +} + +export interface ArrayFieldOperator { + op: ArrayFieldKeys; + content: ArrayField; +} + +export interface ScalarFieldOperator { + op: ScalarFieldKeys; + content: ScalarField; +} + +export type FieldOperator = ArrayFieldOperator | ScalarFieldOperator; + +export type RepoFiltersType = { + op: 'and'; + content: FieldOperator[]; +}; \ No newline at end of file diff --git a/apps/stage/global/types/types.ts b/apps/stage/global/types/types.ts new file mode 100644 index 00000000..f18840a0 --- /dev/null +++ b/apps/stage/global/types/types.ts @@ -0,0 +1,87 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +export enum UserStatus { + APPROVED = 'APPROVED', + DISABLED = 'DISABLED', + PENDING = 'PENDING', + REJECTED = 'REJECTED', +} + +export enum UserType { + ADMIN = 'ADMIN', + USER = 'USER', +} + +export enum Language { + ENGLISH = 'English', + FRENCH = 'French', + SPANISH = 'Spanish', +} + +export enum ProviderType { + GOOGLE = 'GOOGLE', + GITHUB = 'GITHUB', + LINKEDIN = 'LINKEDIN', + ORCID = 'ORCID', + KEYCLOAK = 'KEYCLOAK', +} + +export interface User { + email: string; + type: UserType; + status: UserStatus; + firstName: string; + lastName: string; + createdAt: number; + lastLogin: number; + preferredLanguage?: Language; + providerType: ProviderType; + providerSubjectId: string; + scope: string[]; +} + +export interface UserWithId extends User { + id: string; +} + +export type AlertLevel = 'error' | 'warning' | 'info'; + +export type AlertDef = { + level: AlertLevel; + title: string; + message?: string; + dismissable: boolean; + id: string; +}; + +// Type guards +export const isAlertLevel = (level: any): level is AlertLevel => { + return level === 'error' || level === 'warning' || level === 'info'; +}; + +export const isAlertDef = (obj: any): obj is AlertDef => { + return obj.id && obj.title && obj.dismissable !== undefined && isAlertLevel(obj.level); +}; + +export const isAlertDefs = (obj: any): obj is AlertDef[] => { + return Array.isArray(obj) && obj.every(isAlertDef); +}; diff --git a/apps/stage/global/utils/apiToken.ts b/apps/stage/global/utils/apiToken.ts new file mode 100644 index 00000000..a98cc455 --- /dev/null +++ b/apps/stage/global/utils/apiToken.ts @@ -0,0 +1,30 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +export const parseExpiry = (exp: string) => { + const expFromTodayMs = Date.parse(exp) - Date.now(); + return expFromTodayMs || 0; +}; + +export const getDayValue = (exp: number) => { + const days = Math.floor(exp / 1000 / 60 / 60 / 24); + return `Expires in: ${days} days`; +}; diff --git a/apps/stage/global/utils/constants.ts b/apps/stage/global/utils/constants.ts new file mode 100644 index 00000000..cb48244d --- /dev/null +++ b/apps/stage/global/utils/constants.ts @@ -0,0 +1,83 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import urlJoin from 'url-join'; + +import { getConfig } from '../config'; + +const { NEXT_PUBLIC_KEYCLOAK_HOST, NEXT_PUBLIC_KEYCLOAK_REALM } = getConfig(); + +export const EXPLORER_PATH = '/explorer'; +export const USER_PATH = '/user'; +export const LOGIN_PATH = '/login'; + +export const ROOT_PATH = '/'; + +export enum INTERNAL_PATHS { + MOLECULAR = '/molecular', + DATATABLE_1 = '/dataTableOne', + DATATABLE_2 = '/dataTableTwo', + DATATABLE_3 = '/dataTableThree', + DATATABLE_4 = '/dataTableFour', + DATATABLE_5 = '/dataTableFive', + HOME = '/home', + DOCUMENTATION = '/documentation', + SONG = '/swaggerDocs/song', + LYRIC = '/swaggerDocs/lyric', + LECTERN = '/swaggerDocs/lectern', + SCORE = '/swaggerDocs/score', +} + +// external Swagger links +export const LECTERN_SWAGGER = 'http://localhost:3031/api-docs'; +export const LYRIC_SWAGGER = 'http://localhost:3030/api-docs'; +export const SONG_SWAGGER = 'http://localhost:8080/swagger-ui.html'; +export const SCORE_SWAGGER = 'http://localhost:8087/swagger-ui.html'; + +// external docs links +export const HELP_URL = 'https://github.com/overture-stack/docs/discussions/new?category=support'; +export const EMAIL_SETTING_URL = 'admin@example.com'; +export const DOCS_URL = 'https://docs.overture.bio'; + +// keycloak +export const KEYCLOAK_URL_ISSUER = urlJoin(NEXT_PUBLIC_KEYCLOAK_HOST, 'realms', NEXT_PUBLIC_KEYCLOAK_REALM); +export const KEYCLOAK_URL_TOKEN = urlJoin(KEYCLOAK_URL_ISSUER, 'protocol/openid-connect/token'); +export const KEYCLOAK_API_KEY_ENDPOINT = urlJoin(KEYCLOAK_URL_ISSUER, 'apikey/api_key'); + +export const AUTH_PROVIDER = { + KEYCLOAK: 'keycloak', +}; + +const PROXY_API_PATH = '/api'; +const PROXY_PROTECTED_API_PATH = '/api/protected'; + +export const INTERNAL_API_PROXY = { + DATATABLE_1_ARRANGER: urlJoin(PROXY_API_PATH, 'dataset_1_arranger'), + DATATABLE_2_ARRANGER: urlJoin(PROXY_API_PATH, 'dataset_2_arranger'), + DATATABLE_3_ARRANGER: urlJoin(PROXY_API_PATH, 'dataset_3_arranger'), + DATATABLE_4_ARRANGER: urlJoin(PROXY_API_PATH, 'dataset_4_arranger'), + DATATABLE_5_ARRANGER: urlJoin(PROXY_API_PATH, 'dataset_5_arranger'), + MOLECULAR_ARRANGER: urlJoin(PROXY_API_PATH, 'molecular_arranger'), + PROTECTED_ARRANGER: urlJoin(PROXY_PROTECTED_API_PATH, 'arranger'), + PROTECTED_KEYCLOAK_APIKEY_ENDPOINT: urlJoin(PROXY_PROTECTED_API_PATH, 'keycloak/apikey'), + PROTECTED_KEYCLOAK_TOKEN_ENDPOINT: urlJoin(PROXY_PROTECTED_API_PATH, 'keycloak/token'), + SONG: urlJoin(PROXY_API_PATH, 'song'), +} as const; diff --git a/apps/stage/global/utils/crypt.ts b/apps/stage/global/utils/crypt.ts new file mode 100644 index 00000000..1e6ccdc5 --- /dev/null +++ b/apps/stage/global/utils/crypt.ts @@ -0,0 +1,14 @@ +import Cryptr from 'cryptr'; +import { getConfig } from '../config'; + +const { ACCESSTOKEN_ENCRYPTION_SECRET } = getConfig(); + +const cryptr = new Cryptr(ACCESSTOKEN_ENCRYPTION_SECRET); + +export const encryptContent = (value: string) => { + return cryptr.encrypt(value); +}; + +export const decryptContent = (encryptedValue: string) => { + return cryptr.decrypt(encryptedValue); +}; diff --git a/apps/stage/global/utils/dataTablesDiscovery.ts b/apps/stage/global/utils/dataTablesDiscovery.ts new file mode 100644 index 00000000..c176b3b4 --- /dev/null +++ b/apps/stage/global/utils/dataTablesDiscovery.ts @@ -0,0 +1,49 @@ +// global/utils/dataTablesDiscovery.ts +import fs from 'fs'; +import path from 'path'; + +export interface DataTableInfo { + id: string; + title: string; + path: string; +} + +/** + * Simple utility to discover data tables based on folder names + * in the components/pages/dataTables directory + */ +export function discoverDataTables(): DataTableInfo[] { + try { + const dataTablesPath = path.join(process.cwd(), 'components', 'pages', 'activeDataTables'); + + // Check if directory exists + if (!fs.existsSync(dataTablesPath)) { + console.warn('Data tables directory not found:', dataTablesPath); + return []; + } + + // Read directories + const entries = fs.readdirSync(dataTablesPath, { withFileTypes: true }); + const directories = entries.filter((entry) => entry.isDirectory()); + + // Convert to data table info + return directories.map((dir) => { + // Format the title (capitalize first letter, add spaces between camelCase) + const title = dir.name + .replace(/([A-Z])/g, ' $1') // Add space before capital letters + .replace(/^./, (str) => str.toUpperCase()); // Capitalize first letter + + // Use known path if available, otherwise create a path based on name + const path = `/${dir.name}`; + + return { + id: dir.name, + title: title.trim(), + path, + }; + }); + } catch (error) { + console.error('Error discovering data tables:', error); + return []; + } +} diff --git a/apps/stage/global/utils/getInternalLink.ts b/apps/stage/global/utils/getInternalLink.ts new file mode 100644 index 00000000..0239498f --- /dev/null +++ b/apps/stage/global/utils/getInternalLink.ts @@ -0,0 +1,31 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import urlJoin from 'url-join'; + +import { getConfig } from '../config'; + +const getInternalLink = ({ path }: { path: string }) => { + const { NEXT_PUBLIC_BASE_PATH } = getConfig(); + return urlJoin(NEXT_PUBLIC_BASE_PATH, path); +}; + +export default getInternalLink; diff --git a/apps/stage/global/utils/keycloakUtils.ts b/apps/stage/global/utils/keycloakUtils.ts new file mode 100644 index 00000000..80c809ec --- /dev/null +++ b/apps/stage/global/utils/keycloakUtils.ts @@ -0,0 +1,23 @@ +import { getConfig } from '@/global/config'; + +const { NEXT_PUBLIC_KEYCLOAK_PERMISSION_AUDIENCE } = getConfig(); + +export const permissionBodyParams = () => { + return new URLSearchParams({ + grant_type: 'urn:ietf:params:oauth:grant-type:uma-ticket', + audience: NEXT_PUBLIC_KEYCLOAK_PERMISSION_AUDIENCE, + response_mode: 'permissions', + }); +}; + +export type Permission = { + rsid: string; + rsname: string; + scopes: string[]; +}; + +export const scopesFromPermissions = (permissions: Permission[]) => { + return permissions + .filter(({ scopes }) => scopes) + .flatMap(({ rsname, scopes }) => scopes.flatMap((scope) => [rsname + '.' + scope])); +}; diff --git a/apps/stage/global/utils/pages/index.tsx b/apps/stage/global/utils/pages/index.tsx new file mode 100644 index 00000000..ba41fbfb --- /dev/null +++ b/apps/stage/global/utils/pages/index.tsx @@ -0,0 +1,37 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { PageConfigProps, PageWithConfig } from './types'; + +type CreatePageConfigs = { + getInitialProps?: PageConfigProps['getInitialProps']; + isPublic?: boolean; +}; + +export const createPage = +

    ({ getInitialProps, isPublic = false }: CreatePageConfigs) => + ( + page: React.ComponentType

    & CreatePageConfigs = () =>

    Here's a page
    , + ): PageWithConfig => { + page.getInitialProps = getInitialProps || (async () => []); + page.isPublic = isPublic; + return page as PageWithConfig; + }; diff --git a/apps/stage/global/utils/pages/types.ts b/apps/stage/global/utils/pages/types.ts new file mode 100644 index 00000000..73f7cf64 --- /dev/null +++ b/apps/stage/global/utils/pages/types.ts @@ -0,0 +1,46 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { NextPageContext } from 'next'; +import { type ComponentType } from 'react'; + +export type GetInitialPropsContext = NextPageContext & { + res?: NextPageContext['res'] & { + redirect?: (s: string) => void; + }; +}; + +export type ClientSideGetInitialPropsContext = { + pathname: GetInitialPropsContext['pathname']; + query: GetInitialPropsContext['query']; + asPath?: GetInitialPropsContext['asPath']; +}; + +type GetInitialPropsContextWithEgo = GetInitialPropsContext & { + egoJwt?: string; +}; + +export type PageConfigProps = { + getInitialProps: (args: GetInitialPropsContextWithEgo) => Promise; + isPublic?: boolean; +}; + +export type PageWithConfig = PageConfigProps & ComponentType; \ No newline at end of file diff --git a/apps/stage/global/utils/providerTypeMap.tsx b/apps/stage/global/utils/providerTypeMap.tsx new file mode 100644 index 00000000..82155d24 --- /dev/null +++ b/apps/stage/global/utils/providerTypeMap.tsx @@ -0,0 +1,43 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { GitHubLogo, GoogleLogo, LinkedInLogo, OrcidLogo, KeycloakLogo } from '../../components/theme/icons'; +import { ProviderType } from '../types/types'; + +export type ProviderDetail = { + displayName: string; + path: string; + icon: any; +}; + +export type ProviderMap = { [k in ProviderType]: ProviderDetail }; + +const providerMap: ProviderMap = { + [ProviderType.GOOGLE]: { displayName: 'Google', path: 'google', icon: GoogleLogo }, + [ProviderType.ORCID]: { displayName: 'ORCiD', path: 'orcid', icon: OrcidLogo }, + [ProviderType.GITHUB]: { displayName: 'GitHub', path: 'github', icon: GitHubLogo }, + [ProviderType.LINKEDIN]: { displayName: 'LinkedIn', path: 'linkedin', icon: LinkedInLogo }, + [ProviderType.KEYCLOAK]: { displayName: 'Keycloak', path: 'keycloak', icon: KeycloakLogo }, + // Facebook will be hidden until provider implementation is fixed in Ego https://github.com/overture-stack/ego/issues/555 + // [ProviderType.FACEBOOK]: { displayName: 'Facebook', path: '', icon: FacebookLogo }, +}; + +export default providerMap; diff --git a/apps/stage/global/utils/proxyUtils.ts b/apps/stage/global/utils/proxyUtils.ts new file mode 100644 index 00000000..5f0d7f98 --- /dev/null +++ b/apps/stage/global/utils/proxyUtils.ts @@ -0,0 +1,12 @@ +const convertToRegexPath = (path: string) => { + const escapedPath = path.replaceAll('/', '\\/'); + return new RegExp(`^${escapedPath}\\/?`); +}; + +export const removeFromPath = (url: string, path: string) => { + return url?.replace(convertToRegexPath(path), '') || ''; +}; + +// Setting the NODE_TLS_REJECT_UNAUTHORIZED environment variable to '0' makes TLS connections +// and HTTPS requests insecure by disabling certificate verification +export const SSLSecured = !(Number(process.env.NODE_TLS_REJECT_UNAUTHORIZED) === 0); diff --git a/apps/stage/global/utils/readme.md b/apps/stage/global/utils/readme.md new file mode 100644 index 00000000..40ede42f --- /dev/null +++ b/apps/stage/global/utils/readme.md @@ -0,0 +1,58 @@ +# Dynamic Data Tables Navigation + +This document explains how the dynamic data tables navigation system works. + +## Overview + +The navigation system automatically discovers data tables based on folder names in the `components/pages/dataTables` directory and displays them in both: + +1. The "Explore Data" dropdown in the navigation bar +2. The "Explore the Data" card on the homepage + +## How It Works + +1. The system scans the `components/pages/dataTables` directory for subfolders +2. Each subfolder is treated as a data table +3. The folder name is converted to a display name (e.g., "tabular" → "Tabular", "clinicalData" → "Clinical Data") +4. These names are used to populate the navigation + +## Adding a New Data Table + +To add a new data table to the navigation: + +1. Create a new folder in the `components/pages/dataTables` directory + + - Use camelCase for folder names with multiple words (e.g., `clinicalData`) + - Use lowercase for single-word names (e.g., `genomics`) + +2. Implement your data table components in this folder + + - The existing code inside this folder is not affected by the navigation system + - The system only reads the folder name + +3. That's it! The folder name will be automatically discovered and added to the navigation + +## Example Directory Structure + +``` +components/ +└── pages/ + └── dataTables/ + ├── tabular/ # Shows as "Tabular" in navigation + ├── clinicalData/ # Shows as "Clinical Data" in navigation + └── molecularData/ # Shows as "Molecular Data" in navigation +``` + +## Technical Details + +- The folder name discovery happens on the server side +- An API endpoint (`/api/data-tables`) returns the list of data tables +- The navigation components fetch this list on the client side + +## Troubleshooting + +If your data table doesn't appear in the navigation: + +1. Make sure the folder exists in `components/pages/dataTables/` +2. Check that the server is running with the latest changes +3. Check browser console for any API errors when fetching the data tables list diff --git a/apps/stage/next-env.d.ts b/apps/stage/next-env.d.ts new file mode 100644 index 00000000..4f11a03d --- /dev/null +++ b/apps/stage/next-env.d.ts @@ -0,0 +1,5 @@ +/// +/// + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/basic-features/typescript for more information. diff --git a/apps/stage/next.config.js b/apps/stage/next.config.js new file mode 100644 index 00000000..ce421d36 --- /dev/null +++ b/apps/stage/next.config.js @@ -0,0 +1,173 @@ +const path = require('path'); +const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); +const withPlugins = require('next-compose-plugins'); +const { patchWebpackConfig: patchForGlobalCSS } = require('next-global-css'); +const withTranspileModules = require('next-transpile-modules')(['swagger-ui-react', 'swagger-ui-dist']); +const ExtraWatchWebpackPlugin = require('extra-watch-webpack-plugin'); + +module.exports = withPlugins([withTranspileModules], { + typescript: { + ignoreBuildErrors: true, + }, + webpack: (config, options) => { + if (options.isServer) { + config.externals = ['react', ...config.externals]; + } else { + options.dev && + config.plugins.push(new ForkTsCheckerWebpackPlugin()) && + config.plugins.push( + new ExtraWatchWebpackPlugin({ + dirs: [path.resolve(__dirname, '.', 'node_modules', 'react')], + }), + ); + } + + config.resolve.alias['@emotion/react'] = path.resolve(__dirname, '.', 'node_modules', '@emotion/react'); + config.resolve.alias['react'] = path.resolve(__dirname, '.', 'node_modules', 'react'); + + process.env.NODE_ENV === 'development' && (config.optimization.minimize = false); + + return patchForGlobalCSS(config, options); + }, + publicRuntimeConfig: { + NEXT_PUBLIC_ADMIN_EMAIL: process.env.NEXT_PUBLIC_ADMIN_EMAIL, + NEXT_PUBLIC_APP_COMMIT: process.env.APP_COMMIT, + NEXT_PUBLIC_APP_VERSION: process.env.APP_VERSION, + + // DATATABLE_1 + NEXT_PUBLIC_ARRANGER_DATATABLE_1_API: process.env.NEXT_PUBLIC_ARRANGER_DATATABLE_1_API, + NEXT_PUBLIC_ARRANGER_DATATABLE_1_DOCUMENT_TYPE: process.env.NEXT_PUBLIC_ARRANGER_DATATABLE_1_DOCUMENT_TYPE, + NEXT_PUBLIC_ARRANGER_DATATABLE_1_INDEX: process.env.NEXT_PUBLIC_ARRANGER_DATATABLE_1_INDEX, + NEXT_PUBLIC_ARRANGER_DATATABLE_1_CARDINALITY_PRECISION_THRESHOLD: + process.env.NEXT_PUBLIC_ARRANGER_DATATABLE_1_CARDINALITY_PRECISION_THRESHOLD || 3000, + NEXT_PUBLIC_ARRANGER_DATATABLE_1_MANIFEST_COLUMNS: + process.env.NEXT_PUBLIC_ARRANGER_DATATABLE_1_MANIFEST_COLUMNS || '', + NEXT_PUBLIC_ARRANGER_DATATABLE_1_MAX_BUCKET_COUNTS: + process.env.NEXT_PUBLIC_ARRANGER_DATATABLE_1_MAX_BUCKET_COUNTS || 1000, + NEXT_PUBLIC_ENABLE_DATATABLE_1_QUICKSEARCH: process.env.NEXT_PUBLIC_ENABLE_DATATABLE_1_QUICKSEARCH, + + // DATATABLE_2 + NEXT_PUBLIC_ARRANGER_DATATABLE_2_API: process.env.NEXT_PUBLIC_ARRANGER_DATATABLE_2_API, + NEXT_PUBLIC_ARRANGER_DATATABLE_2_DOCUMENT_TYPE: process.env.NEXT_PUBLIC_ARRANGER_DATATABLE_2_DOCUMENT_TYPE, + NEXT_PUBLIC_ARRANGER_DATATABLE_2_INDEX: process.env.NEXT_PUBLIC_ARRANGER_DATATABLE_2_INDEX, + NEXT_PUBLIC_ARRANGER_DATATABLE_2_CARDINALITY_PRECISION_THRESHOLD: + process.env.NEXT_PUBLIC_ARRANGER_DATATABLE_2_CARDINALITY_PRECISION_THRESHOLD || 3000, + NEXT_PUBLIC_ARRANGER_DATATABLE_2_MANIFEST_COLUMNS: + process.env.NEXT_PUBLIC_ARRANGER_DATATABLE_2_MANIFEST_COLUMNS || '', + NEXT_PUBLIC_ARRANGER_DATATABLE_2_MAX_BUCKET_COUNTS: + process.env.NEXT_PUBLIC_ARRANGER_DATATABLE_2_MAX_BUCKET_COUNTS || 1000, + NEXT_PUBLIC_ENABLE_DATATABLE_2_QUICKSEARCH: process.env.NEXT_PUBLIC_ENABLE_DATATABLE_2_QUICKSEARCH, + + // DATATABLE_3 + NEXT_PUBLIC_ARRANGER_DATATABLE_3_API: process.env.NEXT_PUBLIC_ARRANGER_DATATABLE_3_API, + NEXT_PUBLIC_ARRANGER_DATATABLE_3_DOCUMENT_TYPE: process.env.NEXT_PUBLIC_ARRANGER_DATATABLE_3_DOCUMENT_TYPE, + NEXT_PUBLIC_ARRANGER_DATATABLE_3_INDEX: process.env.NEXT_PUBLIC_ARRANGER_DATATABLE_3_INDEX, + NEXT_PUBLIC_ARRANGER_DATATABLE_3_CARDINALITY_PRECISION_THRESHOLD: + process.env.NEXT_PUBLIC_ARRANGER_DATATABLE_3_CARDINALITY_PRECISION_THRESHOLD || 3000, + NEXT_PUBLIC_ARRANGER_DATATABLE_3_MANIFEST_COLUMNS: + process.env.NEXT_PUBLIC_ARRANGER_DATATABLE_3_MANIFEST_COLUMNS || '', + NEXT_PUBLIC_ARRANGER_DATATABLE_3_MAX_BUCKET_COUNTS: + process.env.NEXT_PUBLIC_ARRANGER_DATATABLE_3_MAX_BUCKET_COUNTS || 1000, + NEXT_PUBLIC_ENABLE_DATATABLE_3_QUICKSEARCH: process.env.NEXT_PUBLIC_ENABLE_DATATABLE_3_QUICKSEARCH, + + // DATATABLE_4 + NEXT_PUBLIC_ARRANGER_DATATABLE_4_API: process.env.NEXT_PUBLIC_ARRANGER_DATATABLE_4_API, + NEXT_PUBLIC_ARRANGER_DATATABLE_4_DOCUMENT_TYPE: process.env.NEXT_PUBLIC_ARRANGER_DATATABLE_4_DOCUMENT_TYPE, + NEXT_PUBLIC_ARRANGER_DATATABLE_4_INDEX: process.env.NEXT_PUBLIC_ARRANGER_DATATABLE_4_INDEX, + NEXT_PUBLIC_ARRANGER_DATATABLE_4_CARDINALITY_PRECISION_THRESHOLD: + process.env.NEXT_PUBLIC_ARRANGER_DATATABLE_4_CARDINALITY_PRECISION_THRESHOLD || 3000, + NEXT_PUBLIC_ARRANGER_DATATABLE_4_MANIFEST_COLUMNS: + process.env.NEXT_PUBLIC_ARRANGER_DATATABLE_4_MANIFEST_COLUMNS || '', + NEXT_PUBLIC_ARRANGER_DATATABLE_4_MAX_BUCKET_COUNTS: + process.env.NEXT_PUBLIC_ARRANGER_DATATABLE_4_MAX_BUCKET_COUNTS || 1000, + NEXT_PUBLIC_ENABLE_DATATABLE_4_QUICKSEARCH: process.env.NEXT_PUBLIC_ENABLE_DATATABLE_4_QUICKSEARCH, + + // DATATABLE_5 + NEXT_PUBLIC_ARRANGER_DATATABLE_5_API: process.env.NEXT_PUBLIC_ARRANGER_DATATABLE_5_API, + NEXT_PUBLIC_ARRANGER_DATATABLE_5_DOCUMENT_TYPE: process.env.NEXT_PUBLIC_ARRANGER_DATATABLE_5_DOCUMENT_TYPE, + NEXT_PUBLIC_ARRANGER_DATATABLE_5_INDEX: process.env.NEXT_PUBLIC_ARRANGER_DATATABLE_5_INDEX, + NEXT_PUBLIC_ARRANGER_DATATABLE_5_CARDINALITY_PRECISION_THRESHOLD: + process.env.NEXT_PUBLIC_ARRANGER_DATATABLE_5_CARDINALITY_PRECISION_THRESHOLD || 3000, + NEXT_PUBLIC_ARRANGER_DATATABLE_5_MANIFEST_COLUMNS: + process.env.NEXT_PUBLIC_ARRANGER_DATATABLE_5_MANIFEST_COLUMNS || '', + NEXT_PUBLIC_ARRANGER_DATATABLE_5_MAX_BUCKET_COUNTS: + process.env.NEXT_PUBLIC_ARRANGER_DATATABLE_5_MAX_BUCKET_COUNTS || 1000, + NEXT_PUBLIC_ENABLE_DATATABLE_5_QUICKSEARCH: process.env.NEXT_PUBLIC_ENABLE_DATATABLE_5_QUICKSEARCH, + + // Song + NEXT_PUBLIC_SONG_API: process.env.NEXT_PUBLIC_SONG_API || 'http://localhost:8080', + NEXT_PUBLIC_LYRIC_API: process.env.NEXT_PUBLIC_LYRIC_API || 'http://localhost:3030', + NEXT_PUBLIC_LECTERN_API: process.env.NEXT_PUBLIC_LECTERN_API || 'http://localhost:3031', + NEXT_PUBLIC_SCORE_API: process.env.NEXT_PUBLIC_SCORE_API || 'http://localhost:8087', + + // Auth & Keycloak + NEXT_PUBLIC_AUTH_PROVIDER: process.env.NEXT_PUBLIC_AUTH_PROVIDER || 'keycloak', + NEXT_PUBLIC_KEYCLOAK_HOST: process.env.NEXT_PUBLIC_KEYCLOAK_HOST || 'http://keycloak:8080', + NEXT_PUBLIC_KEYCLOAK_REALM: process.env.NEXT_PUBLIC_KEYCLOAK_REALM || 'myrealm', + NEXT_PUBLIC_KEYCLOAK_CLIENT_ID: process.env.NEXT_PUBLIC_KEYCLOAK_CLIENT_ID || 'webclient', + NEXT_PUBLIC_KEYCLOAK_PERMISSION_AUDIENCE: process.env.NEXT_PUBLIC_KEYCLOAK_PERMISSION_AUDIENCE || 'dms', + + // using ASSET_PREFIX for the public runtime BASE_PATH because basePath in the top level config was not working + // with the dms reverse proxy setup + NEXT_PUBLIC_BASE_PATH: process.env.ASSET_PREFIX, + NEXT_PUBLIC_DEBUG: process.env.NEXT_PUBLIC_DEBUG, + NEXT_PUBLIC_LAB_NAME: process.env.NEXT_PUBLIC_LAB_NAME, + NEXT_PUBLIC_LOGO_FILENAME: process.env.NEXT_PUBLIC_LOGO_FILENAME, + NEXT_PUBLIC_SSO_PROVIDERS: process.env.NEXT_PUBLIC_SSO_PROVIDERS, + NEXT_PUBLIC_UI_VERSION: process.env.npm_package_version, + NEXT_PUBLIC_ENABLE_REGISTRATION: process.env.NEXT_PUBLIC_ENABLE_REGISTRATION, + + // Banner related configs + NEXT_PUBLIC_SYSTEM_ALERTS: process.env.NEXT_PUBLIC_SYSTEM_ALERTS, + + // MOLECULAR + NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_API: process.env.NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_API, + NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_DOCUMENT_TYPE: process.env.NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_DOCUMENT_TYPE, + NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_INDEX: process.env.NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_INDEX, + NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_CARDINALITY_PRECISION_THRESHOLD: + process.env.NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_CARDINALITY_PRECISION_THRESHOLD || 3000, + NEXT_PUBLIC_ARRANGER_MANIFEST_COLUMNS: process.env.NEXT_PUBLIC_ARRANGER_MANIFEST_COLUMNS || '', + NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_MAX_BUCKET_COUNTS: + process.env.NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_MAX_BUCKET_COUNTS || 1000, + NEXT_PUBLIC_ENABLE_MOLECULAR_QUICKSEARCH: process.env.NEXT_PUBLIC_ENABLE_MOLECULAR_QUICKSEARCH, + }, + assetPrefix: process.env.ASSET_PREFIX || '', + optimizeFonts: false, + experimental: { + esmExternals: 'loose', + }, + async headers() { + return [ + { + source: '/api/:path*', + headers: [ + { key: 'Access-Control-Allow-Origin', value: '*' }, + { key: 'Access-Control-Allow-Methods', value: 'GET,OPTIONS,PATCH,DELETE,POST,PUT' }, + { key: 'Access-Control-Allow-Headers', value: '*' }, + ], + }, + ]; + }, + + async rewrites() { + const isDocker = process.env.IS_DOCKER === 'true'; + return [ + { + source: '/api/song/:path*', + destination: isDocker ? 'http://song:8080/:path*' : 'http://localhost:8080/:path*', + }, + { + source: '/api/lyric/:path*', + destination: isDocker ? 'http://lyric:3030/:path*' : 'http://localhost:3030/:path*', + }, + { + source: '/api/lectern/:path*', + destination: isDocker ? 'http://lectern:3031/:path*' : 'http://localhost:3031/:path*', + }, + { + source: '/api/score/:path*', + destination: isDocker ? 'http://score:8087/:path*' : 'http://localhost:8087/:path*', + }, + ]; + }, +}); diff --git a/apps/stage/ov-logo.png b/apps/stage/ov-logo.png new file mode 100755 index 00000000..51fda130 Binary files /dev/null and b/apps/stage/ov-logo.png differ diff --git a/apps/stage/package-lock.json b/apps/stage/package-lock.json new file mode 100644 index 00000000..c35a13a6 --- /dev/null +++ b/apps/stage/package-lock.json @@ -0,0 +1,11106 @@ +{ + "name": "stage", + "version": "1.1.3", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "stage", + "version": "1.1.3", + "dependencies": { + "@emotion/react": "^11.9.0", + "@emotion/styled": "^11.8.1", + "@overture-stack/arranger-components": "^3.0.0-beta.37", + "@overture-stack/sqon-builder": "^1.1.0", + "@types/marked": "^5.0.2", + "@types/react-syntax-highlighter": "^15.5.13", + "axios": "^0.27.2", + "classnames": "^2.5.1", + "cryptr": "^6.3.0", + "http-proxy": "^1.18.1", + "jsonwebtoken": "^8.5.1", + "jwt-decode": "^3.1.2", + "lodash": "^4.17.21", + "marked": "^15.0.6", + "next": "^12.1.6", + "next-auth": "^4.23.1", + "next-compose-plugins": "^2.2.1", + "next-global-css": "1.3.1", + "next-transpile-modules": "^9.0.0", + "query-string": "^7.1.1", + "react": "^17.0.2", + "react-dom": "^17.0.2", + "react-grid-system": "^7.1.1", + "react-syntax-highlighter": "^15.6.1", + "react-tippy": "^1.4.0", + "swagger-ui-dist": "^4.11.1", + "swagger-ui-react": "^4.11.1", + "url-join": "^5.0.0" + }, + "devDependencies": { + "@babel/preset-typescript": "^7.21.0", + "@emotion/babel-plugin": "^11.9.2", + "@types/http-proxy": "^1.17.11", + "@types/lodash": "^4.14.182", + "@types/node": "^17.0.35", + "@types/react": "^17.0.83", + "@types/react-dom": "^17.0.26", + "@types/swagger-ui-react": "^4.18.3", + "@types/url-join": "^4.0.1", + "extra-watch-webpack-plugin": "^1.0.3", + "fork-ts-checker-webpack-plugin": "^8.0.0", + "jest": "^27.5.1", + "prettier-plugin-organize-imports": "^4.1.0", + "ts-patch": "^2.1.0", + "typescript": "^4.7.2", + "typescript-transform-paths": "^3.4.6" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.5.tgz", + "integrity": "sha512-XvcZi1KWf88RVbF9wn8MN6tYFloU5qX8KjuF3E1PVBmJ9eypXfs4GRiJwLuTZL0iSnJUKn1BFPa5BPZZJyFzPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", + "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.26.0", + "@babel/generator": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.0", + "@babel/parser": "^7.26.0", + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.26.0", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.5.tgz", + "integrity": "sha512-2caSP6fN9I7HOe6nqhtft7V4g7/V/gfDsC3Ag4W7kEzzvRGKqiv0pu0HogPiZ3KaVSoNDhUws6IJjDjpfmYIXw==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.26.5", + "@babel/types": "^7.26.5", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/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, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.26.5.tgz", + "integrity": "sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.26.5", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz", + "integrity": "sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/traverse": "^7.25.9", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz", + "integrity": "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz", + "integrity": "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.26.5.tgz", + "integrity": "sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.26.5.tgz", + "integrity": "sha512-bJ6iIVdYX1YooY2X7w1q6VITt+LnUILtNk7zT78ykuwStx8BauCzxvFqFaHjOpW1bVnSUM1PN1f0p5P21wHxvg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/traverse": "^7.26.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz", + "integrity": "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", + "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.5.tgz", + "integrity": "sha512-SRJ4jYmXRqV1/Xc+TIVG84WjHBXKlxO9sHQnA2Pf12QQEAp1LOh6kDzNHXcUnbH1QI0FDoPPVOt+vyUDucxpaw==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.26.5" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz", + "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.9.tgz", + "integrity": "sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.9.tgz", + "integrity": "sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.26.3.tgz", + "integrity": "sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.26.5.tgz", + "integrity": "sha512-GJhPO0y8SD5EYVCy2Zr+9dSZcEgaSmq5BLR0Oc25TOEhC+ba49vUAGZFjy8v79z9E1mdldq4x9d1xgh4L1d5dQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.26.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/plugin-syntax-typescript": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-typescript": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.26.0.tgz", + "integrity": "sha512-NMk1IGZ5I/oHhoXEElcm+xUnL/szL6xflkFZmoEU9xj1qSJXpiS7rsspYo92B4DRCDvZn2erT5LdsCeXAKNCkg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "@babel/plugin-syntax-jsx": "^7.25.9", + "@babel/plugin-transform-modules-commonjs": "^7.25.9", + "@babel/plugin-transform-typescript": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", + "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", + "license": "MIT", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/runtime-corejs3": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.26.0.tgz", + "integrity": "sha512-YXHu5lN8kJCb1LOb9PgV6pvak43X2h4HvRApcN5SdWeaItQOzfn1hgP6jasD6KWQyJDBxrVmA9o9OivlnNJK/w==", + "license": "MIT", + "dependencies": { + "core-js-pure": "^3.30.2", + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", + "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.5.tgz", + "integrity": "sha512-rkOSPOw+AXbgtwUga3U4u8RpoK9FEFWBNAlTpcnkLFjL5CT+oyHNuUUC/xx6XefEJ16r38r8Bc/lfp6rYuHeJQ==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.5", + "@babel/parser": "^7.26.5", + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.5", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.5.tgz", + "integrity": "sha512-L6mZmwFDK6Cjh1nRCLXpa6no13ZIioJDz7mdkzHv399pThrTa/k0nUlNaenOeh2kWu/iaOQYElEpKPUswUa9Vg==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@braintree/sanitize-url": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-6.0.2.tgz", + "integrity": "sha512-Tbsj02wXCbqGmzdnXNk0SOF19ChhRU70BsroIi4Pm6Ehp56in6vch94mfbdQ17DozxkL3BAVjbZ4Qc1a0HFRAg==", + "license": "MIT" + }, + "node_modules/@emotion/babel-plugin": { + "version": "11.13.5", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz", + "integrity": "sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/serialize": "^1.3.3", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/babel-plugin/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==", + "license": "MIT" + }, + "node_modules/@emotion/cache": { + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.14.0.tgz", + "integrity": "sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.9.0", + "@emotion/sheet": "^1.4.0", + "@emotion/utils": "^1.4.2", + "@emotion/weak-memoize": "^0.4.0", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/hash": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", + "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==", + "license": "MIT" + }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.3.1.tgz", + "integrity": "sha512-/ACwoqx7XQi9knQs/G0qKvv5teDMhD7bXYns9N/wM8ah8iNb8jZ2uNO0YOgiq2o2poIvVtJS2YALasQuMSQ7Kw==", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.9.0" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", + "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==", + "license": "MIT" + }, + "node_modules/@emotion/react": { + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz", + "integrity": "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.13.5", + "@emotion/cache": "^11.14.0", + "@emotion/serialize": "^1.3.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0", + "@emotion/utils": "^1.4.2", + "@emotion/weak-memoize": "^0.4.0", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/serialize": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.3.tgz", + "integrity": "sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==", + "license": "MIT", + "dependencies": { + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/unitless": "^0.10.0", + "@emotion/utils": "^1.4.2", + "csstype": "^3.0.2" + } + }, + "node_modules/@emotion/sheet": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", + "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==", + "license": "MIT" + }, + "node_modules/@emotion/styled": { + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.14.0.tgz", + "integrity": "sha512-XxfOnXFffatap2IyCeJyNov3kiDQWoR08gPUQxvbL7fxKryGBKUZUkG6Hz48DZwVrJSVh9sJboyV1Ds4OW6SgA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.13.5", + "@emotion/is-prop-valid": "^1.3.0", + "@emotion/serialize": "^1.3.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0", + "@emotion/utils": "^1.4.2" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0-rc.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/unitless": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", + "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==", + "license": "MIT" + }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.2.0.tgz", + "integrity": "sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==", + "license": "MIT", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emotion/utils": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.2.tgz", + "integrity": "sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==", + "license": "MIT" + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz", + "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==", + "license": "MIT" + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@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, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.5.1.tgz", + "integrity": "sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^27.5.1", + "jest-util": "^27.5.1", + "slash": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/core": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.5.1.tgz", + "integrity": "sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^27.5.1", + "@jest/reporters": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.8.1", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^27.5.1", + "jest-config": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-resolve-dependencies": "^27.5.1", + "jest-runner": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "jest-watcher": "^27.5.1", + "micromatch": "^4.0.4", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/environment": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", + "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "jest-mock": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz", + "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "@sinonjs/fake-timers": "^8.0.1", + "@types/node": "*", + "jest-message-util": "^27.5.1", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.5.1.tgz", + "integrity": "sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/types": "^27.5.1", + "expect": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.5.1.tgz", + "integrity": "sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-haste-map": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^4.0.1", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^8.1.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/reporters/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/source-map": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.5.1.tgz", + "integrity": "sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9", + "source-map": "^0.6.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/source-map/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/test-result": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.5.1.tgz", + "integrity": "sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz", + "integrity": "sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/test-result": "^27.5.1", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-runtime": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.5.1.tgz", + "integrity": "sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.1.0", + "@jest/types": "^27.5.1", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-util": "^27.5.1", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/transform/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jest/transform/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@next/env": { + "version": "12.3.4", + "resolved": "https://registry.npmjs.org/@next/env/-/env-12.3.4.tgz", + "integrity": "sha512-H/69Lc5Q02dq3o+dxxy5O/oNxFsZpdL6WREtOOtOM1B/weonIwDXkekr1KV5DPVPr12IHFPrMrcJQ6bgPMfn7A==", + "license": "MIT" + }, + "node_modules/@next/swc-android-arm-eabi": { + "version": "12.3.4", + "resolved": "https://registry.npmjs.org/@next/swc-android-arm-eabi/-/swc-android-arm-eabi-12.3.4.tgz", + "integrity": "sha512-cM42Cw6V4Bz/2+j/xIzO8nK/Q3Ly+VSlZJTa1vHzsocJRYz8KT6MrreXaci2++SIZCF1rVRCDgAg5PpqRibdIA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-android-arm64": { + "version": "12.3.4", + "resolved": "https://registry.npmjs.org/@next/swc-android-arm64/-/swc-android-arm64-12.3.4.tgz", + "integrity": "sha512-5jf0dTBjL+rabWjGj3eghpLUxCukRhBcEJgwLedewEA/LJk2HyqCvGIwj5rH+iwmq1llCWbOky2dO3pVljrapg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "12.3.4", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-12.3.4.tgz", + "integrity": "sha512-DqsSTd3FRjQUR6ao0E1e2OlOcrF5br+uegcEGPVonKYJpcr0MJrtYmPxd4v5T6UCJZ+XzydF7eQo5wdGvSZAyA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "12.3.4", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-12.3.4.tgz", + "integrity": "sha512-PPF7tbWD4k0dJ2EcUSnOsaOJ5rhT3rlEt/3LhZUGiYNL8KvoqczFrETlUx0cUYaXe11dRA3F80Hpt727QIwByQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-freebsd-x64": { + "version": "12.3.4", + "resolved": "https://registry.npmjs.org/@next/swc-freebsd-x64/-/swc-freebsd-x64-12.3.4.tgz", + "integrity": "sha512-KM9JXRXi/U2PUM928z7l4tnfQ9u8bTco/jb939pdFUHqc28V43Ohd31MmZD1QzEK4aFlMRaIBQOWQZh4D/E5lQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm-gnueabihf": { + "version": "12.3.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-12.3.4.tgz", + "integrity": "sha512-3zqD3pO+z5CZyxtKDTnOJ2XgFFRUBciOox6EWkoZvJfc9zcidNAQxuwonUeNts6Xbm8Wtm5YGIRC0x+12YH7kw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "12.3.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-12.3.4.tgz", + "integrity": "sha512-kiX0vgJGMZVv+oo1QuObaYulXNvdH/IINmvdZnVzMO/jic/B8EEIGlZ8Bgvw8LCjH3zNVPO3mGrdMvnEEPEhKA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "12.3.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-12.3.4.tgz", + "integrity": "sha512-EETZPa1juczrKLWk5okoW2hv7D7WvonU+Cf2CgsSoxgsYbUCZ1voOpL4JZTOb6IbKMDo6ja+SbY0vzXZBUMvkQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "12.3.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-12.3.4.tgz", + "integrity": "sha512-4csPbRbfZbuWOk3ATyWcvVFdD9/Rsdq5YHKvRuEni68OCLkfy4f+4I9OBpyK1SKJ00Cih16NJbHE+k+ljPPpag==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "12.3.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-12.3.4.tgz", + "integrity": "sha512-YeBmI+63Ro75SUiL/QXEVXQ19T++58aI/IINOyhpsRL1LKdyfK/35iilraZEFz9bLQrwy1LYAR5lK200A9Gjbg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "12.3.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-12.3.4.tgz", + "integrity": "sha512-Sd0qFUJv8Tj0PukAYbCCDbmXcMkbIuhnTeHm9m4ZGjCf6kt7E/RMs55Pd3R5ePjOkN7dJEuxYBehawTR/aPDSQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-ia32-msvc": { + "version": "12.3.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-12.3.4.tgz", + "integrity": "sha512-rt/vv/vg/ZGGkrkKcuJ0LyliRdbskQU+91bje+PgoYmxTZf/tYs6IfbmgudBJk6gH3QnjHWbkphDdRQrseRefQ==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "12.3.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-12.3.4.tgz", + "integrity": "sha512-DQ20JEfTBZAgF8QCjYfJhv2/279M6onxFjdG/+5B0Cyj00/EdBxiWb2eGGFgQhrBbNv/lsvzFbbi0Ptf8Vw/bg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@overture-stack/arranger-components": { + "version": "3.0.0-beta.37", + "resolved": "https://registry.npmjs.org/@overture-stack/arranger-components/-/arranger-components-3.0.0-beta.37.tgz", + "integrity": "sha512-ezhi9w37sIrNP3BRKwrv/C7Nc24jn3zl65hIhGPQ66ltHNVqHnSwIt7ZKJY7yuSGxhbfkZvyh5a66Ps2+8sFog==", + "license": "AGPL-3.0-or-later", + "dependencies": { + "@emotion/react": "^11.10.6", + "@emotion/styled": "^11.10.6", + "@overture-stack/sqon-builder": "^0.0.0", + "@tanstack/react-table": "^8.7.9", + "axios": "^0.27.2", + "babel-polyfill": "^6.26.0", + "classnames": "^2.3.2", + "color": "^4.2.3", + "convert-units": "^2.3.4", + "date-fns": "^2.29.3", + "downshift": "^1.23.2", + "filesize": "^10.0.6", + "formik": "^0.11.11", + "jsonpath": "^1.1.1", + "jsonpath-plus": "^7.2.0", + "lodash": "^4.17.21", + "pluralize": "^8.0.0", + "prettier": "^2.8.5", + "pretty-quick": "^3.1.3", + "ramda": "^0.28.0", + "react-component-component": "^1.2.1", + "react-datepicker": "^4.10.0", + "react-grid-layout": "^0.16.5", + "react-icons": "^4.8.0", + "react-input-range": "^1.3.0", + "react-router-dom": "^4.2.2", + "react-scrollbar-size": "^2.1.0", + "react-spinkit": "^3.0.0", + "react-table-old": "npm:react-table@^6.11.5", + "react-tippy": "^1.4.0", + "react-toastify": "^3.3.2", + "react-treeview": "^0.4.7", + "recompose": "^0.30.0", + "resolve-url": "^0.2.1", + "rxjs": "^5.5.6", + "semantic-ui-css": "^2.4.1", + "semantic-ui-react": "^0.77.2", + "sqon-builder": "^2.0.1", + "typescript": "^4.9.5", + "url-join": "^4.0.1", + "uuid": "^9.0.0" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "@types/react-dom": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + } + }, + "node_modules/@overture-stack/arranger-components/node_modules/@overture-stack/sqon-builder": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/@overture-stack/sqon-builder/-/sqon-builder-0.0.0.tgz", + "integrity": "sha512-VEeg0pNGXMAGA8/9/1wOt1JA0Tdsfs0PupWQMFg5qhxX4gDzHnHc4+kVoz1A4NoMRYpP4DnGkrbSe8M4eE+nKQ==", + "license": "AGPL-3.0-or-later" + }, + "node_modules/@overture-stack/arranger-components/node_modules/react-icons": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.12.0.tgz", + "integrity": "sha512-IBaDuHiShdZqmfc/TwHu6+d6k2ltNCf3AszxNmjJc1KUfXdEeRJOKyNvLmAHaarhzGmTSVygNdyu8/opXv2gaw==", + "license": "MIT", + "peerDependencies": { + "react": "*" + } + }, + "node_modules/@overture-stack/arranger-components/node_modules/url-join": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", + "license": "MIT" + }, + "node_modules/@overture-stack/sqon-builder": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@overture-stack/sqon-builder/-/sqon-builder-1.1.0.tgz", + "integrity": "sha512-HpxJBbhN2FIIpSKOHoezua7/2by9S7qpnuaG5qgpm69nLUX0KnW2fwGVELJ3PMW1DpU8qg74kASozUnST0F+cQ==", + "license": "AGPL-3.0-or-later", + "dependencies": { + "lodash.clonedeep": "^4.5.0", + "zod": "^3.21.4" + } + }, + "node_modules/@panva/hkdf": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@panva/hkdf/-/hkdf-1.2.1.tgz", + "integrity": "sha512-6oclG6Y3PiDFcoyk8srjLfVKyMfVCKJ27JwNPViuXziFpmdz+MZnZN/aKY0JGXgYuO/VghU0jcOAZgWXZ1Dmrw==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "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==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@scarf/scarf": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@scarf/scarf/-/scarf-1.4.0.tgz", + "integrity": "sha512-xxeapPiUXdZAE3che6f3xogoJPeZgig6omHEy1rIY5WVsB3H2BHNnZH+gHG6x91SCWyQCzWGsuL2Hh3ClO5/qQ==", + "hasInstallScript": true, + "license": "Apache-2.0" + }, + "node_modules/@sinonjs/commons": { + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", + "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", + "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^1.7.0" + } + }, + "node_modules/@swagger-api/apidom-ast": { + "version": "1.0.0-beta.7", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ast/-/apidom-ast-1.0.0-beta.7.tgz", + "integrity": "sha512-7QpyF1ypW+1RkJkvpYh95sd9D9EJpEeQdY+APWDmRZFSbDCDbVI1pJ4gniHl5tEcDVjltOHxoorZbxk59OU3xA==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-error": "^1.0.0-beta.7", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0", + "unraw": "^3.0.0" + } + }, + "node_modules/@swagger-api/apidom-ast/node_modules/ramda": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.30.1.tgz", + "integrity": "sha512-tEF5I22zJnuclswcZMc8bDIrwRHRzf+NqVEmqg50ShAZMP7MWeR/RGDthfM/p+BlqvF2fXAzpn8i+SJcYD3alw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda" + } + }, + "node_modules/@swagger-api/apidom-ast/node_modules/ramda-adjunct": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ramda-adjunct/-/ramda-adjunct-5.1.0.tgz", + "integrity": "sha512-8qCpl2vZBXEJyNbi4zqcgdfHtcdsWjOGbiNSEnEBrM6Y0OKOT8UxJbIVGm1TIcjaSu2MxaWcgtsNlKlCk7o7qg==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda-adjunct" + }, + "peerDependencies": { + "ramda": ">= 0.30.0" + } + }, + "node_modules/@swagger-api/apidom-core": { + "version": "1.0.0-beta.7", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-core/-/apidom-core-1.0.0-beta.7.tgz", + "integrity": "sha512-H5B2EBKjs7BzqHmnjxm9pcOdKamyx5VFLCWZhMv76/4NbVM3XM+VRqHdp+WBlpZVieHFtDe+dUmfkh3zFZbIcA==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-ast": "^1.0.0-beta.7", + "@swagger-api/apidom-error": "^1.0.0-beta.7", + "@types/ramda": "~0.30.0", + "minim": "~0.23.8", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0", + "short-unique-id": "^5.0.2", + "ts-mixer": "^6.0.3" + } + }, + "node_modules/@swagger-api/apidom-core/node_modules/ramda": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.30.1.tgz", + "integrity": "sha512-tEF5I22zJnuclswcZMc8bDIrwRHRzf+NqVEmqg50ShAZMP7MWeR/RGDthfM/p+BlqvF2fXAzpn8i+SJcYD3alw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda" + } + }, + "node_modules/@swagger-api/apidom-core/node_modules/ramda-adjunct": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ramda-adjunct/-/ramda-adjunct-5.1.0.tgz", + "integrity": "sha512-8qCpl2vZBXEJyNbi4zqcgdfHtcdsWjOGbiNSEnEBrM6Y0OKOT8UxJbIVGm1TIcjaSu2MxaWcgtsNlKlCk7o7qg==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda-adjunct" + }, + "peerDependencies": { + "ramda": ">= 0.30.0" + } + }, + "node_modules/@swagger-api/apidom-error": { + "version": "1.0.0-beta.7", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-error/-/apidom-error-1.0.0-beta.7.tgz", + "integrity": "sha512-Et47Dj2X3hQRheX9EH7j13gQ0lsYETEQNChT8aFkCCcioObKvv/OdBoB7/CaP7HweFISR3lN3TCkX/72M/uD/g==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7" + } + }, + "node_modules/@swagger-api/apidom-json-pointer": { + "version": "1.0.0-beta.7", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-json-pointer/-/apidom-json-pointer-1.0.0-beta.7.tgz", + "integrity": "sha512-9rjSDnCKLu7Q9y4ZcFA760AgmsEdl8BBgk7AjaVmaKl420fSObCwZ2rhkGccrVqPPOmt8UL1u66/ayQ9fVQbEA==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-core": "^1.0.0-beta.7", + "@swagger-api/apidom-error": "^1.0.0-beta.7", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0" + } + }, + "node_modules/@swagger-api/apidom-json-pointer/node_modules/ramda": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.30.1.tgz", + "integrity": "sha512-tEF5I22zJnuclswcZMc8bDIrwRHRzf+NqVEmqg50ShAZMP7MWeR/RGDthfM/p+BlqvF2fXAzpn8i+SJcYD3alw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda" + } + }, + "node_modules/@swagger-api/apidom-json-pointer/node_modules/ramda-adjunct": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ramda-adjunct/-/ramda-adjunct-5.1.0.tgz", + "integrity": "sha512-8qCpl2vZBXEJyNbi4zqcgdfHtcdsWjOGbiNSEnEBrM6Y0OKOT8UxJbIVGm1TIcjaSu2MxaWcgtsNlKlCk7o7qg==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda-adjunct" + }, + "peerDependencies": { + "ramda": ">= 0.30.0" + } + }, + "node_modules/@swagger-api/apidom-ns-api-design-systems": { + "version": "1.0.0-beta.7", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-api-design-systems/-/apidom-ns-api-design-systems-1.0.0-beta.7.tgz", + "integrity": "sha512-XE/AHS8DNOiHjZYbyd6UC1vF/Slm4bvD2JCejD8BA6lmz7Ij/5qkXZM46XiL7LkS2+ouuyFhx1MgrVQCVxnttw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-core": "^1.0.0-beta.7", + "@swagger-api/apidom-error": "^1.0.0-beta.7", + "@swagger-api/apidom-ns-openapi-3-1": "^1.0.0-beta.7", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0", + "ts-mixer": "^6.0.3" + } + }, + "node_modules/@swagger-api/apidom-ns-api-design-systems/node_modules/ramda": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.30.1.tgz", + "integrity": "sha512-tEF5I22zJnuclswcZMc8bDIrwRHRzf+NqVEmqg50ShAZMP7MWeR/RGDthfM/p+BlqvF2fXAzpn8i+SJcYD3alw==", + "license": "MIT", + "optional": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda" + } + }, + "node_modules/@swagger-api/apidom-ns-api-design-systems/node_modules/ramda-adjunct": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ramda-adjunct/-/ramda-adjunct-5.1.0.tgz", + "integrity": "sha512-8qCpl2vZBXEJyNbi4zqcgdfHtcdsWjOGbiNSEnEBrM6Y0OKOT8UxJbIVGm1TIcjaSu2MxaWcgtsNlKlCk7o7qg==", + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda-adjunct" + }, + "peerDependencies": { + "ramda": ">= 0.30.0" + } + }, + "node_modules/@swagger-api/apidom-ns-asyncapi-2": { + "version": "1.0.0-beta.7", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-asyncapi-2/-/apidom-ns-asyncapi-2-1.0.0-beta.7.tgz", + "integrity": "sha512-QgVzXlZnYnPMqGmv7DWtPthIgTWPjNUwq9EMIhdJZDP9eBEKT3X75P0VZCN7mlSwXOFzkqwMhOKsu9hbJhizmg==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-core": "^1.0.0-beta.7", + "@swagger-api/apidom-ns-json-schema-draft-7": "^1.0.0-beta.7", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0", + "ts-mixer": "^6.0.3" + } + }, + "node_modules/@swagger-api/apidom-ns-asyncapi-2/node_modules/ramda": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.30.1.tgz", + "integrity": "sha512-tEF5I22zJnuclswcZMc8bDIrwRHRzf+NqVEmqg50ShAZMP7MWeR/RGDthfM/p+BlqvF2fXAzpn8i+SJcYD3alw==", + "license": "MIT", + "optional": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda" + } + }, + "node_modules/@swagger-api/apidom-ns-asyncapi-2/node_modules/ramda-adjunct": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ramda-adjunct/-/ramda-adjunct-5.1.0.tgz", + "integrity": "sha512-8qCpl2vZBXEJyNbi4zqcgdfHtcdsWjOGbiNSEnEBrM6Y0OKOT8UxJbIVGm1TIcjaSu2MxaWcgtsNlKlCk7o7qg==", + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda-adjunct" + }, + "peerDependencies": { + "ramda": ">= 0.30.0" + } + }, + "node_modules/@swagger-api/apidom-ns-json-schema-draft-4": { + "version": "1.0.0-beta.7", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-4/-/apidom-ns-json-schema-draft-4-1.0.0-beta.7.tgz", + "integrity": "sha512-hIefo0ubvPuLv+cCfngahhBi5IDyXXvgn5lvivzL7gQk8fnc1J1Lwo0KIOW/Y4X43V9/bM9afAxULegK924xeQ==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-ast": "^1.0.0-beta.7", + "@swagger-api/apidom-core": "^1.0.0-beta.7", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0", + "ts-mixer": "^6.0.4" + } + }, + "node_modules/@swagger-api/apidom-ns-json-schema-draft-4/node_modules/ramda": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.30.1.tgz", + "integrity": "sha512-tEF5I22zJnuclswcZMc8bDIrwRHRzf+NqVEmqg50ShAZMP7MWeR/RGDthfM/p+BlqvF2fXAzpn8i+SJcYD3alw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda" + } + }, + "node_modules/@swagger-api/apidom-ns-json-schema-draft-4/node_modules/ramda-adjunct": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ramda-adjunct/-/ramda-adjunct-5.1.0.tgz", + "integrity": "sha512-8qCpl2vZBXEJyNbi4zqcgdfHtcdsWjOGbiNSEnEBrM6Y0OKOT8UxJbIVGm1TIcjaSu2MxaWcgtsNlKlCk7o7qg==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda-adjunct" + }, + "peerDependencies": { + "ramda": ">= 0.30.0" + } + }, + "node_modules/@swagger-api/apidom-ns-json-schema-draft-6": { + "version": "1.0.0-beta.7", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-6/-/apidom-ns-json-schema-draft-6-1.0.0-beta.7.tgz", + "integrity": "sha512-kI1xF/nGPG2vj5hvGmAcVdbgP0P9ySqn5+VQRHRnAz00Ygi/7TfoyrK8FtUmnUMF9CYpXHPr0SoTlrQPTKfbAA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-core": "^1.0.0-beta.7", + "@swagger-api/apidom-error": "^1.0.0-beta.7", + "@swagger-api/apidom-ns-json-schema-draft-4": "^1.0.0-beta.7", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0", + "ts-mixer": "^6.0.4" + } + }, + "node_modules/@swagger-api/apidom-ns-json-schema-draft-6/node_modules/ramda": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.30.1.tgz", + "integrity": "sha512-tEF5I22zJnuclswcZMc8bDIrwRHRzf+NqVEmqg50ShAZMP7MWeR/RGDthfM/p+BlqvF2fXAzpn8i+SJcYD3alw==", + "license": "MIT", + "optional": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda" + } + }, + "node_modules/@swagger-api/apidom-ns-json-schema-draft-6/node_modules/ramda-adjunct": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ramda-adjunct/-/ramda-adjunct-5.1.0.tgz", + "integrity": "sha512-8qCpl2vZBXEJyNbi4zqcgdfHtcdsWjOGbiNSEnEBrM6Y0OKOT8UxJbIVGm1TIcjaSu2MxaWcgtsNlKlCk7o7qg==", + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda-adjunct" + }, + "peerDependencies": { + "ramda": ">= 0.30.0" + } + }, + "node_modules/@swagger-api/apidom-ns-json-schema-draft-7": { + "version": "1.0.0-beta.7", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-7/-/apidom-ns-json-schema-draft-7-1.0.0-beta.7.tgz", + "integrity": "sha512-ub1eoP/rlxYxWPU26oJ0H11YB1eHK8zNlztFVm588tJv8wAr5NWdDG0fqvpqOxo28wjyoTx9UMudZ+Xw9WHHwA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-core": "^1.0.0-beta.7", + "@swagger-api/apidom-error": "^1.0.0-beta.7", + "@swagger-api/apidom-ns-json-schema-draft-6": "^1.0.0-beta.7", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0", + "ts-mixer": "^6.0.4" + } + }, + "node_modules/@swagger-api/apidom-ns-json-schema-draft-7/node_modules/ramda": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.30.1.tgz", + "integrity": "sha512-tEF5I22zJnuclswcZMc8bDIrwRHRzf+NqVEmqg50ShAZMP7MWeR/RGDthfM/p+BlqvF2fXAzpn8i+SJcYD3alw==", + "license": "MIT", + "optional": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda" + } + }, + "node_modules/@swagger-api/apidom-ns-json-schema-draft-7/node_modules/ramda-adjunct": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ramda-adjunct/-/ramda-adjunct-5.1.0.tgz", + "integrity": "sha512-8qCpl2vZBXEJyNbi4zqcgdfHtcdsWjOGbiNSEnEBrM6Y0OKOT8UxJbIVGm1TIcjaSu2MxaWcgtsNlKlCk7o7qg==", + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda-adjunct" + }, + "peerDependencies": { + "ramda": ">= 0.30.0" + } + }, + "node_modules/@swagger-api/apidom-ns-openapi-2": { + "version": "1.0.0-beta.7", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-2/-/apidom-ns-openapi-2-1.0.0-beta.7.tgz", + "integrity": "sha512-2NUm5a358nqhuAjovtbaY96rOmYKIcLvXEKyIdUhnIjE1xxdf3MLMrsMjjmIBY3TppZnpgdeCJPLtgrZLXKOPg==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-core": "^1.0.0-beta.7", + "@swagger-api/apidom-error": "^1.0.0-beta.7", + "@swagger-api/apidom-ns-json-schema-draft-4": "^1.0.0-beta.7", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0", + "ts-mixer": "^6.0.3" + } + }, + "node_modules/@swagger-api/apidom-ns-openapi-2/node_modules/ramda": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.30.1.tgz", + "integrity": "sha512-tEF5I22zJnuclswcZMc8bDIrwRHRzf+NqVEmqg50ShAZMP7MWeR/RGDthfM/p+BlqvF2fXAzpn8i+SJcYD3alw==", + "license": "MIT", + "optional": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda" + } + }, + "node_modules/@swagger-api/apidom-ns-openapi-2/node_modules/ramda-adjunct": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ramda-adjunct/-/ramda-adjunct-5.1.0.tgz", + "integrity": "sha512-8qCpl2vZBXEJyNbi4zqcgdfHtcdsWjOGbiNSEnEBrM6Y0OKOT8UxJbIVGm1TIcjaSu2MxaWcgtsNlKlCk7o7qg==", + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda-adjunct" + }, + "peerDependencies": { + "ramda": ">= 0.30.0" + } + }, + "node_modules/@swagger-api/apidom-ns-openapi-3-0": { + "version": "1.0.0-beta.7", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-3-0/-/apidom-ns-openapi-3-0-1.0.0-beta.7.tgz", + "integrity": "sha512-Zo1qq4bsSMfIFQsIArmZVVVJli0WZHH3ooqB/c2Gx0pLsZYp4cnXSvOwdQ9llsYFaDJfxS7w5pE5O9Wd9Vcntw==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-core": "^1.0.0-beta.7", + "@swagger-api/apidom-error": "^1.0.0-beta.7", + "@swagger-api/apidom-ns-json-schema-draft-4": "^1.0.0-beta.7", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0", + "ts-mixer": "^6.0.3" + } + }, + "node_modules/@swagger-api/apidom-ns-openapi-3-0/node_modules/ramda": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.30.1.tgz", + "integrity": "sha512-tEF5I22zJnuclswcZMc8bDIrwRHRzf+NqVEmqg50ShAZMP7MWeR/RGDthfM/p+BlqvF2fXAzpn8i+SJcYD3alw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda" + } + }, + "node_modules/@swagger-api/apidom-ns-openapi-3-0/node_modules/ramda-adjunct": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ramda-adjunct/-/ramda-adjunct-5.1.0.tgz", + "integrity": "sha512-8qCpl2vZBXEJyNbi4zqcgdfHtcdsWjOGbiNSEnEBrM6Y0OKOT8UxJbIVGm1TIcjaSu2MxaWcgtsNlKlCk7o7qg==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda-adjunct" + }, + "peerDependencies": { + "ramda": ">= 0.30.0" + } + }, + "node_modules/@swagger-api/apidom-ns-openapi-3-1": { + "version": "1.0.0-beta.7", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-3-1/-/apidom-ns-openapi-3-1-1.0.0-beta.7.tgz", + "integrity": "sha512-RRKvgp2/HeyXcYzkr+j3R3oGdM3mIHoTeG6aiegqZ8hK2eThZgQin5b1EZwBXGisTJ7zktQg283OHm3OwXF/bQ==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-ast": "^1.0.0-beta.7", + "@swagger-api/apidom-core": "^1.0.0-beta.7", + "@swagger-api/apidom-json-pointer": "^1.0.0-beta.7", + "@swagger-api/apidom-ns-openapi-3-0": "^1.0.0-beta.7", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0", + "ts-mixer": "^6.0.3" + } + }, + "node_modules/@swagger-api/apidom-ns-openapi-3-1/node_modules/ramda": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.30.1.tgz", + "integrity": "sha512-tEF5I22zJnuclswcZMc8bDIrwRHRzf+NqVEmqg50ShAZMP7MWeR/RGDthfM/p+BlqvF2fXAzpn8i+SJcYD3alw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda" + } + }, + "node_modules/@swagger-api/apidom-ns-openapi-3-1/node_modules/ramda-adjunct": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ramda-adjunct/-/ramda-adjunct-5.1.0.tgz", + "integrity": "sha512-8qCpl2vZBXEJyNbi4zqcgdfHtcdsWjOGbiNSEnEBrM6Y0OKOT8UxJbIVGm1TIcjaSu2MxaWcgtsNlKlCk7o7qg==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda-adjunct" + }, + "peerDependencies": { + "ramda": ">= 0.30.0" + } + }, + "node_modules/@swagger-api/apidom-ns-workflows-1": { + "version": "1.0.0-beta.7", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-workflows-1/-/apidom-ns-workflows-1-1.0.0-beta.7.tgz", + "integrity": "sha512-Iu20m9c9Fl7Bk9dK3gtlD3Yy3eu53D+SLXcIc73f70IipUOVy8ntcVVI4km4+tu9T9RAeWljW28kVKeFMuYYSQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-core": "^1.0.0-beta.7", + "@swagger-api/apidom-ns-openapi-3-1": "^1.0.0-beta.7", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0", + "ts-mixer": "^6.0.3" + } + }, + "node_modules/@swagger-api/apidom-ns-workflows-1/node_modules/ramda": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.30.1.tgz", + "integrity": "sha512-tEF5I22zJnuclswcZMc8bDIrwRHRzf+NqVEmqg50ShAZMP7MWeR/RGDthfM/p+BlqvF2fXAzpn8i+SJcYD3alw==", + "license": "MIT", + "optional": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda" + } + }, + "node_modules/@swagger-api/apidom-ns-workflows-1/node_modules/ramda-adjunct": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ramda-adjunct/-/ramda-adjunct-5.1.0.tgz", + "integrity": "sha512-8qCpl2vZBXEJyNbi4zqcgdfHtcdsWjOGbiNSEnEBrM6Y0OKOT8UxJbIVGm1TIcjaSu2MxaWcgtsNlKlCk7o7qg==", + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda-adjunct" + }, + "peerDependencies": { + "ramda": ">= 0.30.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-api-design-systems-json": { + "version": "1.0.0-beta.7", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-api-design-systems-json/-/apidom-parser-adapter-api-design-systems-json-1.0.0-beta.7.tgz", + "integrity": "sha512-vqRSf7GMfOdS5WB54f5ZsCXVoq7OfwR6Snk0KbZc/8a6SZvc6gg+IvNwne3eATVAK6YKBFR5+SWCzBMxtF5iLQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-core": "^1.0.0-beta.7", + "@swagger-api/apidom-ns-api-design-systems": "^1.0.0-beta.7", + "@swagger-api/apidom-parser-adapter-json": "^1.0.0-beta.7", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-api-design-systems-json/node_modules/ramda": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.30.1.tgz", + "integrity": "sha512-tEF5I22zJnuclswcZMc8bDIrwRHRzf+NqVEmqg50ShAZMP7MWeR/RGDthfM/p+BlqvF2fXAzpn8i+SJcYD3alw==", + "license": "MIT", + "optional": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-api-design-systems-json/node_modules/ramda-adjunct": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ramda-adjunct/-/ramda-adjunct-5.1.0.tgz", + "integrity": "sha512-8qCpl2vZBXEJyNbi4zqcgdfHtcdsWjOGbiNSEnEBrM6Y0OKOT8UxJbIVGm1TIcjaSu2MxaWcgtsNlKlCk7o7qg==", + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda-adjunct" + }, + "peerDependencies": { + "ramda": ">= 0.30.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-api-design-systems-yaml": { + "version": "1.0.0-beta.7", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-api-design-systems-yaml/-/apidom-parser-adapter-api-design-systems-yaml-1.0.0-beta.7.tgz", + "integrity": "sha512-3Pb5Uf5rYC0uwRJpiZqYx1587IKRlTzy+vq81fiJyxfKZAhuIMRoBZ/4aYvZH474lNY/aGwFfI9hwGfVDXk22A==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-core": "^1.0.0-beta.7", + "@swagger-api/apidom-ns-api-design-systems": "^1.0.0-beta.7", + "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-beta.7", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-api-design-systems-yaml/node_modules/ramda": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.30.1.tgz", + "integrity": "sha512-tEF5I22zJnuclswcZMc8bDIrwRHRzf+NqVEmqg50ShAZMP7MWeR/RGDthfM/p+BlqvF2fXAzpn8i+SJcYD3alw==", + "license": "MIT", + "optional": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-api-design-systems-yaml/node_modules/ramda-adjunct": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ramda-adjunct/-/ramda-adjunct-5.1.0.tgz", + "integrity": "sha512-8qCpl2vZBXEJyNbi4zqcgdfHtcdsWjOGbiNSEnEBrM6Y0OKOT8UxJbIVGm1TIcjaSu2MxaWcgtsNlKlCk7o7qg==", + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda-adjunct" + }, + "peerDependencies": { + "ramda": ">= 0.30.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-asyncapi-json-2": { + "version": "1.0.0-beta.7", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-asyncapi-json-2/-/apidom-parser-adapter-asyncapi-json-2-1.0.0-beta.7.tgz", + "integrity": "sha512-6eJ0NQOmp5cr5Vd5DYXGcJAPJfipODaDRweXbQ1rcLXTew1unxEDenY9NJamdjYqUb59UfmN1+yKEymC7mh0ow==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-core": "^1.0.0-beta.7", + "@swagger-api/apidom-ns-asyncapi-2": "^1.0.0-beta.7", + "@swagger-api/apidom-parser-adapter-json": "^1.0.0-beta.7", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-asyncapi-json-2/node_modules/ramda": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.30.1.tgz", + "integrity": "sha512-tEF5I22zJnuclswcZMc8bDIrwRHRzf+NqVEmqg50ShAZMP7MWeR/RGDthfM/p+BlqvF2fXAzpn8i+SJcYD3alw==", + "license": "MIT", + "optional": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-asyncapi-json-2/node_modules/ramda-adjunct": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ramda-adjunct/-/ramda-adjunct-5.1.0.tgz", + "integrity": "sha512-8qCpl2vZBXEJyNbi4zqcgdfHtcdsWjOGbiNSEnEBrM6Y0OKOT8UxJbIVGm1TIcjaSu2MxaWcgtsNlKlCk7o7qg==", + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda-adjunct" + }, + "peerDependencies": { + "ramda": ">= 0.30.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-asyncapi-yaml-2": { + "version": "1.0.0-beta.7", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-asyncapi-yaml-2/-/apidom-parser-adapter-asyncapi-yaml-2-1.0.0-beta.7.tgz", + "integrity": "sha512-tnWThcuWwWBCoXwVBldoFJ3dLC4JjotDEWwKwqYMdz9s6Bh5oI7hWVsikV0Xc8sxt+TVfGp3jH+T5ATLV2uhIA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-core": "^1.0.0-beta.7", + "@swagger-api/apidom-ns-asyncapi-2": "^1.0.0-beta.7", + "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-beta.7", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-asyncapi-yaml-2/node_modules/ramda": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.30.1.tgz", + "integrity": "sha512-tEF5I22zJnuclswcZMc8bDIrwRHRzf+NqVEmqg50ShAZMP7MWeR/RGDthfM/p+BlqvF2fXAzpn8i+SJcYD3alw==", + "license": "MIT", + "optional": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-asyncapi-yaml-2/node_modules/ramda-adjunct": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ramda-adjunct/-/ramda-adjunct-5.1.0.tgz", + "integrity": "sha512-8qCpl2vZBXEJyNbi4zqcgdfHtcdsWjOGbiNSEnEBrM6Y0OKOT8UxJbIVGm1TIcjaSu2MxaWcgtsNlKlCk7o7qg==", + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda-adjunct" + }, + "peerDependencies": { + "ramda": ">= 0.30.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-json": { + "version": "1.0.0-beta.7", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-json/-/apidom-parser-adapter-json-1.0.0-beta.7.tgz", + "integrity": "sha512-9BmMjiwOObnLJTiX3jh1bR4qIroqBduIx6gzBt/WXr2APQn7tmRxsqgU8RGSgx6QioeIwdVs4/wLv6GssFa5IQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-ast": "^1.0.0-beta.7", + "@swagger-api/apidom-core": "^1.0.0-beta.7", + "@swagger-api/apidom-error": "^1.0.0-beta.7", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0", + "tree-sitter": "=0.22.1", + "tree-sitter-json": "=0.24.8", + "web-tree-sitter": "=0.24.5" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-json/node_modules/ramda": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.30.1.tgz", + "integrity": "sha512-tEF5I22zJnuclswcZMc8bDIrwRHRzf+NqVEmqg50ShAZMP7MWeR/RGDthfM/p+BlqvF2fXAzpn8i+SJcYD3alw==", + "license": "MIT", + "optional": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-json/node_modules/ramda-adjunct": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ramda-adjunct/-/ramda-adjunct-5.1.0.tgz", + "integrity": "sha512-8qCpl2vZBXEJyNbi4zqcgdfHtcdsWjOGbiNSEnEBrM6Y0OKOT8UxJbIVGm1TIcjaSu2MxaWcgtsNlKlCk7o7qg==", + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda-adjunct" + }, + "peerDependencies": { + "ramda": ">= 0.30.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-json/node_modules/tree-sitter": { + "version": "0.22.1", + "resolved": "https://registry.npmjs.org/tree-sitter/-/tree-sitter-0.22.1.tgz", + "integrity": "sha512-gRO+jk2ljxZlIn20QRskIvpLCMtzuLl5T0BY6L9uvPYD17uUrxlxWkvYCiVqED2q2q7CVtY52Uex4WcYo2FEXw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "node-addon-api": "^8.2.1", + "node-gyp-build": "^4.8.2" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-openapi-json-2": { + "version": "1.0.0-beta.7", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-json-2/-/apidom-parser-adapter-openapi-json-2-1.0.0-beta.7.tgz", + "integrity": "sha512-uPrp4Oe17xUz0/yevZ35fv78lSaa0RhYVrSRTcXEZMApxyXoQFfVQTdbzJCFdKkDar/dnp9W6+0EANpY4T5nTQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-core": "^1.0.0-beta.7", + "@swagger-api/apidom-ns-openapi-2": "^1.0.0-beta.7", + "@swagger-api/apidom-parser-adapter-json": "^1.0.0-beta.7", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-openapi-json-2/node_modules/ramda": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.30.1.tgz", + "integrity": "sha512-tEF5I22zJnuclswcZMc8bDIrwRHRzf+NqVEmqg50ShAZMP7MWeR/RGDthfM/p+BlqvF2fXAzpn8i+SJcYD3alw==", + "license": "MIT", + "optional": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-openapi-json-2/node_modules/ramda-adjunct": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ramda-adjunct/-/ramda-adjunct-5.1.0.tgz", + "integrity": "sha512-8qCpl2vZBXEJyNbi4zqcgdfHtcdsWjOGbiNSEnEBrM6Y0OKOT8UxJbIVGm1TIcjaSu2MxaWcgtsNlKlCk7o7qg==", + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda-adjunct" + }, + "peerDependencies": { + "ramda": ">= 0.30.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-openapi-json-3-0": { + "version": "1.0.0-beta.7", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-json-3-0/-/apidom-parser-adapter-openapi-json-3-0-1.0.0-beta.7.tgz", + "integrity": "sha512-UM/p6ir+GJSrIv5kpqu480cO5RHc5/dSbojuJUFVpn+cjuP3ir1oxBXpC2L6PRQW683/wMfr/VbPMHEkQlzgZQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-core": "^1.0.0-beta.7", + "@swagger-api/apidom-ns-openapi-3-0": "^1.0.0-beta.7", + "@swagger-api/apidom-parser-adapter-json": "^1.0.0-beta.7", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-openapi-json-3-0/node_modules/ramda": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.30.1.tgz", + "integrity": "sha512-tEF5I22zJnuclswcZMc8bDIrwRHRzf+NqVEmqg50ShAZMP7MWeR/RGDthfM/p+BlqvF2fXAzpn8i+SJcYD3alw==", + "license": "MIT", + "optional": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-openapi-json-3-0/node_modules/ramda-adjunct": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ramda-adjunct/-/ramda-adjunct-5.1.0.tgz", + "integrity": "sha512-8qCpl2vZBXEJyNbi4zqcgdfHtcdsWjOGbiNSEnEBrM6Y0OKOT8UxJbIVGm1TIcjaSu2MxaWcgtsNlKlCk7o7qg==", + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda-adjunct" + }, + "peerDependencies": { + "ramda": ">= 0.30.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-openapi-json-3-1": { + "version": "1.0.0-beta.7", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-json-3-1/-/apidom-parser-adapter-openapi-json-3-1-1.0.0-beta.7.tgz", + "integrity": "sha512-Ku3ZZ1fOvaGwDYJiGjV3zipPuru3S8ayMIgw+iLsMUv6eG76Lqcz0JWpge+jBI1IBbDoANdcT/U6d25KWI+ygQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-core": "^1.0.0-beta.7", + "@swagger-api/apidom-ns-openapi-3-1": "^1.0.0-beta.7", + "@swagger-api/apidom-parser-adapter-json": "^1.0.0-beta.7", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-openapi-json-3-1/node_modules/ramda": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.30.1.tgz", + "integrity": "sha512-tEF5I22zJnuclswcZMc8bDIrwRHRzf+NqVEmqg50ShAZMP7MWeR/RGDthfM/p+BlqvF2fXAzpn8i+SJcYD3alw==", + "license": "MIT", + "optional": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-openapi-json-3-1/node_modules/ramda-adjunct": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ramda-adjunct/-/ramda-adjunct-5.1.0.tgz", + "integrity": "sha512-8qCpl2vZBXEJyNbi4zqcgdfHtcdsWjOGbiNSEnEBrM6Y0OKOT8UxJbIVGm1TIcjaSu2MxaWcgtsNlKlCk7o7qg==", + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda-adjunct" + }, + "peerDependencies": { + "ramda": ">= 0.30.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-openapi-yaml-2": { + "version": "1.0.0-beta.7", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-yaml-2/-/apidom-parser-adapter-openapi-yaml-2-1.0.0-beta.7.tgz", + "integrity": "sha512-VdgCJuc8OVlrSSLLWdMtAPLyQUP4x8tAkUX5ktbZwXSfRYcBa8TRcuq8KYIpCI9VOteSmAWlJFdMn2iZj3Yg9g==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-core": "^1.0.0-beta.7", + "@swagger-api/apidom-ns-openapi-2": "^1.0.0-beta.7", + "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-beta.7", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-openapi-yaml-2/node_modules/ramda": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.30.1.tgz", + "integrity": "sha512-tEF5I22zJnuclswcZMc8bDIrwRHRzf+NqVEmqg50ShAZMP7MWeR/RGDthfM/p+BlqvF2fXAzpn8i+SJcYD3alw==", + "license": "MIT", + "optional": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-openapi-yaml-2/node_modules/ramda-adjunct": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ramda-adjunct/-/ramda-adjunct-5.1.0.tgz", + "integrity": "sha512-8qCpl2vZBXEJyNbi4zqcgdfHtcdsWjOGbiNSEnEBrM6Y0OKOT8UxJbIVGm1TIcjaSu2MxaWcgtsNlKlCk7o7qg==", + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda-adjunct" + }, + "peerDependencies": { + "ramda": ">= 0.30.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-openapi-yaml-3-0": { + "version": "1.0.0-beta.7", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-yaml-3-0/-/apidom-parser-adapter-openapi-yaml-3-0-1.0.0-beta.7.tgz", + "integrity": "sha512-aXugHhjWKYPWNNca/Lzn59DheSemariMGZT+8W2fdBx3I0kIfLrtlKQETboaNMMFutkuuqcdhw9OPqYza7iAcA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-core": "^1.0.0-beta.7", + "@swagger-api/apidom-ns-openapi-3-0": "^1.0.0-beta.7", + "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-beta.7", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-openapi-yaml-3-0/node_modules/ramda": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.30.1.tgz", + "integrity": "sha512-tEF5I22zJnuclswcZMc8bDIrwRHRzf+NqVEmqg50ShAZMP7MWeR/RGDthfM/p+BlqvF2fXAzpn8i+SJcYD3alw==", + "license": "MIT", + "optional": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-openapi-yaml-3-0/node_modules/ramda-adjunct": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ramda-adjunct/-/ramda-adjunct-5.1.0.tgz", + "integrity": "sha512-8qCpl2vZBXEJyNbi4zqcgdfHtcdsWjOGbiNSEnEBrM6Y0OKOT8UxJbIVGm1TIcjaSu2MxaWcgtsNlKlCk7o7qg==", + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda-adjunct" + }, + "peerDependencies": { + "ramda": ">= 0.30.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-openapi-yaml-3-1": { + "version": "1.0.0-beta.7", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-yaml-3-1/-/apidom-parser-adapter-openapi-yaml-3-1-1.0.0-beta.7.tgz", + "integrity": "sha512-fusfnfzHADUGcilBqTvscwJMt8QTo04/ZZkujnVpp4FZdmRL+xsiJO+DyGBrKw62sQj9zj8QnwxODnUDiFWkug==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-core": "^1.0.0-beta.7", + "@swagger-api/apidom-ns-openapi-3-1": "^1.0.0-beta.7", + "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-beta.7", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-openapi-yaml-3-1/node_modules/ramda": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.30.1.tgz", + "integrity": "sha512-tEF5I22zJnuclswcZMc8bDIrwRHRzf+NqVEmqg50ShAZMP7MWeR/RGDthfM/p+BlqvF2fXAzpn8i+SJcYD3alw==", + "license": "MIT", + "optional": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-openapi-yaml-3-1/node_modules/ramda-adjunct": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ramda-adjunct/-/ramda-adjunct-5.1.0.tgz", + "integrity": "sha512-8qCpl2vZBXEJyNbi4zqcgdfHtcdsWjOGbiNSEnEBrM6Y0OKOT8UxJbIVGm1TIcjaSu2MxaWcgtsNlKlCk7o7qg==", + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda-adjunct" + }, + "peerDependencies": { + "ramda": ">= 0.30.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-workflows-json-1": { + "version": "1.0.0-beta.7", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-workflows-json-1/-/apidom-parser-adapter-workflows-json-1-1.0.0-beta.7.tgz", + "integrity": "sha512-YIwUVc9Ajt/ec99/p5PlAxwuHK7SS9aOZoBIJJSr2eDlO/P5KrjOCTDYelWV/80ZKD0tT67LZk9KcZ6Zy3KyQA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-core": "^1.0.0-beta.7", + "@swagger-api/apidom-ns-workflows-1": "^1.0.0-beta.7", + "@swagger-api/apidom-parser-adapter-json": "^1.0.0-beta.7", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-workflows-json-1/node_modules/ramda": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.30.1.tgz", + "integrity": "sha512-tEF5I22zJnuclswcZMc8bDIrwRHRzf+NqVEmqg50ShAZMP7MWeR/RGDthfM/p+BlqvF2fXAzpn8i+SJcYD3alw==", + "license": "MIT", + "optional": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-workflows-json-1/node_modules/ramda-adjunct": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ramda-adjunct/-/ramda-adjunct-5.1.0.tgz", + "integrity": "sha512-8qCpl2vZBXEJyNbi4zqcgdfHtcdsWjOGbiNSEnEBrM6Y0OKOT8UxJbIVGm1TIcjaSu2MxaWcgtsNlKlCk7o7qg==", + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda-adjunct" + }, + "peerDependencies": { + "ramda": ">= 0.30.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-workflows-yaml-1": { + "version": "1.0.0-beta.7", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-workflows-yaml-1/-/apidom-parser-adapter-workflows-yaml-1-1.0.0-beta.7.tgz", + "integrity": "sha512-Dw0u95uLFjkufeTKDfk7mo/dZz+nDmWBBmgnSxf+sbvJUbdml9y3EExyPNnjxERGU9rV2zdreST/WIJ6MGOL5g==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-core": "^1.0.0-beta.7", + "@swagger-api/apidom-ns-workflows-1": "^1.0.0-beta.7", + "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-beta.7", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-workflows-yaml-1/node_modules/ramda": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.30.1.tgz", + "integrity": "sha512-tEF5I22zJnuclswcZMc8bDIrwRHRzf+NqVEmqg50ShAZMP7MWeR/RGDthfM/p+BlqvF2fXAzpn8i+SJcYD3alw==", + "license": "MIT", + "optional": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-workflows-yaml-1/node_modules/ramda-adjunct": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ramda-adjunct/-/ramda-adjunct-5.1.0.tgz", + "integrity": "sha512-8qCpl2vZBXEJyNbi4zqcgdfHtcdsWjOGbiNSEnEBrM6Y0OKOT8UxJbIVGm1TIcjaSu2MxaWcgtsNlKlCk7o7qg==", + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda-adjunct" + }, + "peerDependencies": { + "ramda": ">= 0.30.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-yaml-1-2": { + "version": "1.0.0-beta.7", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-yaml-1-2/-/apidom-parser-adapter-yaml-1-2-1.0.0-beta.7.tgz", + "integrity": "sha512-3l4eoTPw07bpvJOYES/OuP5x/OsLcTaNj4ebDZW9pqN7IAIgKMF0QaIO63EqHrAhhpIqpFrgBRx+p/wUZUJ38g==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-ast": "^1.0.0-beta.7", + "@swagger-api/apidom-core": "^1.0.0-beta.7", + "@swagger-api/apidom-error": "^1.0.0-beta.7", + "@tree-sitter-grammars/tree-sitter-yaml": "=0.7.0", + "@types/ramda": "~0.30.0", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0", + "tree-sitter": "=0.22.1", + "web-tree-sitter": "=0.24.5" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-yaml-1-2/node_modules/@tree-sitter-grammars/tree-sitter-yaml": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@tree-sitter-grammars/tree-sitter-yaml/-/tree-sitter-yaml-0.7.0.tgz", + "integrity": "sha512-GOMIK3IaDvECD0eZEhAsLl03RMtM1E8StxuGMn6PpMKFg7jyQ+jSzxJZ4Jmc/tYitah9/AECt8o4tlRQ5yEZQg==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "node-addon-api": "^8.3.0", + "node-gyp-build": "^4.8.4" + }, + "peerDependencies": { + "tree-sitter": "^0.22.1" + }, + "peerDependenciesMeta": { + "tree-sitter": { + "optional": true + } + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-yaml-1-2/node_modules/ramda": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.30.1.tgz", + "integrity": "sha512-tEF5I22zJnuclswcZMc8bDIrwRHRzf+NqVEmqg50ShAZMP7MWeR/RGDthfM/p+BlqvF2fXAzpn8i+SJcYD3alw==", + "license": "MIT", + "optional": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-yaml-1-2/node_modules/ramda-adjunct": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ramda-adjunct/-/ramda-adjunct-5.1.0.tgz", + "integrity": "sha512-8qCpl2vZBXEJyNbi4zqcgdfHtcdsWjOGbiNSEnEBrM6Y0OKOT8UxJbIVGm1TIcjaSu2MxaWcgtsNlKlCk7o7qg==", + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda-adjunct" + }, + "peerDependencies": { + "ramda": ">= 0.30.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-yaml-1-2/node_modules/tree-sitter": { + "version": "0.22.1", + "resolved": "https://registry.npmjs.org/tree-sitter/-/tree-sitter-0.22.1.tgz", + "integrity": "sha512-gRO+jk2ljxZlIn20QRskIvpLCMtzuLl5T0BY6L9uvPYD17uUrxlxWkvYCiVqED2q2q7CVtY52Uex4WcYo2FEXw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "node-addon-api": "^8.2.1", + "node-gyp-build": "^4.8.2" + } + }, + "node_modules/@swagger-api/apidom-reference": { + "version": "1.0.0-beta.7", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-reference/-/apidom-reference-1.0.0-beta.7.tgz", + "integrity": "sha512-WefW2Q2if8B86vQnK9rg5USeyxp/ZkRFh6fAVK9lsGjTEOG0j5C7Dz6xa+fGszHWgoEVP6qDUVpcNrpo134hFg==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-core": "^1.0.0-beta.7", + "@types/ramda": "~0.30.0", + "axios": "^1.7.4", + "minimatch": "^7.4.3", + "process": "^0.11.10", + "ramda": "~0.30.0", + "ramda-adjunct": "^5.0.0" + }, + "optionalDependencies": { + "@swagger-api/apidom-error": "^1.0.0-beta.3 <1.0.0-rc.0", + "@swagger-api/apidom-json-pointer": "^1.0.0-beta.3 <1.0.0-rc.0", + "@swagger-api/apidom-ns-asyncapi-2": "^1.0.0-beta.3 <1.0.0-rc.0", + "@swagger-api/apidom-ns-openapi-2": "^1.0.0-beta.3 <1.0.0-rc.0", + "@swagger-api/apidom-ns-openapi-3-0": "^1.0.0-beta.3 <1.0.0-rc.0", + "@swagger-api/apidom-ns-openapi-3-1": "^1.0.0-beta.3 <1.0.0-rc.0", + "@swagger-api/apidom-ns-workflows-1": "^1.0.0-beta.3 <1.0.0-rc.0", + "@swagger-api/apidom-parser-adapter-api-design-systems-json": "^1.0.0-beta.3 <1.0.0-rc.0", + "@swagger-api/apidom-parser-adapter-api-design-systems-yaml": "^1.0.0-beta.3 <1.0.0-rc.0", + "@swagger-api/apidom-parser-adapter-asyncapi-json-2": "^1.0.0-beta.3 <1.0.0-rc.0", + "@swagger-api/apidom-parser-adapter-asyncapi-yaml-2": "^1.0.0-beta.3 <1.0.0-rc.0", + "@swagger-api/apidom-parser-adapter-json": "^1.0.0-beta.3 <1.0.0-rc.0", + "@swagger-api/apidom-parser-adapter-openapi-json-2": "^1.0.0-beta.3 <1.0.0-rc.0", + "@swagger-api/apidom-parser-adapter-openapi-json-3-0": "^1.0.0-beta.3 <1.0.0-rc.0", + "@swagger-api/apidom-parser-adapter-openapi-json-3-1": "^1.0.0-beta.3 <1.0.0-rc.0", + "@swagger-api/apidom-parser-adapter-openapi-yaml-2": "^1.0.0-beta.3 <1.0.0-rc.0", + "@swagger-api/apidom-parser-adapter-openapi-yaml-3-0": "^1.0.0-beta.3 <1.0.0-rc.0", + "@swagger-api/apidom-parser-adapter-openapi-yaml-3-1": "^1.0.0-beta.3 <1.0.0-rc.0", + "@swagger-api/apidom-parser-adapter-workflows-json-1": "^1.0.0-beta.3 <1.0.0-rc.0", + "@swagger-api/apidom-parser-adapter-workflows-yaml-1": "^1.0.0-beta.3 <1.0.0-rc.0", + "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-beta.3 <1.0.0-rc.0" + } + }, + "node_modules/@swagger-api/apidom-reference/node_modules/axios": { + "version": "1.7.9", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz", + "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/@swagger-api/apidom-reference/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@swagger-api/apidom-reference/node_modules/minimatch": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.6.tgz", + "integrity": "sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@swagger-api/apidom-reference/node_modules/ramda": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.30.1.tgz", + "integrity": "sha512-tEF5I22zJnuclswcZMc8bDIrwRHRzf+NqVEmqg50ShAZMP7MWeR/RGDthfM/p+BlqvF2fXAzpn8i+SJcYD3alw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda" + } + }, + "node_modules/@swagger-api/apidom-reference/node_modules/ramda-adjunct": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ramda-adjunct/-/ramda-adjunct-5.1.0.tgz", + "integrity": "sha512-8qCpl2vZBXEJyNbi4zqcgdfHtcdsWjOGbiNSEnEBrM6Y0OKOT8UxJbIVGm1TIcjaSu2MxaWcgtsNlKlCk7o7qg==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda-adjunct" + }, + "peerDependencies": { + "ramda": ">= 0.30.0" + } + }, + "node_modules/@swaggerexpert/cookie": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@swaggerexpert/cookie/-/cookie-1.4.1.tgz", + "integrity": "sha512-ZRbRC2017wMs+uZeIOC55ghwgbTxeolo+s6I0njzqina7MTrOhz8WMfTj0KGk3hfBUO/yhTQD/aQZ0lQHEIKxQ==", + "license": "Apache-2.0", + "dependencies": { + "apg-lite": "^1.0.3" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/@swc/helpers": { + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.11.tgz", + "integrity": "sha512-rEUrBSGIoSFuYxwBYtlUFMlE2CwGhmW+w9355/5oduSw8e5h2+Tj4UrAGNNgP9915++wj5vkQo0UuOBqOAq4nw==", + "license": "MIT", + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tanstack/react-table": { + "version": "8.20.6", + "resolved": "https://registry.npmjs.org/@tanstack/react-table/-/react-table-8.20.6.tgz", + "integrity": "sha512-w0jluT718MrOKthRcr2xsjqzx+oEM7B7s/XXyfs19ll++hlId3fjTm+B2zrR3ijpANpkzBAr15j1XGVOMxpggQ==", + "license": "MIT", + "dependencies": { + "@tanstack/table-core": "8.20.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, + "node_modules/@tanstack/table-core": { + "version": "8.20.5", + "resolved": "https://registry.npmjs.org/@tanstack/table-core/-/table-core-8.20.5.tgz", + "integrity": "sha512-P9dF7XbibHph2PFRz8gfBKEXEY/HJPOhym8CHmjF8y3q5mWpKx9xtZapXQUWCgkqvsK0R46Azuz+VaxD4Xl+Tg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "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==", + "dev": true, + "license": "MIT", + "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.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "dev": true, + "license": "MIT", + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", + "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/eslint": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", + "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/hast": { + "version": "2.3.10", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz", + "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2" + } + }, + "node_modules/@types/hoist-non-react-statics": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.6.tgz", + "integrity": "sha512-lPByRJUer/iN/xa4qpyL0qmL11DqNW81iU/IG1S3uvRUq4oKagz8VCxZjiWkumgt66YT3vOdDgZ0o32sGKtCEw==", + "license": "MIT", + "dependencies": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, + "node_modules/@types/http-proxy": { + "version": "1.17.15", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.15.tgz", + "integrity": "sha512-25g5atgiVNTIv0LBDTg1H74Hvayx0ajtJPLLcYE3whFv75J0pWNtOBzaXJQgDTmrX1bx5U9YC2w/n65BN1HwRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/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, + "license": "MIT" + }, + "node_modules/@types/lodash": { + "version": "4.17.14", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.14.tgz", + "integrity": "sha512-jsxagdikDiDBeIRaPYtArcT8my4tN1og7MtMRquFT3XNA6axxyHDRUemqDz/taRDdOUn0GnGHRCuff4q48sW9A==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/marked": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@types/marked/-/marked-5.0.2.tgz", + "integrity": "sha512-OucS4KMHhFzhz27KxmWg7J+kIYqyqoW5kdIEI319hqARQQUTqhao3M/F+uFnDXD0Rg72iDDZxZNxq5gvctmLlg==", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "17.0.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", + "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", + "license": "MIT" + }, + "node_modules/@types/prettier": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", + "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/prop-types": { + "version": "15.7.14", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz", + "integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==", + "license": "MIT" + }, + "node_modules/@types/ramda": { + "version": "0.30.2", + "resolved": "https://registry.npmjs.org/@types/ramda/-/ramda-0.30.2.tgz", + "integrity": "sha512-PyzHvjCalm2BRYjAU6nIB3TprYwMNOUY/7P/N8bSzp9W/yM2YrtGtAnnVtaCNSeOZ8DzKyFDvaqQs7LnWwwmBA==", + "license": "MIT", + "dependencies": { + "types-ramda": "^0.30.1" + } + }, + "node_modules/@types/react": { + "version": "17.0.83", + "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.83.tgz", + "integrity": "sha512-l0m4ArKJvmFtR4e8UmKrj1pB4tUgOhJITf+mADyF/p69Ts1YAR/E+G9XEM0mHXKVRa1dQNHseyyDNzeuAXfXQw==", + "license": "MIT", + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "^0.16", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "17.0.26", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.26.tgz", + "integrity": "sha512-Z+2VcYXJwOqQ79HreLU/1fyQ88eXSSFh6I3JdrEHQIfYSI0kCQpTGvOrbE6jFGGYXKsHuwY9tBa/w5Uo6KzrEg==", + "license": "MIT", + "peerDependencies": { + "@types/react": "^17.0.0" + } + }, + "node_modules/@types/react-syntax-highlighter": { + "version": "15.5.13", + "resolved": "https://registry.npmjs.org/@types/react-syntax-highlighter/-/react-syntax-highlighter-15.5.13.tgz", + "integrity": "sha512-uLGJ87j6Sz8UaBAooU0T6lWJ0dBmjZgN1PZTrj05TNql2/XpC6+4HhMT5syIdFUUt+FASfCeLLv4kBygNU+8qA==", + "license": "MIT", + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/react-table": { + "version": "6.8.15", + "resolved": "https://registry.npmjs.org/@types/react-table/-/react-table-6.8.15.tgz", + "integrity": "sha512-5+1Fv5aqvjEvfmjDhGyJgtA/spUSuTcUWSP8e2QS6vdFUdDeRiQmqDK+2619mm9htlmWMgb8vUMUlpsKXmUgRg==", + "license": "MIT", + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/scheduler": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", + "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==", + "license": "MIT" + }, + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/swagger-ui-react": { + "version": "4.18.3", + "resolved": "https://registry.npmjs.org/@types/swagger-ui-react/-/swagger-ui-react-4.18.3.tgz", + "integrity": "sha512-Mo/R7IjDVwtiFPs84pWvh5pI9iyNGBjmfielxqbOh2Jv+8WVSDVe8Nu25kb5BOuV2xmGS3o33jr6nwDJMBcX+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "license": "MIT" + }, + "node_modules/@types/url-join": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/url-join/-/url-join-4.0.3.tgz", + "integrity": "sha512-3l1qMm3wqO0iyC5gkADzT95UVW7C/XXcdvUcShOideKF0ddgVRErEQQJXBd2kvQm+aSgqhBGHGB38TgMeT57Ww==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/use-sync-external-store": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz", + "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==", + "license": "MIT" + }, + "node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@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, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "dev": true, + "license": "MIT", + "peer": 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, + "license": "MIT", + "peer": 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, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", + "dev": true, + "license": "MIT", + "peer": 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, + "license": "MIT", + "peer": 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, + "license": "MIT", + "peer": 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, + "license": "Apache-2.0", + "peer": 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, + "license": "MIT", + "peer": 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, + "license": "MIT", + "peer": 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, + "license": "MIT", + "peer": 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, + "license": "MIT", + "peer": 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, + "license": "MIT", + "peer": 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, + "license": "MIT", + "peer": 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, + "license": "BSD-3-Clause", + "peer": 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, + "license": "Apache-2.0", + "peer": 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==", + "license": "BSD-2-Clause" + }, + "node_modules/abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "deprecated": "Use your platform's native atob() and btoa() methods instead", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + } + }, + "node_modules/acorn-globals/node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "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/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, + "license": "MIT", + "peer": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/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, + "license": "MIT", + "peer": 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/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, + "license": "MIT", + "peer": true + }, + "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, + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/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, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/apg-lite": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/apg-lite/-/apg-lite-1.0.4.tgz", + "integrity": "sha512-B32zCN3IdHIc99Vy7V9BaYTUzLeRA8YXYY1aQD1/5I2aqIrO0coi4t6hJPqMisidlBxhyME8UexkHt31SlR6Og==", + "license": "BSD-2-Clause" + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "license": "MIT" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "license": "ISC", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/autobind-decorator": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/autobind-decorator/-/autobind-decorator-1.4.3.tgz", + "integrity": "sha512-FRzT10Vc0lzgDOhMTpm9a2kZF6Q+MMGwd6Y7OGgHigMZwGz7vpN4qH9ifiPTum8mhJQV9UqLPperHxc9yalAAA==", + "license": "MIT" + }, + "node_modules/autolinker": { + "version": "3.16.2", + "resolved": "https://registry.npmjs.org/autolinker/-/autolinker-3.16.2.tgz", + "integrity": "sha512-JiYl7j2Z19F9NdTmirENSUUIIL/9MytEWtmzhfmsKPCp9E+G35Y0UNCMoM9tFigxT59qSc8Ml2dlZXOCVTYwuA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + } + }, + "node_modules/axios": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", + "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" + } + }, + "node_modules/babel-jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", + "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^27.5.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", + "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.0.0", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, + "node_modules/babel-polyfill": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", + "integrity": "sha512-F2rZGQnAdaHWQ8YAoeRbukc7HS9QgdgeyJ0rQDd485v9opwuPvjpPFcOOT/WmkKTdgy9ESgSPXDcTNpzrGr6iQ==", + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "regenerator-runtime": "^0.10.5" + } + }, + "node_modules/babel-polyfill/node_modules/regenerator-runtime": { + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", + "integrity": "sha512-02YopEIhAgiBHWeoTiA8aitHDt8z6w+rQqNuIftlM+ZtvSl/brTouaU7DW6GO/cHtvxJvS4Hwv2ibKdxIRi24w==", + "license": "MIT" + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.1.0.tgz", + "integrity": "sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", + "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-plugin-jest-hoist": "^27.5.1", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==", + "license": "MIT", + "dependencies": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "node_modules/babel-runtime/node_modules/regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "license": "MIT" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/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, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bowser": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-1.9.4.tgz", + "integrity": "sha512-9IdMmj2KjigRq6oWhmwv1W36pDuA4STQZ8q6YO9um+x07xgYNCD3Oou+WP/3L1HNz7iqythGet3/p4wvc8AAwQ==", + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/browserslist": { + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", + "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001688", + "electron-to-chromium": "^1.5.73", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.1" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", + "license": "BSD-3-Clause" + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001695", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001695.tgz", + "integrity": "sha512-vHyLade6wTgI2u1ec3WQBxv+2BrTERV28UXQu9LO6lZ9pYeMk34vjXFLOxo1A4UBA8XTL4njRQZdno/yYaSmWw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/change-emitter": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/change-emitter/-/change-emitter-0.1.6.tgz", + "integrity": "sha512-YXzt1cQ4a2jqazhcuSWEOc1K2q8g9H6eWNsyZgi640LDzRWVQ2eDe+Y/kVdftH+vYdPF2rgDb3dLdpxE1jvAxw==", + "license": "MIT" + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/character-entities": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", + "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", + "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", + "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/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, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.1.tgz", + "integrity": "sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA==", + "dev": true, + "license": "MIT" + }, + "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==", + "license": "MIT" + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/clsx": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", + "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.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==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/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==", + "license": "MIT", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/comma-separated-tokens": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz", + "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==", + "license": "MIT", + "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, + "license": "MIT", + "peer": 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==", + "license": "MIT" + }, + "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, + "license": "MIT" + }, + "node_modules/convert-units": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/convert-units/-/convert-units-2.3.4.tgz", + "integrity": "sha512-ERHfdA0UhHJp1IpwE6PnFJx8LqG7B1ZjJ20UvVCmopEnVCfER68Tbe3kvN63dLbYXDA2xFWRE6zd4Wsf0w7POg==", + "license": "MIT", + "dependencies": { + "lodash.foreach": "2.3.x", + "lodash.keys": "2.3.x" + } + }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/copy-to-clipboard": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz", + "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==", + "license": "MIT", + "dependencies": { + "toggle-selection": "^1.0.6" + } + }, + "node_modules/core-js": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", + "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", + "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.", + "hasInstallScript": true, + "license": "MIT" + }, + "node_modules/core-js-pure": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.40.0.tgz", + "integrity": "sha512-AtDzVIgRrmRKQai62yuSIN5vNiQjcJakJb4fbhVw3ehxx7Lohphvw9SGNWKhLFqSxC4ilD0g/L1huAYFQU3Q6A==", + "hasInstallScript": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "license": "MIT", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cryptr": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/cryptr/-/cryptr-6.3.0.tgz", + "integrity": "sha512-TA4byAuorT8qooU9H8YJhBwnqD151i1rcauHfJ3Divg6HmukHB2AYMp0hmjv2873J2alr4t15QqC7zAnWFrtfQ==", + "license": "MIT" + }, + "node_modules/css-in-js-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-2.0.1.tgz", + "integrity": "sha512-PJF0SpJT+WdbVVt0AOYp9C8GnuruRlL/UFW7932nLWmFLQTaWEzTBQEx7/hn4BuV+WON75iAViSUJLiU3PKbpA==", + "license": "MIT", + "dependencies": { + "hyphenate-style-name": "^1.0.2", + "isobject": "^3.0.1" + } + }, + "node_modules/css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "license": "MIT" + }, + "node_modules/cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", + "dev": true, + "license": "MIT" + }, + "node_modules/cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssom": "~0.3.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cssstyle/node_modules/cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true, + "license": "MIT" + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT" + }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/date-fns": { + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", + "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.21.0" + }, + "engines": { + "node": ">=0.11" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/date-fns" + } + }, + "node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decimal.js": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", + "dev": true, + "license": "MIT" + }, + "node_modules/decode-uri-component": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", + "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", + "dev": true, + "license": "MIT" + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "license": "MIT" + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/diff-sequences": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", + "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/dom-helpers": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz", + "integrity": "sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.1.2" + } + }, + "node_modules/domexception": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "deprecated": "Use your platform's native DOMException instead", + "dev": true, + "license": "MIT", + "dependencies": { + "webidl-conversions": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/domexception/node_modules/webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/dompurify": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.0.2.tgz", + "integrity": "sha512-B8c6JdiEpxAKnd8Dm++QQxJL4lfuc757scZtcapj6qjTjrQzyq5iAyznLKVvK+77eYNiFblHBlt7MM0fOeqoKw==", + "license": "(MPL-2.0 OR Apache-2.0)" + }, + "node_modules/downshift": { + "version": "1.31.16", + "resolved": "https://registry.npmjs.org/downshift/-/downshift-1.31.16.tgz", + "integrity": "sha512-RskXmiGSoz0EHAyBrmTBGSLHg6+NYDGuLu2W3GpmuOe6hmZEWhCiQrq5g6DWzhnUaJD41xHbbfC6j1Fe86YqgA==", + "license": "MIT", + "peerDependencies": { + "prop-types": ">=15", + "react": ">=0.14.x" + } + }, + "node_modules/drange": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/drange/-/drange-1.1.1.tgz", + "integrity": "sha512-pYxfDYpued//QpnLIm4Avk7rsNtAtQkUES2cwAYSvD/wd2pKD71gN2Ebj3e7klzXwjocvE8c5vx/1fxwpqmSxA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.84", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.84.tgz", + "integrity": "sha512-I+DQ8xgafao9Ha6y0qjHHvpZ9OfyA1qKlkHkjywxzniORU2awxyz7f/iVJcULmrF2yrM3nHQf+iDjJtbbexd/g==", + "dev": true, + "license": "ISC" + }, + "node_modules/emittery": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", + "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.0.tgz", + "integrity": "sha512-0/r0MySGYG8YqlayBZ6MuCfECmHFdJ5qyPh8s8wa5Hnm6SaFLSK1VYCbj+NKp090Nm1caZhD+QTnmxO7esYGyQ==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-module-lexer": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", + "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/escodegen/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-scope/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "license": "MIT" + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expect": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", + "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/extra-watch-webpack-plugin": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/extra-watch-webpack-plugin/-/extra-watch-webpack-plugin-1.0.3.tgz", + "integrity": "sha512-ZScQdMH6hNofRRN6QMQFg+aa5vqimfBgnPXmRDhdaLpttT6hrzpY9Oyren3Gh/FySPrgsvKCNbx/NFA7XNdIsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob": "^7.1.2", + "is-glob": "^4.0.0", + "lodash.uniq": "^4.5.0", + "schema-utils": "^0.4.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-json-patch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-3.1.1.tgz", + "integrity": "sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ==", + "license": "MIT" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", + "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/fault": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz", + "integrity": "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==", + "license": "MIT", + "dependencies": { + "format": "^0.2.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/fbjs": { + "version": "0.8.18", + "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.18.tgz", + "integrity": "sha512-EQaWFK+fEPSoibjNy8IxUtaFOMXcWsY0JaVrQoZR9zC8N2Ygf9iDITPWjUTVIax95b6I742JFLqASHfsag/vKA==", + "license": "MIT", + "dependencies": { + "core-js": "^1.0.0", + "isomorphic-fetch": "^2.1.1", + "loose-envify": "^1.0.0", + "object-assign": "^4.1.0", + "promise": "^7.1.1", + "setimmediate": "^1.0.5", + "ua-parser-js": "^0.7.30" + } + }, + "node_modules/fbjs/node_modules/core-js": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", + "integrity": "sha512-ZiPp9pZlgxpWRu0M+YWbm6+aQ84XEfH1JRXvfOc/fILWI0VKhLC2LX13X1NYq4fULzLMq7Hfh43CSo2/aIaUPA==", + "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.", + "license": "MIT" + }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, + "node_modules/filesize": { + "version": "10.1.6", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-10.1.6.tgz", + "integrity": "sha512-sJslQKU2uM33qH5nqewAwVB2QgR6w1aMNsYUp3aN5rMRyXEwJGmZvaWzeJFNTOXWlHQyBFCWrdj3fV/fsTOX8w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 10.4.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==", + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/filter-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz", + "integrity": "sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", + "license": "MIT" + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-yarn-workspace-root": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz", + "integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==", + "license": "Apache-2.0", + "dependencies": { + "micromatch": "^4.0.2" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/fork-ts-checker-webpack-plugin": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-8.0.0.tgz", + "integrity": "sha512-mX3qW3idpueT2klaQXBzrIM/pHw+T0B/V9KHEvNrqijTq9NFnMZU6oreVxDYcf33P8a5cW+67PjodNHthGnNVg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.16.7", + "chalk": "^4.1.2", + "chokidar": "^3.5.3", + "cosmiconfig": "^7.0.1", + "deepmerge": "^4.2.2", + "fs-extra": "^10.0.0", + "memfs": "^3.4.1", + "minimatch": "^3.0.4", + "node-abort-controller": "^3.0.1", + "schema-utils": "^3.1.1", + "semver": "^7.3.5", + "tapable": "^2.2.1" + }, + "engines": { + "node": ">=12.13.0", + "yarn": ">=1.0.0" + }, + "peerDependencies": { + "typescript": ">3.6.0", + "webpack": "^5.11.0" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "license": "MIT", + "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/fork-ts-checker-webpack-plugin/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/form-data": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/format": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", + "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==", + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "license": "MIT", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/formik": { + "version": "0.11.11", + "resolved": "https://registry.npmjs.org/formik/-/formik-0.11.11.tgz", + "integrity": "sha512-RZm1k/HCXyA0caTvWqcGizdV2kI1g3qT1009du62GP50Helcwe9eZTd+MOiyln6UGUqgTRNo0C7NUpzF5JjUCA==", + "license": "MIT", + "dependencies": { + "lodash.clonedeep": "^4.5.0", + "lodash.isequal": "4.5.0", + "lodash.topath": "4.5.2", + "prop-types": "^15.5.10", + "warning": "^3.0.0" + }, + "peerDependencies": { + "react": ">=15" + } + }, + "node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/fs-monkey": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.6.tgz", + "integrity": "sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg==", + "dev": true, + "license": "Unlicense" + }, + "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==", + "license": "ISC" + }, + "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, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glamor": { + "version": "2.20.40", + "resolved": "https://registry.npmjs.org/glamor/-/glamor-2.20.40.tgz", + "integrity": "sha512-DNXCd+c14N9QF8aAKrfl4xakPk5FdcFwmH7sD0qnC0Pr7xoZ5W9yovhUrY/dJc3psfGGXC58vqQyRtuskyUJxA==", + "license": "MIT", + "dependencies": { + "fbjs": "^0.8.12", + "inline-style-prefixer": "^3.0.6", + "object-assign": "^4.1.1", + "prop-types": "^15.5.10", + "through": "^2.3.8" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true + }, + "node_modules/global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hast-util-parse-selector": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz", + "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hastscript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz", + "integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==", + "license": "MIT", + "dependencies": { + "@types/hast": "^2.0.0", + "comma-separated-tokens": "^1.0.0", + "hast-util-parse-selector": "^2.0.0", + "property-information": "^5.0.0", + "space-separated-tokens": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/highlight.js": { + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", + "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", + "license": "BSD-3-Clause", + "engines": { + "node": "*" + } + }, + "node_modules/highlightjs-vue": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/highlightjs-vue/-/highlightjs-vue-1.0.0.tgz", + "integrity": "sha512-PDEfEF102G23vHmPhLyPboFCD+BkMGu+GuJe2d9/eH4FsCwvgBpnc9n0pGE+ffKdph38s6foEZiEjdgHdzp+IA==", + "license": "CC0-1.0" + }, + "node_modules/history": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", + "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.1.2", + "loose-envify": "^1.2.0", + "resolve-pathname": "^3.0.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0", + "value-equal": "^1.0.1" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "license": "BSD-3-Clause", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/html-encoding-sniffer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-encoding": "^1.0.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true, + "license": "MIT" + }, + "node_modules/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==", + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/hyphenate-style-name": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.1.0.tgz", + "integrity": "sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==", + "license": "BSD-3-Clause" + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/immutable": { + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.2.tgz", + "integrity": "sha512-15gZoQ38eYjEjxkorfbcgBKBL6R7T459OuK+CpcWt7O3KF4uPCx2tD0uFETlUDIyo+1789crbMhTvQBSR5yBMg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-local": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "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.", + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, + "license": "ISC" + }, + "node_modules/inline-style-prefixer": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-3.0.8.tgz", + "integrity": "sha512-ne8XIyyqkRaNJ1JfL1NYzNdCNxq+MCBQhC8NgOQlzNm2vv3XxlP0VSLQUbSRCF6KPEoveCVEpayHoHzcMyZsMQ==", + "license": "MIT", + "dependencies": { + "bowser": "^1.7.3", + "css-in-js-utils": "^2.0.0" + } + }, + "node_modules/interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/is-alphabetical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", + "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", + "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", + "license": "MIT", + "dependencies": { + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "license": "MIT" + }, + "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, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "license": "MIT", + "dependencies": { + "ci-info": "^2.0.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-ci/node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "license": "MIT" + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-decimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", + "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "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, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hexadecimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", + "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isomorphic-fetch": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", + "integrity": "sha512-9c4TNAKYXM5PRyVcwUZrF3W09nQ+sO7+jydgs4ZGW9dhsLG2VOlISJABombdQqQRXCwuYG3sYV/puGf5rp0qmA==", + "license": "MIT", + "dependencies": { + "node-fetch": "^1.0.1", + "whatwg-fetch": ">=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, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-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, + "license": "BSD-3-Clause", + "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, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", + "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/core": "^27.5.1", + "import-local": "^3.0.2", + "jest-cli": "^27.5.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.5.1.tgz", + "integrity": "sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "execa": "^5.0.0", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-circus": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.5.1.tgz", + "integrity": "sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "expect": "^27.5.1", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-cli": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.5.1.tgz", + "integrity": "sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/core": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "import-local": "^3.0.2", + "jest-config": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "prompts": "^2.0.1", + "yargs": "^16.2.0" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-config": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.5.1.tgz", + "integrity": "sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.8.0", + "@jest/test-sequencer": "^27.5.1", + "@jest/types": "^27.5.1", + "babel-jest": "^27.5.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.9", + "jest-circus": "^27.5.1", + "jest-environment-jsdom": "^27.5.1", + "jest-environment-node": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-jasmine2": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-runner": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-diff": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", + "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-docblock": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.5.1.tgz", + "integrity": "sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-each": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.5.1.tgz", + "integrity": "sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "jest-get-type": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-environment-jsdom": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz", + "integrity": "sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1", + "jsdom": "^16.6.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-environment-node": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.5.1.tgz", + "integrity": "sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.5.1.tgz", + "integrity": "sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^27.5.1", + "jest-serializer": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", + "micromatch": "^4.0.4", + "walker": "^1.0.7" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-jasmine2": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz", + "integrity": "sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/source-map": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "expect": "^27.5.1", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-leak-detector": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz", + "integrity": "sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", + "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-message-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.5.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-mock": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", + "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", + "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.5.1.tgz", + "integrity": "sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "resolve": "^1.20.0", + "resolve.exports": "^1.1.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz", + "integrity": "sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-snapshot": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-runner": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.5.1.tgz", + "integrity": "sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^27.5.1", + "@jest/environment": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.8.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^27.5.1", + "jest-environment-jsdom": "^27.5.1", + "jest-environment-node": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-leak-detector": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", + "source-map-support": "^0.5.6", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-runtime": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.5.1.tgz", + "integrity": "sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/globals": "^27.5.1", + "@jest/source-map": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "execa": "^5.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-mock": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-serializer": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.5.1.tgz", + "integrity": "sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-snapshot": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.5.1.tgz", + "integrity": "sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.7.2", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.0.0", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/babel__traverse": "^7.0.4", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^27.5.1", + "graceful-fs": "^4.2.9", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-util": "^27.5.1", + "natural-compare": "^1.4.0", + "pretty-format": "^27.5.1", + "semver": "^7.3.2" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-validate": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.5.1.tgz", + "integrity": "sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^27.5.1", + "leven": "^3.1.0", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-watcher": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.5.1.tgz", + "integrity": "sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "jest-util": "^27.5.1", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "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, + "license": "MIT", + "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, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jose": { + "version": "4.15.9", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", + "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/jquery": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz", + "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==", + "license": "MIT" + }, + "node_modules/js-file-download": { + "version": "0.4.12", + "resolved": "https://registry.npmjs.org/js-file-download/-/js-file-download-0.4.12.tgz", + "integrity": "sha512-rML+NkoD08p5Dllpjo0ffy4jRHeY6Zsapvr/W86N7E0yuzAO6qa5X9+xog6zQNlH102J7IXljNY2FtS6Lj3ucg==", + "license": "MIT" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsdom": { + "version": "16.7.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", + "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", + "dev": true, + "license": "MIT", + "dependencies": { + "abab": "^2.0.5", + "acorn": "^8.2.4", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.3.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.1", + "domexception": "^2.0.1", + "escodegen": "^2.0.0", + "form-data": "^3.0.0", + "html-encoding-sniffer": "^2.0.1", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.0", + "parse5": "6.0.1", + "saxes": "^5.0.1", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.0.0", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.1.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.5.0", + "ws": "^7.4.6", + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jsdom/node_modules/form-data": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.2.tgz", + "integrity": "sha512-sJe+TQb2vIaIyO783qN6BlMYWMw3WBOHA1Ay2qxsnjuafEOQFJ2JakedOQirT6D5XPRxDvS7AHYyem9fTpb4LQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "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==", + "license": "MIT" + }, + "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, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonpath": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/jsonpath/-/jsonpath-1.1.1.tgz", + "integrity": "sha512-l6Cg7jRpixfbgoWgkrl77dgEj8RPvND0wMH6TwQmi9Qs4TFfS9u5cUFnbeKTwj5ga5Y3BTGGNI28k117LJ009w==", + "license": "MIT", + "dependencies": { + "esprima": "1.2.2", + "static-eval": "2.0.2", + "underscore": "1.12.1" + } + }, + "node_modules/jsonpath-plus": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-7.2.0.tgz", + "integrity": "sha512-zBfiUPM5nD0YZSBT/o/fbCUlCcepMIdP0CJZxM1+KgA4f2T206f6VAg9e7mX35+KlMaIc5qXW34f3BnwJ3w+RA==", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/jsonpath/node_modules/esprima": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.2.2.tgz", + "integrity": "sha512-+JpPZam9w5DuJ3Q67SqsMGtiHKENSMRVoxvArfJZK01/BfLEObtZ6orJa/MtoGNR/rfMgp5837T41PAmTwAv/A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/jsonwebtoken": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", + "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", + "license": "MIT", + "dependencies": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=4", + "npm": ">=1.4.28" + } + }, + "node_modules/jsonwebtoken/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "license": "MIT", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jwt-decode": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz", + "integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==", + "license": "MIT" + }, + "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, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/klaw-sync": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz", + "integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.11" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "license": "MIT", + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "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==", + "license": "MIT" + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/loaders.css": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/loaders.css/-/loaders.css-0.1.2.tgz", + "integrity": "sha512-Rhowlq24ey1VOeor+3wYOt9+MjaxBOJm1u4KlQgNC3+0xJ0LS4wq4iG57D/BPzvuD/7HHDGQOWJ+81oR2EI9bQ==", + "license": "MIT" + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/lodash._basebind": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lodash._basebind/-/lodash._basebind-2.3.0.tgz", + "integrity": "sha512-SHqM7YCuJ+BeGTs7lqpWnmdHEeF4MWxS3dksJctHFNxR81FXPOzA4bS5Vs5CpcGTkBpM8FCl+YEbQEblRw8ABg==", + "license": "MIT", + "dependencies": { + "lodash._basecreate": "~2.3.0", + "lodash._setbinddata": "~2.3.0", + "lodash.isobject": "~2.3.0" + } + }, + "node_modules/lodash._basecreate": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-2.3.0.tgz", + "integrity": "sha512-vwZaWldZwS2y9b99D8i9+WtgiZXbHKsBsMrpxJEqTsNW20NhJo5W8PBQkeQO9CmxuqEYn8UkMnfEM2MMT4cVrw==", + "license": "MIT", + "dependencies": { + "lodash._renative": "~2.3.0", + "lodash.isobject": "~2.3.0", + "lodash.noop": "~2.3.0" + } + }, + "node_modules/lodash._basecreatecallback": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lodash._basecreatecallback/-/lodash._basecreatecallback-2.3.0.tgz", + "integrity": "sha512-Ev+pDzzfVfgbiucpXijconLGRBar7/+KNCf05kSnk4CmdDVhAy1RdbU9efCJ/o9GXI08JdUGwZ+5QJ3QX3kj0g==", + "license": "MIT", + "dependencies": { + "lodash._setbinddata": "~2.3.0", + "lodash.bind": "~2.3.0", + "lodash.identity": "~2.3.0", + "lodash.support": "~2.3.0" + } + }, + "node_modules/lodash._basecreatewrapper": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lodash._basecreatewrapper/-/lodash._basecreatewrapper-2.3.0.tgz", + "integrity": "sha512-YLycQ7k8AB9Wc1EOvLNxuRWcqipDkMXq2GCgnLWQR6qtgTb3gY3LELzEpnFshrEO4LOLs+R2EpcY+uCOZaLQ8Q==", + "license": "MIT", + "dependencies": { + "lodash._basecreate": "~2.3.0", + "lodash._setbinddata": "~2.3.0", + "lodash._slice": "~2.3.0", + "lodash.isobject": "~2.3.0" + } + }, + "node_modules/lodash._createwrapper": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lodash._createwrapper/-/lodash._createwrapper-2.3.0.tgz", + "integrity": "sha512-XjaI/rzg9W+WO4WJDQ+PRlHD5sAMJ1RhJLuT65cBxLCb1kIYs4U20jqvTDGAWyVT3c34GYiLd9AreHYuB/8yJA==", + "license": "MIT", + "dependencies": { + "lodash._basebind": "~2.3.0", + "lodash._basecreatewrapper": "~2.3.0", + "lodash.isfunction": "~2.3.0" + } + }, + "node_modules/lodash._objecttypes": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lodash._objecttypes/-/lodash._objecttypes-2.3.0.tgz", + "integrity": "sha512-jbA6QyHt9cw3BzvbWzIcnU3Z12jSneT6xBgz3Y782CJsN1tV5aTBKrFo2B4AkeHBNaxSrbPYZZpi1Lwj3xjdtg==", + "license": "MIT" + }, + "node_modules/lodash._renative": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lodash._renative/-/lodash._renative-2.3.0.tgz", + "integrity": "sha512-v44MRirqYqZGK/h5UKoVqXWF2L+LUiLTU+Ogu5rHRVWJUA1uWIlHaMpG8f/OA8j++BzPMQij9+erXHtgFcbuwg==", + "license": "MIT" + }, + "node_modules/lodash._setbinddata": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lodash._setbinddata/-/lodash._setbinddata-2.3.0.tgz", + "integrity": "sha512-xMFfbF7dL+sFtrdE49uHFmfpBAEwlFtfgMp86nQRlAF6aizYL+3MTbnYMKJSkP1W501PhsgiBED5kBbZd8kR2g==", + "license": "MIT", + "dependencies": { + "lodash._renative": "~2.3.0", + "lodash.noop": "~2.3.0" + } + }, + "node_modules/lodash._shimkeys": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lodash._shimkeys/-/lodash._shimkeys-2.3.0.tgz", + "integrity": "sha512-9Iuyi7TiWMGa/9+2rqEE+Zwye4b/U2w7Saw6UX1h6Xs88mEER+uz9FZcEBPKMVKsad9Pw5GNAcIBRnW2jNpneQ==", + "license": "MIT", + "dependencies": { + "lodash._objecttypes": "~2.3.0" + } + }, + "node_modules/lodash._slice": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lodash._slice/-/lodash._slice-2.3.0.tgz", + "integrity": "sha512-7C61GhzRUv36gTafr+RIb+AomCAYsSATEoK4OP0VkNBcwvsM022Z22AVgqjjzikeNO1U29LzsJZDvLbiNPUYvA==", + "license": "MIT" + }, + "node_modules/lodash.bind": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lodash.bind/-/lodash.bind-2.3.0.tgz", + "integrity": "sha512-goakyOo+FMN8lttMPnZ0UNlr5RlzX4IrUXyTJPT2A0tGCMXySupond9wzvDqTvVmYTcQjIKGrj8naJDS2xWAlQ==", + "license": "MIT", + "dependencies": { + "lodash._createwrapper": "~2.3.0", + "lodash._renative": "~2.3.0", + "lodash._slice": "~2.3.0" + } + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", + "license": "MIT" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "license": "MIT" + }, + "node_modules/lodash.foreach": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-2.3.0.tgz", + "integrity": "sha512-yLnyptVRJd0//AbGp480grgQG9iaDIV5uOgSbpurRy1dYybPbjNTLQ3FyLEQ84buVLPG7jyaiyvpzgfOutRB3Q==", + "license": "MIT", + "dependencies": { + "lodash._basecreatecallback": "~2.3.0", + "lodash.forown": "~2.3.0" + } + }, + "node_modules/lodash.forown": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lodash.forown/-/lodash.forown-2.3.0.tgz", + "integrity": "sha512-dUnCsuQTtq3Y7bxPNoEEqjJjPL2ftLtcz2PTeRKvhbpdM514AvnqCjewHGsm/W+dwspIwa14KoWEZeizJ7smxA==", + "license": "MIT", + "dependencies": { + "lodash._basecreatecallback": "~2.3.0", + "lodash._objecttypes": "~2.3.0", + "lodash.keys": "~2.3.0" + } + }, + "node_modules/lodash.identity": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lodash.identity/-/lodash.identity-2.3.0.tgz", + "integrity": "sha512-NYJ2r2cwy3tkx/saqbIZEX6oQUzjWTnGRu7d/zmBjMCZos3eHBxCpbvWFWSetv8jFVrptsp6EbWjzNgBKhUoOA==", + "license": "MIT" + }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==", + "license": "MIT" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", + "license": "MIT" + }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", + "license": "MIT" + }, + "node_modules/lodash.isfunction": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-2.3.0.tgz", + "integrity": "sha512-X5lteBYlCrVO7Qc00fxP8W90fzRp6Ax9XcHANmU3OsZHdSyIVZ9ZlX5QTTpRq8aGY+9I5Rmd0UTzTIIyWPugEQ==", + "license": "MIT" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==", + "license": "MIT" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==", + "license": "MIT" + }, + "node_modules/lodash.isobject": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-2.3.0.tgz", + "integrity": "sha512-jo1pfV61C4TE8BfEzqaHj6EIKiSkFANJrB6yscwuCJMSRw5tbqjk4Gv7nJzk4Z6nFKobZjGZ8Qd41vmnwgeQqQ==", + "license": "MIT", + "dependencies": { + "lodash._objecttypes": "~2.3.0" + } + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "license": "MIT" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "license": "MIT" + }, + "node_modules/lodash.keys": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.3.0.tgz", + "integrity": "sha512-c0UW0ffqMxSCtoVbmVt2lERJLkEqgoOn2ejPsWXzr0ZrqRbl3uruGgwHzhtqXxi6K/ei3Ey7zimOqSwXgzazPg==", + "license": "MIT", + "dependencies": { + "lodash._renative": "~2.3.0", + "lodash._shimkeys": "~2.3.0", + "lodash.isobject": "~2.3.0" + } + }, + "node_modules/lodash.noop": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lodash.noop/-/lodash.noop-2.3.0.tgz", + "integrity": "sha512-NpSm8HRm1WkBBWHUveDukLF4Kfb5P5E3fjHc9Qre9A11nNubozLWD2wH3UBTZbu+KSuX8aSUvy9b+PUyEceJ8g==", + "license": "MIT" + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "license": "MIT" + }, + "node_modules/lodash.support": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lodash.support/-/lodash.support-2.3.0.tgz", + "integrity": "sha512-etc7VWbB0U3Iya8ixj2xy4sDBN3jvPX7ODi8iXtn4KkkjNpdngrdc7Vlt5jub/Vgqx6/dWtp7Ml9awhCQPYKGQ==", + "license": "MIT", + "dependencies": { + "lodash._renative": "~2.3.0" + } + }, + "node_modules/lodash.topath": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/lodash.topath/-/lodash.topath-4.5.2.tgz", + "integrity": "sha512-1/W4dM+35DwvE/iEd1M9ekewOSTlpFekhw9mhAtrwjVqUr83/ilQiyAvmg4tVX7Unkcfl1KC+i9WdaT4B6aQcg==", + "license": "MIT" + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", + "dev": true, + "license": "MIT" + }, + "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==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lowlight": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.20.0.tgz", + "integrity": "sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==", + "license": "MIT", + "dependencies": { + "fault": "^1.0.0", + "highlight.js": "~10.7.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/marked": { + "version": "15.0.6", + "resolved": "https://registry.npmjs.org/marked/-/marked-15.0.6.tgz", + "integrity": "sha512-Y07CUOE+HQXbVDCGl3LXggqJDbXDP2pArc2C1N1RRMN0ONiShoSsIInMd5Gsxupe7fKLpgimTV+HOJ9r7bA+pg==", + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/memfs": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", + "dev": true, + "license": "Unlicense", + "dependencies": { + "fs-monkey": "^1.0.4" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "license": "MIT" + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/minim": { + "version": "0.23.8", + "resolved": "https://registry.npmjs.org/minim/-/minim-0.23.8.tgz", + "integrity": "sha512-bjdr2xW1dBCMsMGGsUeqM4eFI60m94+szhxWys+B1ztIt6gWSfeGBdSVCIawezeHYLYn0j6zrsXdQS/JllBzww==", + "license": "MIT", + "dependencies": { + "lodash": "^4.15.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "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, + "license": "MIT" + }, + "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, + "license": "MIT", + "peer": true + }, + "node_modules/neotraverse": { + "version": "0.6.18", + "resolved": "https://registry.npmjs.org/neotraverse/-/neotraverse-0.6.18.tgz", + "integrity": "sha512-Z4SmBUweYa09+o6pG+eASabEpP6QkQ70yHj351pQoEXIs8uHbaU2DWVmzBANKgflPa47A50PtB2+NgRpQvr7vA==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/next": { + "version": "12.3.4", + "resolved": "https://registry.npmjs.org/next/-/next-12.3.4.tgz", + "integrity": "sha512-VcyMJUtLZBGzLKo3oMxrEF0stxh8HwuW976pAzlHhI3t8qJ4SROjCrSh1T24bhrbjw55wfZXAbXPGwPt5FLRfQ==", + "license": "MIT", + "dependencies": { + "@next/env": "12.3.4", + "@swc/helpers": "0.4.11", + "caniuse-lite": "^1.0.30001406", + "postcss": "8.4.14", + "styled-jsx": "5.0.7", + "use-sync-external-store": "1.2.0" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": ">=12.22.0" + }, + "optionalDependencies": { + "@next/swc-android-arm-eabi": "12.3.4", + "@next/swc-android-arm64": "12.3.4", + "@next/swc-darwin-arm64": "12.3.4", + "@next/swc-darwin-x64": "12.3.4", + "@next/swc-freebsd-x64": "12.3.4", + "@next/swc-linux-arm-gnueabihf": "12.3.4", + "@next/swc-linux-arm64-gnu": "12.3.4", + "@next/swc-linux-arm64-musl": "12.3.4", + "@next/swc-linux-x64-gnu": "12.3.4", + "@next/swc-linux-x64-musl": "12.3.4", + "@next/swc-win32-arm64-msvc": "12.3.4", + "@next/swc-win32-ia32-msvc": "12.3.4", + "@next/swc-win32-x64-msvc": "12.3.4" + }, + "peerDependencies": { + "fibers": ">= 3.1.0", + "node-sass": "^6.0.0 || ^7.0.0", + "react": "^17.0.2 || ^18.0.0-0", + "react-dom": "^17.0.2 || ^18.0.0-0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "fibers": { + "optional": true + }, + "node-sass": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/next-auth": { + "version": "4.24.11", + "resolved": "https://registry.npmjs.org/next-auth/-/next-auth-4.24.11.tgz", + "integrity": "sha512-pCFXzIDQX7xmHFs4KVH4luCjaCbuPRtZ9oBUjUhOk84mZ9WVPf94n87TxYI4rSRf9HmfHEF8Yep3JrYDVOo3Cw==", + "license": "ISC", + "dependencies": { + "@babel/runtime": "^7.20.13", + "@panva/hkdf": "^1.0.2", + "cookie": "^0.7.0", + "jose": "^4.15.5", + "oauth": "^0.9.15", + "openid-client": "^5.4.0", + "preact": "^10.6.3", + "preact-render-to-string": "^5.1.19", + "uuid": "^8.3.2" + }, + "peerDependencies": { + "@auth/core": "0.34.2", + "next": "^12.2.5 || ^13 || ^14 || ^15", + "nodemailer": "^6.6.5", + "react": "^17.0.2 || ^18 || ^19", + "react-dom": "^17.0.2 || ^18 || ^19" + }, + "peerDependenciesMeta": { + "@auth/core": { + "optional": true + }, + "nodemailer": { + "optional": true + } + } + }, + "node_modules/next-auth/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/next-compose-plugins": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/next-compose-plugins/-/next-compose-plugins-2.2.1.tgz", + "integrity": "sha512-OjJ+fV15FXO2uQXQagLD4C0abYErBjyjE0I0FHpOEIB8upw0hg1ldFP6cqHTJBH1cZqy96OeR3u1dJ+Ez2D4Bg==", + "license": "MIT" + }, + "node_modules/next-global-css": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/next-global-css/-/next-global-css-1.3.1.tgz", + "integrity": "sha512-+OnTwQKmv1lDP7r4R3T94oq6372R9UGVivchBQu49j7ZjzvSXHCnv93yAuhgMkvUgAbGifTs8sQ5YL9wjyAxfA==", + "license": "MIT" + }, + "node_modules/next-transpile-modules": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/next-transpile-modules/-/next-transpile-modules-9.1.0.tgz", + "integrity": "sha512-yzJji65xDqcIqjvx5vPJcs1M+MYQTzLM1pXH/qf8Q88ohx+bwVGDc1AeV+HKr1NwvMCNTpwVPSFI7cA5WdyeWA==", + "license": "MIT", + "dependencies": { + "enhanced-resolve": "^5.10.0", + "escalade": "^3.1.1" + } + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "license": "MIT" + }, + "node_modules/node-abort-controller": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", + "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==", + "license": "MIT" + }, + "node_modules/node-addon-api": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.3.0.tgz", + "integrity": "sha512-8VOpLHFrOQlAH+qA0ZzuGRlALRA6/LVh8QJldbrC4DY0hXoMP0l4Acq8TzFC018HztWiRqyCEj2aTWY2UvnJUg==", + "license": "MIT", + "optional": true, + "engines": { + "node": "^18 || ^20 || >= 21" + } + }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "3.2.10", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.2.10.tgz", + "integrity": "sha512-MhuzNwdURnZ1Cp4XTazr69K0BTizsBroX7Zx3UgDSVcZYKF/6p0CBe4EUb/hLqmzVhl0UpYfgRljQ4yxE+iCxA==", + "license": "MIT", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/node-fetch-commonjs": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch-commonjs/-/node-fetch-commonjs-3.3.2.tgz", + "integrity": "sha512-VBlAiynj3VMLrotgwOS3OyECFxas5y7ltLcK4t41lMUZeaK15Ym4QRkqN0EQKAFL42q9i21EPKjzLUPfltR72A==", + "license": "MIT", + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/node-gyp-build": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", + "license": "MIT", + "optional": true, + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "dev": true, + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nwsapi": { + "version": "2.2.16", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.16.tgz", + "integrity": "sha512-F1I/bimDpj3ncaNDhfyMWuFqmQDBwDB0Fogc2qpL3BWvkQteFD/8BzWuIRl83rq0DXfm8SGt/HFhLXZyljTXcQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/oauth": { + "version": "0.9.15", + "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz", + "integrity": "sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA==", + "license": "MIT" + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", + "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/oidc-token-hash": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/oidc-token-hash/-/oidc-token-hash-5.0.3.tgz", + "integrity": "sha512-IF4PcGgzAr6XXSff26Sk/+P4KZFJVuHAJZj3wgO3vX2bMdNVp/QXTP3P7CEm9V1IdG8lDLY3HhiqpsE/nOwpPw==", + "license": "MIT", + "engines": { + "node": "^10.13.0 || >=12.0.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", + "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0", + "is-wsl": "^2.1.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/openapi-path-templating": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/openapi-path-templating/-/openapi-path-templating-2.1.0.tgz", + "integrity": "sha512-fLs5eJmLyU8wPRz+JSH5uLE7TE4Ohg6VHOtj0C0AlD3GTCCcw2LgKW6MSN1A8ZBKHEg2O4/d02knmVU1nvGAKQ==", + "license": "Apache-2.0", + "dependencies": { + "apg-lite": "^1.0.4" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/openapi-server-url-templating": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/openapi-server-url-templating/-/openapi-server-url-templating-1.3.0.tgz", + "integrity": "sha512-DPlCms3KKEbjVQb0spV6Awfn6UWNheuG/+folQPzh/wUaKwuqvj8zt5gagD7qoyxtE03cIiKPgLFS3Q8Bz00uQ==", + "license": "Apache-2.0", + "dependencies": { + "apg-lite": "^1.0.4" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/openid-client": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-5.7.1.tgz", + "integrity": "sha512-jDBPgSVfTnkIh71Hg9pRvtJc6wTwqjRkN88+gCFtYWrlP4Yx2Dsrow8uPi3qLr/aeymPF3o2+dS+wOpglK04ew==", + "license": "MIT", + "dependencies": { + "jose": "^4.15.9", + "lru-cache": "^6.0.0", + "object-hash": "^2.2.0", + "oidc-token-hash": "^5.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/openid-client/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/openid-client/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "license": "ISC" + }, + "node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "license": "MIT", + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-entities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", + "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", + "license": "MIT", + "dependencies": { + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true, + "license": "MIT" + }, + "node_modules/patch-package": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-6.5.1.tgz", + "integrity": "sha512-I/4Zsalfhc6bphmJTlrLoOcAF87jcxko4q0qsv4bGcurbr8IskEOtdnt9iCmsQVGL1B+iUhSQqweyTLJfCF9rA==", + "license": "MIT", + "dependencies": { + "@yarnpkg/lockfile": "^1.1.0", + "chalk": "^4.1.2", + "cross-spawn": "^6.0.5", + "find-yarn-workspace-root": "^2.0.0", + "fs-extra": "^9.0.0", + "is-ci": "^2.0.0", + "klaw-sync": "^6.0.0", + "minimist": "^1.2.6", + "open": "^7.4.2", + "rimraf": "^2.6.3", + "semver": "^5.6.0", + "slash": "^2.0.0", + "tmp": "^0.0.33", + "yaml": "^1.10.2" + }, + "bin": { + "patch-package": "index.js" + }, + "engines": { + "node": ">=10", + "npm": ">5" + } + }, + "node_modules/patch-package/node_modules/cross-spawn": { + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz", + "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==", + "license": "MIT", + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/patch-package/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "license": "MIT", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/patch-package/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/patch-package/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/patch-package/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/patch-package/node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "license": "MIT", + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/patch-package/node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/patch-package/node_modules/slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/patch-package/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "license": "MIT", + "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", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT" + }, + "node_modules/path-to-regexp": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", + "integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==", + "license": "MIT", + "dependencies": { + "isarray": "0.0.1" + } + }, + "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==", + "license": "MIT", + "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==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/popper.js": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz", + "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==", + "deprecated": "You can find the new Popper v2 at @popperjs/core, this package is dedicated to the legacy v1", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/postcss": { + "version": "8.4.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz", + "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/preact": { + "version": "10.25.4", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.25.4.tgz", + "integrity": "sha512-jLdZDb+Q+odkHJ+MpW/9U5cODzqnB+fy2EiHSZES7ldV5LK7yjlVzTp7R8Xy6W6y75kfK8iWYtFVH7lvjwrCMA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + } + }, + "node_modules/preact-render-to-string": { + "version": "5.2.6", + "resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-5.2.6.tgz", + "integrity": "sha512-JyhErpYOvBV1hEPwIxc/fHWXPfnEGdRKxc8gFdAZ7XV4tlzyzG847XAyEZqoDnynP88akM4eaHcSOzNcLWFguw==", + "license": "MIT", + "dependencies": { + "pretty-format": "^3.8.0" + }, + "peerDependencies": { + "preact": ">=10" + } + }, + "node_modules/preact-render-to-string/node_modules/pretty-format": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-3.8.0.tgz", + "integrity": "sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==", + "license": "MIT" + }, + "node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "license": "MIT", + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-plugin-organize-imports": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/prettier-plugin-organize-imports/-/prettier-plugin-organize-imports-4.1.0.tgz", + "integrity": "sha512-5aWRdCgv645xaa58X8lOxzZoiHAldAPChljr/MT0crXVOWTZ+Svl4hIWlz+niYSlO6ikE5UXkN1JrRvIP2ut0A==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "prettier": ">=2.0", + "typescript": ">=2.9", + "vue-tsc": "^2.1.0" + }, + "peerDependenciesMeta": { + "vue-tsc": { + "optional": true + } + } + }, + "node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/pretty-format/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true, + "license": "MIT" + }, + "node_modules/pretty-quick": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-3.3.1.tgz", + "integrity": "sha512-3b36UXfYQ+IXXqex6mCca89jC8u0mYLqFAN5eTQKoXO6oCQYcIVYZEB/5AlBHI7JPYygReM2Vv6Vom/Gln7fBg==", + "license": "MIT", + "dependencies": { + "execa": "^4.1.0", + "find-up": "^4.1.0", + "ignore": "^5.3.0", + "mri": "^1.2.0", + "picocolors": "^1.0.0", + "picomatch": "^3.0.1", + "tslib": "^2.6.2" + }, + "bin": { + "pretty-quick": "dist/cli.js" + }, + "engines": { + "node": ">=10.13" + }, + "peerDependencies": { + "prettier": "^2.0.0" + } + }, + "node_modules/pretty-quick/node_modules/execa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/pretty-quick/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pretty-quick/node_modules/human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "license": "Apache-2.0", + "engines": { + "node": ">=8.12.0" + } + }, + "node_modules/pretty-quick/node_modules/picomatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-3.0.1.tgz", + "integrity": "sha512-I3EurrIQMlRc9IaAZnqRR044Phh2DXY+55o7uJ0V+hYZAcQYSuFWsc9q5PvyDHUSCe1Qxn/iBz+78s86zWnGag==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/prismjs": { + "version": "1.29.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", + "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "license": "MIT", + "dependencies": { + "asap": "~2.0.3" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/property-information": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz", + "integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==", + "license": "MIT", + "dependencies": { + "xtend": "^4.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, + "node_modules/psl": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", + "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "funding": { + "url": "https://github.com/sponsors/lupomontero" + } + }, + "node_modules/pump": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", + "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/query-string": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-7.1.3.tgz", + "integrity": "sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==", + "license": "MIT", + "dependencies": { + "decode-uri-component": "^0.2.2", + "filter-obj": "^1.1.0", + "split-on-first": "^1.0.0", + "strict-uri-encode": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "license": "MIT" + }, + "node_modules/ramda": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.28.0.tgz", + "integrity": "sha512-9QnLuG/kPVgWvMQ4aODhsBUFKOUmnbUnsSXACv+NCQZcHbeb+v8Lodp8OVxtRULN1/xOyYLLaL6npE6dMq5QTA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda" + } + }, + "node_modules/randexp": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.5.3.tgz", + "integrity": "sha512-U+5l2KrcMNOUPYvazA3h5ekF80FHTUG+87SEAmHZmolh1M+i/WyTCxVzmi+tidIa1tM4BSe8g2Y/D3loWDjj+w==", + "license": "MIT", + "dependencies": { + "drange": "^1.0.2", + "ret": "^0.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/react": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", + "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-component-component": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/react-component-component/-/react-component-component-1.2.1.tgz", + "integrity": "sha512-Hjoe/BxUQPQ+mK57TYZdJgpJtxB34cIU1atFk0NuK3KRA9IxF6lSyYeYAOX3jIQlQbEy07QJuB26P2wahVrtUA==", + "license": "MIT", + "peerDependencies": { + "react": "15.x || ^16.0.0" + } + }, + "node_modules/react-copy-to-clipboard": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/react-copy-to-clipboard/-/react-copy-to-clipboard-5.1.0.tgz", + "integrity": "sha512-k61RsNgAayIJNoy9yDsYzDe/yAZAzEbEgcz3DZMhF686LEyukcE1hzurxe85JandPUG+yTfGVFzuEw3xt8WP/A==", + "license": "MIT", + "dependencies": { + "copy-to-clipboard": "^3.3.1", + "prop-types": "^15.8.1" + }, + "peerDependencies": { + "react": "^15.3.0 || 16 || 17 || 18" + } + }, + "node_modules/react-datepicker": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-4.25.0.tgz", + "integrity": "sha512-zB7CSi44SJ0sqo8hUQ3BF1saE/knn7u25qEMTO1CQGofY1VAKahO8k9drZtp0cfW1DMfoYLR3uSY1/uMvbEzbg==", + "license": "MIT", + "dependencies": { + "@popperjs/core": "^2.11.8", + "classnames": "^2.2.6", + "date-fns": "^2.30.0", + "prop-types": "^15.7.2", + "react-onclickoutside": "^6.13.0", + "react-popper": "^2.3.0" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17 || ^18", + "react-dom": "^16.9.0 || ^17 || ^18" + } + }, + "node_modules/react-debounce-input": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/react-debounce-input/-/react-debounce-input-3.3.0.tgz", + "integrity": "sha512-VEqkvs8JvY/IIZvh71Z0TC+mdbxERvYF33RcebnodlsUZ8RSgyKe2VWaHXv4+/8aoOgXLxWrdsYs2hDhcwbUgA==", + "license": "MIT", + "dependencies": { + "lodash.debounce": "^4", + "prop-types": "^15.8.1" + }, + "peerDependencies": { + "react": "^15.3.0 || 16 || 17 || 18" + } + }, + "node_modules/react-dom": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", + "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "scheduler": "^0.20.2" + }, + "peerDependencies": { + "react": "17.0.2" + } + }, + "node_modules/react-draggable": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/react-draggable/-/react-draggable-3.3.2.tgz", + "integrity": "sha512-oaz8a6enjbPtx5qb0oDWxtDNuybOylvto1QLydsXgKmwT7e3GXC2eMVDwEMIUYJIFqVG72XpOv673UuuAq6LhA==", + "license": "MIT", + "dependencies": { + "classnames": "^2.2.5", + "prop-types": "^15.6.0" + } + }, + "node_modules/react-event-listener": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/react-event-listener/-/react-event-listener-0.5.10.tgz", + "integrity": "sha512-YZklRszh9hq3WP3bdNLjFwJcTCVe7qyTf5+LWNaHfZQaZrptsefDK2B5HHpOsEEaMHvjllUPr0+qIFVTSsurow==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "7.0.0-beta.42", + "fbjs": "^0.8.16", + "prop-types": "^15.6.0", + "warning": "^3.0.0" + }, + "peerDependencies": { + "react": "^15.3.0 || ^16.0.0" + } + }, + "node_modules/react-event-listener/node_modules/@babel/runtime": { + "version": "7.0.0-beta.42", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.0.0-beta.42.tgz", + "integrity": "sha512-iOGRzUoONLOtmCvjUsZv3mZzgCT6ljHQY5fr1qG1QIiJQwtM7zbPWGGpa3QWETq+UqwWyJnoi5XZDZRwZDFciQ==", + "license": "MIT", + "dependencies": { + "core-js": "^2.5.3", + "regenerator-runtime": "^0.11.1" + } + }, + "node_modules/react-event-listener/node_modules/regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "license": "MIT" + }, + "node_modules/react-fast-compare": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", + "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==", + "license": "MIT" + }, + "node_modules/react-grid-layout": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/react-grid-layout/-/react-grid-layout-0.16.6.tgz", + "integrity": "sha512-h2EsYgsqcESLJeevQSJsEKp8hhh+phOlXDJoMhlV2e7T3VWQL+S6iCF3iD/LK19r4oyRyOMDEir0KV+eLXrAyw==", + "license": "MIT", + "dependencies": { + "classnames": "2.x", + "lodash.isequal": "^4.0.0", + "prop-types": "15.x", + "react-draggable": "3.x", + "react-resizable": "1.x" + } + }, + "node_modules/react-grid-system": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/react-grid-system/-/react-grid-system-7.3.2.tgz", + "integrity": "sha512-SR5FKJvvN+Sl/OqSpyhLaesfc2cHKxFlP5xL53jUp3m+vF40OYiJbCuW+U43YeNEZQUfR38K3Ec+dVxl9y6MUg==", + "license": "MIT", + "dependencies": { + "prop-types": "^15.7.2" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.x" + } + }, + "node_modules/react-immutable-proptypes": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/react-immutable-proptypes/-/react-immutable-proptypes-2.2.0.tgz", + "integrity": "sha512-Vf4gBsePlwdGvSZoLSBfd4HAP93HDauMY4fDjXhreg/vg6F3Fj/MXDNyTbltPC/xZKmZc+cjLu3598DdYK6sgQ==", + "license": "MIT", + "dependencies": { + "invariant": "^2.2.2" + }, + "peerDependencies": { + "immutable": ">=3.6.2" + } + }, + "node_modules/react-immutable-pure-component": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/react-immutable-pure-component/-/react-immutable-pure-component-2.2.2.tgz", + "integrity": "sha512-vkgoMJUDqHZfXXnjVlG3keCxSO/U6WeDQ5/Sl0GK2cH8TOxEzQ5jXqDXHEL/jqk6fsNxV05oH5kD7VNMUE2k+A==", + "license": "MIT", + "peerDependencies": { + "immutable": ">= 2 || >= 4.0.0-rc", + "react": ">= 16.6", + "react-dom": ">= 16.6" + } + }, + "node_modules/react-input-range": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/react-input-range/-/react-input-range-1.3.0.tgz", + "integrity": "sha512-G//kJqUHo7zQA5PuGZNKhuzhGcj83FJsv62tcP4Eo61DUC/0usHPYxFfIZ3zOfdMWuWEaduD6N4lNsZMmaOJgw==", + "license": "MIT", + "dependencies": { + "autobind-decorator": "^1.3.4", + "prop-types": "^15.5.8" + }, + "peerDependencies": { + "react": "^15.0.0 || ^16.0.0", + "react-dom": "^15.0.0 || ^16.0.0" + } + }, + "node_modules/react-inspector": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/react-inspector/-/react-inspector-6.0.2.tgz", + "integrity": "sha512-x+b7LxhmHXjHoU/VrFAzw5iutsILRoYyDq97EDYdFpPLcvqtEzk4ZSZSQjnFPbr5T57tLXnHcqFYoN1pI6u8uQ==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.4 || ^17.0.0 || ^18.0.0" + } + }, + "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==", + "license": "MIT" + }, + "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==", + "license": "MIT" + }, + "node_modules/react-onclickoutside": { + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/react-onclickoutside/-/react-onclickoutside-6.13.1.tgz", + "integrity": "sha512-LdrrxK/Yh9zbBQdFbMTXPp3dTSN9B+9YJQucdDu3JNKRrbdU+H+/TVONJoWtOwy4II8Sqf1y/DTI6w/vGPYW0w==", + "license": "MIT", + "funding": { + "type": "individual", + "url": "https://github.com/Pomax/react-onclickoutside/blob/master/FUNDING.md" + }, + "peerDependencies": { + "react": "^15.5.x || ^16.x || ^17.x || ^18.x", + "react-dom": "^15.5.x || ^16.x || ^17.x || ^18.x" + } + }, + "node_modules/react-popper": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.3.0.tgz", + "integrity": "sha512-e1hj8lL3uM+sgSR4Lxzn5h1GxBlpa4CQz0XLF8kx4MDrDRWY0Ena4c97PUeSX9i5W3UAfDP0z0FXCTQkoXUl3Q==", + "license": "MIT", + "dependencies": { + "react-fast-compare": "^3.0.1", + "warning": "^4.0.2" + }, + "peerDependencies": { + "@popperjs/core": "^2.0.0", + "react": "^16.8.0 || ^17 || ^18", + "react-dom": "^16.8.0 || ^17 || ^18" + } + }, + "node_modules/react-popper/node_modules/warning": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/react-redux": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.1.3.tgz", + "integrity": "sha512-n0ZrutD7DaX/j9VscF+uTALI3oUPa/pO4Z3soOBIjuRn/FzVu6aehhysxZCLi6y7duMf52WNZGMl7CtuK5EnRw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.1", + "@types/hoist-non-react-statics": "^3.3.1", + "@types/use-sync-external-store": "^0.0.3", + "hoist-non-react-statics": "^3.3.2", + "react-is": "^18.0.0", + "use-sync-external-store": "^1.0.0" + }, + "peerDependencies": { + "@types/react": "^16.8 || ^17.0 || ^18.0", + "@types/react-dom": "^16.8 || ^17.0 || ^18.0", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0", + "react-native": ">=0.59", + "redux": "^4 || ^5.0.0-beta.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + }, + "redux": { + "optional": true + } + } + }, + "node_modules/react-redux/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "license": "MIT" + }, + "node_modules/react-resizable": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/react-resizable/-/react-resizable-1.11.1.tgz", + "integrity": "sha512-S70gbLaAYqjuAd49utRHibtHLrHXInh7GuOR+6OO6RO6uleQfuBnWmZjRABfqNEx3C3Z6VPLg0/0uOYFrkfu9Q==", + "license": "MIT", + "dependencies": { + "prop-types": "15.x", + "react-draggable": "^4.0.3" + }, + "peerDependencies": { + "react": "0.14.x || 15.x || 16.x || 17.x", + "react-dom": "0.14.x || 15.x || 16.x || 17.x" + } + }, + "node_modules/react-resizable/node_modules/react-draggable": { + "version": "4.4.6", + "resolved": "https://registry.npmjs.org/react-draggable/-/react-draggable-4.4.6.tgz", + "integrity": "sha512-LtY5Xw1zTPqHkVmtM3X8MUOxNDOUhv/khTgBgrUvwaS064bwVvxT+q5El0uUFNx5IEPKXuRejr7UqLwBIg5pdw==", + "license": "MIT", + "dependencies": { + "clsx": "^1.1.1", + "prop-types": "^15.8.1" + }, + "peerDependencies": { + "react": ">= 16.3.0", + "react-dom": ">= 16.3.0" + } + }, + "node_modules/react-router": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-4.3.1.tgz", + "integrity": "sha512-yrvL8AogDh2X42Dt9iknk4wF4V8bWREPirFfS9gLU1huk6qK41sg7Z/1S81jjTrGHxa3B8R3J6xIkDAA6CVarg==", + "license": "MIT", + "dependencies": { + "history": "^4.7.2", + "hoist-non-react-statics": "^2.5.0", + "invariant": "^2.2.4", + "loose-envify": "^1.3.1", + "path-to-regexp": "^1.7.0", + "prop-types": "^15.6.1", + "warning": "^4.0.1" + }, + "peerDependencies": { + "react": ">=15" + } + }, + "node_modules/react-router-dom": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-4.3.1.tgz", + "integrity": "sha512-c/MlywfxDdCp7EnB7YfPMOfMD3tOtIjrQlj/CKfNMBxdmpJP8xcz5P/UAFn3JbnQCNUxsHyVVqllF9LhgVyFCA==", + "license": "MIT", + "dependencies": { + "history": "^4.7.2", + "invariant": "^2.2.4", + "loose-envify": "^1.3.1", + "prop-types": "^15.6.1", + "react-router": "^4.3.1", + "warning": "^4.0.1" + }, + "peerDependencies": { + "react": ">=15" + } + }, + "node_modules/react-router-dom/node_modules/warning": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/react-router/node_modules/hoist-non-react-statics": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz", + "integrity": "sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw==", + "license": "BSD-3-Clause" + }, + "node_modules/react-router/node_modules/warning": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/react-scrollbar-size": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/react-scrollbar-size/-/react-scrollbar-size-2.1.0.tgz", + "integrity": "sha512-9dDUJvk7S48r0TRKjlKJ9e/LkLLYgc9LdQR6W21I8ZqtSrEsedPOoMji4nU3DHy7fx2l8YMScJS/N7qiloYzXQ==", + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.26.0", + "prop-types": "^15.6.0", + "react-event-listener": "^0.5.1", + "stifle": "^1.0.2" + }, + "peerDependencies": { + "react": "^15.3.0 || ^16.0.0" + } + }, + "node_modules/react-spinkit": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/react-spinkit/-/react-spinkit-3.0.0.tgz", + "integrity": "sha512-RrfGRPjqxHQiy7quPqhjPynTu0zobgQaZu1QYBMpJJ6pCSRRRK16EZMaxdE6fLVYFRJWpX/eGATWLMoVFFT5uQ==", + "license": "MIT", + "dependencies": { + "classnames": "^2.2.3", + "loaders.css": "^0.1.2", + "object-assign": "^4.1.0", + "prop-types": "^15.5.8" + } + }, + "node_modules/react-syntax-highlighter": { + "version": "15.6.1", + "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-15.6.1.tgz", + "integrity": "sha512-OqJ2/vL7lEeV5zTJyG7kmARppUjiB9h9udl4qHQjjgEos66z00Ia0OckwYfRxCSFrW8RJIBnsBwQsHZbVPspqg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.3.1", + "highlight.js": "^10.4.1", + "highlightjs-vue": "^1.0.0", + "lowlight": "^1.17.0", + "prismjs": "^1.27.0", + "refractor": "^3.6.0" + }, + "peerDependencies": { + "react": ">= 0.14.0" + } + }, + "node_modules/react-table-old": { + "name": "react-table", + "version": "6.11.5", + "resolved": "https://registry.npmjs.org/react-table/-/react-table-6.11.5.tgz", + "integrity": "sha512-LM+AS9v//7Y7lAlgTWW/cW6Sn5VOb3EsSkKQfQTzOW8FngB1FUskLLNEVkAYsTX9LjOWR3QlGjykJqCE6eXT/g==", + "license": "MIT", + "dependencies": { + "@types/react-table": "^6.8.5", + "classnames": "^2.2.5", + "react-is": "^16.8.1" + }, + "peerDependencies": { + "prop-types": "^15.7.0", + "react": "^16.x.x", + "react-dom": "^16.x.x" + } + }, + "node_modules/react-tippy": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/react-tippy/-/react-tippy-1.4.0.tgz", + "integrity": "sha512-r/hM5XK9Ztr2ZY7IWKuRmISTlUPS/R6ddz6PO2EuxCgW+4JBcGZRPU06XcVPRDCOIiio8ryBQFrXMhFMhsuaHA==", + "license": "MIT", + "dependencies": { + "popper.js": "^1.11.1" + } + }, + "node_modules/react-toastify": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-3.4.3.tgz", + "integrity": "sha512-9teTL5In66vsv7O1LnbMQVKmT3CUcTL95sdy8GW5XX5J5uRFY3xSXRqRIcJtD4HSCrjTU2e72pwOiy73VgvJ1Q==", + "license": "MIT", + "dependencies": { + "glamor": "^2.20.40", + "prop-types": "^15.6.0", + "react-transition-group": "^2.2.1" + }, + "peerDependencies": { + "react": ">=15.0.0", + "react-dom": ">=15.0.0" + } + }, + "node_modules/react-transition-group": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz", + "integrity": "sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==", + "license": "BSD-3-Clause", + "dependencies": { + "dom-helpers": "^3.4.0", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2", + "react-lifecycles-compat": "^3.0.4" + }, + "peerDependencies": { + "react": ">=15.0.0", + "react-dom": ">=15.0.0" + } + }, + "node_modules/react-treeview": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/react-treeview/-/react-treeview-0.4.7.tgz", + "integrity": "sha512-k1Q954z/Ts3O9QW4SI1dGZVOwGbGJwjMGQvN/JhAknF1vifRp6bCLJiPaQ3br5af7Mdk7HSAb3JiyQIQJnnaPQ==", + "license": "MIT", + "dependencies": { + "prop-types": "^15.5.8" + }, + "peerDependencies": { + "react": ">=0.14.0" + } + }, + "node_modules/readdirp": { + "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" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", + "dev": true, + "dependencies": { + "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/recompose": { + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/recompose/-/recompose-0.30.0.tgz", + "integrity": "sha512-ZTrzzUDa9AqUIhRk4KmVFihH0rapdCSMFXjhHbNrjAWxBuUD/guYlyysMnuHjlZC/KRiOKRtB4jf96yYSkKE8w==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.0.0", + "change-emitter": "^0.1.2", + "fbjs": "^0.8.1", + "hoist-non-react-statics": "^2.3.1", + "react-lifecycles-compat": "^3.0.2", + "symbol-observable": "^1.0.4" + }, + "peerDependencies": { + "react": "^0.14.0 || ^15.0.0 || ^16.0.0" + } + }, + "node_modules/recompose/node_modules/hoist-non-react-statics": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz", + "integrity": "sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw==", + "license": "BSD-3-Clause" + }, + "node_modules/redux": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", + "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.9.2" + } + }, + "node_modules/redux-immutable": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/redux-immutable/-/redux-immutable-4.0.0.tgz", + "integrity": "sha512-SchSn/DWfGb3oAejd+1hhHx01xUoxY+V7TeK0BKqpkLKiQPVFf7DYzEaKmrEVxsWxielKfSK9/Xq66YyxgR1cg==", + "license": "BSD-3-Clause", + "peerDependencies": { + "immutable": "^3.8.1 || ^4.0.0-rc.1" + } + }, + "node_modules/refractor": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/refractor/-/refractor-3.6.0.tgz", + "integrity": "sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==", + "license": "MIT", + "dependencies": { + "hastscript": "^6.0.0", + "parse-entities": "^2.0.0", + "prismjs": "~1.27.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/refractor/node_modules/prismjs": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.27.0.tgz", + "integrity": "sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "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==", + "license": "MIT" + }, + "node_modules/remarkable": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/remarkable/-/remarkable-2.0.1.tgz", + "integrity": "sha512-YJyMcOH5lrR+kZdmB0aJJ4+93bEojRZ1HGDn9Eagu6ibg7aVZhc3OWbbShRid+Q5eAfsEqWxpe+g5W5nYNfNiA==", + "license": "MIT", + "dependencies": { + "argparse": "^1.0.10", + "autolinker": "^3.11.0" + }, + "bin": { + "remarkable": "bin/remarkable.js" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "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==", + "license": "MIT" + }, + "node_modules/reselect": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.8.tgz", + "integrity": "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==", + "license": "MIT" + }, + "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==", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-cwd/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-pathname": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", + "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==", + "license": "MIT" + }, + "node_modules/resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==", + "deprecated": "https://github.com/lydell/resolve-url#deprecated", + "license": "MIT" + }, + "node_modules/resolve.exports": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.1.tgz", + "integrity": "sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/ret": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.2.2.tgz", + "integrity": "sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rxjs": { + "version": "5.5.12", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.12.tgz", + "integrity": "sha512-xx2itnL5sBbqeeiVgNPVuQQ1nC8Jp2WfNJhXWHmElW9YmrpS9UVnNzhP3EH3HFqexO5Tlp8GhYY+WEcqcVMvGw==", + "license": "Apache-2.0", + "dependencies": { + "symbol-observable": "1.0.1" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/rxjs/node_modules/symbol-observable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz", + "integrity": "sha512-Kb3PrPYz4HanVF1LVGuAdW6LoVgIwjUYJGzFe7NDrBLCN4lsV/5J0MFurV+ygS4bRVwrCEt2c7MQ1R2a72oJDw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "dev": true, + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/scheduler": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", + "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "node_modules/schema-utils": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", + "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.1.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/semantic-ui-css": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/semantic-ui-css/-/semantic-ui-css-2.5.0.tgz", + "integrity": "sha512-jIWn3WXXE2uSaWCcB+gVJVRG3masIKtTMNEP2X8Aw909H2rHpXGneYOxzO3hT8TpyvB5/dEEo9mBFCitGwoj1A==", + "license": "MIT", + "dependencies": { + "jquery": "x.*" + } + }, + "node_modules/semantic-ui-react": { + "version": "0.77.2", + "resolved": "https://registry.npmjs.org/semantic-ui-react/-/semantic-ui-react-0.77.2.tgz", + "integrity": "sha512-VwxY6oGLrBO2xoJiAW/vn40GL4WGZYWxtbrHIKYE1xChTOFlDxyIULMdnuAHOTbrbOYbLQ0X7LpdvEEYmieiJw==", + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.25.0", + "classnames": "^2.2.5", + "fbjs": "^0.8.16", + "lodash": "^4.17.4", + "prop-types": "^15.5.10" + }, + "peerDependencies": { + "react": ">=0.14.0 <= 16", + "react-dom": ">=0.14.0 <= 16" + } + }, + "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, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/serialize-error": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-8.1.0.tgz", + "integrity": "sha512-3NnuWfM6vBYoy5gZFvHiYsVbafvI9vZv/+jlIigFn4oP4zjNPK3LhcY0xSCgeb1a5L8jO71Mit9LlNoi2UfDDQ==", + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/serialize-error/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==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "license": "MIT" + }, + "node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "license": "(MIT AND BSD-3-Clause)", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/shelljs": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "bin": { + "shjs": "bin/shjs" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/short-unique-id": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/short-unique-id/-/short-unique-id-5.2.0.tgz", + "integrity": "sha512-cMGfwNyfDZ/nzJ2k2M+ClthBIh//GlZl1JEf47Uoa9XR11bz8Pa2T2wQO4bVrRdH48LrIDWJahQziKo3MjhsWg==", + "license": "Apache-2.0", + "bin": { + "short-unique-id": "bin/short-unique-id", + "suid": "bin/short-unique-id" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "license": "ISC" + }, + "node_modules/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==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "license": "MIT" + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "license": "BSD-3-Clause", + "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, + "license": "MIT", + "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, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/space-separated-tokens": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz", + "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/split-on-first": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz", + "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "license": "BSD-3-Clause" + }, + "node_modules/sqon-builder": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/sqon-builder/-/sqon-builder-2.0.1.tgz", + "integrity": "sha512-eIhGxzYrI9nCql6zXiPBe5KFFXdSMkVKnwyrx5IxYVSM15euH1VkikSE8pVB4lhZnjOXI5AyL1kTZJDMwJtDwA==", + "license": "GPL-3.0-or-later" + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/static-eval": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.0.2.tgz", + "integrity": "sha512-N/D219Hcr2bPjLxPiV+TQE++Tsmrady7TqAJugLy7Xk1EumfDWS/f5dtBbkRCGE7wKKXuYockQoj8Rm2/pVKyg==", + "license": "MIT", + "dependencies": { + "escodegen": "^1.8.1" + } + }, + "node_modules/static-eval/node_modules/escodegen": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "license": "BSD-2-Clause", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=4.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/static-eval/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/static-eval/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==", + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stifle": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stifle/-/stifle-1.1.1.tgz", + "integrity": "sha512-INvON4DXLAWxpor+f0ZHnYQYXBqDXQRW1znLpf5/C/AWzJ0eQQAThfdqHQ5BDkiyywD67rQGvbE4LC+Aig6K/Q==", + "license": "MIT" + }, + "node_modules/strict-uri-encode": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz", + "integrity": "sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/styled-jsx": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.0.7.tgz", + "integrity": "sha512-b3sUzamS086YLRuvnaDigdAewz1/EFYlHpYBP5mZovKEdQQOIIYq8lApylub3HHZ6xFjV051kkGU7cudJmrXEA==", + "license": "MIT", + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==", + "license": "MIT" + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", + "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/swagger-client": { + "version": "3.33.2", + "resolved": "https://registry.npmjs.org/swagger-client/-/swagger-client-3.33.2.tgz", + "integrity": "sha512-LL91X4+KZr3qMdm2knL1ncF104LlmQMNlrlQwm83r793eQiOdB5iuEz1ppdRv/r211vZE66m38VzHclXmqwW7A==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime-corejs3": "^7.22.15", + "@scarf/scarf": "=1.4.0", + "@swagger-api/apidom-core": ">=1.0.0-beta.6 <1.0.0-rc.0", + "@swagger-api/apidom-error": ">=1.0.0-beta.6 <1.0.0-rc.0", + "@swagger-api/apidom-json-pointer": ">=1.0.0-beta.6 <1.0.0-rc.0", + "@swagger-api/apidom-ns-openapi-3-1": ">=1.0.0-beta.6 <1.0.0-rc.0", + "@swagger-api/apidom-reference": ">=1.0.0-beta.6 <1.0.0-rc.0", + "@swaggerexpert/cookie": "^1.4.1", + "deepmerge": "~4.3.0", + "fast-json-patch": "^3.0.0-1", + "js-yaml": "^4.1.0", + "neotraverse": "=0.6.18", + "node-abort-controller": "^3.1.1", + "node-fetch-commonjs": "^3.3.2", + "openapi-path-templating": "^2.0.1", + "openapi-server-url-templating": "^1.2.0", + "ramda": "^0.30.1", + "ramda-adjunct": "^5.0.0" + } + }, + "node_modules/swagger-client/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/swagger-client/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==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/swagger-client/node_modules/ramda": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.30.1.tgz", + "integrity": "sha512-tEF5I22zJnuclswcZMc8bDIrwRHRzf+NqVEmqg50ShAZMP7MWeR/RGDthfM/p+BlqvF2fXAzpn8i+SJcYD3alw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda" + } + }, + "node_modules/swagger-client/node_modules/ramda-adjunct": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ramda-adjunct/-/ramda-adjunct-5.1.0.tgz", + "integrity": "sha512-8qCpl2vZBXEJyNbi4zqcgdfHtcdsWjOGbiNSEnEBrM6Y0OKOT8UxJbIVGm1TIcjaSu2MxaWcgtsNlKlCk7o7qg==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda-adjunct" + }, + "peerDependencies": { + "ramda": ">= 0.30.0" + } + }, + "node_modules/swagger-ui-dist": { + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-4.19.1.tgz", + "integrity": "sha512-n/gFn+R7G/BXWwl5UZLw6F1YgWOlf3zkwGlsPhTMhNtAAolBGKg0JS5b2RKt5NI6/hSopVaSrki2wTIMUDDy2w==", + "license": "Apache-2.0" + }, + "node_modules/swagger-ui-react": { + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/swagger-ui-react/-/swagger-ui-react-4.19.1.tgz", + "integrity": "sha512-km83cp5ZlmCfROOq6QD1E7bM9f0RsvNrM2C1756UqZ6rRM0J3ex3ySyWa5+mcJRltn0eUB5NahqW8c6I4qwC6A==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime-corejs3": "^7.22.5", + "@braintree/sanitize-url": "=6.0.2", + "base64-js": "^1.5.1", + "classnames": "^2.3.1", + "css.escape": "1.5.1", + "deep-extend": "0.6.0", + "dompurify": "=3.0.2", + "ieee754": "^1.2.1", + "immutable": "^3.x.x", + "js-file-download": "^0.4.12", + "js-yaml": "=4.1.0", + "lodash": "^4.17.21", + "patch-package": "^6.5.0", + "prop-types": "^15.8.1", + "randexp": "^0.5.3", + "randombytes": "^2.1.0", + "react-copy-to-clipboard": "5.1.0", + "react-debounce-input": "=3.3.0", + "react-immutable-proptypes": "2.2.0", + "react-immutable-pure-component": "^2.2.0", + "react-inspector": "^6.0.1", + "react-redux": "^8.0.5", + "react-syntax-highlighter": "^15.5.0", + "redux": "^4.1.2", + "redux-immutable": "^4.0.0", + "remarkable": "^2.0.1", + "reselect": "^4.1.8", + "serialize-error": "^8.1.0", + "sha.js": "^2.4.11", + "swagger-client": "^3.19.8", + "url-parse": "^1.5.8", + "xml": "=1.0.1", + "xml-but-prettier": "^1.0.1", + "zenscroll": "^4.0.2" + }, + "peerDependencies": { + "react": ">=17.0.0", + "react-dom": ">=17.0.0" + } + }, + "node_modules/swagger-ui-react/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/swagger-ui-react/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==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/symbol-observable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", + "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true, + "license": "MIT" + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/terminal-link": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/terser": { + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.37.0.tgz", + "integrity": "sha512-B8wRRkmre4ERucLM/uXx4MOV5cbnOlVAqUst+1+iLKPI0dOgFO28f84ptoQt9HEI537PMzfYa/d+GEPKTRXmYA==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.11", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.11.tgz", + "integrity": "sha512-RVCsMfuD0+cTt3EwX8hSl2Ks56EbFHWmhluwcqoPKtBnfjiT6olaq7PRIRfhyU8nnC2MrnDrBLfrD/RGE+cVXQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "jest-worker": "^27.4.5", + "schema-utils": "^4.3.0", + "serialize-javascript": "^6.0.2", + "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/terser-webpack-plugin/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, + "license": "MIT", + "peer": 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/terser-webpack-plugin/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, + "license": "MIT", + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/terser-webpack-plugin/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, + "license": "MIT", + "peer": true + }, + "node_modules/terser-webpack-plugin/node_modules/schema-utils": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz", + "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==", + "dev": true, + "license": "MIT", + "peer": 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/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/throat": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.2.tgz", + "integrity": "sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "license": "MIT" + }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", + "license": "MIT" + }, + "node_modules/tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==", + "license": "MIT" + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "license": "MIT", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true, + "license": "BSD-3-Clause" + }, + "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==", + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toggle-selection": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", + "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==", + "license": "MIT" + }, + "node_modules/tough-cookie": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", + "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tough-cookie/node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/tr46": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", + "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tree-sitter": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/tree-sitter/-/tree-sitter-0.21.1.tgz", + "integrity": "sha512-7dxoA6kYvtgWw80265MyqJlkRl4yawIjO7S5MigytjELkX43fV2WsAXzsNfO7sBpPPCF5Gp0+XzHk0DwLCq3xQ==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "node-addon-api": "^8.0.0", + "node-gyp-build": "^4.8.0" + } + }, + "node_modules/tree-sitter-json": { + "version": "0.24.8", + "resolved": "https://registry.npmjs.org/tree-sitter-json/-/tree-sitter-json-0.24.8.tgz", + "integrity": "sha512-Tc9ZZYwHyWZ3Tt1VEw7Pa2scu1YO7/d2BCBbKTx5hXwig3UfdQjsOPkPyLpDJOn/m1UBEWYAtSdGAwCSyagBqQ==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "node-addon-api": "^8.2.2", + "node-gyp-build": "^4.8.2" + }, + "peerDependencies": { + "tree-sitter": "^0.21.1" + }, + "peerDependenciesMeta": { + "tree-sitter": { + "optional": true + } + } + }, + "node_modules/ts-mixer": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.4.tgz", + "integrity": "sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA==", + "license": "MIT" + }, + "node_modules/ts-patch": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ts-patch/-/ts-patch-2.1.0.tgz", + "integrity": "sha512-+6LbQSGgHUnK+grgk9nvKhesc0/dDNxms0IL1XPZeTfmPFCx/QSuwz9k+9yFe0xYDD7xBlHYK0Zp0qrTCaJcAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2", + "glob": "^8.0.3", + "global-prefix": "^3.0.0", + "minimist": "^1.2.6", + "resolve": "^1.22.1", + "shelljs": "^0.8.5", + "strip-ansi": "^6.0.1" + }, + "bin": { + "ts-patch": "bin/cli.js" + }, + "peerDependencies": { + "typescript": ">=4.0.0" + } + }, + "node_modules/ts-patch/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/ts-patch/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/ts-patch/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-toolbelt": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/ts-toolbelt/-/ts-toolbelt-9.6.0.tgz", + "integrity": "sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w==", + "license": "Apache-2.0" + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "license": "MIT", + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/types-ramda": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/types-ramda/-/types-ramda-0.30.1.tgz", + "integrity": "sha512-1HTsf5/QVRmLzcGfldPFvkVsAdi1db1BBKzi7iW3KBUlOICg/nKnFS+jGqDJS3YD8VsWbAh7JiHeBvbsw8RPxA==", + "license": "MIT", + "dependencies": { + "ts-toolbelt": "^9.6.0" + } + }, + "node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/typescript-transform-paths": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/typescript-transform-paths/-/typescript-transform-paths-3.5.3.tgz", + "integrity": "sha512-5y2l2iPKNHKOj08/1i+02+ljBVUhWcXQLXomiOXCmNpiTuSxIkj0dM1LUE7OOAt53+/6KidY+sFTCP781J64Eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimatch": "^9.0.5" + }, + "peerDependencies": { + "typescript": ">=3.6.5" + } + }, + "node_modules/typescript-transform-paths/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/typescript-transform-paths/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/ua-parser-js": { + "version": "0.7.40", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.40.tgz", + "integrity": "sha512-us1E3K+3jJppDBa3Tl0L3MOJiGhe1C6P0+nIvQAFYbxlMAx0h81eOwLmU57xgqToduDDPx3y5QsdjPfDu+FgOQ==", + "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" + } + ], + "license": "MIT", + "bin": { + "ua-parser-js": "script/cli.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/underscore": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", + "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==", + "license": "MIT" + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unraw": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unraw/-/unraw-3.0.0.tgz", + "integrity": "sha512-08/DA66UF65OlpUDIQtbJyrqTR0jTAlJ+jsnkQ4jxR7+K5g5YG1APZKQSMCE1vqqmD+2pv6+IdEjmopFatacvg==", + "license": "MIT" + }, + "node_modules/update-browserslist-db": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz", + "integrity": "sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/url-join": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-5.0.0.tgz", + "integrity": "sha512-n2huDr9h9yzd6exQVnH/jU5mr+Pfx08LRXXZhkLLetAMESRj+anQsTAh940iMrIetKAmry9coFuZQ2jY8/p3WA==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "license": "MIT", + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "node_modules/use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-to-istanbul": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", + "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", + "dev": true, + "license": "ISC", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/v8-to-istanbul/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true, + "license": "MIT" + }, + "node_modules/v8-to-istanbul/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, + "license": "BSD-3-Clause", + "engines": { + "node": ">= 8" + } + }, + "node_modules/value-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", + "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==", + "license": "MIT" + }, + "node_modules/w3c-hr-time": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "deprecated": "Use your platform's native performance.now() and performance.timeOrigin.", + "dev": true, + "license": "MIT", + "dependencies": { + "browser-process-hrtime": "^1.0.0" + } + }, + "node_modules/w3c-xmlserializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", + "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/warning": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz", + "integrity": "sha512-jMBt6pUrKn5I+OGgtQ4YZLdhIeJmObddh6CsibPxyQ5yPZm1XExSyzC1LCNX7BzhxWgiHmizBWJTHJIjMjTQYQ==", + "license": "BSD-3-Clause", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/watchpack": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", + "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/web-tree-sitter": { + "version": "0.24.5", + "resolved": "https://registry.npmjs.org/web-tree-sitter/-/web-tree-sitter-0.24.5.tgz", + "integrity": "sha512-+J/2VSHN8J47gQUAvF8KDadrfz6uFYVjxoxbKWDoXVsH2u7yLdarCnIURnrMA6uSRkgX3SdmqM5BOoQjPdSh5w==", + "license": "MIT", + "optional": true + }, + "node_modules/webidl-conversions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=10.4" + } + }, + "node_modules/webpack": { + "version": "5.97.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.97.1.tgz", + "integrity": "sha512-EksG6gFY3L1eFMROS/7Wzgrii5mBAFe4rIr3r2BTfo7bcc+DWwFZ4OJ/miOuHJO/A85HwyI4eQ0F6IKXesO7Fg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.6", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.14.0", + "browserslist": "^4.24.0", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.1", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10.13.0" + } + }, + "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, + "license": "MIT", + "peer": 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/whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "0.4.24" + } + }, + "node_modules/whatwg-fetch": { + "version": "3.6.20", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", + "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==", + "license": "MIT" + }, + "node_modules/whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", + "dev": true, + "license": "MIT" + }, + "node_modules/whatwg-url": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", + "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash": "^4.7.0", + "tr46": "^2.1.0", + "webidl-conversions": "^6.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", + "integrity": "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==", + "license": "MIT" + }, + "node_modules/xml-but-prettier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/xml-but-prettier/-/xml-but-prettier-1.0.1.tgz", + "integrity": "sha512-C2CJaadHrZTqESlH03WOyw0oZTtoy2uEg6dSDF6YRg+9GnYNub53RRemLpnvtbHDFelxMx4LajiFsYeR6XJHgQ==", + "license": "MIT", + "dependencies": { + "repeat-string": "^1.5.2" + } + }, + "node_modules/xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true, + "license": "MIT" + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/zenscroll": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/zenscroll/-/zenscroll-4.0.2.tgz", + "integrity": "sha512-jEA1znR7b4C/NnaycInCU6h/d15ZzCd1jmsruqOKnZP6WXQSMH3W2GL+OXbkruslU4h+Tzuos0HdswzRUk/Vgg==", + "license": "Unlicense" + }, + "node_modules/zod": { + "version": "3.24.1", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.1.tgz", + "integrity": "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} diff --git a/apps/stage/package.json b/apps/stage/package.json new file mode 100644 index 00000000..83abdde2 --- /dev/null +++ b/apps/stage/package.json @@ -0,0 +1,81 @@ +{ + "name": "stage", + "version": "1.1.3", + "scripts": { + "clearNextTemp": "rm -rf ./.next", + "dev": "npm run clearNextTemp && next dev", + "build": "npm run clearNextTemp && next build", + "linkArranger": "npm link @overture-stack/arranger-components --ignore-scripts", + "patchTS": "ts-patch install -s", + "prepare": "npm run patchTS", + "reset": "npm run clearNextTemp && rm -rf ./node_modules", + "start": "next start", + "test": "jest" + }, + "dependencies": { + "@emotion/react": "^11.9.0", + "@emotion/styled": "^11.8.1", + "@overture-stack/arranger-components": "^3.0.0-beta.37", + "@overture-stack/sqon-builder": "^1.1.0", + "@types/marked": "^5.0.2", + "@types/react-syntax-highlighter": "^15.5.13", + "axios": "^0.27.2", + "classnames": "^2.5.1", + "cryptr": "^6.3.0", + "http-proxy": "^1.18.1", + "jsonwebtoken": "^8.5.1", + "jwt-decode": "^3.1.2", + "lodash": "^4.17.21", + "marked": "^15.0.6", + "next": "^12.1.6", + "next-auth": "^4.23.1", + "next-compose-plugins": "^2.2.1", + "next-global-css": "1.3.1", + "next-transpile-modules": "^9.0.0", + "query-string": "^7.1.1", + "react": "^17.0.2", + "react-dom": "^17.0.2", + "react-grid-system": "^7.1.1", + "react-syntax-highlighter": "^15.6.1", + "react-tippy": "^1.4.0", + "swagger-ui-dist": "^4.11.1", + "swagger-ui-react": "^4.11.1", + "url-join": "^5.0.0" + }, + "devDependencies": { + "@babel/preset-typescript": "^7.21.0", + "@emotion/babel-plugin": "^11.9.2", + "@types/http-proxy": "^1.17.11", + "@types/lodash": "^4.14.182", + "@types/node": "^17.0.35", + "@types/react": "^17.0.83", + "@types/react-dom": "^17.0.26", + "@types/swagger-ui-react": "^4.18.3", + "@types/url-join": "^4.0.1", + "extra-watch-webpack-plugin": "^1.0.3", + "fork-ts-checker-webpack-plugin": "^8.0.0", + "jest": "^27.5.1", + "prettier-plugin-organize-imports": "^4.1.0", + "ts-patch": "^2.1.0", + "typescript": "^4.7.2", + "typescript-transform-paths": "^3.4.6" + }, + "prettier": { + "printWidth": 120, + "trailingComma": "all", + "semi": true, + "singleQuote": true, + "useTabs": true + }, + "overrides": { + "@emotion/react": "^11.9.0", + "@emotion/styled": "^11.8.1", + "@types/react": "^17.0.83", + "@types/react-dom": "^17.0.26", + "node-fetch": "3.2", + "graphiql": "1.5.17", + "react": "^17.0.2", + "react-dom": "^17.0.2" + }, + "private": true +} diff --git a/apps/stage/pages/_app.tsx b/apps/stage/pages/_app.tsx new file mode 100644 index 00000000..97e4d4ad --- /dev/null +++ b/apps/stage/pages/_app.tsx @@ -0,0 +1,69 @@ +import { getSession, SessionProvider } from 'next-auth/react'; +import { AppContext } from 'next/app'; +import Router from 'next/router'; +import { useEffect } from 'react'; +import Root from '../components/Root'; +import { getConfig } from '../global/config'; +import { AUTH_PROVIDER, LOGIN_PATH } from '../global/utils/constants'; +import getInternalLink from '../global/utils/getInternalLink'; +import { PageWithConfig } from '../global/utils/pages/types'; + +const DMSApp = ({ + Component, + pageProps, + ctx, + session, +}: { + Component: PageWithConfig; + pageProps: { [k: string]: any }; + ctx: any; + session: any; +}) => { + const { NEXT_PUBLIC_AUTH_PROVIDER } = getConfig(); + + useEffect(() => { + if (NEXT_PUBLIC_AUTH_PROVIDER === AUTH_PROVIDER.KEYCLOAK) { + if (!session && !Component.isPublic) { + Router.push({ + pathname: getInternalLink({ path: LOGIN_PATH }), + query: { session_expired: true }, + }); + } + } + }, [session, Component.isPublic, NEXT_PUBLIC_AUTH_PROVIDER]); + + return ( + + + + + + ); +}; + +DMSApp.getInitialProps = async ({ ctx, Component }: AppContext & { Component: PageWithConfig }) => { + let pageProps = {}; + + // Safely handle getInitialProps if it exists + if (Component.getInitialProps) { + try { + pageProps = await Component.getInitialProps({ ...ctx }); + } catch (error) { + console.error('Error in getInitialProps:', error); + } + } + + const session = await getSession(ctx); + + return { + ctx: { + pathname: ctx.pathname, + query: ctx.query, + asPath: ctx.asPath, + }, + pageProps, + session, + }; +}; + +export default DMSApp; diff --git a/apps/stage/pages/_document.tsx b/apps/stage/pages/_document.tsx new file mode 100644 index 00000000..56556890 --- /dev/null +++ b/apps/stage/pages/_document.tsx @@ -0,0 +1,28 @@ +import { Html, Head, Main, NextScript } from 'next/document'; +import urlJoin from 'url-join'; + +import { getConfig } from '../global/config'; + +const Document = () => { + const { NEXT_PUBLIC_BASE_PATH } = getConfig(); + + return ( + + + + + + + + +
    + + + + ); +}; + +export default Document; diff --git a/apps/stage/pages/_error.tsx b/apps/stage/pages/_error.tsx new file mode 100644 index 00000000..c60a3517 --- /dev/null +++ b/apps/stage/pages/_error.tsx @@ -0,0 +1,61 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { get } from 'lodash'; +import React from 'react'; +import ClientError from '../components/ClientError'; + +import Error403 from '../components/pages/403'; +import Error404 from '../components/pages/404'; +import Error500 from '../components/pages/500'; +import { createPage } from '../global/utils/pages'; + +export const ERROR_STATUS_KEY = 'statusCode'; + +const Error = createPage({ + getInitialProps: async ({ query, res, err }) => { + if (get(err, ERROR_STATUS_KEY) === 403 || get(query, 'error_code') === '403') { + if (res) { + res[ERROR_STATUS_KEY] = 403; + } + } + return { + query, + [ERROR_STATUS_KEY]: get(res, ERROR_STATUS_KEY) || get(err, ERROR_STATUS_KEY) || null, + }; + }, + isPublic: true, +})(({ query, ...props }) => { + const errorCode = props[ERROR_STATUS_KEY]; + + switch (errorCode) { + case 404: + return ; + case 403: + return ; + case 500: + return ; + default: + return ; + } +}); + +export default Error; diff --git a/apps/stage/pages/api/[...proxy].ts b/apps/stage/pages/api/[...proxy].ts new file mode 100644 index 00000000..5a41e839 --- /dev/null +++ b/apps/stage/pages/api/[...proxy].ts @@ -0,0 +1,196 @@ +import { getConfig } from '@/global/config'; +import { INTERNAL_API_PROXY } from '@/global/utils/constants'; +import { removeFromPath, SSLSecured } from '@/global/utils/proxyUtils'; +import type { ServerResponse } from 'http'; +import httpProxy from 'http-proxy'; +import type { NextApiRequest, NextApiResponse } from 'next'; + +const proxy = httpProxy.createProxyServer(); + +const { + NEXT_PUBLIC_ARRANGER_DATATABLE_1_API, + NEXT_PUBLIC_ARRANGER_DATATABLE_2_API, + NEXT_PUBLIC_ARRANGER_DATATABLE_3_API, + NEXT_PUBLIC_ARRANGER_DATATABLE_4_API, + NEXT_PUBLIC_ARRANGER_DATATABLE_5_API, + NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_API, + NEXT_PUBLIC_SONG_API, + NEXT_PUBLIC_LYRIC_API, + NEXT_PUBLIC_LECTERN_API, + NEXT_PUBLIC_SCORE_API, +} = getConfig(); + +export const config = { + api: { + bodyParser: false, + externalResolver: true, + }, +}; + +// Error handling +proxy.on('error', function (err, req, res) { + const response = res as ServerResponse; + if (!response.headersSent) { + response.writeHead(500, { 'Content-Type': 'application/json' }); + response.end(JSON.stringify({ error: 'Proxy Server Error', details: err.message })); + } + console.error('Proxy Server Error:', err); +}); + +// Request logging +proxy.on('proxyReq', function (proxyReq, req, _res) { + console.log('Proxy Request:', { + path: proxyReq.path, + target: proxyReq.getHeader('host'), + originalUrl: (req as NextApiRequest).url, + }); +}); + +// Response handling +proxy.on('proxyRes', function (proxyRes, req, res) { + const response = res as ServerResponse; + response.setHeader('Access-Control-Allow-Origin', '*'); + response.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); + response.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); + response.setHeader('Access-Control-Allow-Credentials', 'true'); + + // Log response status + console.log('Proxy Response:', { + status: proxyRes.statusCode, + path: (req as NextApiRequest).url, + }); +}); + +export default async function handler(req: NextApiRequest, res: NextApiResponse) { + try { + // Handle CORS preflight + if (req.method === 'OPTIONS') { + res.setHeader('Access-Control-Allow-Origin', '*'); + res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); + res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); + res.setHeader('Access-Control-Allow-Credentials', 'true'); + return res.status(200).end(); + } + + let path = req.url; + let target = ''; + + // Handle Arranger requests + if (req.url?.startsWith(INTERNAL_API_PROXY.MOLECULAR_ARRANGER)) { + path = removeFromPath(req?.url, INTERNAL_API_PROXY.MOLECULAR_ARRANGER); + target = NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_API; + } else if (req.url?.startsWith(INTERNAL_API_PROXY.DATATABLE_1_ARRANGER)) { + path = removeFromPath(req?.url, INTERNAL_API_PROXY.DATATABLE_1_ARRANGER); + target = NEXT_PUBLIC_ARRANGER_DATATABLE_1_API; + } else if (req.url?.startsWith(INTERNAL_API_PROXY.DATATABLE_2_ARRANGER)) { + path = removeFromPath(req?.url, INTERNAL_API_PROXY.DATATABLE_2_ARRANGER); + target = NEXT_PUBLIC_ARRANGER_DATATABLE_2_API; + } else if (req.url?.startsWith(INTERNAL_API_PROXY.DATATABLE_3_ARRANGER)) { + path = removeFromPath(req?.url, INTERNAL_API_PROXY.DATATABLE_3_ARRANGER); + target = NEXT_PUBLIC_ARRANGER_DATATABLE_3_API; + } else if (req.url?.startsWith(INTERNAL_API_PROXY.DATATABLE_4_ARRANGER)) { + path = removeFromPath(req?.url, INTERNAL_API_PROXY.DATATABLE_4_ARRANGER); + target = NEXT_PUBLIC_ARRANGER_DATATABLE_4_API; + } else if (req.url?.startsWith(INTERNAL_API_PROXY.DATATABLE_5_ARRANGER)) { + path = removeFromPath(req?.url, INTERNAL_API_PROXY.DATATABLE_5_ARRANGER); + target = NEXT_PUBLIC_ARRANGER_DATATABLE_5_API; + } + // Handle Service API requests + else if (path?.startsWith('/api/song/')) { + // Special case for Swagger API docs - try multiple possible paths + if (path.match(/\/(api-docs|swagger|docs|openapi|v2\/api-docs)/)) { + path = '/v2/api-docs'; + } else { + path = path.replace('/api/song', ''); + } + target = NEXT_PUBLIC_SONG_API; + } else if (path?.startsWith('/api/lyric/')) { + // Special case for Swagger API docs - try multiple possible paths + if (path.match(/\/(api-docs|swagger|docs|openapi|v2\/api-docs)/)) { + path = '/api-docs'; + } else { + path = path.replace('/api/lyric', ''); + } + target = NEXT_PUBLIC_LYRIC_API; + } else if (path?.startsWith('/api/lectern/')) { + // Special case for Swagger API docs - try multiple possible paths + if (path.match(/\/(api-docs|swagger|docs|openapi|v2\/api-docs)/)) { + path = '/api-docs'; + } else { + path = path.replace('/api/lectern', ''); + } + target = NEXT_PUBLIC_LECTERN_API; + } else if (path?.startsWith('/api/score/')) { + // Special case for Swagger API docs - try multiple possible paths + if (path.match(/\/(api-docs|swagger|docs|openapi|v2\/api-docs)/)) { + path = '/v2/api-docs'; + } else { + path = path.replace('/api/score', ''); + } + target = NEXT_PUBLIC_SCORE_API; + } else { + return res.status(404).json({ error: 'Service not found', path }); + } + + if (!target) { + console.warn('No target found for path:', path); + return res.status(404).json({ error: 'No target service configured', path }); + } + + // Update request URL + req.url = path; + + // Don't forward cookies + req.headers.cookie = ''; + + console.log('Proxying request:', { + path: req.url, + target, + method: req.method, + originalUrl: path, + }); + + return new Promise((resolve, reject) => { + proxy.web( + req, + res, + { + target, + changeOrigin: true, + secure: SSLSecured, + headers: { + 'Access-Control-Allow-Origin': '*', + }, + timeout: 30000, + }, + (err) => { + console.error('Proxy error:', { + error: err, + path: req.url, + target, + }); + reject(err); + }, + ); + }).catch((error: Error) => { + console.error('Request failed:', error); + if (!res.headersSent) { + res.status(500).json({ + error: 'Proxy error occurred', + message: error.message, + target, + path: req.url, + }); + } + }); + } catch (error) { + const err = error as Error; + console.error('Handler error:', err); + if (!res.headersSent) { + res.status(500).json({ + error: 'Internal server error', + message: err.message, + }); + } + } +} diff --git a/apps/stage/pages/api/auth/[...nextauth].ts b/apps/stage/pages/api/auth/[...nextauth].ts new file mode 100644 index 00000000..2836cdf8 --- /dev/null +++ b/apps/stage/pages/api/auth/[...nextauth].ts @@ -0,0 +1,79 @@ +import type { GetServerSidePropsContext, NextApiRequest, NextApiResponse } from 'next'; +import NextAuth, { AuthOptions } from 'next-auth'; +import KeycloakProvider from 'next-auth/providers/keycloak'; +import axios from 'axios'; + +import { getConfig } from '@/global/config'; +import { KEYCLOAK_URL_ISSUER, KEYCLOAK_URL_TOKEN, AUTH_PROVIDER } from '@/global/utils/constants'; +import { encryptContent } from '@/global/utils/crypt'; +import { permissionBodyParams, scopesFromPermissions } from '@/global/utils/keycloakUtils'; + +const { + NEXT_PUBLIC_KEYCLOAK_CLIENT_ID, + KEYCLOAK_CLIENT_SECRET, + SESSION_ENCRYPTION_SECRET, +} = getConfig(); + +export const fetchScopes = async (accessToken: string) => { + const { data } = await axios.post(KEYCLOAK_URL_TOKEN, permissionBodyParams(), { + headers: { + 'content-type': 'application/x-www-form-urlencoded', + authorization: 'Bearer ' + accessToken, + accept: '*/*', + }, + }); + + return data ? scopesFromPermissions(data) : []; +}; + +export const getAuthOptions = ( + req: GetServerSidePropsContext['req'] | NextApiRequest, +): AuthOptions => { + return { + secret: SESSION_ENCRYPTION_SECRET, + providers: [ + KeycloakProvider({ + clientId: NEXT_PUBLIC_KEYCLOAK_CLIENT_ID, + clientSecret: KEYCLOAK_CLIENT_SECRET, + issuer: KEYCLOAK_URL_ISSUER, + }), + ], + pages: { + signIn: '/login', + }, + callbacks: { + async jwt({ token, user, account, profile, trigger }: any) { + if (trigger === 'signIn' && account?.provider === AUTH_PROVIDER.KEYCLOAK) { + token.account = account; + token.profile = profile; + token.scopes = await fetchScopes(token.account.access_token); + } + return token; + }, + async session({ token, session }: any) { + if (token.account.provider === AUTH_PROVIDER.KEYCLOAK) { + session.account = { + accessToken: encryptContent(token?.account?.access_token), + provider: token?.account?.provider, + }; + session.user.firstName = token?.profile?.given_name; + session.user.lastName = token?.profile?.family_name; + session.user.emailVerified = token?.profile?.email_verified; + session.user.id = token?.sub; + if (!session.user.email) session.user.email = token?.profile?.email; + session.scopes = token?.scopes; + } + return session; + }, + }, + session: { + strategy: 'jwt', + maxAge: 60 * 60, // 1 hour + }, + debug: false, + }; +}; + +export default async function auth(req: NextApiRequest, res: NextApiResponse) { + return await NextAuth(req, res, getAuthOptions(req)); +} \ No newline at end of file diff --git a/apps/stage/pages/api/data-tables.ts b/apps/stage/pages/api/data-tables.ts new file mode 100644 index 00000000..cf59a2ce --- /dev/null +++ b/apps/stage/pages/api/data-tables.ts @@ -0,0 +1,14 @@ +// pages/api/data-tables.ts +import { NextApiRequest, NextApiResponse } from 'next'; +import { discoverDataTables } from '../../global/utils/dataTablesDiscovery'; + +export default function handler(req: NextApiRequest, res: NextApiResponse) { + try { + // Simply read folder names and return them + const dataTables = discoverDataTables(); + res.status(200).json(dataTables); + } catch (error) { + console.error('Error fetching data tables:', error); + res.status(500).json({ error: 'Failed to fetch data tables' }); + } +} diff --git a/apps/stage/pages/api/docs.ts b/apps/stage/pages/api/docs.ts new file mode 100644 index 00000000..e9e18129 --- /dev/null +++ b/apps/stage/pages/api/docs.ts @@ -0,0 +1,28 @@ +import fs from 'fs'; +import { NextApiRequest, NextApiResponse } from 'next'; +import path from 'path'; + +export default function handler(req: NextApiRequest, res: NextApiResponse) { + try { + const docsDirectory = path.join(process.cwd(), 'public', 'docs'); + + // Check if directory exists + if (!fs.existsSync(docsDirectory)) { + return res.status(404).json({ error: 'Documentation directory not found' }); + } + + const filenames = fs + .readdirSync(docsDirectory) + .filter((filename) => filename.endsWith('.md')) + .sort(); + + if (filenames.length === 0) { + return res.status(404).json({ error: 'No documentation files found' }); + } + + res.status(200).json(filenames); + } catch (error) { + console.error('Error reading docs directory:', error); + res.status(500).json({ error: 'Unable to read documentation files' }); + } +} diff --git a/apps/stage/pages/api/protected/[...proxy].ts b/apps/stage/pages/api/protected/[...proxy].ts new file mode 100644 index 00000000..8dd4443e --- /dev/null +++ b/apps/stage/pages/api/protected/[...proxy].ts @@ -0,0 +1,92 @@ +import type { NextApiRequest, NextApiResponse } from 'next'; +import { getServerSession } from 'next-auth/next'; +import httpProxy from 'http-proxy'; + +import { getAuthOptions } from '../auth/[...nextauth]'; +import { getConfig } from '@/global/config'; +import { + INTERNAL_API_PROXY, + KEYCLOAK_API_KEY_ENDPOINT, + KEYCLOAK_URL_TOKEN, +} from '@/global/utils/constants'; +import { decryptContent } from '@/global/utils/crypt'; +import { removeFromPath, SSLSecured } from '@/global/utils/proxyUtils'; + +const proxy = httpProxy.createProxyServer(); + +const { NEXT_PUBLIC_ARRANGER_API } = getConfig(); + +// You can export a config variable from any API route in Next.js. +// We'll use this to disable the bodyParser, otherwise Next.js +// would read and parse the entire request body before we +// can forward the request to the API. By skipping the bodyParser, +// we can just stream all requests through to the actual API. +export const config = { + api: { + bodyParser: false, + }, +}; + +// Add event listener for proxyRes to handle CORS headers +proxy.on('proxyRes', (proxyRes, req, res) => { + const response = res as NextApiResponse; + response.setHeader('Access-Control-Allow-Origin', '*'); + response.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); + response.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); + response.setHeader('Access-Control-Allow-Credentials', 'true'); + }); + +export default async function handler(req: NextApiRequest, res: NextApiResponse) { + // Handle preflight requests + if (req.method === 'OPTIONS') { + res.setHeader('Access-Control-Allow-Origin', '*'); + res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); + res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); + res.setHeader('Access-Control-Allow-Credentials', 'true'); + return res.status(200).end(); + } + + let path = req.url; + let target = ''; + if (req.url?.startsWith(INTERNAL_API_PROXY.PROTECTED_ARRANGER)) { + path = removeFromPath(req?.url, INTERNAL_API_PROXY.PROTECTED_ARRANGER); + target = NEXT_PUBLIC_ARRANGER_API; + } else if (req.url?.startsWith(INTERNAL_API_PROXY.PROTECTED_KEYCLOAK_APIKEY_ENDPOINT)) { + path = removeFromPath(req?.url, INTERNAL_API_PROXY.PROTECTED_KEYCLOAK_APIKEY_ENDPOINT); + target = KEYCLOAK_API_KEY_ENDPOINT; + } else if (req.url?.startsWith(INTERNAL_API_PROXY.PROTECTED_KEYCLOAK_TOKEN_ENDPOINT)) { + path = removeFromPath(req?.url, INTERNAL_API_PROXY.PROTECTED_KEYCLOAK_TOKEN_ENDPOINT); + target = KEYCLOAK_URL_TOKEN; + } else { + return res.status(404).end(); + } + req.url = path; + + const session = await getServerSession(req, res, getAuthOptions(req)); + + console.info(`protected proxy - proxing to target:${target} path:${path}`); + + if (session?.account?.accessToken) { + req.headers['Authorization'] = 'Bearer ' + decryptContent(session?.account?.accessToken); + } + + // Don't forward cookies to the API: + req.headers.cookie = ''; + + proxy.web( + req, + res, + { + target, + changeOrigin: true, + secure: SSLSecured, + headers: { + 'Access-Control-Allow-Origin': '*', + }, + }, + (err) => { + console.error(`Proxy error URL: ${req.url}. Error: ${JSON.stringify(err)}`); + return res.status(500).json(err); + }, + ); +} diff --git a/apps/stage/pages/dataTableOne/index.tsx b/apps/stage/pages/dataTableOne/index.tsx new file mode 100644 index 00000000..72d1ab5c --- /dev/null +++ b/apps/stage/pages/dataTableOne/index.tsx @@ -0,0 +1,13 @@ +import DataTableOne from '../../components/pages/activeDataTables/dataTableOne'; +import { createPage } from '../../global/utils/pages'; + +const DataSetOneExplorationPage = createPage({ + getInitialProps: async ({ query, egoJwt }) => { + return { query, egoJwt }; + }, + isPublic: true, +})(() => { + return ; +}); + +export default DataSetOneExplorationPage; diff --git a/apps/stage/pages/dataTableTwo/index.tsx b/apps/stage/pages/dataTableTwo/index.tsx new file mode 100644 index 00000000..2721e3cb --- /dev/null +++ b/apps/stage/pages/dataTableTwo/index.tsx @@ -0,0 +1,13 @@ +import DataTableTwo from '../../components/pages/activeDataTables/dataTableTwo'; +import { createPage } from '../../global/utils/pages'; + +const DataSetTwoExplorationPage = createPage({ + getInitialProps: async ({ query, egoJwt }) => { + return { query, egoJwt }; + }, + isPublic: true, +})(() => { + return ; +}); + +export default DataSetTwoExplorationPage; diff --git a/apps/stage/pages/documentation/[slug].tsx b/apps/stage/pages/documentation/[slug].tsx new file mode 100644 index 00000000..806dbe57 --- /dev/null +++ b/apps/stage/pages/documentation/[slug].tsx @@ -0,0 +1,221 @@ +// pages/documentation/[slug].tsx +import fs from 'fs'; +import { marked } from 'marked'; +import { GetStaticPaths, GetStaticProps, NextPage } from 'next'; +import { useRouter } from 'next/router'; +import path from 'path'; +import HeroBanner from '../../components/HeroBanner'; +import PageLayout from '../../components/PageLayout'; +import Sidebar from '../../components/pages/documentation/DocContainer/Sidebar'; +import styles from '../../components/pages/documentation/DocContainer/styles'; +import { Section, SidebarSection } from '../../components/pages/documentation/DocContainer/types'; +import { extractHeadings, renderMarkdown } from '../../components/pages/documentation/DocContainer/utils/markdown'; +import { PageWithConfig } from '../../global/utils/pages/types'; + +interface DocumentationPageProps { + section: Section; + sections: SidebarSection[]; + headings: { id: string; text: string; level: number }[]; +} + +const DocumentationPage: NextPage = ({ section, sections, headings }) => { + const router = useRouter(); + + return ( + +
    + +
    + +
    + +
    + + {/* Table of Contents for this section */} + {headings.length > 0 && ( +
    +

    On This Page

    + +
    + )} +
    +
    +
    + ); +}; + +export const getStaticPaths: GetStaticPaths = async () => { + // Read markdown files + const docsDirectory = path.join(process.cwd(), 'public', 'docs'); + const files = fs + .readdirSync(docsDirectory) + .filter((filename) => filename.endsWith('.md')) + .sort(); + + const paths = files.map((filename) => ({ + params: { slug: createSlug(filename) }, + })); + + return { + paths, + fallback: false, + }; +}; + +export const getStaticProps: GetStaticProps = async ({ params }) => { + const slug = params?.slug as string; + + try { + // Read all markdown files + const docsDirectory = path.join(process.cwd(), 'public', 'docs'); + const files = fs + .readdirSync(docsDirectory) + .filter((filename) => filename.endsWith('.md')) + .sort(); + + // Find the matching file + const matchingFile = files.find((filename) => createSlug(filename) === slug); + + if (!matchingFile) { + return { notFound: true }; + } + + // Read the content of the matching file + const filePath = path.join(docsDirectory, matchingFile); + const content = fs.readFileSync(filePath, 'utf8'); + + // Extract headings for the table of contents + const headings = extractHeadings(content); + + // Prepare section data + const section: Section = { + title: getDocumentTitle(content), + markdownPath: `/docs/${matchingFile}`, + content, + order: getDocumentOrder(matchingFile), + id: createSlug(matchingFile), + }; + + // Prepare all sections for sidebar navigation + const sectionsPromises = files.map(async (filename) => { + const sectionPath = path.join(docsDirectory, filename); + const sectionContent = fs.readFileSync(sectionPath, 'utf8'); + return { + title: getDocumentTitle(sectionContent), + id: createSlug(filename), + }; + }); + + const sections = await Promise.all(sectionsPromises); + + return { + props: { + section, + sections, + headings, + }, + }; + } catch (error) { + console.error('Error in getStaticProps:', error); + return { notFound: true }; + } +}; + +// Mark the page as public +(DocumentationPage as PageWithConfig).isPublic = true; + +// Utility functions +function createSlug(filename: string): string { + return filename + .replace(/^\d+[-_]?/, '') // Remove leading number and optional separator + .replace(/\.md$/, '') // Remove .md extension + .toLowerCase() + .replace(/\s+/g, '-') // Replace spaces with hyphens + .replace(/[^\w-]/g, ''); // Remove non-word characters +} + +function getDocumentOrder(filename: string): number { + const match = filename.match(/^(\d+)/); + return match ? parseInt(match[1], 10) : 999; +} + +function getDocumentTitle(content: string): string { + const titleMatch = content.match(/^#\s+(.+)$/m); + return titleMatch ? titleMatch[1].trim() : 'Untitled Section'; +} + +export default DocumentationPage; diff --git a/apps/stage/pages/documentation/index.tsx b/apps/stage/pages/documentation/index.tsx new file mode 100644 index 00000000..c6745c64 --- /dev/null +++ b/apps/stage/pages/documentation/index.tsx @@ -0,0 +1,116 @@ +// pages/documentation/index.tsx +import fs from 'fs'; +import { GetStaticProps } from 'next'; +import Link from 'next/link'; +import path from 'path'; +import HeroBanner from '../../components/HeroBanner'; +import PageLayout from '../../components/PageLayout'; +import Sidebar from '../../components/pages/documentation/DocContainer/Sidebar'; +import styles from '../../components/pages/documentation/DocContainer/styles'; +import { SidebarSection } from '../../components/pages/documentation/DocContainer/types'; +import { PageWithConfig } from '../../global/utils/pages/types'; + +interface DocumentationIndexProps { + sections: SidebarSection[]; +} + +const DocumentationIndex: React.FC = ({ sections }) => { + return ( + +
    + +
    + +
    +
    +

    Prelude Documentation

    +

    Prelude Documentation

    +

    + Welcome to the Prelude documentation. Use the sidebar to navigate through different sections of our + comprehensive guide. +

    +

    Available Sections

    +
      + {sections.map((section) => ( +
    • + {section.title} +
    • + ))} +
    +
    +
    +
    +
    +
    + ); +}; + +export const getStaticProps: GetStaticProps = async () => { + try { + // Use Node.js fs to read markdown files directly + const docsDirectory = path.join(process.cwd(), 'public', 'docs'); + const files = fs + .readdirSync(docsDirectory) + .filter((filename) => filename.endsWith('.md')) + .sort(); + + // Prepare sections + const sectionsPromises = files.map(async (filename) => { + const filePath = path.join(docsDirectory, filename); + const content = fs.readFileSync(filePath, 'utf8'); + + return { + title: getDocumentTitle(content), + id: createSlug(filename), + order: getDocumentOrder(filename), + }; + }); + + const sections = await Promise.all(sectionsPromises); + sections.sort((a, b) => a.order - b.order); + + return { + props: { + sections, + }, + }; + } catch (error) { + console.error('Error in getStaticProps:', error); + return { + props: { + sections: [], + error: 'Failed to load documentation', + }, + }; + } +}; + +// Mark the page as public +(DocumentationIndex as PageWithConfig).isPublic = true; + +// Utility functions +function createSlug(filename: string): string { + return filename + .replace(/^\d+[-_]?/, '') // Remove leading number and optional separator + .replace(/\.md$/, '') // Remove .md extension + .toLowerCase() + .replace(/\s+/g, '-') // Replace spaces with hyphens + .replace(/[^\w-]/g, ''); // Remove non-word characters +} + +function getDocumentOrder(filename: string): number { + const match = filename.match(/^(\d+)/); + return match ? parseInt(match[1], 10) : 999; +} + +function getDocumentTitle(content: string): string { + const titleMatch = content.match(/^#\s+(.+)$/m); + return titleMatch ? titleMatch[1].trim() : 'Untitled Section'; +} + +export default DocumentationIndex; diff --git a/apps/stage/pages/home/index.tsx b/apps/stage/pages/home/index.tsx new file mode 100644 index 00000000..9a0d607c --- /dev/null +++ b/apps/stage/pages/home/index.tsx @@ -0,0 +1,19 @@ +import Home from '@/components/pages/home'; +import SystemAlerts from '@/components/SystemAlerts'; +import { createPage } from '../../global/utils/pages'; + +const HomePage = createPage({ + getInitialProps: async ({ query, egoJwt }) => { + return { query, egoJwt }; + }, + isPublic: true, +})(() => { + return ( + <> + + + + ); +}); + +export default HomePage; diff --git a/apps/stage/pages/index.tsx b/apps/stage/pages/index.tsx new file mode 100644 index 00000000..8004ef48 --- /dev/null +++ b/apps/stage/pages/index.tsx @@ -0,0 +1,30 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import { createPage } from '../global/utils/pages'; +import HomePage from './home'; + +const LandingPage = createPage({ + getInitialProps: async () => null, + isPublic: true, +})(HomePage); + +export default LandingPage; diff --git a/apps/stage/pages/login/index.tsx b/apps/stage/pages/login/index.tsx new file mode 100644 index 00000000..b2f96973 --- /dev/null +++ b/apps/stage/pages/login/index.tsx @@ -0,0 +1,11 @@ +import Login from '../../components/pages/login'; +import { createPage } from '../../global/utils/pages'; + +const LoginPage = createPage({ + getInitialProps: async () => {}, + isPublic: true, +})(() => { + return ; +}); + +export default LoginPage; diff --git a/apps/stage/pages/molecular/index.tsx b/apps/stage/pages/molecular/index.tsx new file mode 100644 index 00000000..d8c3b373 --- /dev/null +++ b/apps/stage/pages/molecular/index.tsx @@ -0,0 +1,13 @@ +import File from '../../components/pages/molecular'; +import { createPage } from '../../global/utils/pages'; + +const MolecularExplorationPage = createPage({ + getInitialProps: async ({ query, egoJwt }) => { + return { query, egoJwt }; + }, + isPublic: true, +})(() => { + return ; +}); + +export default MolecularExplorationPage; diff --git a/apps/stage/pages/swaggerDocs/lectern.tsx b/apps/stage/pages/swaggerDocs/lectern.tsx new file mode 100644 index 00000000..39ea8eaf --- /dev/null +++ b/apps/stage/pages/swaggerDocs/lectern.tsx @@ -0,0 +1,33 @@ +import Lectern from '../../components/pages/swaggerDocs/Lectern'; +import { createPage } from '../../global/utils/pages'; + +// Define your alerts, this could come from an API or be static +// const alertsJson: AlertDef[] = [ +// { +// level: 'warning', +// title: 'Lectern API Unavailable?', +// message: +// 'If you are using Prelude Phase1 the Lectern Swagger API will not work as lectern is not deployed until Phase3.', +// dismissable: true, +// id: 'lectern-api-unavailability', // Make sure each alert has a unique ID +// }, +// ]; + +const LecternApiPage = createPage({ + getInitialProps: async ({ query }) => { + return { query }; + }, + isPublic: true, +})(() => { + return ( + <> + {/* Add the SystemAlerts banner above your Lectern component */} + {/* */} + + {/* The actual content of the page */} + + + ); +}); + +export default LecternApiPage; diff --git a/apps/stage/pages/swaggerDocs/lyric.tsx b/apps/stage/pages/swaggerDocs/lyric.tsx new file mode 100644 index 00000000..aa7a7b21 --- /dev/null +++ b/apps/stage/pages/swaggerDocs/lyric.tsx @@ -0,0 +1,33 @@ +import Lyric from '../../components/pages/swaggerDocs/Lyric'; +import { createPage } from '../../global/utils/pages'; + +// Define your alerts, this could come from an API or be static +// const alertsJson: AlertDef[] = [ +// { +// level: 'warning', +// title: 'Lyric API Unavailable?', +// message: +// 'If you are using Prelude Phase1 the Lyric Swagger API will not work as lyric is not deployed until Phase3.', +// dismissable: true, +// id: 'lyric-api-unavailability', // Make sure each alert has a unique ID +// }, +// ]; + +const LyricApiPage = createPage({ + getInitialProps: async ({ query }) => { + return { query }; + }, + isPublic: true, +})(() => { + return ( + <> + {/* Add the SystemAlerts banner above your Lyric component */} + {/* */} + + {/* The actual content of the page */} + + + ); +}); + +export default LyricApiPage; diff --git a/apps/stage/pages/swaggerDocs/score.tsx b/apps/stage/pages/swaggerDocs/score.tsx new file mode 100644 index 00000000..8ea5d0e7 --- /dev/null +++ b/apps/stage/pages/swaggerDocs/score.tsx @@ -0,0 +1,33 @@ +import Score from '../../components/pages/swaggerDocs/Score'; +import { createPage } from '../../global/utils/pages'; + +// Define your alerts, this could come from an API or be static +// const alertsJson: AlertDef[] = [ +// { +// level: 'warning', +// title: 'Score API Unavailable?', +// message: +// 'If you are using Prelude Phase1 the Score Swagger API will not work as score is not deployed until Phase3.', +// dismissable: true, +// id: 'score-api-unavailability', // Make sure each alert has a unique ID +// }, +// ]; + +const ScoreApiPage = createPage({ + getInitialProps: async ({ query }) => { + return { query }; + }, + isPublic: true, +})(() => { + return ( + <> + {/* Add the SystemAlerts banner above your Score component */} + {/* */} + + {/* The actual content of the page */} + + + ); +}); + +export default ScoreApiPage; diff --git a/apps/stage/pages/swaggerDocs/song.tsx b/apps/stage/pages/swaggerDocs/song.tsx new file mode 100644 index 00000000..0f9618fc --- /dev/null +++ b/apps/stage/pages/swaggerDocs/song.tsx @@ -0,0 +1,32 @@ +import Song from '../../components/pages/swaggerDocs/Song'; +import { createPage } from '../../global/utils/pages'; + +// Define your alerts, this could come from an API or be static +// const alertsJson: AlertDef[] = [ +// { +// level: 'warning', +// title: 'Song API Unavailable?', +// message: 'If you are using Prelude Phase1 the Song Swagger API will not work as song is not deployed until Phase3.', +// dismissable: true, +// id: 'song-api-unavailability', // Make sure each alert has a unique ID +// }, +// ]; + +const SongApiPage = createPage({ + getInitialProps: async ({ query }) => { + return { query }; + }, + isPublic: true, +})(() => { + return ( + <> + {/* Add the SystemAlerts banner above your Song component */} + {/* */} + + {/* The actual content of the page */} + + + ); +}); + +export default SongApiPage; diff --git a/apps/stage/pages/user/index.tsx b/apps/stage/pages/user/index.tsx new file mode 100644 index 00000000..15ce2e71 --- /dev/null +++ b/apps/stage/pages/user/index.tsx @@ -0,0 +1,35 @@ +/* + * + * Copyright (c) 2022 The Ontario Institute for Cancer Research. All rights reserved + * + * This program and the accompanying materials are made available under the terms of + * the GNU Affero General Public License v3.0. You should have received a copy of the + * GNU Affero General Public License along with this program. + * If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +import React from 'react'; + +import User from '../../components/pages/user'; +import { createPage } from '../../global/utils/pages'; + +const UserPage = createPage({ + getInitialProps: async ({ egoJwt }) => { + return { egoJwt }; + }, +})(() => { + return ; +}); + +export default UserPage; diff --git a/apps/stage/prettier.config.js b/apps/stage/prettier.config.js new file mode 100644 index 00000000..c487aa9b --- /dev/null +++ b/apps/stage/prettier.config.js @@ -0,0 +1,8 @@ +module.exports = { + organizeImportsSkipDestructiveCodeActions: true, + printWidth: 120, + semi: true, + singleQuote: true, + trailingComma: 'all', + useTabs: true, +}; \ No newline at end of file diff --git a/apps/stage/productDMS.svg b/apps/stage/productDMS.svg new file mode 100644 index 00000000..1d8876d0 --- /dev/null +++ b/apps/stage/productDMS.svg @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/stage/public/docs/00-introduction.md b/apps/stage/public/docs/00-introduction.md new file mode 100644 index 00000000..7007921d --- /dev/null +++ b/apps/stage/public/docs/00-introduction.md @@ -0,0 +1,123 @@ +# Introduction + +## Introduction + +**Prelude** is a toolkit designed for the **planning and development stages** of Overture data platform implementation. It helps teams incrementally build and validate platform requirements, enabling them to: + +- Systematically verify requirements and user workflows +- Minimize technical overhead during planning and prototyping +- Create a comprehensive blueprint for production deployment + +**Important:** Prelude is **not intended for production environments**. It serves as a preparatory tool to ensure successful production deployments. We are actively enhancing resources to support teams transitioning from Prelude to production. + +We welcome feedback and suggestions—please share them via our [ideas forum](https://github.com/overture-stack/docs/discussions/categories/ideas). + +## Development Phases + +Prelude is structured into four incremental phases: + +![Development Phases](/docs/images/DevelopmentPhases.png "Prelude Development Phases") + +| **Phase** | **Focus** | **Components** | +| --------------------------------------- | ----------------------------------- | --------------------------------- | +| **Phase 1:** Data Exploration & Theming | Data visualization in the portal | Elasticsearch, Arranger, Stage | +| **Phase 2:** Tabular Data Management | Backend data storage and validation | Lyric, Lectern, Postgres, MongoDB | +| **Phase 3:** File Management | File storage and metadata tracking | Song, Score, Object Storage | +| **_Phase 4:_** Identity & Access | Security and user management | Keycloak integration | + +**Phase 4** is not included in Prelude v1 and will be implemented in a future release. + +## Supplemental Tools + +### Composer + +**Composer** transforms your data into base Overture configurations, generating: + +- **Elasticsearch Mappings** – Defines the structure and indexing settings for your data +- **Arranger UI Configs** – Configures the user interface for data exploration and visualization +- **Lectern Dictionary and Schema** – Creates data dictionaries and schemas for tabular data +- **Song Schema** – Generates schema configurations for file metadata + +These configurations provide a foundation for Overture components, ensuring consistent data representation and interoperability. + +### Conductor + +**Conductor** streamlines interactions with Overture APIs, offering: + +- **Elasticsearch Management** + + - Update Elasticsearch mappings + - Transform and load CSV data into Elasticsearch + +- **Metadata and Schema Handling** + + - Validate and submit schema dictionaries to Lectern + - Register Lectern dictionaries with Lyric + +- **Data Management** + - Upload tabular data to Lyric + - Create Song studies + - Update Song with analysis schemas + - Upload and publish file data with Song and Score + +The guides here provide detailed instructions for using Conductor. Since Conductor abstracts interactions with Overture APIs, we reference the relevant API endpoints at each phase. To supplement this, [Overture Swagger docs and API pages](/swaggerDocs/overview) are integrated within this portal for easy exploration and interaction. + +**Note:** Swagger APIs are only available when running phases that include the respective service. + +## Getting Started + +_If you’re reading from the Prelude documentation page, this section may be redundant._ + +### 1. Clone the repository + +```sh +git clone -b prelude https://github.com/overture-stack/conductor.git +cd conductor +``` + +### 2. Pre-deployment Check + +Run a pre-deployment check: + +```sh +make Phase0 +``` + +**Requirements:** + +- **Docker Desktop 4.39.0+** with: + - 8-core CPU minimum + - 8 GB memory + - 2 GB swap + - 64 GB virtual disk +- **Node.js 18+ and npm 9+** + +### 3. Build the local Stage UI image + +```sh +cd apps/stage +docker build -t stageimage:1.0 . +``` + +### 4. Deploy Phase 1 + +Run from the root directory: + +```sh +make phase1 +``` + +### 5. Access the Portal + +Once running, access the portal at: [http://localhost:3000](http://localhost:3000). + +All Prelude documentation is available in the **Documentation** tab here or on our [documentation site](https://docs.overture.bio/other-software/prelude). + +## Support + +For assistance, reach out via our [community support channels](https://docs.overture.bio/community/support): + +- **Public support:** Use GitHub issues +- **Private inquiries:** Contact us via OICR Slack or [contact@overture.bio](mailto:contact@overture.bio) + +We’re actively working on resources to help teams transition to production. If you have suggestions, post them on our [GitHub discussion forum](https://github.com/overture-stack/docs/discussions/categories/ideas). diff --git a/apps/stage/public/docs/01-phaseOne.md b/apps/stage/public/docs/01-phaseOne.md new file mode 100644 index 00000000..0eacc5fe --- /dev/null +++ b/apps/stage/public/docs/01-phaseOne.md @@ -0,0 +1,537 @@ +# Phase One + +## Overview + +**This guide is for** those in phase one of Prelude's deployment process. The primary goal is to set up and configure Stage, Arranger, and Elasticsearch such that you will be able to access and exploring your tabular data through data exploration pages. + +**By the end of this guide you will be able to:** + +1. Generate and configure Elasticsearch mappings +2. Generate and configure Arranger UI configs +3. Transform and load your CSV data into Elasticsearch and onto the data table +4. Create multiple data exploration pages for independent datasets +5. Theme your Stage UI to match your organization's branding + +## Prerequisites and Requirements + +**You will need:** + +- Tabular Data in the form of CSV (more details in step 1 below) +- A basic understanding of the following software: + - [Elasticsearch 7.17](https://www.elastic.co/guide/en/elasticsearch/reference/7.17/index.html) + - [Arranger](https://docs.overture.bio/docs/core-software/arranger/overview/) + - [Stage](https://docs.overture.bio/docs/core-software/Stage/overview) +- Optionally we use [Elasticvue](https://elasticvue.com/installation) for viewing, maintaining, configuring, and troubleshooting Elasticsearch + +### Quick Setup Verification + +If you are starting from this point or want to ensure your system is ready, run the following command from the root of the Prelude directory: + +```bash +make phase0 +``` + +This command performs a pre-deployment check and provides all the information you need to set up your system for success. + +## Background Information + +Phase One focuses on configuring how your data will be displayed in the front-end portal. During this phase, you'll determine the number of data tables needed and their configurations. This is also the ideal time to apply custom theming to your portal. The goal is to establish the look and feel of the user experience before proceeding to more complex back-end data management configurations. + +### Architecture Overview + +The phase architecture is diagramed below and detailed in the following table: + +![Phase 1 Architecture Diagram](/docs/images/phase1.png "Phase 1 Architecture Diagram") + +| Component | Description | +| ---------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | +| **Conductor** | A command-line tool for processing CSV files into Elasticsearch. It handles data transformation and loading. | +| **Composer** | A command-line tool for generating base Oveture configuration files. | +| **[Elasticsearch](https://www.elastic.co/guide/en/elasticsearch/reference/7.17/elasticsearch-intro.html)** | A powerful search and analytics engine that enables flexible and efficient querying of massive datasets. | +| **[Arranger](https://docs.overture.bio/docs/core-software/arranger/overview)** | A search API and UI component generation service that creates configurable data exploration interfaces. | +| **[Stage](https://docs.overture.bio/docs/core-software/stage/overview/)** | A React-based user interface framework designed for easy deployment of customizable data portals. | + +## Step 1: Preparing your data + +The `data` folder at the root of this project is for storing data files used in +your project. Below are guidelines for data management: + +- **File Format**: We support multiple delimiters, but Comma-Separated Values (CSV) are the recommended format for tabular data input. +- **Headers**: Include headers in your CSV files to ensure clear column identification. These headers will directly map to your Elasticsearch index field names. +- **Data Privacy**: When working with sensitive data, add your data files to `.gitignore` before committing to GitHub to prevent accidental exposure. +- **Data Size**: There are no strict size limitations beyond the resource constraints of Docker and Elasticsearch. For development and testing, we recommend using a representative sample of approximately 500 records. + +Each CSV file in the `data` folder should represent an independent dataset that you want to view within the exploration tables. + +### Implementation + +1. Collect your tabular datasets in CSV format +2. Place CSV files in the `data` folder +3. Ensure each CSV file: + - Has clear, descriptive headers + - Represents a distinct, independent dataset + - Contains a representative sample of data + +You should also ensure that your headers do not conflict with any elasticsearch or graphQL naming conventions, a summary of invalid characters and reserved words is provided in the dropdown below. + +
    +Header Naming Conventions + +**Prohibited Characters**: Avoid using `:, >, <, ., [space], ,, /, \, ?, #, [, ], {, }, ", *, |, +, @, &, (, ), !, ^` in column headers. + +**Length Restriction**: Maximum header length is 255 characters. + +**Reserved Words**: Do not use these as column headers: +`_type`, `_id`, `_source`, `_all`, `_parent`, `_field_names`, `_routing`, `_index`, `_size`, `_timestamp`, `_ttl`, `_meta`, `_doc`, `__typename`, `__schema`, `__type` + +**Best Practices**: + +- Use snake_case or camelCase +- Keep headers descriptive but concise +- Avoid special characters and spaces +- Use lowercase letters + +**Example**: + +- **Good**: `user_id,first_name,last_name,email_address` +- **Bad**: `User ID!,First Name,Email@Address` + +Following these guidelines ensures smooth Elasticsearch indexing and prevents data ingestion issues. + +
    + +### Validation + +To verify successful data preparation: + +- Your data folder should include one CSV file for each desired data table: + + ``` + project-root/ + └── data/ + ├── datatable1.csv + ├── datatable2.csv + └── datatable3.csv + ``` + +- Open each CSV file and confirm: + - Headers are present and valid + - Data is clean and formatted consistently + - No sensitive information is exposed +- Confirm your `.gitignore` includes data files if necessary + +**Next Steps:** After completing data preparation, you'll be ready to generate your Arranger and Stage configuration files. + +## Step 2: Update portal configurations + +Introduction: Provide a brief overview of what this step accomplishes and why it's necessary + +### A) Install Composer + +1. Move to the Composer App directory: + + ``` + cd ./apps/composer + ``` + +2. Run the following commands: + + ``` + npm install + npm run build + npm install -g + ``` + +3. **Validate:** From the root directory test that Composer is working by running `composer -h` you should be able to see help text outlining the available commands. + +### B) Generate Elasticsearch index mappings + +1. Run the following Composer command to generate elasticsearch index mappings using your data files: + + ``` + composer -p generateElasticsearchMapping -f ./data/datatable1.csv -i datatable1 -o ./configs/elasticsearchConfigs/datatable1-mapping.json + ``` + +
    + Command Breakdown + + In this command: + + - `-p generateElasticsearchMapping`: Specifies the operation to generate an Elasticsearch mapping schema + - `-f ./data/datatable1.csv`: Specifies the input data file to analyze + - `-i datatable1`: Sets the Elasticsearch index name to "datatable1" + - `-o ./configs/elasticsearchConfigs/datatable1-mapping.json`: Sets the output path for the generated mapping file + + The command analyzes the structure of datatable1.csv and creates an appropriate Elasticsearch mapping configuration, which defines how the data will be indexed and searched in Elasticsearch. + + A detailed overview of all available options for the generateElasticsearchMapping command can be seen by running `composer -h` + +
    + + ![Output](/docs/images/generateElasticsearchMapping.png "Terminal output from generateElasticsearchMapping") + +2. Validate and review the generated mapping template(s): + + After running the command, examine the generated index mapping in the `configs/elasticsearchConfigs` directory. The mapping contains several critical components: + + - **Index Pattern:** `"index_patterns": ["datatable1-*"]` - This template will apply to all indices that start with "datatable1-" + - **Aliases:** `"datatable1_centric": {}` - An alias that can be used to reference all matching indices as one + - **Data Structure:** Note how all fields are nested under a `data` object, providing clean organization + +
    + Key Elements to Review + + - **Field Types:** Most fields are set as `keyword` type for exact matching, with numeric values like `age_at_diagnosis`, `treatment_start`, and `followup_interval` appropriately set as `integer` types + + - **Metadata Structure:** The auto-generated `submission_metadata` object contains important tracking fields: + ```json + "submission_metadata": { + "type": "object", + "properties": { + "submitter_id": { "type": "keyword", "null_value": "No Data" }, + "processing_started": { "type": "date" }, + "processed_at": { "type": "date" }, + "source_file": { "type": "keyword", "null_value": "No Data" }, + "record_number": { "type": "integer" }, + "hostname": { "type": "keyword", "null_value": "No Data" }, + "username": { "type": "keyword", "null_value": "No Data" } + } + } + ``` + - **Index Settings:** The configuration uses minimal settings with 1 shard and 0 replicas: + ```json + "settings": { + "number_of_shards": 1, + "number_of_replicas": 0 + } + ``` + These settings are appropriate for development but can and should be adjusted as we move foward. +
    + +3. Repeat the above steps for your remaining datasets, make sure to name your indices and files appropriatly. + + **Next Step:** Once you're satisfied with the mapping configuration, you're ready to move on to the next step, generating and confuring the Arranger configuration files. + +### C) Generating our Arranger configuration files + +1. Run the following Composer command to generate Arranger configuration files using your index mapping templates: + + ``` + composer -p generateArrangerConfigs -f ./configs/elasticsearchConfigs/datatable1-mapping.json -o ./configs/arrangerConfigs/datatable1/ + ``` + +
    + Command Breakdown + + In this command: + + - `-p generateArrangerConfigs`: Specifies the operation to generate Arranger configuration files + - `-f ./configs/elasticsearchConfigs/datatable1-mapping.json`: Specifies the input Elasticsearch mapping file to use as a template + - `-o ./configs/arrangerConfigs/datatable1/`: Sets the output directory for the generated Arranger configuration files + + The command analyzes the Elasticsearch mapping structure and creates appropriate Arranger configuration files, which define how data will be displayed, filtered, and queried in the Arranger UI. + + A detailed overview of all available options for the generateArrangerConfigs command can be seen by running `composer -h generateArrangerConfigs` + +
    + + ![Output](/docs/images/generateArrangerConfigs.png "Terminal output from generateArrangerConfigs") + +2. Validate and review the generated arranger configuration file: + + - **Directory structure:** should now look like the following + + ``` + configs + ├── arrangerConfigs + │ └── datatable1 + │ ├── base.json # Core configuration + │ ├── extended.json # Field display settings + │ ├── facets.json # Filter panel configuration + │ └── table.json # Table display settings + └── elasticsearchConfigs + └── datatable1-mapping.json + + ``` + + - **Base.json:** update the index field of your base.json file to match relevant index alias. In this case `datatable1-index`. + + ``` + { + "documentType": "file", + "index": "datatable1-centric" + } + ``` + + - **Extended.json** `fieldNames` should be accurate in the extended.json, take time to review and update the `displayNames` as these will be how fields are read from the front-end UI. + - **Table.json** By default `canChangeShow`, `show`, and `sortable` are set to true. Update these fields accordingly. For information see our documentation covering [Arrangers table configuration fields](https://docs.overture.bio/docs/core-software/Arranger/usage/arranger-components#table-configuration-tablejson) + - **Facets.json** By default `active` and `show` are set to true. Update these fields accordingly. The order of the elements will also match the order of the facets as they appear in the facet panel, update accordingly. For information see our documentation covering [Arrangers facet configuration fields](https://docs.overture.bio/docs/core-software/Arranger/usage/arranger-components#facet-configuration-facetsjson) + +3. Repeat the above steps for your remaining datasets. + + **Next Step:** After generating your Elasticsearch mappings and Arranger configuration files, the next step is to update the docker-compose.yml file to properly connect these components. + +## Step 3: Updating the docker-compose + +This step configures your docker-compose.yml file to properly connect your data sources, Elasticsearch, Arranger, and Stage. You'll update environment variables and service configurations to reflect your specific dataset configurations. + +1. **Update the following Environment Variables within the conductor image**: + + Modify the `conductor` service environment variables to reference your dataset(s): + + ```yaml + # Elasticsearch Index Configuration + ES_INDEX_COUNT: 1 # Update this if you have multiple datasets + + # First index + ES_INDEX_0_NAME: datatable1-index + ES_INDEX_0_TEMPLATE_FILE: configs/elasticsearchConfigs/datatable1-mapping.json + ES_INDEX_0_TEMPLATE_NAME: datatable1_template + ES_INDEX_0_ALIAS_NAME: datatable1_centric + # Add more indices if needed + # ES_INDEX_1_NAME: datatable2-index + # ES_INDEX_1_TEMPLATE_FILE: configs/elasticsearchConfigs/datatable2-mapping.json + # ES_INDEX_1_TEMPLATE_NAME: datatable2_template + # ES_INDEX_1_ALIAS_NAME: datatable2_centric + ``` + +2. **Configure Arranger Services**: + + For each dataset, configure a separate Arranger service. Update the `arranger-clinical` service (or rename it appropriately) and add additional Arranger services if needed: + + ```yaml + arranger-datatable1: + profiles: ["phase1", "phase2", "phase3", "stageDev", "default"] + image: ghcr.io/overture-stack/arranger-server:3.0.0-beta.36 + container_name: arranger-datatable1 # Rename to match above + platform: linux/amd64 + depends_on: + conductor: + condition: service_healthy + ports: + - "5050:5050" # Use unique ports for each Arranger instance + volumes: + - ./configs/arrangerConfigs/datatable1:/app/modules/server/configs # Point to the relevant generated config + environment: + # Elasticsearch Variables + ES_HOST: http://elasticsearch:9200 + ES_USER: elastic + ES_PASS: myelasticpassword + ES_ARRANGER_SET_INDEX: datatable1_arranger_set + # Arranger Variables + PORT: 5050 # Required + DEBUG: false + ENABLE_LOGS: false + ``` + + - Make sure to use unique ports for each Arranger instance, this includes updating the ports section as well as the `PORT` environment variable for each Arranger instance + - Make sure you point the volume path provided to the relevant arranger config + +3. **Update the Arranger Count in Conductor**: + + If you have multiple datasets/Arranger instances, update the `ARRANGER_COUNT` and add URLs for each: + + ```yaml + # Arranger Services Configuration + ARRANGER_COUNT: 1 # Update this if you have multiple Arrangers + ARRANGER_0_URL: http://arranger-datatable1:5050 + # ARRANGER_1_URL: http://arranger-datatable2:5051 + ``` + + - Here `ARRANGER_1_URL` is commented, make sure to uncomment any additionally added arranger URLs + +4. **Ensure all services are on the same network**: + + The following should be included with each added service + + ```yaml + networks: + - conductor-network + ``` + +5. **pre-configure the Stage Environment variable**: + + Update the Stage service environment variables to connect to your Arranger instances: + + ```yaml + # Tabular Arranger Variables + NEXT_PUBLIC_ARRANGER_DATATABLE_1_DATA_API: http://arranger-datatable1:5050 + NEXT_PUBLIC_ARRANGER_DATATABLE_1_DATA_DOCUMENT_TYPE: file + NEXT_PUBLIC_ARRANGER_DATATABLE_1_INDEX: datatable1_centric + # Add more Arranger connections if needed + NEXT_PUBLIC_ARRANGER_DATATABLE_2_API: http://arranger-datatable2:5051 + NEXT_PUBLIC_ARRANGER_DATATABLE_2_DOCUMENT_TYPE: file + NEXT_PUBLIC_ARRANGER_DATATABLE_2_INDEX: datatable2_centric + # Add more Arranger connections if needed + NEXT_PUBLIC_ARRANGER_DATATABLE_3_API: http://arranger-datatable2:5051 + NEXT_PUBLIC_ARRANGER_DATATABLE_3_DOCUMENT_TYPE: file + NEXT_PUBLIC_ARRANGER_DATATABLE_3_INDEX: datatable2_centric + # Add more Arranger connections if needed + # NEXT_PUBLIC_ARRANGER_DATATABLE_4_API: http://arranger-datatable2:5051 + # NEXT_PUBLIC_ARRANGER_DATATABLE_4_DOCUMENT_TYPE: file + # NEXT_PUBLIC_ARRANGER_DATATABLE_4_INDEX: datatable2_centric + ``` + +### Validation + +After updating your docker-compose.yml file, verify the configuration: + +1. **Validate Port Mappings**: + + - Each Arranger instance should have a unique port + - Ports should not conflict with other services + +2. **Start the Services**: + + Run `make phase1` to start your services. + +3. **Check Service Health**: + + The deployment script should verify all services are running correctly. + +**Next Steps:** We will run through the process of adding a third data table to stage. + +## Step 4: Updating Stage (Optional) + +This step guides you through customizing Stage UI to incorporate multiple data exploration tables and update the theming to match your organization's branding. + +1. **Reset your environment** to ensure a clean state: + + ```bash + make reset + ``` + +2. **Run Stage complementary services** in development mode: + + ```bash + make stage-dev + ``` + +3. **Set up local Stage development environment**: + + To run Stage locally for development and customization: + + ```bash + # Navigate to the Stage directory + cd apps/stage + + # Copy the example environment file + cp .env.stageDev .env + + # Install dependencies + npm ci + + # Start the development server + npm run dev + ``` + + Your development server will be accessible at: http://localhost:3000 + +4. **Creating New Data Exploration Pages**: + +A) Create a new table component + +5. **Customize Stage Theming** (Optional): + +Update theme colors to match your organization's branding: + +Update the logo by replacing the image file at `apps/stage/public/images/logo.svg` + +Customize x.y.x + +**Next Steps:** Once you have completed the Stage customization, you're ready to upload your data to make it available in the Elasticsearch indices and visible in your data exploration tables. + +## Step 5: Uploading your data (To Be Updated) + +With Arranger, Stage, and Elasticsearch now configured, it's time to upload our data. We will use Conductor to transform our CSV files into Elasticsearch documents and upload them into the portal. + +### Installing Composer + +1. Move to the Conductor App directory: + + ``` + cd ./apps/conductor + ``` + +2. Run the following commands: + + ``` + npm install + npm run build + npm install -g + ``` + +3. **Validate:** From the root directory test that Conductor is working by running `conductor -h` you should be able to see help text outlining the available commands. + +4. Run the Conductor `upload` command to upload your data: + + ``` + conductor upload -f ./data/datatable1.csv -i datatable1-index + ``` + +
    + Command Breakdown + + In this command: + + - `-f ./data/datatable1.csv`: Specifies the input data file to upload + - `-i datatable1-index`: Specifies the target Elasticsearch index + + Additional options: + + - `-b, --batch-size `: Number of records to upload in each batch (default: 1000) + - `--delimiter `: CSV delimiter character (default: comma) + - `-o, --output `: Path for saving upload logs + + The command processes your CSV file, transforms it according to the index mapping structure, and uploads it to Elasticsearch in batches. + + Full command reference can be seen by running `conductor upload -h` +
    + +5. Monitor the upload process: + + The command will display progress information including: + + - Number of records processed + - Processing speed (records per second) + - Current upload status + - Error counts (if any) + +6. Repeat for additional datasets: + + If you have multiple datasets, repeat the upload command for each one, ensuring you specify the correct index name: + + ``` + conductor upload -f ./data/datatable2.csv -i datatable2-index + ``` + +### Validation + +To verify that your data was successfully uploaded: + +1. **Check the Conductor Output**: + + - Confirm the final message shows successful completion + - Verify the record count matches your expectations + - Check for any error messages + +2. **Verify Data in Elasticsearch**: + + - Open Elasticvue (http://localhost:9200) if you have it installed + - Navigate to Indices and select your index (e.g., `datatable1-index`) + - Browse documents to ensure they contain the expected data + - Run a sample query to test data retrieval + +3. **Check Data in Stage UI**: + - Navigate to http://localhost:3000 in your browser + - Go to your data exploration page + - Verify that your data appears in the table + - Test the search and filter functionality to ensure it works correctly + +If you encounter any issues: + +- Check Elasticsearch logs for indexing errors +- Verify your CSV file follows the guidelines outlined in Step 1 +- Ensure the index name in your upload command matches the index pattern in your mapping template + +**Next Steps:** With your data successfully uploaded and available in the Elasticsearch index, you can now fully explore and interact with your data through the Stage UI. diff --git a/apps/stage/public/docs/02-phaseTwo.md b/apps/stage/public/docs/02-phaseTwo.md new file mode 100644 index 00000000..7e62c957 --- /dev/null +++ b/apps/stage/public/docs/02-phaseTwo.md @@ -0,0 +1,816 @@ +# Phase Two + +## Overview + +**In this guide you will** extend your data management capabilities by implementing robust data submission validation, storage, and publication processes. + +**By the end of this guide you will be able to:** + +1. Validate data submissions using the Lectern dictionary schema manager +2. Complete an end-to-end data submission workflow with Lyric +3. Index validated data with Maestro +4. Access and view indexed data through the front-end UI configured in Phase One + +## Prerequisites + +**You will need:** + +- Your data table file(s) from Phase One (which may need to be divided into multiple schemas) +- A basic understanding of the following Overture services: + - [Lectern](https://docs.overture.bio/docs/core-software/Lectern/overview) - Dictionary schema management + - [Lyric](https://docs.overture.bio/docs/core-software/Lyric/overview/) - Submission workflow management + - [Maestro](https://docs.overture.bio/docs/core-software/Maestro/overview) - Data indexing service + +## Background Information + +Phase Two establishes your data submission and management workflow. This phase introduces tools to validate, store, and publish data while maintaining data integrity and consistency across your platform. + +Your Phase One data file may need to be divided into multiple segments represented as schemas to support distributed data collection from different teams or departments. + +### Architecture Overview + +The Phase Two architecture includes these components: + +![Phase 2 Architecture](/docs/images/phase2.png 'Phase 2 Architecture') + +| Component | Purpose | +| ---------------------------------------------------------------------------- | --------------------------------------------------------------------- | +| **[Lectern](https://docs.overture.bio/docs/core-software/Lectern/overview)** | Dictionary schema manager that defines and validates data structures | +| **[Lyric](https://docs.overture.bio/docs/core-software/Lyric/overview)** | Submission management system for data validation and workflow control | +| **[Maestro](https://docs.overture.bio/docs/core-software/Maestro/overview)** | Data indexing and storage service for submitted data | + +## Step 1: Deploy Phase 2 Services + +1. Run the deployment command: + + ```bash + make phase2 + ``` + +2. Verify service health: + - The deployment script should automatically verify that all services are running correctly + - Check the container logs if any service fails to start properly + +## Step 2: Set Up Data Dictionary + +In phase one we represented our data as a flat file with each row representing a single entity. Yet, data often involves complex relationships between entities. For example, a single donor can have multiple diagnoses, and this one-to-many relationship cannot be properly represented in a flat, single-table structure without data duplication or loss of information. + +When dealing with nested or hierarchical data structurers, a relational approach using multiple schemas is necessary to acaccuratelycuratley represent these relationships. + +### A) Prepare Your Tabular Data + +Depending on your data complexity you will need to organize information into multiple related schemas that can be properly linked. For this we will use Lectern, Overtures schema dictionary manager + +**Example: Clinical Data Schema Division** + +For demonstration purposes, we've separated our clinical cancer dataset from Phase One's `dataTable1.csv` into four logical files: + +![Enitity Relationship](/docs/images/entityRelationshipDiagram.png 'Entity Relationship Diagram') + +| File | Owner | Relationship | +| ----------------- | ------------------------------------------- | ---------------------------------------------------------------------------------------- | +| **donor.csv** | Demographic information and primary IDs | One donor can have many diagnoses | +| **diagnosis.csv** | Condition details with references to donors | Each diagnosis belongs to exactly one donor (via donor_id) | +| **treatment.csv** | Intervention details linked to diagnoses | Each treatment belongs to exactly one donor (via donor_id) | +| **followup.csv** | Outcome information linked to diagnoses | For simplicity each followup is associated with exactly one treatment (via treatment_id) | + +Based on the above we have taken our flat data file from phaseOne and segmented it accordingly: + +``` +data/ +├── datatable1.csv # Original combined file +└── segmentedDataTable1/ # Directory with segmented files + ├── donor.csv + ├── diagnosis.csv + ├── treatment.csv + └── followup.csv +``` + +Analyze your own data to determine if similar division is required. If not, you can proceed with a single schema representing your original data structure. + +Looking at the document in progress, I'll help refine and complete steps B and C for the Phase Two guide. These steps focus on generating and customizing a Lectern dictionary schema from data files. + +### B) Generate the Dictionary + +Now that we have established our data structure and organized our files, we can proceed with creating our Lectern dictionary schema. + +1. To generate a base Lectern dictionary schema from multiple segmented data files, run: + + ```bash + composer -p generateLecternDictionary -f ./data/segmentedData/ -n example-dictionary -v 1.0 -o ./configs/lecternDictionaries/ + ``` + +2. For a single data file, you can point to your flat file: + + ```bash + composer -p generateLecternDictionary -f ./data/dataTable1.csv -n dataTableOneDictionary -v 1.0 -o ./configs/lecternDictionaries/ + ``` + +
    + Command Breakdown + + In this command: + + - `-p generateLecternDictionary`: Specifies the operation to generate a Lectern dictionary + - `-f ./data/segmentedData/`: Specifies the directory containing our segmented data files + - `-n example-dictionary`: Names the dictionary + - `-v 1.0`: Sets the dictionary version + - `-o ./configs/lecternDictionaries/`: Output directory for the generated dictionary + + The command analyzes the structure of input CSV files and creates a base data Lectern dictionary defining the structure of the dataset. Each file will be represented as a schema, with the file name used as the schema name in the generated dictionary. +
    + +3. After running the command, verify that the dictionary file was created in the output directory: + +### C) Review and Update the Lectern Dictionary + +The generated dictionary provides a basic structure derived from your CSV files. Now we'll review and update each component to improve data validation and establish entity relationships. + +#### 1. Dictionary Metadata + +We will first update our top-level dictionary metadata: + +```json +{ + "name": "example-dictionary", + "description": "A Lectern dictionary for Overture's Phase Two Prelude guide focused on clinical cancer data", + "version": "1.0", + "meta": { + "createdAt": "2025-03-20T10:30:00.000Z", + "createdBy": "Mitchell Shiell", + "primaryContact": "mshiell@oicr.on.ca" + } +} +``` + +#### 2. Schema Descriptions + +We will next update each schema with more descriptive information: + +
    +Click here to view our updated dictionary +```json +"schemas": [ + { + "name": "donor", + "description": "Core demographic information about donors. One donor can have multiple diagnoses, treatments, and followups.", + "fields": [ + // Schema fields... + ], + "meta": { + "sourceFile": "donor.csv", + "primaryEntity": true + } + }, + { + "name": "diagnosis", + "description": "Clinical diagnosis details linked to a donor via donor_id. Each diagnosis belongs to exactly one donor.", + "fields": [ + // Schema fields... + ], + "meta": { + "sourceFile": "diagnosis.csv" + } + }, + { + "name": "treatment", + "description": "Treatment information linked to a donor and diagnosis. Each treatment belongs to exactly one donor.", + "fields": [ + // Schema fields... + ], + "meta": { + "sourceFile": "treatment.csv" + } + }, + { + "name": "followup", + "description": "Follow-up assessment information linked to treatments and donors. Each followup is associated with exactly one treatment.", + "fields": [ + // Schema fields... + ], + "meta": { + "sourceFile": "followup.csv" + } + } +] +``` +
    + +#### 3. Field Definitions + +Review and update field definitions to include proper data types, validation rules, and meaningful descriptions. Here are some examples of how to enhance field definitions: + +
    +Click here to view examples of updated fields +```json +"fields": [ + { + "name": "donor_id", + "description": "Unique identifier for a donor across the system", + "valueType": "string", + "restrictions": { + "required": true, + "unique": true, + "regex": "^DO\\d{4}$" + }, + "meta": { + "displayName": "Donor ID", + "examples": ["DO0599", "DO0600"] + } + }, + { + "name": "age_at_diagnosis", + "description": "Age of the donor at the time of diagnosis in years", + "valueType": "integer", + "restrictions": { + "required": true, + "range": {"min": 0, "max": 120} + }, + "meta": { + "displayName": "Age at Diagnosis", + "units": "years" + } + }, + { + "name": "vital_status", + "description": "Current vital status of the donor", + "valueType": "string", + "restrictions": { + "required": true, + "codeList": [ + {"code": "Alive", "description": "Donor is alive at last follow-up"}, + {"code": "Deceased", "description": "Donor is deceased"} + ] + }, + "meta": { + "displayName": "Vital Status" + } + } +] +``` +
    + +For more information on Lectern validation rules see our [preliminary Lectern documentation found here](https://github.com/overture-stack/lectern/blob/develop/docs/dictionary-reference.md) + +#### 4. Defining Entity Relationships + +The `foreignKey` restriction establishes relationships between different schemas in your Lectern dictionary: + +```json +"restrictions": { + "foreignKey": [ + { + "schema": "donor", + "mappings": [{ "local": "donor_id", "foreign": "donor_id" }] + } + ] +} +``` + +
    +Syntax Breakdown + +- The `foreignKey` field defines a parent-child relationship between two schemas + - `"schema": "donor"` specifies that this schema references the "donor" schema + - `"mappings"` indicates which fields connect the two schemas: + - `"local": "donor_id"` is the field in the current schema + - `"foreign": "donor_id"` is the field in the referenced (donor) schema + +This constraint ensures that every value in the current schema's `donor_id` field must exist in the `donor_id` field of the donor schema. For example, you cannot add a diagnosis record with a donor ID that doesn't exist in the donor table, maintaining data integrity across your related schemas. + +
    + +We will add foreign key constraints to establish the relationships diagrammed earlier: + +
    +Click here to view the updated dictionary +```json +"schemas": [ + { + "name": "donor", + "description": "Core demographic information about donors. One donor can have multiple diagnoses, treatments, and followups.", + "fields": [ + // Fields... + ], + "restrictions": { + "primaryKey": ["donor_id"] + }, + "meta": { + "sourceFile": "donor.csv", + "primaryEntity": true + } + }, + { + "name": "diagnosis", + "description": "Clinical diagnosis details linked to a donor via donor_id. Each diagnosis belongs to exactly one donor.", + "fields": [ + // Fields... + ], + "restrictions": { + "primaryKey": ["diagnosis_id"], + "foreignKey": [ + { + "schema": "donor", + "mappings": [{ "local": "donor_id", "foreign": "donor_id" }] + } + ] + }, + "meta": { + "sourceFile": "diagnosis.csv" + } + }, + { + "name": "treatment", + "description": "Treatment information linked to a donor and diagnosis. Each treatment belongs to exactly one donor.", + "fields": [ + // Fields... + ], + "restrictions": { + "primaryKey": ["treatment_id"], + "foreignKey": [ + { + "schema": "donor", + "mappings": [{ "local": "donor_id", "foreign": "donor_id" }] + } + ] + }, + "meta": { + "sourceFile": "treatment.csv" + } + }, + { + "name": "followup", + "description": "Follow-up assessment information linked to treatments and donors. Each followup is associated with exactly one treatment.", + "fields": [ + // Fields... + ], + "restrictions": { + "primaryKey": ["followup_id"], + "foreignKey": [ + { + "schema": "treatment", + "mappings": [{ "local": "treatment_id", "foreign": "treatment_id" }] + } + ] + }, + "meta": { + "sourceFile": "followup.csv" + } + } +] +``` + +
    + +#### 5. Save your updated dictionary + +The Lectern dictionary is now properly configured with appropriate schemas, field definitions, and entity relationships that accurately represent our data model. In the next steps, we will update lectern with our dictionary and then use this dictionary to validate and process data submissions through Lyric and Maestro. + +
    +Click here to view the completed dictionary + +``` +{ + "name": "example-dictionary", + "description": "A Lectern dictionary for Overture's Phase Two Prelude guide focused on clinical cancer data", + "version": "1.0", + "meta": { + "createdAt": "2025-03-20T10:30:00.000Z", + "createdBy": "Mitchell Shiell", + "primaryContact": "mshiell@oicr.on.ca" + }, + "schemas": [ + { + "name": "donor", + "description": "Core demographic information about donors. One donor can have multiple diagnoses, treatments, and followups.", + "fields": [ + { + "name": "donor_id", + "description": "Unique identifier for a donor across the system", + "valueType": "string", + "restrictions": { + "required": true, + "unique": true, + "regex": "^DO\\d{4}$" + }, + "meta": { + "displayName": "Donor ID", + "examples": ["DO0599", "DO0600"] + } + }, + { + "name": "gender", + "description": "Gender of the donor", + "valueType": "string", + "restrictions": { + "required": true, + "codeList": [ + {"code": "Male", "description": "Male donor"}, + {"code": "Female", "description": "Female donor"} + ] + }, + "meta": { + "displayName": "Gender" + } + }, + { + "name": "vital_status", + "description": "Current vital status of the donor", + "valueType": "string", + "restrictions": { + "required": true, + "codeList": [ + {"code": "Alive", "description": "Donor is alive at last follow-up"}, + {"code": "Deceased", "description": "Donor is deceased"} + ] + }, + "meta": { + "displayName": "Vital Status" + } + } + ], + "restrictions": { + "primaryKey": ["donor_id"] + }, + "meta": { + "createdAt": "2025-03-20T16:11:06.493Z", + "sourceFile": "donor.csv", + "primaryEntity": true + } + }, + { + "name": "diagnosis", + "description": "Clinical diagnosis details linked to a donor via donor_id. Each diagnosis belongs to exactly one donor.", + "fields": [ + { + "name": "diagnosis_id", + "description": "Unique identifier for a diagnosis record", + "valueType": "string", + "restrictions": { + "required": true, + "unique": true, + "regex": "^PD\\d{6}$" + }, + "meta": { + "displayName": "Diagnosis ID", + "examples": ["PD059901", "PD059902"] + } + }, + { + "name": "donor_id", + "description": "Reference to the donor this diagnosis belongs to", + "valueType": "string", + "restrictions": { + "required": true, + "regex": "^DO\\d{4}$" + }, + "meta": { + "displayName": "Donor ID", + "examples": ["DO0599", "DO0600"] + } + }, + { + "name": "primary_site", + "description": "Primary anatomical site of the diagnosed condition", + "valueType": "string", + "restrictions": { + "required": true + }, + "meta": { + "displayName": "Primary Site", + "examples": ["Breast", "Lung", "Prostate gland"] + } + }, + { + "name": "age_at_diagnosis", + "description": "Age of the donor at the time of diagnosis in years", + "valueType": "integer", + "restrictions": { + "required": true, + "range": {"min": 0, "max": 120} + }, + "meta": { + "displayName": "Age at Diagnosis", + "units": "years" + } + }, + { + "name": "cancer_type", + "description": "Type of cancer diagnosed using ICD-O-3 topography codes", + "valueType": "string", + "restrictions": { + "required": true, + "regex": "^C[0-9]{2}(\\.[0-9])?$" + }, + "meta": { + "displayName": "Cancer Type", + "examples": ["C50.1", "C34.1", "C61"] + } + }, + { + "name": "staging_system", + "description": "Staging system used for cancer classification", + "valueType": "string", + "restrictions": { + "required": true + }, + "meta": { + "displayName": "Staging System", + "examples": ["AJCC 8th edition", "FIGO staging system", "Gleason grade group system"] + } + }, + { + "name": "stage", + "description": "Stage of cancer according to the specified staging system", + "valueType": "string", + "restrictions": { + "required": true + }, + "meta": { + "displayName": "Stage", + "examples": ["Stage I", "Stage IV", "Grade Group 2"] + } + } + ], + "restrictions": { + "primaryKey": ["diagnosis_id"], + "foreignKey": [ + { + "schema": "donor", + "mappings": [{ "local": "donor_id", "foreign": "donor_id" }] + } + ] + }, + "meta": { + "createdAt": "2025-03-20T16:11:06.491Z", + "sourceFile": "diagnosis.csv" + } + }, + { + "name": "treatment", + "description": "Treatment information linked to a donor and diagnosis. Each treatment belongs to exactly one donor.", + "fields": [ + { + "name": "donor_id", + "description": "Reference to the donor receiving this treatment", + "valueType": "string", + "restrictions": { + "required": true, + "regex": "^DO\\d{4}$" + }, + "meta": { + "displayName": "Donor ID", + "examples": ["DO0599", "DO0600"] + } + }, + { + "name": "treatment_id", + "description": "Unique identifier for a treatment record", + "valueType": "string", + "restrictions": { + "required": true, + "unique": true, + "regex": "^TR\\d{6}$" + }, + "meta": { + "displayName": "Treatment ID", + "examples": ["TR059901", "TR059902"] + } + }, + { + "name": "treatment_type", + "description": "Type of treatment administered", + "valueType": "string", + "restrictions": { + "required": true, + "codeList": [ + {"code": "Surgery", "description": "Surgical procedure"}, + {"code": "Radiation therapy", "description": "Radiation therapy"}, + {"code": "Chemotherapy", "description": "Chemical treatment"}, + {"code": "Hormonal therapy", "description": "Hormone-based therapy"} + ] + }, + "meta": { + "displayName": "Treatment Type" + } + }, + { + "name": "treatment_start", + "description": "Days since diagnosis when treatment started", + "valueType": "integer", + "restrictions": { + "required": true, + "range": {"min": 0} + }, + "meta": { + "displayName": "Treatment Start", + "units": "days" + } + }, + { + "name": "treatment_duration", + "description": "Duration of the treatment in days", + "valueType": "integer", + "restrictions": { + "required": true, + "range": {"min": 1} + }, + "meta": { + "displayName": "Treatment Duration", + "units": "days" + } + }, + { + "name": "treatment_response", + "description": "Response to the treatment", + "valueType": "string", + "restrictions": { + "required": true, + "codeList": [ + {"code": "Complete response", "description": "Complete disappearance of disease"}, + {"code": "Partial response", "description": "Reduction in disease burden"}, + {"code": "Disease progression", "description": "Increase in disease burden"} + ] + }, + "meta": { + "displayName": "Treatment Response" + } + } + ], + "restrictions": { + "primaryKey": ["treatment_id"], + "foreignKey": [ + { + "schema": "donor", + "mappings": [{ "local": "donor_id", "foreign": "donor_id" }] + } + ] + }, + "meta": { + "createdAt": "2025-03-20T16:11:06.495Z", + "sourceFile": "treatment.csv" + } + }, + { + "name": "followup", + "description": "Follow-up assessment information linked to treatments and donors. Each followup is associated with exactly one treatment.", + "fields": [ + { + "name": "treatment_id", + "description": "Reference to the treatment this followup is associated with", + "valueType": "string", + "restrictions": { + "required": true, + "regex": "^TR\\d{6}$" + }, + "meta": { + "displayName": "Treatment ID", + "examples": ["TR059901", "TR059902"] + } + }, + { + "name": "followup_id", + "description": "Unique identifier for a followup record", + "valueType": "string", + "restrictions": { + "required": true, + "unique": true, + "regex": "^FO\\d{6}$" + }, + "meta": { + "displayName": "Followup ID", + "examples": ["FO059901", "FO059902"] + } + }, + { + "name": "followup_interval", + "description": "Time since treatment completion in days", + "valueType": "integer", + "restrictions": { + "required": true, + "range": {"min": 0} + }, + "meta": { + "displayName": "Followup Interval", + "units": "days" + } + }, + { + "name": "disease_status", + "description": "Status of the disease at followup", + "valueType": "string", + "restrictions": { + "required": true, + "codeList": [ + {"code": "No evidence of disease", "description": "No clinical evidence of disease"}, + {"code": "Complete remission", "description": "Complete disappearance of all signs of cancer"}, + {"code": "Stable", "description": "Cancer is neither decreasing nor increasing"}, + {"code": "Progression NOS", "description": "Disease has worsened"} + ] + }, + "meta": { + "displayName": "Disease Status" + } + } + ], + "restrictions": { + "primaryKey": ["followup_id"], + "foreignKey": [ + { + "schema": "treatment", + "mappings": [{ "local": "treatment_id", "foreign": "treatment_id" }] + } + ] + }, + "meta": { + "createdAt": "2025-03-20T16:11:06.494Z", + "sourceFile": "followup.csv" + } + } + ] +} +``` + +
    + +## Step 3: Upload the Dictionary to Lectern + +```bash +conductor lecternUpload -s ./configs/lecternDictionaries/dictionary.json -u http://localhost:3031 +``` + +
    +Command Breakdown + +Lectern Upload Command: + +- `-s`, `--schema-file` Schema JSON file to upload (required) +- `-u`, `--lectern-url` Lectern server URL (default: http://localhost:3031) +- `-t`, `--auth-token` Authentication token (optional) +- `-o`, `--output` Output directory for logs + +Example: `conductor lecternUpload -s data-dictionary.json` + +This step uploads the dictionary to Lectern. + +
    + +## Step 4: Register the Lectern Dictionary with Lyric + +Register your updated dictionary with Lyric: + +```bash +conductor lyricRegister -c clinical-cancer --dict-name example-dictionary -v 1.0 -e donor +``` + +
    +Command Breakdown + +Lyric Register Dictionary Command: + +- `-u`, `--lyric-url` Lyric server URL (default: http://localhost:3030) +- `-c`, `--category-name` The category name that will correspond to this dictionary +- `--dict-name` Dictionary name +- `-v`, `--dictionary-version` Dictionary version +- `-e`, `--default-centric-entity` Default centric entity (default: clinical_data) + +Example: `conductor lyricRegister -c my-category --dict-name my-dictionary -v 2.0` + +This step updates the dictionary with Lyric, preparing it for data submission and validation. + +
    + +## Step 5: Upload Data to Lyric + +To upload the data files: + +```bash +conductor lyricUpload -d ./data/segmentedData/-c clinical-cancer -g OICR +``` + +
    + Command Breakdown + +In these commands: + +- `-d, --data-directory `: Path to the specific CSV data file +- `-c, --category-id clinical-cancer`: Category ID for the submission +- `-g, --organization cancer-center`: Organization name submitting the data +- Additional options include: + - `-u, --lyric-url `: Lyric server URL + - `-l, --lectern-url `: Lectern server URL + - `-m, --max-retries `: Maximum retry attempts + +
    + +## Additional Resources + +- [Lectern Documentation](https://docs.overture.bio/docs/core-software/Lectern/overview) +- [Lyric Documentation](https://docs.overture.bio/docs/core-software/Lyric/overview/) +- [Maestro Documentation](https://docs.overture.bio/docs/core-software/Maestro/overview) + +Support & Contributions + +For support, feature requests, and bug reports, please see our [Support Guide](/support). + +For detailed information on how to contribute to this project, please see our Contributing Guide. diff --git a/apps/stage/public/docs/03-phaseThree.md b/apps/stage/public/docs/03-phaseThree.md new file mode 100644 index 00000000..1a043d8d --- /dev/null +++ b/apps/stage/public/docs/03-phaseThree.md @@ -0,0 +1,543 @@ +# Phase Three + +## Overview + +**This guide is for** those in phase three of Prelude's deployment process. The primary goal is to implement file management capabilities by setting up Song and Score, which allow you to track, validate, and store genomic files and their associated metadata. + +**By the end of this guide you will be able to:** + +1. Define and configure file metadata schemas for Song +2. Upload and manage files using Score's object storage integration +3. Complete an end-to-end file submission and retrieval workflow + +## Prerequisites and Requirements + +**You will need:** + +- Sample files to upload (BAM, FASTQ, VCF, or other research data files) +- It will help to have a basic understanding of the following Overture services: + - [Song](https://docs.overture.bio/docs/core-software/Song/overview) - Metadata tracking service for files + - [Score](https://docs.overture.bio/docs/core-software/Score/overview) - File transfer service for object storage + - [Minio](https://min.io/) - Local object storage service (S3-compatible) + +## Background Information + +Phase Three introduces file management capabilities to your Overture platform. While Phases One and Two focused on tabular data, Phase Three extends the platform to handle large files like genomic sequences, images, and other research artifacts. + +The Song and Score services work together to provide a complete file management solution: + +- **Song** tracks metadata about your files (description, file type, checksums, etc.) +- **Score** handles the actual file transfer to and from object storage + +This separation of concerns allows for efficient file handling with rich metadata capabilities. + +### Architecture Overview + +Phase Three adds file management components to the existing architecture: + +![Phase 3 Architecture Diagram](/docs/images/phase3.png "Phase 3 Architecture Diagram") + +> **Note:** Full integration between file metadata and tabular data from Phase Two will be included in a future update. For more information, see the footnotes section at the bottom of this page. + +| Component | Purpose | +| ------------------------------------------------------------------------ | --------------------------------------------------------------- | +| **[Song](https://docs.overture.bio/docs/core-software/Song/overview)** | Tracks and validates file metadata | +| **[Score](https://docs.overture.bio/docs/core-software/Score/overview)** | Manages secure file transfer to and from object storage | +| **Minio** | S3-compatible object storage for files (local development only) | + +## Step 1: Deploy Phase 3 Services + +Let's start by deploying the Phase 3 services: + +1. Run the deployment command: + + ```bash + make phase3 + ``` + +2. Verify service health: + + The deployment script should automatically verify that all services are running correctly. You should see the following components running: + + - Song (file metadata service) + - Score (file transfer service) + - Minio (object storage) + - SongDb (Postgres Db for Song Metadata) + - All previously deployed services from Phases 1 and 2 + +## Step 2: Define Your File Metadata Structure + +Before uploading files, we need to understand how file metadata is structured in Song. + +### A) Understanding File Metadata Structure + +Song uses a hierarchical model to organize file metadata: + +1. **Study**: A top-level container for related data (e.g., a research project) +2. **Analysis**: A group of related files with common metadata +3. **File**: Individual file metadata (name, type, size, checksum) + +This structure allows for flexible organization of files based on your research needs. + +### B) Custom Analysis Schemas in Song + +Song uses Analysis Schemas to validate submitted metadata. Let's understand how to create one: + +#### Minimal Example + +A minimal Analysis Schema contains just the required structure: + +```json +{ + "name": "sequencing_experiment", + "options": {}, + "schema": { + "type": "object", + "required": ["experiment"], + "properties": { + "experiment": {} + } + } +} +``` + +#### Schema Options + +The `options` property defines extra validations for your analysis schema: + +```json +"options": { + "fileTypes": ["bam", "cram"], + "externalValidations": [ + { + "url": "http://localhost:8099/", + "jsonPath": "experiment.someId" + } + ] +} +``` + +- **File Types**: Restrict which file types are allowed in this analysis + + ```json + "fileTypes": ["bam", "cram"] + ``` + + Setting this to an empty array `[]` allows any file type. + +- **External Validations**: Validate metadata against external services + + ```json + "externalValidations": [ + { + "url": "http://example.com/{study}/donor/{value}", + "jsonPath": "experiment.donorId" + } + ] + ``` + + This example validates a donor ID against an external service. When submitting an analysis with `"donorId": "id01"` in a study called "ABC123", Song would send a validation request to `http://example.com/ABC123/donor/id01`. + + > **Note**: The URL may cause errors if it contains tokens matching the `{word}` format other than `{study}` and `{value}` + +## Step 3: Prepare Your Files for Upload + +Now prepare some mock files for testing our upload to Song and Score: + +### A) Organize Your Files + +1. Create a directory for your files: + + ```bash + mkdir -p data/fileData/upload + ``` + +2. Place your data files in this directory. Alternatively for testing, you can create a sample file: + + ```bash + # Create a simple test file + dd if=/dev/urandom of=data/fileData/upload/test_rg3.bam bs=1M count=10 + ``` + + This command creates a 10MB random file. Note the file size (10MB = 10485760 bytes), as you'll need this for your metadata. + +3. Calculate the MD5 checksum for each file: + + ```bash + md5sum data/fileData/upload/test_rg3.bam > data/fileData/upload/test_rg3.bam.md5 + ``` + + This step is critical for file integrity verification. Song will validate that the file you upload matches the checksum provided in your metadata. + +The file size and MD5 checksum are both required in your actual metadata submission. When you create your metadata.json file for submission later, you'll need to include both the accurate file size and the MD5 checksum calculated here. + +### B) Creating the File Metadata Template + +Create a file metadata template that serves as an example to generate your Song schema. This is not a submission file, but rather a representative sample of your data structure: + +```json +{ + "analysisType": { + "name": "sequencing_experiment", + "version": 1 + }, + "experiment": { + "platform": "ILLUMINA", + "instrumentModel": "HiSeq 2500", + "libraryStrategy": "WGS", + "sequencingCenter": "OICR" + }, + "sample": { + "submitterSampleId": "SA-123", + "matchedNormalSubmitterSampleId": "SA-456", + "sampleType": "DNA", + "specimen": { + "submitterSpecimenId": "SP-123", + "specimenType": "Normal", + "donor": { + "submitterDonorId": "DO0599", + "gender": "Male" + } + } + }, + "files": [ + { + "fileName": "test_rg3.bam", + "fileSize": 133684363564, + "fileType": "BAM", + "fileMd5sum": "9a793e90d0d1e11301ea8da996446e59", + "fileAccess": "controlled" + } + ] +} +``` + +This template will be used next with the `generateSongSchema` command to create a validation schema. When creating this template, include field structures and examples that represent your typical data, as these will inform the validation rules in the generated schema. + +## Step 4: Generate a Song Schema Using Composer + +Now we'll use Composer to generate a Song schema that will validate metadata submissions: + +```bash +composer -p generateSongSchema -f ./data/fileData/file-metadata.json -o ./configs/songSchemas/ -n sequencing_experiment --file-types bam cram +``` + +
    +Command Breakdown + +In this command: + +- `-p generateSongSchema`: Specifies the operation to generate a Song schema +- `-f ./data/fileData/file-metadata.json`: Specifies the input metadata description file +- `-o ./configs/songSchemas/`: Output directory for the generated schema +- `-n sequencing_experiment`: Names the schema +- `--file-types bam cram`: Restricts the allowed file types to BAM and CRAM files + +Additional options: + +- You can add more file types by adding them to the list: `--file-types bam cram vcf fastq` +
    + +Review the generated schema in `./configs/songSchemas/sequencing_experiment.json` and customize as needed, particularly the `options` section to add external validations if required. + +## Step 5: Create a Study and Register Schema + +### A) Create a Study in Song + +Before uploading files, you need to create a study in Song: + +```bash +conductor songCreateStudy -i cancer-genomics -n "Cancer Genomics Research Study" -g "My Organization" --description "A study for cancer genomics data" +``` + +
    +Command Breakdown + +In this command: + +- `-i cancer-genomics`: The study ID +- `-n "Cancer Genomics Research Study"`: The study name +- `-g "My Organization"`: The organization conducting the study +- `--description "A study for cancer genomics data"`: A description of the study +- Additional options: + - `-u, --song-url `: Song server URL (default: http://localhost:8080) + - `-t, --auth-token `: Authentication token (default: 123) + - `--force`: Force creation even if study exists + +This command creates a container study in Song where all your file metadata will be organized. + +
    + +### B) Register Schema with Song + +Now register your schema with Song: + +```bash +conductor songUploadSchema -s ./configs/songSchemas/sequencing_experiment.json +``` + +
    +Command Breakdown + +In this command: + +- `-s, --schema-file `: Path to the schema file +- Additional options: + - `-u, --song-url `: Song server URL (default: http://localhost:8080) + - `-t, --auth-token `: Authentication token (default: 123) + - `-o, --output `: Output directory for logs + +This command registers your schema with Song, enabling it to validate metadata submissions against this schema. + +
    + +## Step 6: Upload Files Using Song and Score + +We'll use the individual Song and Score commands to submit metadata, upload files, and publish the analysis: + +### A) Create the Submission Metadata + +Create a file called `analysis.json` in the `data/fileData/upload` directory: + +```json +{ + "studyId": "cancer-genomics", + "analysisType": { + "name": "sequencing_experiment", + "version": 1 + }, + "experiment": { + "platform": "ILLUMINA", + "instrumentModel": "HiSeq 2500", + "libraryStrategy": "WGS", + "sequencingCenter": "OICR" + }, + "samples": [ + { + "submitterSampleId": "SA-123", + "matchedNormalSubmitterSampleId": "SA-456", + "sampleType": "DNA", + "specimen": { + "submitterSpecimenId": "SP-123", + "specimenType": "Normal", + "donor": { + "submitterDonorId": "DO0599", + "gender": "Male" + } + } + } + ], + "files": [ + { + "fileName": "test_rg3.bam", + "fileType": "BAM", + "fileMd5sum": "REPLACE_WITH_ACTUAL_MD5", + "fileAccess": "controlled" + } + ] +} +``` + +Replace `"REPLACE_WITH_ACTUAL_MD5"` with the actual MD5 checksum from the previous step. + +### B) Step-by-Step Submission + +You'll need to perform each step of the process separately: + +1. **Submit the analysis metadata to Song**: + + ```bash + conductor songSubmitAnalysis -a ./data/fileData/upload/analysis.json -i cancer-genomics + ``` + +
    + Command Breakdown + + In this command: + + - `-a, --analysis-file `: Analysis JSON file to submit + - `-i, --study-id `: Study ID + - Additional options: + - `-u, --song-url `: Song server URL (default: http://localhost:8080) + - `--allow-duplicates`: Allow duplicate analysis submissions + - `-t, --auth-token `: Authentication token (default: 123) + - `--force`: Force studyId from command line instead of from file +
    + + This command will return an analysis ID. Make sure to save it for the next steps. + +2. **Upload the files to Score**: + + ```bash + conductor scoreManifestUpload -a ANALYSIS_ID -d ./data/fileData/upload + ``` + + Replace `ANALYSIS_ID` with the ID from the previous step. + +
    + Command Breakdown + + In this command: + + - `-a, --analysis-id `: Analysis ID from Song submission + - `-d, --data-dir `: Directory containing data files + - Additional options: + - `-o, --output-dir `: Directory for manifest output (default: ./output) + - `-m, --manifest-file `: Path for manifest file + - `-u, --song-url `: Song server URL (default: http://localhost:8080) + - `-s, --score-url `: Score server URL (default: http://localhost:8087) + - `-t, --auth-token `: Authentication token (default: 123) +
    + +3. **Publish the analysis**: + + ```bash + conductor songPublishAnalysis -a ANALYSIS_ID -i cancer-genomics + ``` + + Replace `ANALYSIS_ID` with the same ID used in the upload step. + +
    + Command Breakdown + + In this command: + + - `-a, --analysis-id `: Analysis ID to publish + - `-i, --study-id `: Study ID + - Additional options: + - `-u, --song-url `: Song server URL (default: http://localhost:8080) + - `-t, --auth-token `: Authentication token (default: 123) + - `--ignore-undefined-md5`: Ignore files with undefined MD5 checksums +
    + +## Step 7: Verify and Access Your Files + +### A) Verify Files in Song + +Check that your files are properly registered in Song: + +```bash +curl -X GET http://localhost:8080/studies/cancer-genomics/analysis/ANALYSIS_ID +``` + +Replace `ANALYSIS_ID` with your actual analysis ID. + +You should see a JSON response with all the metadata about your analysis and files. + +### B) Download Files Using Score + +To download files that have been uploaded and published: + +```bash +# Create a directory for your downloads +mkdir -p data/fileData/download + +# Download the analysis files +conductor scoreManifestUpload -a ANALYSIS_ID -d ./data/fileData/download --download-only +``` + +Replace `ANALYSIS_ID` with your actual analysis ID. + +
    +Command Breakdown + +In this command: + +- `-a, --analysis-id `: Analysis ID to download +- `-d, --data-dir `: Directory to save downloaded files +- `--download-only`: Only download files, don't upload +- Additional options: + - `-u, --song-url `: Song server URL (default: http://localhost:8080) + - `-s, --score-url `: Score server URL (default: http://localhost:8087) + - `-t, --auth-token `: Authentication token (default: 123) + +This command downloads all files associated with the specified analysis. + +
    + +### C) Explore Files in Minio + +You can also explore your uploaded files in the Minio object storage interface: + +1. Open http://localhost:9001 in your browser +2. Login with: + - Username: `minio` + - Password: `minio123` +3. Navigate to the `score-data` bucket to see your uploaded files + +## Step 8: Configure Stage for File Access (Optional) + +To enable file access through the Stage portal: + +1. Update Stage's configuration in your docker-compose.yml: + + ```yaml + stage: + environment: + # Add file download configuration + NEXT_PUBLIC_DOWNLOAD_ENABLED: "true" + NEXT_PUBLIC_DOWNLOAD_URL: "http://localhost:8087/download" + NEXT_PUBLIC_SONG_URL: "http://localhost:8080" + ``` + +2. Restart Stage: + + ```bash + docker-compose restart stage + ``` + +3. Navigate to your data exploration page in Stage to see file download options + +## Advanced Topics + +### Linking Files to Clinical Data + +> **Note:** Full integration between file metadata and tabular data from Phase Two will be included in a future update. + +In future releases, you'll be able to create a comprehensive data model by linking your file metadata with clinical data from Phase Two. This will typically involve: + +1. Using common identifiers (e.g., donor IDs, sample IDs) in both systems +2. Creating a Maestro configuration that indexes both clinical and file data +3. Building unified search experiences in Stage + +For now, focus on configuring Song and Score correctly to establish your file management capabilities. + +### Creating Complex File Schemas + +For more complex research data, you may need to create more detailed schemas. Refer to the [Song Schema documentation](https://github.com/overture-stack/SONG/blob/develop/song-docs/schemas/example-schema.json) for advanced examples. + +## Troubleshooting + +### Common Issues and Solutions + +1. **Metadata Validation Errors** + + If you encounter validation errors when submitting metadata: + + - Check that your metadata matches your schema definition + - Ensure all required fields are provided + - Verify the schema version matches what's registered in Song + +2. **File Upload Failures** + + If file uploads fail: + + - Verify file checksums match what's declared in the metadata + - Check permissions on the upload directory + - Ensure Score can connect to the object storage + +3. **File Download Issues** + + If downloads fail: + + - Check that the analysis is published + - Verify Score configuration is correct + - Ensure the output directory is writable + +## Additional Resources + +- [Song Documentation](https://docs.overture.bio/docs/core-software/Song/overview) +- [Score Documentation](https://docs.overture.bio/docs/core-software/Score/overview) +- [Minio Documentation](https://docs.min.io/) + +For support, feature requests, and bug reports, please see our [Support Guide](/support). diff --git a/apps/stage/public/docs/04-phaseFour.md b/apps/stage/public/docs/04-phaseFour.md new file mode 100644 index 00000000..fdedf978 --- /dev/null +++ b/apps/stage/public/docs/04-phaseFour.md @@ -0,0 +1,7 @@ +# Phase Four + +## Coming Soon + +Phase Four will guide you through setting up Keycloak to handle the authorization and authentication of users and applications. This will be included within Prelude version 2.0.0 which is targeted for completetion by July 2025. + +![Phase4](/docs/images/phase4.png "Phase 4 architecture") diff --git a/apps/stage/public/docs/10-support.md b/apps/stage/public/docs/10-support.md new file mode 100644 index 00000000..3559abe7 --- /dev/null +++ b/apps/stage/public/docs/10-support.md @@ -0,0 +1,56 @@ +# Support + +## Support + +We take pride in our software and are passionate about helping others use them. If you are looking for help or collaboration, here is how you can get in touch. + +## GitHub Discussions + +Our primary platform for community support, feature requests, and general discussions is GitHub Discussions. This allows us to keep all conversations in one place and make them easily searchable for future reference. + +## Contacting by email + +If you have a collaboration or business enquiry you can reach us by email at **contact@overture.bio** + +### Getting Help + +- [Create a Support Discussion](https://github.com/overture-stack/docs/discussions/categories/support) + - If you need assistance with Overture, please create a new discussion in our support category. + - Before creating a new discussion, please search existing discussions to see if your question has already been answered. + +### Feature Requests + +We love hearing your ideas for improving Overture! Before making a feature request, please check our current roadmap to see if your idea is already planned: + +- [Overture feature roadmap](https://github.com/orgs/overture-stack/projects/11/views/1) + +If your idea isn't on the roadmap, feel free to create a new discussion in our Ideas category: + +- [Submit a Feature Request](https://github.com/overture-stack/docs/discussions/categories/ideas) + +## GitHub Issues + +We use GitHub Issues primarily for tracking confirmed bugs and ticketing development tasks. + +### Reporting Bugs + +If you come across a potential bug or issue, please post it as a GitHub support discussion first: + +- [**Report a Potential Bug**](https://github.com/overture-stack/docs/discussions/categories/support) + +This allows us to confirm the issue and gather more information if needed. If we determine that further development is required, we will create a GitHub Issue from your discussion post. + +## Staying Informed + +- [Release Announcements](https://github.com/overture-stack/docs/discussions/categories/announcements) + - To stay up-to-date with the latest Overture releases and updates, keep an eye on our Announcements category in our GitHub Discussions. + +## Community Guidelines + +When participating in our community, please adhere to the following guidelines: + +1. Be respectful and inclusive of all community members. +2. Provide as much relevant information as possible when asking for help. +3. Use clear and descriptive titles for your discussions and issues. +4. Search existing discussions before creating a new one to avoid duplicates. +5. Follow the GitHub Community Guidelines and abide by our [code of conduct](https://docs.overture.bio/community/code-of-conduct). diff --git a/apps/stage/public/docs/11-contribution.md b/apps/stage/public/docs/11-contribution.md new file mode 100644 index 00000000..a46a00f6 --- /dev/null +++ b/apps/stage/public/docs/11-contribution.md @@ -0,0 +1,95 @@ +# Contributing + +## Code of Conduct + +By participating in this project, you are expected to abide by our [Code of Conduct](https://docs.overture.bio/community/code-of-conduct). Please take the time to read it carefully before contributing. + +## Get Involved + +**Getting Started:** Our primary platform for community support, feature requests, and general discussions is [GitHub Discussions](https://github.com/overture-stack/docs/discussions). This allows us to keep all conversations in one place and make them easily searchable for future reference. + +- **Feature Requests & Proposals:** We love hearing your ideas for improving Overture! Feel free to [**submit a feature request**](https://github.com/overture-stack/docs/discussions/categories/ideas) by creating a new discussion in our Ideas category + +- **Reporting Bugs:** We use GitHub Issues primarily for tracking confirmed bugs and ticketing development tasks. If you come across a potential bug or issue, please first post it to our [**GitHub support discussion forum**](https://github.com/overture-stack/docs/discussions/categories/support). + - This allows us to confirm the issue and gather more information if needed. If we determine that further development is required, we will create and tag you into a GitHub Issue from your discussion post. + +## Our Development Process + +We use GitHub issues and pull requests for communication related to code changes. + +### Branch Organization + +We use the following standard branches: + +- `main` is for stable production code +- `develop` is the integration branch for new features + +## Pull Requests + +### Submitting a Pull Request + +We welcome and encourage pull requests from the community. To submit a pull request, please follow these steps: + +1. **Fork the Repository**: Fork the Overture repository on GitHub. +2. **Clone Your Fork**: Clone your forked repository to your local machine. +3. **Create a New Branch**: Create a new branch for your changes. Use lowercase and hyphens (e.g., `feature/user-authentication`). Include ticket/issue numbers when applicable (e.g., `feature/PROJ-123-user-authentication`). +4. **Make Your Changes**: Implement your changes and commit them to your branch. Write clear, concise commit messages in present tense (e.g., "Add feature" not "Added feature"). Reference issue numbers in commits when applicable. +5. **Push Your Changes**: Push your changes to your forked repository. +6. **Submit a Pull Request**: Open a pull request against the main repository. + +### Best Practices + +1. **Keep PRs as small as possible:** Focus on one feature or bug fix per pull request. Break large changes into smaller, more manageable pieces making it easier for reviewers to understand and approve your changes. + +2. **Use descriptive titles:** Start with a verb (e.g., "Add", "Fix", "Update", "Refactor"), briefly summarize the main purpose of the PR and include the issue number if applicable (e.g., "Fix user authentication bug (#123)"). + +3. **Describe how you tested it:** Explain the testing process you followed and mention any new automated tests you've added. + +4. **Provide a clear description:** Explain the purpose of your changes and list the main modifications you've made. Mention any potential side effects or areas that might need extra attention. + +5. **Link related issues:** Reference any related issues or pull requests. Use GitHub keywords to automatically link issues (e.g., "Closes #123", "Fixes #456"). +6. **Keep the PR's branch up-to-date:** Regularly rebase your branch on the latest main branch and resolve any merge conflicts promptly. + +7. **Respond to feedback:** Be open to suggestions and willing to make changes. Address all comments from reviewers. If you disagree with a suggestion, explain your reasoning politely. + +8. **Include documentation updates:** If your changes affect user-facing features, update or create and issue detailing the relevant changes need to the documentation. Where appropriate include inline comments for complex code sections. + +9. **Be patient:** Reviewers will likely be unable to respond immediately. However, feel free to follow up politely if you haven't received feedback after a reasonable time. + +### Using Draft Pull Requests + +Draft Pull Requests are an excellent way to document work in progress and facilitate early feedback. Use them to: + +- Organize your thoughts and process +- Share early work and ideas with the team +- Get feedback on implementation approaches before finalizing code +- Track progress on long-running features + +Guidelines for Draft Pull Requests: + +1. **Creation**: + - Open a pull request and select "Create draft pull request" + - Clearly mark the title with [WIP] or [DRAFT] prefix +2. **Description**: + - Outline the current state of the work + - List planned tasks or improvements + - Highlight areas where feedback is specifically needed +3. **Updates**: + - Regularly update the description or provide comments following commits with progress notes + +- Use task lists (using `- [ ]` in Markdown) to track completion of sub-tasks + +4. **Collaboration**: + - Encourage early feedback and discussion + - Use the pull request comments for design discussions +5. **Finalization**: + - Complete all planned work and address feedback + - Update tests and documentation + - Click "Ready for review" to move out of draft state + +### Merging a Pull Request + +- Ensure all CI checks pass +- Obtain the required number of approvals +- Use the project's specified merge strategy (Typically squash and merge) +- Delete the source branch after merging if no longer needed diff --git a/apps/stage/public/docs/images/DevelopmentPhases.png b/apps/stage/public/docs/images/DevelopmentPhases.png new file mode 100644 index 00000000..e1dc16dc Binary files /dev/null and b/apps/stage/public/docs/images/DevelopmentPhases.png differ diff --git a/apps/stage/public/docs/images/entityRelationshipDiagram.png b/apps/stage/public/docs/images/entityRelationshipDiagram.png new file mode 100644 index 00000000..cfbb8bcc Binary files /dev/null and b/apps/stage/public/docs/images/entityRelationshipDiagram.png differ diff --git a/apps/stage/public/docs/images/generateArrangerConfigs.png b/apps/stage/public/docs/images/generateArrangerConfigs.png new file mode 100644 index 00000000..54d912d5 Binary files /dev/null and b/apps/stage/public/docs/images/generateArrangerConfigs.png differ diff --git a/apps/stage/public/docs/images/generateElasticsearchMapping.png b/apps/stage/public/docs/images/generateElasticsearchMapping.png new file mode 100644 index 00000000..3dbb863e Binary files /dev/null and b/apps/stage/public/docs/images/generateElasticsearchMapping.png differ diff --git a/apps/stage/public/docs/images/generateLecternDictionary.png b/apps/stage/public/docs/images/generateLecternDictionary.png new file mode 100644 index 00000000..3fb9a439 Binary files /dev/null and b/apps/stage/public/docs/images/generateLecternDictionary.png differ diff --git a/apps/stage/public/docs/images/phase1.png b/apps/stage/public/docs/images/phase1.png new file mode 100644 index 00000000..5c9e7201 Binary files /dev/null and b/apps/stage/public/docs/images/phase1.png differ diff --git a/apps/stage/public/docs/images/phase2.png b/apps/stage/public/docs/images/phase2.png new file mode 100644 index 00000000..1e11ed34 Binary files /dev/null and b/apps/stage/public/docs/images/phase2.png differ diff --git a/apps/stage/public/docs/images/phase3.png b/apps/stage/public/docs/images/phase3.png new file mode 100644 index 00000000..2960b857 Binary files /dev/null and b/apps/stage/public/docs/images/phase3.png differ diff --git a/apps/stage/public/docs/images/phase4.png b/apps/stage/public/docs/images/phase4.png new file mode 100644 index 00000000..52218d1e Binary files /dev/null and b/apps/stage/public/docs/images/phase4.png differ diff --git a/apps/stage/public/images/color-pallette.png b/apps/stage/public/images/color-pallette.png new file mode 100644 index 00000000..e096ea6c Binary files /dev/null and b/apps/stage/public/images/color-pallette.png differ diff --git a/apps/stage/public/images/favicon.ico b/apps/stage/public/images/favicon.ico new file mode 100644 index 00000000..e58d67fc Binary files /dev/null and b/apps/stage/public/images/favicon.ico differ diff --git a/apps/stage/public/images/navbar-logo.png b/apps/stage/public/images/navbar-logo.png new file mode 100644 index 00000000..6bf407c4 Binary files /dev/null and b/apps/stage/public/images/navbar-logo.png differ diff --git a/apps/stage/public/static/avatar.svg b/apps/stage/public/static/avatar.svg new file mode 100644 index 00000000..f0dec484 --- /dev/null +++ b/apps/stage/public/static/avatar.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/apps/stage/public/static/checkmark.svg b/apps/stage/public/static/checkmark.svg new file mode 100644 index 00000000..5774eb4d --- /dev/null +++ b/apps/stage/public/static/checkmark.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/apps/stage/public/static/chevron-down.svg b/apps/stage/public/static/chevron-down.svg new file mode 100644 index 00000000..af08b983 --- /dev/null +++ b/apps/stage/public/static/chevron-down.svg @@ -0,0 +1,3 @@ + + + diff --git a/apps/stage/public/static/dismiss.svg b/apps/stage/public/static/dismiss.svg new file mode 100644 index 00000000..f037f3d1 --- /dev/null +++ b/apps/stage/public/static/dismiss.svg @@ -0,0 +1,3 @@ + + + diff --git a/apps/stage/public/static/facebook.svg b/apps/stage/public/static/facebook.svg new file mode 100644 index 00000000..498d29be --- /dev/null +++ b/apps/stage/public/static/facebook.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/stage/public/static/github.svg b/apps/stage/public/static/github.svg new file mode 100644 index 00000000..783bf393 --- /dev/null +++ b/apps/stage/public/static/github.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/stage/public/static/google.svg b/apps/stage/public/static/google.svg new file mode 100644 index 00000000..546d2a94 --- /dev/null +++ b/apps/stage/public/static/google.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/stage/public/static/illustration.svg b/apps/stage/public/static/illustration.svg new file mode 100644 index 00000000..ccc9a65f --- /dev/null +++ b/apps/stage/public/static/illustration.svg @@ -0,0 +1,171 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/stage/public/static/keycloak.svg b/apps/stage/public/static/keycloak.svg new file mode 100644 index 00000000..7e890894 --- /dev/null +++ b/apps/stage/public/static/keycloak.svg @@ -0,0 +1,160 @@ + + + + + + + + + + + + + keycloak_deliverables + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apps/stage/public/static/linkedin.svg b/apps/stage/public/static/linkedin.svg new file mode 100644 index 00000000..03f7b08a --- /dev/null +++ b/apps/stage/public/static/linkedin.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/stage/public/static/logomark.svg b/apps/stage/public/static/logomark.svg new file mode 100644 index 00000000..8c38c1aa --- /dev/null +++ b/apps/stage/public/static/logomark.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/stage/public/static/orcid.svg b/apps/stage/public/static/orcid.svg new file mode 100644 index 00000000..9e7635f1 --- /dev/null +++ b/apps/stage/public/static/orcid.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/stage/public/static/overture-user.svg b/apps/stage/public/static/overture-user.svg new file mode 100644 index 00000000..532e3dd2 --- /dev/null +++ b/apps/stage/public/static/overture-user.svg @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/stage/public/static/primary.svg b/apps/stage/public/static/primary.svg new file mode 100644 index 00000000..72caa657 --- /dev/null +++ b/apps/stage/public/static/primary.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/stage/tests/index.test.js b/apps/stage/tests/index.test.js new file mode 100644 index 00000000..63337c41 --- /dev/null +++ b/apps/stage/tests/index.test.js @@ -0,0 +1,5 @@ +describe('Test', () => { + it('says hello world', () => { + expect(1 + 1).toEqual(2); + }); +}); diff --git a/apps/stage/tsconfig.json b/apps/stage/tsconfig.json new file mode 100644 index 00000000..1b322a45 --- /dev/null +++ b/apps/stage/tsconfig.json @@ -0,0 +1,39 @@ +{ + "compilerOptions": { + "target": "ESNext", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "alwaysStrict": true /* Ensure 'use strict' is always emitted. */, + "strict": true /* Enable all strict type-checking options. */, + "forceConsistentCasingInFileNames": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "jsxImportSource": "@emotion/react", + "incremental": true, + "noImplicitAny": true /* Enable error reporting for expressions and declarations with an implied `any` type.. */, + "strictNullChecks": true /* When type checking, take into account `null` and `undefined`. */, + "baseUrl": "./", + "paths": { + "@/public": ["./public"], + "@/*": ["./*"], + "react": ["./node_modules/@types/react"] + }, + "plugins": [ + { + "transform": "typescript-transform-paths" + }, // absolute paths for source files + { + "transform": "typescript-transform-paths", + "afterDeclarations": true + } // absolute paths for .d.ts files + ] + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "additional.d.ts"], + "exclude": ["node_modules"] +} diff --git a/conductorScripts/deployments/arrangerDev.sh b/conductorScripts/deployments/arrangerDev.sh deleted file mode 100755 index 80f4eafe..00000000 --- a/conductorScripts/deployments/arrangerDev.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/sh - -# Welcome -echo -e "\033[1;36m╔═════════════════════════════════════════╗\033[0m" -echo -e "\033[1;36m║ Welcome to the ArrangerDev QuickStart ║\033[0m" -echo -e "\033[1;36m╚═════════════════════════════════════════╝\033[0m" - -# rs = "Run Script" a simple function to apply permissions and run scripts -rs() { - chmod +x "$1" && "$1" - } - -# Elasticsearch Setup -echo -e "\033[1;35m[1/2]\033[0m Setting up Elasticsearch" -rs /scripts/services/elasticSearchSetup.sh - -# Update Conductor to Healthy Status -echo "healthy" > /health/conductor_health -echo -e "\033[1;36mConductor:\033[0m Updating Container Status. Health check file created" - -# Check Stage -echo -e "\033[1;35m[2/2]\033[0m Checking Stage" -rs /scripts/services/stageCheck.sh - -# Remove Health Check File -rm /health/conductor_health - -# Success and Next Steps -echo -e "\033[1;36m╔════════════════════════════════════════╗\033[0m" -echo -e "\033[1;36m║ Arranger Dev Service Setup Complete ║\033[0m" -echo -e "\033[1;36m╚════════════════════════════════════════╝\033[0m\n" -echo -e "\033[1m1️⃣ To run Arranger locally, start by cloning the repo:\033[0m\n" -echo -e " \033[1;32mgit clone https://github.com/overture-stack/arranger.git\033[0m\n" -echo -e "\033[1m2️⃣ Navigate to the cloned directory:\033[0m\n" -echo -e " \033[1;32mcd arranger\033[0m\n" -echo -e "\033[1m3️⃣ Copy the example environment file:\033[0m\n" -echo -e " \033[1;32mcp .env.arrangerDev .env\033[0m\n" -echo -e "\033[1m4️⃣ Install the dependencies:\033[0m\n" -echo -e " \033[1;32mnpm ci\033[0m\n" -echo -e "\033[1m5️⃣ Bootstrap the project:\033[0m\n" -echo -e " \033[1;32mnpm run bootstrap\033[0m\n" -echo -e "\033[1m6️⃣ Run the development server:\033[0m\n" -echo -e " \033[1;32mnpm run server\033[0m\n" diff --git a/conductorScripts/deployments/maestroDev.sh b/conductorScripts/deployments/maestroDev.sh deleted file mode 100755 index 899a9302..00000000 --- a/conductorScripts/deployments/maestroDev.sh +++ /dev/null @@ -1,56 +0,0 @@ -#!/bin/sh - -# Welcome -echo -e "\033[1;36m╔════════════════════════════════════════╗\033[0m" -echo -e "\033[1;36m║ Welcome to the MaestroDev QuickStart ║\033[0m" -echo -e "\033[1;36m╚════════════════════════════════════════╝\033[0m" - -# rs = "Run Script" a simple function to apply permissions and run scripts -rs() { - chmod +x "$1" && "$1" - } - -# Keycloak and Song Db Setup -echo -e "\033[1;35m[1/6]\033[0m Setting up Song & Keycloak databases" -rs /scripts/services/keycloakDbSetup.sh -rs /scripts/services/songDbSetup.sh - -# Minio Check -echo -e "\033[1;35m[2/6]\033[0m Checking Minio Object Storage" -rs /scripts/services/minioCheck.sh - -# Score Setup -echo -e "\033[1;35m[3/6]\033[0m Checking on Score" -rs /scripts/services/scoreCheck.sh - -# Song Check -echo -e "\033[1;35m[4/6]\033[0m Checking Song" -rs /scripts/services/songCheck.sh - -# Elasticsearch Setup -echo -e "\033[1;35m[5/6]\033[0m Setting up Elasticsearch" -rs /scripts/services/elasticsearchSetup.sh - -# Check Keycloak -echo -e "\033[1;35m[6/6]\033[0m Checking Keycloak" -rs /scripts/services/keycloakCheck.sh - -# Success and Next Steps -echo -e "\033[1;36m╔══════════════════════════════════════╗\033[0m" -echo -e "\033[1;36m║ MaestroDev Service Setup Complete ║\033[0m" -echo -e "\033[1;36m╚══════════════════════════════════════╝\033[0m\n" - -echo -e "\033[1m1️⃣ To run Score locally, start by cloning the repo:\033[0m\n" -echo -e " \033[1;32mgit clone https://github.com/overture-stack/maestro.git\033[0m\n" - -echo -e "\033[1m2️⃣ Navigate to the cloned directory:\033[0m\n" -echo -e " \033[1;32mcd maestro\033[0m\n" - -echo -e "\033[1m3️⃣ Build the application \033[1;34m(requires JDK11 & Maven3)\033[0m:\033[0m\n" -echo -e " \033[1;32m./mvnw clean install -DskipTests\033[0m\n" - -echo -e "\033[1m4️⃣ Start the development server:\033[0m\n" -echo -e " \033[1;32m./mvnw spring-boot:run -pl maestro-app\033[0m\n" - -echo -e "\033[1mMaestro's Swagger UI can be accessed from:\n" -echo -e " \033[1;32mhttp://localhost:11235/api-docs\033[0m\n" diff --git a/conductorScripts/deployments/platform.sh b/conductorScripts/deployments/platform.sh deleted file mode 100755 index ded7c1c7..00000000 --- a/conductorScripts/deployments/platform.sh +++ /dev/null @@ -1,71 +0,0 @@ -#!/bin/sh - -# Welcome -echo -e "\033[1;36m╔═══════════════════════════════════════════════════╗\033[0m" -echo -e "\033[1;36m║ Welcome to the Overture Platform QuickStart ║\033[0m" -echo -e "\033[1;36m╚═══════════════════════════════════════════════════╝\033[0m" - -# rs = "Run Script" a simple function to apply permissions and run scripts -rs() { - chmod +x "$1" && "$1" - } - -# Cleanup any existing healthcheck file -rs scripts/services/healthcheckCleanup.sh - -# Database Setups -echo -e "\033[1;35m[1/9]\033[0m Setting up Song & Keycloak databases" -rs /scripts/services/songDbSetup.sh -rs /scripts/services/keycloakDbSetup.sh - -# Minio Check -echo -e "\033[1;35m[2/9]\033[0m Checking Minio Object Storage" -rs /scripts/services/minioCheck.sh - -# Score Setup -echo -e "\033[1;35m[3/9]\033[0m Checking on Score" -rs /scripts/services/scoreCheck.sh - -# Song Setup -echo -e "\033[1;35m[4/9]\033[0m Checking on Song" -rs /scripts/services/songCheck.sh - -# Elasticsearch Setup -echo -e "\033[1;35m[5/9]\033[0m Setting up Elasticsearch" -rs /scripts/services/elasticSearchSetup.sh - -# Update Conductor to Healthy Status, this signals search and exploration services (maestro, arranger, stage) to startup -echo "healthy" > /health/conductor_health -echo -e "\033[1;36mConductor:\033[0m Updating Container Status. Health check file created" - -# Check Stage -echo -e "\033[1;35m[7/9]\033[0m Checking Stage" -rs /scripts/services/stageCheck.sh - -# Check Arranger -echo -e "\033[1;35m[6/9]\033[0m Checking Arranger" -rs /scripts/services/arrangerCheck.sh - -# Check Maestro -echo -e "\033[1;35m[8/9]\033[0m Checking Maestro" -rs /scripts/services/maestroCheck.sh - -# Check Keycloak -echo -e "\033[1;35m[9/9]\033[0m Checking Keycloak" -rs /scripts/services/keycloakCheck.sh - -# Remove Health Check File -rm /health/conductor_health - -# Success and Next Steps -echo -e "\033[1;36m╔══════════════════════════════════════════╗\033[0m" -echo -e "\033[1;36m║ Overture QuickStart Setup Complete ║\033[0m" -echo -e "\033[1;36m╚══════════════════════════════════════════╝\033[0m" -echo -e "\n" -echo -e "\033[1m🌐 Front-end Portal:\033[0m" -echo -e " \033[1;32mhttp://localhost:3000\033[0m\n" -echo -e "\033[1m📚 Overture Platform Guides:\033[0m" -echo -e " \033[1;32mhttps://www.overture.bio/documentation/guides/\033[0m\n" -echo -e "\033[1m🛠️ QuickStart Information:\033[0m" -echo -e " Check the \033[1;33mdocker-compose.yml\033[0m file for details on this QuickStart," -echo -e " including links to relevant sections of our deployment guide.\n" diff --git a/conductorScripts/deployments/scoreDev.sh b/conductorScripts/deployments/scoreDev.sh deleted file mode 100755 index 57a045e2..00000000 --- a/conductorScripts/deployments/scoreDev.sh +++ /dev/null @@ -1,48 +0,0 @@ -#!/bin/sh - -# Welcome -echo -e "\033[1;36m╔════════════════════════════════════╗\033[0m" -echo -e "\033[1;36m║ Welcome to the ScoreDev QuickStart ║\033[0m" -echo -e "\033[1;36m╚════════════════════════════════════╝\033[0m" - -# rs = "Run Script" a simple function to apply permissions and run scripts -rs() { - chmod +x "$1" && "$1" - } - -# Keycloak and Song Db Setup -echo -e "\033[1;35m[1/4]\033[0m Setting up Song & Keycloak databases" -rs /scripts/services/keycloakDbSetup.sh -rs /scripts/services/songDbSetup.sh - -# Minio Check -echo -e "\033[1;35m[2/4]\033[0m Checking Minio Object Storage" -rs /scripts/services/minioCheck.sh - -# Song Setup -echo -e "\033[1;35m[3/6]\033[0m Checking Song" -rs /scripts/services/songCheck.sh - -# Keycloak Check -echo -e "\033[1;35m[4/4]\033[0m Checking Keycloak" -rs /scripts/services/keycloakCheck.sh - -# Success and Next Steps -echo -e "\033[1;36m╔══════════════════════════════════════╗\033[0m" -echo -e "\033[1;36m║ ScoreDev Service Setup Complete ║\033[0m" -echo -e "\033[1;36m╚══════════════════════════════════════╝\033[0m\n" - -echo -e "\033[1m1️⃣ To run Score locally, start by cloning the repo:\033[0m\n" -echo -e " \033[1;32mgit clone https://github.com/overture-stack/score.git\033[0m\n" - -echo -e "\033[1m2️⃣ Navigate to the cloned directory:\033[0m\n" -echo -e " \033[1;32mcd score\033[0m\n" - -echo -e "\033[1m3️⃣ Build the application \033[1;34m(requires JDK11 & Maven3)\033[0m:\033[0m\n" -echo -e " \033[1;32m./mvnw clean install -DskipTests\033[0m\n" - -echo -e "\033[1m4️⃣ Start the development server:\033[0m\n" -echo -e " \033[1;32m./mvnw spring-boot:run -Dspring-boot.run.profiles=default,s3,secure,dev -pl score-server\033[0m\n" - -echo -e "\033[1mScores Swagger UI can be accessed from:\n" -echo -e " \033[1;32mhttp://localhost:8087/swagger-ui.html\033[0m\n" diff --git a/conductorScripts/deployments/songDev.sh b/conductorScripts/deployments/songDev.sh deleted file mode 100755 index 879ca012..00000000 --- a/conductorScripts/deployments/songDev.sh +++ /dev/null @@ -1,48 +0,0 @@ -#!/bin/sh - -# Welcome -echo -e "\033[1;36m╔═════════════════════════════════════╗\033[0m" -echo -e "\033[1;36m║ Welcome to the SongDev QuickStart ║\033[0m" -echo -e "\033[1;36m╚═════════════════════════════════════╝\033[0m" - -# rs = "Run Script" a simple function to apply permissions and run scripts -rs() { - chmod +x "$1" && "$1" - } - -# Keycloak and Song Db Setup -echo -e "\033[1;35m[1/4]\033[0m Setting up Song and Keycloak databases" -rs /scripts/services/keycloakDbSetup.sh -rs /scripts/services/songDbSetup.sh - -# Minio Check -echo -e "\033[1;35m[2/4]\033[0m Checking Minio Object Storage" -rs /scripts/services/minioCheck.sh - -# Score Setup -echo -e "\033[1;35m[3/4]\033[0m Checking Score" -rs /scripts/services/scoreCheck.sh - -# Keycloak Check -echo -e "\033[1;35m[4/4]\033[0m Checking Keycloak" -rs /scripts/services/keycloakCheck.sh - -# Success and Next Steps -echo -e "\033[1;36m╔══════════════════════════════════════╗\033[0m" -echo -e "\033[1;36m║ SongDev Service Setup Complete ║\033[0m" -echo -e "\033[1;36m╚══════════════════════════════════════╝\033[0m\n" - -echo -e "\033[1m1️⃣ To run Song locally, start by cloning the repo:\033[0m\n" -echo -e " \033[1;32mgit clone https://github.com/overture-stack/song.git\033[0m\n" - -echo -e "\033[1m2️⃣ Navigate to the cloned directory:\033[0m\n" -echo -e " \033[1;32mcd song\033[0m\n" - -echo -e "\033[1m3️⃣ Build the application \033[1;34m(Requires JDK11)\033[0m:\033[0m\n" -echo -e " \033[1;32m./mvnw clean install -DskipTests\033[0m\n" - -echo -e "\033[1m4️⃣ Start the development server:\033[0m\n" -echo -e " \033[1;32m./mvnw spring-boot:run -Dspring-boot.run.profiles=default,dev,secure -pl song-server\033[0m\n" - -echo -e "\033[1mSongs Swagger UI can be accessed from:\n" -echo -e " \033[1;32mhttp://localhost:8080/swagger-ui.html\033[0m\n" diff --git a/conductorScripts/deployments/stageDev.sh b/conductorScripts/deployments/stageDev.sh deleted file mode 100755 index d36544fc..00000000 --- a/conductorScripts/deployments/stageDev.sh +++ /dev/null @@ -1,61 +0,0 @@ -#!/bin/sh - -# Welcome -echo -e "\033[1;36m╔══════════════════════════════════════════╗\033[0m" -echo -e "\033[1;36m║ Welcome to the StageDev QuickStart ║\033[0m" -echo -e "\033[1;36m╚══════════════════════════════════════════╝\033[0m" - -# rs = "Run Script" a simple function to apply permissions and run scripts -rs() { - chmod +x "$1" && "$1" - } - -# Keycloak Db Setup -echo -e "\033[1;35m[1/4]\033[0m Setting up Keycloak database" -rs /scripts/services/keycloakDbSetup.sh - -# Elasticsearch Setup -echo -e "\033[1;35m[2/4]\033[0m Setting up Elasticsearch" -rs /scripts/services/elasticSearchSetup.sh - -# Update Conductor to Healthy Status -echo "healthy" > /health/conductor_health -echo -e "\033[1;36mConductor:\033[0m Updating Container Status. Health check file created" - -# Check Arranger -echo -e "\033[1;35m[3/4]\033[0m Checking Arranger" -rs /scripts/services/arrangerCheck.sh - -# Keycloak Check -echo -e "\033[1;35m[4/4]\033[0m Checking Keycloak" -rs /scripts/services/keycloakCheck.sh - -# Remove Health Check File -rm /health/conductor_health - -# Success and Next Steps -echo -e "\033[1;36m╔═══════════════════════════════════════╗\033[0m" -echo -e "\033[1;36m║ Stage Dev Service Setup Complete ║\033[0m" -echo -e "\033[1;36m╚═══════════════════════════════════════╝\033[0m\n" - -echo -e "\033[1m1️⃣ To run Stage locally, start by cloning the repo:\033[0m\n" -echo -e " \033[1;32mgit clone https://github.com/overture-stack/stage.git\033[0m\n" - -echo -e "\033[1m2️⃣ Navigate to the cloned directory:\033[0m\n" -echo -e " \033[1;32mcd stage\033[0m\n" - -echo -e "\033[1m3️⃣ Copy the example environment file:\033[0m\n" -echo -e " \033[1;32mcp .env.stageDev .env\033[0m\n" - -echo -e "\033[1m4️⃣ Install the dependencies:\033[0m\n" -echo -e " \033[1;32mnpm ci\033[0m\n" - -echo -e "\033[1m This will require:\033[0m" -echo -e "\033[1;34m - Node v16 or higher\033[0m" -echo -e "\033[1;34m - npm v8.3.0 or higher\033[0m\n" - -echo -e "\033[1m5️⃣ Run the development server:\033[0m\n" -echo -e " \033[1;32mnpm run dev\033[0m\n" - -echo -e "\033[1mYour development server will be accessible at:\n" -echo -e " \033[1;32mhttp://localhost:3000\033[0m\n" diff --git a/conductorScripts/services/arrangerCheck.sh b/conductorScripts/services/arrangerCheck.sh deleted file mode 100755 index 5a9a5709..00000000 --- a/conductorScripts/services/arrangerCheck.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -echo -e "Checking if Arranger is reachable" - until curl -s -o /dev/null -w "%{http_code}" "http://arranger-server:5050/graphql" | grep -q "200"; do - echo -e "\033[1;36mArranger:\033[0m Not yet reachable, checking again in 20 seconds" - sleep 20 - done -echo -e "\033[1;32mSuccess:\033[0m Arranger is now reachable" diff --git a/conductorScripts/services/elasticsearchSetup.sh b/conductorScripts/services/elasticsearchSetup.sh deleted file mode 100755 index 6587a161..00000000 --- a/conductorScripts/services/elasticsearchSetup.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/bin/sh - -# Wait for Elasticsearch -echo -e "\033[1;36mElasticsearch:\033[0m Starting up (this may take a few minutes)" -sleep 20 -until curl -s -u elastic:myelasticpassword -X GET "http://elasticsearch:9200/_cluster/health" > /dev/null; do - echo -e "\033[1;36mElasticsearch:\033[0m Not yet reachable, checking again in 30 seconds" - sleep 30 -done -echo -e "\033[1;32mSuccess:\033[0m Elasticsearch is reachable" - -# Set up Elasticsearch index template -echo -e "Setting up the Elasticsearch index template" -if ! curl -s -u elastic:myelasticpassword "http://elasticsearch:9200/_template/index_template" | grep -q "\"index_patterns\""; then - curl -s -u elastic:myelasticpassword -X PUT "http://elasticsearch:9200/_template/index_template" \ - -H "Content-Type: application/json" -d @/usr/share/elasticsearch/config/quickstart_index_template.json > /dev/null && - echo -e "\033[1;32mSuccess:\033[0m Elasticsearch index template created successfully" -else - echo -e "\033[1;36mElasticsearch:\033[0m Index template already exists, skipping creation" -fi - -# Set up Elasticsearch index and alias (needs failure check) -echo -e "Setting up the Elasticsearch index and alias" -echo -e "\033[1;36mElasticsearch:\033[0m Checking if Elasticsearch index exists" -if ! curl -s -f -u elastic:myelasticpassword -X GET "http://elasticsearch:9200/overture-quickstart-index" > /dev/null 2>&1; then - echo -e "\033[1;36mElasticsearch:\033[0m Creating Elasticsearch index and alias" - response=$(curl -s -w "\n%{http_code}" -u elastic:myelasticpassword -X PUT "http://elasticsearch:9200/overture-quickstart-index" \ - -H "Content-Type: application/json" -d "{\"aliases\": {\"file_centric\": {\"is_write_index\": true}}}") - http_code=$(echo "$response" | tail -n1) - body=$(echo "$response" | sed '$d') - echo -e "\033[1;32mSuccess:\033[0m Index and alias created successfully, Elasticsearch setup complete" -else - echo -e "\033[1;36mElasticsearch:\033[0m Index already exists, skipping creation" -fi - -# Importing Elasticsearch Documents -echo -e "Importing Elasticsearch Documents" -for f in ./es-docs/*.json; do - object_id=$(basename "$f" .json) - curl --user elastic:myelasticpassword -sL -X POST \ - -H "Content-Type: application/json" \ - "http://elasticsearch:9200/overture-quickstart-index/_doc/$object_id" \ - -d "@$f" > /dev/null -done -echo -e "\033[1;32mSuccess:\033[0m Document import complete" diff --git a/conductorScripts/services/healthcheckCleanup.sh b/conductorScripts/services/healthcheckCleanup.sh deleted file mode 100755 index 8cb3521c..00000000 --- a/conductorScripts/services/healthcheckCleanup.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -# If the health check file exists on startup it needs to be removed -rm /health/conductor_health 2>/dev/null diff --git a/conductorScripts/services/kafkaSetup.sh b/conductorScripts/services/kafkaSetup.sh deleted file mode 100755 index 6589fc96..00000000 --- a/conductorScripts/services/kafkaSetup.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh - -# Quick check if Kafka is ready -until /bin/kafka-topics --bootstrap-server kafka:9092 --list > /dev/null 2>&1; do - echo -e "\033[1;33mWaiting:\033[0m Kafka not ready yet..." - sleep 5 -done - -# Create topic if it doesn't exist -echo -e "\033[1;36mSetting up Kafka:\033[0m Creating Kafka topic for Song" -/bin/kafka-topics --bootstrap-server kafka:9092 --create --if-not-exists \ - --topic song-analysis \ - --partitions 1 \ - --replication-factor 1 \ - --config cleanup.policy=delete \ - --config retention.ms=604800000 - -# Update healthcheck to just verify -echo "Verifying Kafka topic creation" -/bin/kafka-topics --bootstrap-server kafka:9092 --describe --topic song-analysis -echo -e "\033[1;32mSuccess:\033[0m Kafka Overture Setup Script Complete" diff --git a/conductorScripts/services/keycloakCheck.sh b/conductorScripts/services/keycloakCheck.sh deleted file mode 100755 index 4cf752d1..00000000 --- a/conductorScripts/services/keycloakCheck.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -# Check for Keycloak -until [ "$(curl -s -o /dev/null -w "%{http_code}" "http://keycloak:8080/health/live")" = "200" ]; do - echo -e "\033[1;36mKeycloak:\033[0m Not yet reachable, checking again in 30 seconds" - sleep 30 -done -echo -e "\033[1;32mSuccess:\033[0m Keycloak is reachable" diff --git a/conductorScripts/services/keycloakDbSetup.sh b/conductorScripts/services/keycloakDbSetup.sh deleted file mode 100755 index 3af80fa0..00000000 --- a/conductorScripts/services/keycloakDbSetup.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh - -# Create missing empty directories not tracked by git and needed by postgres -echo -e "Setting up empty directories for Keycloaks postgres database" -mkdir -p keycloak/db-folder-init/pg_tblspc -mkdir -p keycloak/db-folder-init/pg_stat -mkdir -p keycloak/db-folder-init/pg_stat_tmp -mkdir -p keycloak/db-folder-init/pg_replslot -mkdir -p keycloak/db-folder-init/pg_dynshmem -mkdir -p keycloak/db-folder-init/pg_twophase -mkdir -p keycloak/db-folder-init/pg_notify -mkdir -p keycloak/db-folder-init/pg_serial -mkdir -p keycloak/db-folder-init/pg_snapshots -mkdir -p keycloak/db-folder-init/pg_commit_ts -mkdir -p keycloak/db-folder-init/pg_wal/archive_status -mkdir -p keycloak/db-folder-init/pg_logical/snapshots -mkdir -p keycloak/db-folder-init/pg_logical/mappings diff --git a/conductorScripts/services/maestroCheck.sh b/conductorScripts/services/maestroCheck.sh deleted file mode 100755 index 7a60c551..00000000 --- a/conductorScripts/services/maestroCheck.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh - -# Check Maestro -echo -e "Checking if Maestro is reachable (this may take a few minutes)" -until curl -s -X POST "http://maestro:11235/index/repository/song.overture/study/demo" -H "accept: */*" -d "{}" | grep -q "true"; do - echo -e "\033[1;36mMaestro:\033[0m Not yet reachable, checking again in 30 seconds" - sleep 30 -done -echo -e "\033[1;32mSuccess:\033[0m Maestro is now reachable" diff --git a/conductorScripts/services/minioCheck.sh b/conductorScripts/services/minioCheck.sh deleted file mode 100755 index 8af12e6d..00000000 --- a/conductorScripts/services/minioCheck.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -until [ "$(curl -s -o /dev/null -w "%{http_code}" "http://minio:9000/minio/health/live")" = "200" ]; do - echo -e "\033[1;36mMinio:\033[0m Not yet reachable, checking again in 15 seconds" - sleep 15 -done -echo -e "\033[1;32mSuccess:\033[0m Minio is reachable" diff --git a/conductorScripts/services/scoreCheck.sh b/conductorScripts/services/scoreCheck.sh deleted file mode 100755 index cba7bcec..00000000 --- a/conductorScripts/services/scoreCheck.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -# Check for Score -until [ "$(curl -s -o /dev/null -w "%{http_code}" "http://score:8087/download/ping" -H "accept: */*" -H "Authorization: 68fb42b4-f1ed-4e8c-beab-3724b99fe528" -H "User-Agent: unknown")" = "200" ]; do - echo -e "\033[1;36mScore:\033[0m Not yet reachable, checking again in 20 seconds" - sleep 20 -done -echo -e "\033[1;32mSuccess:\033[0m Score is now reachable" diff --git a/conductorScripts/services/songCheck.sh b/conductorScripts/services/songCheck.sh deleted file mode 100755 index fd515161..00000000 --- a/conductorScripts/services/songCheck.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -# Check for Song -until [ "$(curl -s -o /dev/null -w "%{http_code}" "http://song:8080/isAlive" -H "accept: */*")" = "200" ]; do - echo -e "\033[1;36mSong:\033[0m Not yet reachable, checking again in 20 seconds" - sleep 20 -done -echo -e "\033[1;32mSuccess:\033[0m Song is now reachable" diff --git a/conductorScripts/services/songDbSetup.sh b/conductorScripts/services/songDbSetup.sh deleted file mode 100755 index 8d1b1950..00000000 --- a/conductorScripts/services/songDbSetup.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -# Create missing empty directories not tracked by git and needed by postgres -echo -e "Setting up empty directories for Songs postgres database" -mkdir -p song/db-folder-init/pg_tblspc -mkdir -p song/db-folder-init/pg_stat -mkdir -p song/db-folder-init/pg_stat_tmp -mkdir -p song/db-folder-init/pg_twophase -mkdir -p song/db-folder-init/pg_snapshots -mkdir -p song/db-folder-init/pg_commit_ts -mkdir -p song/db-folder-init/pg_logical/snapshotss -mkdir -p song/db-folder-init/pg_logical/mappings -mkdir -p song/db-folder-init/pg_replslot -mkdir -p song/db-folder-init/pg_logical/snapshots diff --git a/conductorScripts/services/stageCheck.sh b/conductorScripts/services/stageCheck.sh deleted file mode 100755 index f07d08b9..00000000 --- a/conductorScripts/services/stageCheck.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh - -# Check Stage -echo -e "Checking if Stage is reachable" - until curl -s -o /dev/null -w "%{http_code}" "http://stage:3000" | grep -q "200"; do - echo -e "\033[1;36mStage:\033[0m Not yet reachable, checking again in 10 seconds" - sleep 10 - done -echo -e "\033[1;32mSuccess:\033[0m Stage is now reachable" diff --git a/configs b/configs new file mode 120000 index 00000000..f54f94d2 --- /dev/null +++ b/configs @@ -0,0 +1 @@ +./apps/conductor/configs \ No newline at end of file diff --git a/configurationFiles/arrangerConfigs/base.json b/configurationFiles/arrangerConfigs/base.json deleted file mode 100644 index 53750805..00000000 --- a/configurationFiles/arrangerConfigs/base.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "documentType": "file", - "index": "overture-quickstart-index" -} \ No newline at end of file diff --git a/configurationFiles/arrangerConfigs/extended.json b/configurationFiles/arrangerConfigs/extended.json deleted file mode 100644 index 9dd88fe4..00000000 --- a/configurationFiles/arrangerConfigs/extended.json +++ /dev/null @@ -1,324 +0,0 @@ -{ - "extended": [ - { - "displayName": "Object ID", - "fieldName": "object_id" - }, - { - "displayName": "Study", - "fieldName": "study_id" - }, - { - "displayName": "Data Type", - "fieldName": "data_type" - }, - { - "displayName": "Format", - "fieldName": "file_type" - }, - { - "displayName": "Access", - "fieldName": "file_access" - }, - { - "displayName": "Analysis Id", - "fieldName": "analysis.analysis_id" - }, - { - "displayName": "Analysis Type", - "fieldName": "analysis.analysis_type" - }, - { - "displayName": "Analysis Version", - "fieldName": "analysis.analysis_version" - }, - { - "displayName": "Analysis State", - "fieldName": "analysis.analysis_state" - }, - { - "displayName": "Last Updated", - "fieldName": "analysis.updated_at" - }, - { - "displayName": "First Published On", - "fieldName": "analysis.first_published_at" - }, - { - "displayName": "Last Published On", - "fieldName": "analysis.published_at" - }, - { - "displayName": "Strategy", - "fieldName": "analysis.experiment.experimentalStrategy" - }, - { - "displayName": "Model", - "fieldName": "analysis.experiment.model" - }, - { - "displayName": "Platform", - "fieldName": "analysis.experiment.platform" - }, - { - "displayName": "Sequencing Center", - "fieldName": "analysis.experiment.sequencingCenter" - }, - { - "displayName": "Sequencing Date", - "fieldName": "analysis.experiment.sequencingDate" - }, - { - "displayName": "Contact Email", - "fieldName": "analysis.collaborator.contactEmail" - }, - { - "displayName": "Contributor", - "fieldName": "analysis.collaborator.name" - }, - { - "displayName": "Created At", - "fieldName": "analysis.createdAt" - }, - { - "displayName": "Cause of Death", - "fieldName": "analysis.donor.causeOfDeath" - }, - { - "displayName": "Age At Diagnosis", - "fieldName": "analysis.donor.primaryDiagnosis.ageAtDiagnosis" - }, - { - "displayName": "Cancer Type Code", - "fieldName": "analysis.donor.primaryDiagnosis.cancerTypeCode" - }, - { - "displayName": "Stage", - "fieldName": "analysis.donor.primaryDiagnosis.clinicalStageGroup" - }, - { - "displayName": "Tumour Staging System", - "fieldName": "analysis.donor.primaryDiagnosis.clinicalTumourStagingSystem" - }, - { - "displayName": "Status At Follow Up", - "fieldName": "analysis.donor.primaryDiagnosis.followUp.diseaseStatusAtFollowUp" - }, - { - "displayName": "Interval Of Follow Up (Days)", - "fieldName": "analysis.donor.primaryDiagnosis.followUp.intervalOfFollowUp" - }, - { - "displayName": "Follow Up Id", - "fieldName": "analysis.donor.primaryDiagnosis.followUp.submitterFollowUpId" - }, - { - "displayName": "Follow-Up Treatment Id", - "fieldName": "analysis.donor.primaryDiagnosis.followUp.submitterTreatmentId" - }, - { - "displayName": "Donor Primary Diagnosis Id", - "fieldName": "analysis.donor.primaryDiagnosis.submitterPrimaryDiagnosisId" - }, - { - "displayName": "Chemotherapy Drug", - "fieldName": "analysis.donor.primaryDiagnosis.treatment.chemotherapy.drugName" - }, - { - "displayName": "Response to Treatment", - "fieldName": "analysis.donor.primaryDiagnosis.treatment.responseToTreatment" - }, - { - "displayName": "Treatment Id", - "fieldName": "analysis.donor.primaryDiagnosis.treatment.submitterTreatmentId" - }, - { - "displayName": "Treatment Duration (Days)", - "fieldName": "analysis.donor.primaryDiagnosis.treatment.treatmentDuration" - }, - { - "displayName": "Treatment Start Date", - "fieldName": "analysis.donor.primaryDiagnosis.treatment.treatmentStartInterval" - }, - { - "displayName": "Primary Site", - "fieldName": "analysis.donor.primarySite" - }, - { - "displayName": "Donor Id", - "fieldName": "analysis.donor.submitterDonorId" - }, - { - "displayName": "Survival Time (Days)", - "fieldName": "analysis.donor.survivalTime" - }, - { - "displayName": "Vital Status", - "fieldName": "analysis.donor.vitalStatus" - }, - { - "displayName": "DOI", - "fieldName": "analysis.publication.doi" - }, - { - "displayName": "Publication Status", - "fieldName": "analysis.publication.publication" - }, - { - "displayName": "Location", - "fieldName": "analysis.specimen.specimenAnatomicLocation" - }, - { - "displayName": "Specimen Primary Diagnosis Id", - "fieldName": "analysis.specimen.submitterPrimaryDiagnosisId" - }, - { - "displayName": "Specimen Id", - "fieldName": "analysis.specimen.submitterSpecimenId" - }, - { - "displayName": "Tumour Grade", - "fieldName": "analysis.specimen.tumourGrade" - }, - { - "displayName": "Grading System", - "fieldName": "analysis.specimen.tumourGradingSystem" - }, - { - "displayName": "Genome Build", - "fieldName": "analysis.workflow.genomeBuild" - }, - { - "displayName": "Workflow Analysis Type", - "fieldName": "analysis.workflow.inputs.analysisType" - }, - { - "displayName": "Workflow Normal Analysis Id", - "fieldName": "analysis.workflow.inputs.normalAnalysisId" - }, - { - "displayName": "Workflow Tumour Analysis Id", - "fieldName": "analysis.workflow.inputs.tumourAnalysisId" - }, - { - "displayName": "Workflow Run Id", - "fieldName": "analysis.workflow.runId" - }, - { - "displayName": "Workflow Session Id", - "fieldName": "analysis.workflow.sessionId" - }, - { - "displayName": "Workflow", - "fieldName": "analysis.workflow.workflowName" - }, - { - "displayName": "Workflow Short Name", - "fieldName": "analysis.workflow.workflowShortName" - }, - { - "displayName": "Workflow Version", - "fieldName": "analysis.workflow.workflowVersion" - }, - { - "displayName": "File Name", - "fieldName": "file.name" - }, - { - "displayName": "Data Type", - "fieldName": "file.data_type" - }, - { - "displayName": "Md5sum", - "fieldName": "file.md5sum" - }, - { - "displayName": "Size", - "fieldName": "file.size" - }, - { - "displayName": "Object Id", - "fieldName": "file.index_file.object_id" - }, - { - "displayName": "Index File Name", - "fieldName": "file.index_file.name" - }, - { - "displayName": "Index File Type", - "fieldName": "file.index_file.file_type" - }, - { - "displayName": "Index File Md5sum", - "fieldName": "file.index_file.md5sum" - }, - { - "displayName": "Index Data Type", - "fieldName": "file.index_file.data_type" - }, - { - "displayName": "Index Data Size", - "fieldName": "file.index_file.size" - }, - { - "displayName": "Song Donor Id", - "fieldName": "donors.donor_id" - }, - { - "displayName": "Donor Id", - "fieldName": "donors.submitter_donor_id" - }, - { - "displayName": "Reported Gender", - "fieldName": "donors.gender" - }, - { - "displayName": "Speciment Id", - "fieldName": "donors.specimens.specimen_id" - }, - { - "displayName": "Specimen Type", - "fieldName": "donors.specimens.specimen_type" - }, - { - "displayName": "Submitter Specimen Id", - "fieldName": "donors.specimens.submitter_specimen_id" - }, - { - "displayName": "Sample Id", - "fieldName": "donors.specimens.samples.sample_id" - }, - { - "displayName": "Submitter Sample Id", - "fieldName": "donors.specimens.samples.submitter_sample_id" - }, - { - "displayName": "Sample Type", - "fieldName": "donors.specimens.samples.sample_type" - }, - { - "displayName": "Matched Normal Id", - "fieldName": "donors.specimens.samples.matched_normal_submitter_sample_id" - }, - { - "displayName": "Tumour Normal Designation", - "fieldName": "donors.specimens.tumour_normal_designation" - }, - { - "displayName": "Specimen Tissue Source", - "fieldName": "donors.specimens.specimen_tissue_source" - }, - { - "displayName": "Data Category", - "fieldName": "dataCategory" - }, - { - "displayName": "JBrowse Coordinates", - "fieldName": "jbrowseCoordinates" - }, - { - "displayName": "Repository Code", - "fieldName": "repositories.code" - } - ] - } \ No newline at end of file diff --git a/configurationFiles/arrangerConfigs/facets.json b/configurationFiles/arrangerConfigs/facets.json deleted file mode 100644 index 6230fa5e..00000000 --- a/configurationFiles/arrangerConfigs/facets.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "facets": { - "aggregations": [ - { - "active": true, - "fieldName": "analysis__collaborator__name", - "show": true - }, - { - "active": true, - "fieldName": "file_access", - "show": true - }, - { - "active": true, - "fieldName": "analysis__donor__primarySite", - "show": true - }, - { - "active": true, - "fieldName": "donors__gender", - "show": true - }, - { - "active": true, - "fieldName": "analysis__donor__primaryDiagnosis__ageAtDiagnosis", - "show": true - }, - { - "active": true, - "fieldName": "donors__specimens__specimen_tissue_source", - "show": true - }, - { - "active": true, - "fieldName": "file_type", - "show": true - }, - { - "active": true, - "fieldName": "data_type", - "show": true - }, - { - "active": true, - "fieldName": "analysis__workflow__workflowName", - "show": true - }, - { - "active": true, - "fieldName": "analysis__publication__publication", - "show": true - } - ] - } -} \ No newline at end of file diff --git a/configurationFiles/arrangerConfigs/matchbox.json b/configurationFiles/arrangerConfigs/matchbox.json deleted file mode 100644 index bba293b6..00000000 --- a/configurationFiles/arrangerConfigs/matchbox.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "matchbox": [ - - ] - } \ No newline at end of file diff --git a/configurationFiles/arrangerConfigs/table.json b/configurationFiles/arrangerConfigs/table.json deleted file mode 100644 index c0f51a79..00000000 --- a/configurationFiles/arrangerConfigs/table.json +++ /dev/null @@ -1,600 +0,0 @@ -{ - "table": { - "columns": [ - { - "canChangeShow": true, - "fieldName": "donors.submitter_donor_id", - "jsonPath": "$.donors.hits.edges[*].node.submitter_donor_id", - "query": "donors { hits { edges { node { submitter_donor_id } } } }", - "show": true, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.collaborator.name", - "jsonPath": "$.analysis.collaborator.hits.edges[*].node.name", - "query": "analysis { collaborator { hits { edges { node { name } } } } }", - "show": true, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "file_access", - "show": true, - "sortable": true - }, - - { - "canChangeShow": true, - "fieldName": "data_type", - "show": true, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "file_type", - "show": true, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.experiment.experimentalStrategy", - "show": true, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.experiment.platform", - "show": true, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.analysis_id", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "object_id", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.analysis_type", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.analysis_version", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.analysis_state", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.updated_at", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "study_id", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.first_published_at", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.published_at", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.experiment.model", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.experiment.sequencingCenter", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.experiment.sequencingDate", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.collaborator.contactEmail", - "jsonPath": "$.analysis.collaborator.hits.edges[*].node.contactEmail", - "query": "analysis { collaborator { hits { edges { node { contactEmail } } } } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.createdAt", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.donor.causeOfDeath", - "jsonPath": "$.analysis.donor.causeOfDeath", - "query": "analysis { donor { causeOfDeath } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.donor.primaryDiagnosis.ageAtDiagnosis", - "jsonPath": "$.analysis.donor.primaryDiagnosis.hits.edges[*].node.ageAtDiagnosis", - "query": "analysis { donor { primaryDiagnosis { hits { edges { node { ageAtDiagnosis } } } } } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.donor.primaryDiagnosis.cancerTypeCode", - "jsonPath": "$.analysis.donor.primaryDiagnosis.hits.edges[*].node.cancerTypeCode", - "query": "analysis { donor { primaryDiagnosis { hits { edges { node { cancerTypeCode } } } } } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.donor.primaryDiagnosis.clinicalStageGroup", - "jsonPath": "$.analysis.donor.primaryDiagnosis.hits.edges[*].node.clinicalStageGroup", - "query": "analysis { donor { primaryDiagnosis { hits { edges { node { clinicalStageGroup } } } } } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.donor.primaryDiagnosis.clinicalTumourStagingSystem", - "jsonPath": "$.analysis.donor.primaryDiagnosis.hits.edges[*].node.clinicalTumourStagingSystem", - "query": "analysis { donor { primaryDiagnosis { hits { edges { node { clinicalTumourStagingSystem } } } } } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.donor.primaryDiagnosis.followUp.diseaseStatusAtFollowUp", - "jsonPath": "$.analysis.donor.primaryDiagnosis.hits.edges[*].node.followUp.hits.edges[*].node.diseaseStatusAtFollowUp", - "query": "analysis { donor { primaryDiagnosis { hits { edges { node { followUp { hits { edges { node { diseaseStatusAtFollowUp } } } } } } } } } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.donor.primaryDiagnosis.followUp.intervalOfFollowUp", - "jsonPath": "$.analysis.donor.primaryDiagnosis.hits.edges[*].node.followUp.hits.edges[*].node.intervalOfFollowUp", - "query": "analysis { donor { primaryDiagnosis { hits { edges { node { followUp { hits { edges { node { intervalOfFollowUp } } } } } } } } } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.donor.primaryDiagnosis.followUp.submitterFollowUpId", - "jsonPath": "$.analysis.donor.primaryDiagnosis.hits.edges[*].node.followUp.hits.edges[*].node.submitterFollowUpId", - "query": "analysis { donor { primaryDiagnosis { hits { edges { node { followUp { hits { edges { node { submitterFollowUpId } } } } } } } } } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.donor.primaryDiagnosis.followUp.submitterTreatmentId", - "jsonPath": "$.analysis.donor.primaryDiagnosis.hits.edges[*].node.followUp.hits.edges[*].node.submitterTreatmentId", - "query": "analysis { donor { primaryDiagnosis { hits { edges { node { followUp { hits { edges { node { submitterTreatmentId } } } } } } } } } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.donor.primaryDiagnosis.submitterPrimaryDiagnosisId", - "jsonPath": "$.analysis.donor.primaryDiagnosis.hits.edges[*].node.submitterPrimaryDiagnosisId", - "query": "analysis { donor { primaryDiagnosis { hits { edges { node { submitterPrimaryDiagnosisId } } } } } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.donor.primaryDiagnosis.treatment.chemotherapy.drugName", - "jsonPath": "$.analysis.donor.primaryDiagnosis.hits.edges[*].node.treatment.hits.edges[*].node.chemotherapy.hits.edges[*].node.drugName", - "query": "analysis { donor { primaryDiagnosis { hits { edges { node { treatment { hits { edges { node { chemotherapy { hits { edges { node { drugName } } } } } } } } } } } } } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.donor.primaryDiagnosis.treatment.responseToTreatment", - "jsonPath": "$.analysis.donor.primaryDiagnosis.hits.edges[*].node.treatment.hits.edges[*].node.responseToTreatment", - "query": "analysis { donor { primaryDiagnosis { hits { edges { node { treatment { hits { edges { node { responseToTreatment } } } } } } } } } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.donor.primaryDiagnosis.treatment.submitterTreatmentId", - "jsonPath": "$.analysis.donor.primaryDiagnosis.hits.edges[*].node.treatment.hits.edges[*].node.submitterTreatmentId", - "query": "analysis { donor { primaryDiagnosis { hits { edges { node { treatment { hits { edges { node { submitterTreatmentId } } } } } } } } } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.donor.primaryDiagnosis.treatment.treatmentDuration", - "jsonPath": "$.analysis.donor.primaryDiagnosis.hits.edges[*].node.treatment.hits.edges[*].node.treatmentDuration", - "query": "analysis { donor { primaryDiagnosis { hits { edges { node { treatment { hits { edges { node { treatmentDuration } } } } } } } } } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.donor.primaryDiagnosis.treatment.treatmentStartInterval", - "jsonPath": "$.analysis.donor.primaryDiagnosis.hits.edges[*].node.treatment.hits.edges[*].node.treatmentStartInterval", - "query": "analysis { donor { primaryDiagnosis { hits { edges { node { treatment { hits { edges { node { treatmentStartInterval } } } } } } } } } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.donor.primarySite", - "jsonPath": "$.analysis.donor.primarySite", - "query": "analysis { donor { primarySite } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.donor.submitterDonorId", - "jsonPath": "$.analysis.donor.submitterDonorId", - "query": "analysis { donor { submitterDonorId } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.donor.survivalTime", - "jsonPath": "$.analysis.donor.survivalTime", - "query": "analysis { donor { survivalTime } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.donor.vitalStatus", - "jsonPath": "$.analysis.donor.vitalStatus", - "query": "analysis { donor { vitalStatus } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.publication.doi", - "jsonPath": "$.analysis.publication.doi", - "query": "analysis { publication { doi } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.publication.publication", - "jsonPath": "$.analysis.publication.publication", - "query": "analysis { publication { publication } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.specimen.specimenAnatomicLocation", - "jsonPath": "$.analysis.specimen.specimenAnatomicLocation", - "query": "analysis { specimen { specimenAnatomicLocation } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.specimen.submitterPrimaryDiagnosisId", - "jsonPath": "$.analysis.specimen.submitterPrimaryDiagnosisId", - "query": "analysis { specimen { submitterPrimaryDiagnosisId } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.specimen.submitterSpecimenId", - "jsonPath": "$.analysis.specimen.submitterSpecimenId", - "query": "analysis { specimen { submitterSpecimenId } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.specimen.tumourGrade", - "jsonPath": "$.analysis.specimen.tumourGrade", - "query": "analysis { specimen { tumourGrade } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.specimen.tumourGradingSystem", - "jsonPath": "$.analysis.specimen.tumourGradingSystem", - "query": "analysis { specimen { tumourGradingSystem } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.workflow.genomeBuild", - "jsonPath": "$.analysis.workflow.genomeBuild", - "query": "analysis { workflow { genomeBuild } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.workflow.inputs.analysisType", - "jsonPath": "$.analysis.workflow.inputs.hits.edges[*].node.analysisType", - "query": "analysis { workflow { inputs { hits { edges { node { analysisType } } } } } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.workflow.inputs.normalAnalysisId", - "jsonPath": "$.analysis.workflow.inputs.hits.edges[*].node.normalAnalysisId", - "query": "analysis { workflow { inputs { hits { edges { node { normalAnalysisId } } } } } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.workflow.inputs.tumourAnalysisId", - "jsonPath": "$.analysis.workflow.inputs.hits.edges[*].node.tumourAnalysisId", - "query": "analysis { workflow { inputs { hits { edges { node { tumourAnalysisId } } } } } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.workflow.runId", - "jsonPath": "$.analysis.workflow.runId", - "query": "analysis { workflow { runId } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.workflow.sessionId", - "jsonPath": "$.analysis.workflow.sessionId", - "query": "analysis { workflow { sessionId } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.workflow.workflowName", - "jsonPath": "$.analysis.workflow.workflowName", - "query": "analysis { workflow { workflowName } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.workflow.workflowShortName", - "jsonPath": "$.analysis.workflow.workflowShortName", - "query": "analysis { workflow { workflowShortName } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "analysis.workflow.workflowVersion", - "jsonPath": "$.analysis.workflow.workflowVersion", - "query": "analysis { workflow { workflowVersion } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "file.name", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "file.data_type", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "file.md5sum", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "displayType": "bytes", - "fieldName": "file.size", - "show": true, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "file.index_file.object_id", - "jsonPath": "$.file.index_file.object_id", - "query": "file { index_file { object_id } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "file.index_file.name", - "jsonPath": "$.file.index_file.name", - "query": "file { index_file { name } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "file.index_file.file_type", - "jsonPath": "$.file.index_file.file_type", - "query": "file { index_file { file_type } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "file.index_file.md5sum", - "jsonPath": "$.file.index_file.md5sum", - "query": "file { index_file { md5sum } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "file.index_file.data_type", - "jsonPath": "$.file.index_file.data_type", - "query": "file { index_file { data_type } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "file.index_file.size", - "jsonPath": "$.file.index_file.size", - "query": "file { index_file { size } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "donors.donor_id", - "jsonPath": "$.donors.hits.edges[*].node.donor_id", - "query": "donors { hits { edges { node { donor_id } } } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "donors.gender", - "jsonPath": "$.donors.hits.edges[*].node.gender", - "query": "donors { hits { edges { node { gender } } } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "donors.specimens.specimen_id", - "jsonPath": "$.donors.hits.edges[*].node.specimens.hits.edges[*].node.specimen_id", - "query": "donors { hits { edges { node { specimens { hits { edges { node { specimen_id } } } } } } } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "donors.specimens.specimen_type", - "jsonPath": "$.donors.hits.edges[*].node.specimens.hits.edges[*].node.specimen_type", - "query": "donors { hits { edges { node { specimens { hits { edges { node { specimen_type } } } } } } } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "donors.specimens.submitter_specimen_id", - "jsonPath": "$.donors.hits.edges[*].node.specimens.hits.edges[*].node.submitter_specimen_id", - "query": "donors { hits { edges { node { specimens { hits { edges { node { submitter_specimen_id } } } } } } } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "donors.specimens.samples.sample_id", - "jsonPath": "$.donors.hits.edges[*].node.specimens.hits.edges[*].node.samples.hits.edges[*].node.sample_id", - "query": "donors { hits { edges { node { specimens { hits { edges { node { samples { hits { edges { node { sample_id } } } } } } } } } } } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "donors.specimens.samples.submitter_sample_id", - "jsonPath": "$.donors.hits.edges[*].node.specimens.hits.edges[*].node.samples.hits.edges[*].node.submitter_sample_id", - "query": "donors { hits { edges { node { specimens { hits { edges { node { samples { hits { edges { node { submitter_sample_id } } } } } } } } } } } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "donors.specimens.samples.sample_type", - "jsonPath": "$.donors.hits.edges[*].node.specimens.hits.edges[*].node.samples.hits.edges[*].node.sample_type", - "query": "donors { hits { edges { node { specimens { hits { edges { node { samples { hits { edges { node { sample_type } } } } } } } } } } } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "donors.specimens.samples.matched_normal_submitter_sample_id", - "jsonPath": "$.donors.hits.edges[*].node.specimens.hits.edges[*].node.samples.hits.edges[*].node.matched_normal_submitter_sample_id", - "query": "donors { hits { edges { node { specimens { hits { edges { node { samples { hits { edges { node { matched_normal_submitter_sample_id } } } } } } } } } } } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "donors.specimens.tumour_normal_designation", - "jsonPath": "$.donors.hits.edges[*].node.specimens.hits.edges[*].node.tumour_normal_designation", - "query": "donors { hits { edges { node { specimens { hits { edges { node { tumour_normal_designation } } } } } } } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "donors.specimens.specimen_tissue_source", - "jsonPath": "$.donors.hits.edges[*].node.specimens.hits.edges[*].node.specimen_tissue_source", - "query": "donors { hits { edges { node { specimens { hits { edges { node { specimen_tissue_source } } } } } } } }", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "dataCategory", - "show": false, - "sortable": true - }, - { - "canChangeShow": true, - "fieldName": "jbrowseCoordinates", - "show": false, - "sortable": true - }, - { - "canChangeShow": false, - "fieldName": "repositories.code", - "jsonPath": "$.repositories.hits.edges[*].node.code", - "query": "repositories { hits { edges { node { code } } } }", - "show": false, - "sortable": true - } - ] - } -} \ No newline at end of file diff --git a/configurationFiles/elasticsearchConfigs/es-docs/02732061-9daf-5a64-99f5-c550320c7916.json b/configurationFiles/elasticsearchConfigs/es-docs/02732061-9daf-5a64-99f5-c550320c7916.json deleted file mode 100644 index 56c836ba..00000000 --- a/configurationFiles/elasticsearchConfigs/es-docs/02732061-9daf-5a64-99f5-c550320c7916.json +++ /dev/null @@ -1 +0,0 @@ -{"object_id": "02732061-9daf-5a64-99f5-c550320c7916", "study_id": "demo", "data_type": "Aligned Reads", "file_type": "CRAM", "file_access": "controlled", "analysis": {"analysis_id": "4ab918ab-a6e9-4cc8-b918-aba6e98cc8b1", "analysis_type": "quickStartSchema", "analysis_version": 1, "analysis_state": "PUBLISHED", "updated_at": 1720110840020, "first_published_at": 1720110840007, "published_at": 1720110840007, "experiment": {"model": "PromethION", "platform": "ONT", "sequencingDate": "2022-12-12T19:00:00.000Z", "sequencingCenter": "GATC", "experimentalStrategy": "WXS"}, "analysisStateHistory": [{"initialState": "UNPUBLISHED", "updatedState": "PUBLISHED", "updatedAt": "2024-07-04T16:34:00.007328"}], "collaborator": [{"name": "OICR", "contactEmail": "sturedman@micr.ca"}], "createdAt": "2024-07-04T16:20:48.424137", "donor": {"primarySite": "Brain", "vitalStatus": "Deceased", "causeOfDeath": "Died of cancer", "survivalTime": 1092, "primaryDiagnosis": [{"followUp": [{"relapseType": null, "intervalOfFollowUp": 95, "submitterFollowUpId": "FO923401", "submitterTreatmentId": "TR923401", "diseaseStatusAtFollowUp": "Relapse or recurrence"}], "treatment": [{"radiation": [{"anatomicalSiteIrradiated": "Neck", "radiationTherapyModality": "Heavy Ions"}], "chemotherapy": [{"drugName": "Azacitidine"}], "treatmentType": ["Chemotherapy", "Radiation therapy"], "treatmentDuration": 1, "responseToTreatment": "Partial response", "submitterTreatmentId": "TR923401", "treatmentStartInterval": 50}], "ageAtDiagnosis": 40, "cancerTypeCode": "C71.8", "clinicalStageGroup": "Stage I", "clinicalTumourStagingSystem": "Rai staging system", "submitterPrimaryDiagnosisId": "PD923401"}, {"followUp": [{"relapseType": null, "intervalOfFollowUp": 67, "submitterFollowUpId": "FO923402", "submitterTreatmentId": "TR923402", "diseaseStatusAtFollowUp": "No evidence of disease"}], "treatment": [{"chemotherapy": [{"drugName": "Tamoxifen"}], "treatmentType": ["Chemotherapy"], "treatmentDuration": 66, "responseToTreatment": "Complete response", "submitterTreatmentId": "TR923402", "treatmentStartInterval": 78}], "ageAtDiagnosis": 75, "cancerTypeCode": "C71.7", "clinicalStageGroup": "Stage II", "clinicalTumourStagingSystem": "St Jude staging system", "submitterPrimaryDiagnosisId": "PD923402"}], "submitterDonorId": "DO9234"}, "publication": {"doi": "10.1038/s41591-023-02650-10", "publication": "Nature"}, "specimen": {"tumourGrade": "G2", "submitterSpecimenId": "SP923402", "tumourGradingSystem": "Three-tier grading system", "specimenAnatomicLocation": "C60", "submitterPrimaryDiagnosisId": "PD923401"}, "workflow": {"runId": "RI9234", "inputs": [{"analysisId": "00000000-0000-0000-0000-0000000009234", "analysisType": "sequencing_experiment"}], "sessionId": "SI9234", "genomeBuild": "GRCh38_hla_decoy_ebv", "workflowName": "Bowtie2 Alignment", "workflowVersion": "0.1.0", "workflowShortName": "Bowtie2Aln"}}, "file": {"name": "SP923412.cram", "md5sum": "cc20167c878bd3302e91be057701686b", "size": 116014, "data_type": "Aligned Reads", "index_file": {"object_id": "f701f36d-c795-5dd4-9e4c-e9c33a9dd284", "name": "SP923412.cram.crai", "file_type": "CRAI", "md5sum": "114d6d5a7568666bb5fe3b365197f137", "data_type": "Aligned Reads", "size": 52, "dataCategory": "Sequencing Reads", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "dataCategory": "Sequencing Reads", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "repositories": [{"code": "song.overture", "organization": "Overture", "name": "Overture", "type": "S3", "country": "CA", "url": "http://song:8080"}], "donors": [{"donor_id": "986121a4-adf0-570b-8a4d-7ef5e63ad06a", "submitter_donor_id": "DO9234", "gender": "Male", "specimens": [{"specimen_id": "40d1385d-6a3c-575c-994b-3fab94bc9c66", "specimen_type": "Tumour - unknown if derived from primary or metastatic", "submitter_specimen_id": "SP923412", "samples": [{"sample_id": "40d1385d-6a3c-575c-994b-3fab94bc9c66", "submitter_sample_id": "SP923412", "sample_type": "Total DNA", "matched_normal_submitter_sample_id": "SP923402"}], "tumour_normal_designation": "Tumour", "specimen_tissue_source": "Lymph node"}]}], "dataCategory": "Sequencing Reads", "jbrowseCoordinates": "hg38:chr1:100000-200000"} \ No newline at end of file diff --git a/configurationFiles/elasticsearchConfigs/es-docs/190e1812-563f-5158-9b35-0925edea4a1d.json b/configurationFiles/elasticsearchConfigs/es-docs/190e1812-563f-5158-9b35-0925edea4a1d.json deleted file mode 100644 index 383187b0..00000000 --- a/configurationFiles/elasticsearchConfigs/es-docs/190e1812-563f-5158-9b35-0925edea4a1d.json +++ /dev/null @@ -1 +0,0 @@ -{"object_id": "190e1812-563f-5158-9b35-0925edea4a1d", "study_id": "demo", "data_type": "Aligned Reads", "file_type": "BAM", "file_access": "controlled", "analysis": {"analysis_id": "dc444dde-ffe1-4ffd-844d-deffe19ffd49", "analysis_type": "quickStartSchema", "analysis_version": 1, "analysis_state": "PUBLISHED", "updated_at": 1720110731277, "first_published_at": 1720110731270, "published_at": 1720110731270, "experiment": {"model": "PromethION", "platform": "ONT", "sequencingDate": "2022-12-12T19:00:00.000Z", "sequencingCenter": "GATC", "experimentalStrategy": "WGS"}, "analysisStateHistory": [{"initialState": "UNPUBLISHED", "updatedState": "PUBLISHED", "updatedAt": "2024-07-04T16:32:11.270145"}], "collaborator": [{"name": "OICR", "contactEmail": "sturedman@micr.ca"}], "createdAt": "2024-07-04T16:20:30.946428", "donor": {"primarySite": "Bronchus and lung", "vitalStatus": "Alive", "causeOfDeath": null, "survivalTime": null, "primaryDiagnosis": [{"followUp": [{"relapseType": null, "intervalOfFollowUp": 74, "submitterFollowUpId": "FO745301", "submitterTreatmentId": "TR745301", "diseaseStatusAtFollowUp": "Relapse or recurrence"}], "treatment": [{"treatmentType": ["Hormonal therapy"], "hormoneTherapy": [{"drugName": "Letrozole"}], "treatmentDuration": 32, "responseToTreatment": "Partial response", "submitterTreatmentId": "TR745301", "treatmentStartInterval": 38}], "ageAtDiagnosis": 30, "cancerTypeCode": "C34.3", "clinicalStageGroup": "Stage IB1", "clinicalTumourStagingSystem": "FIGO staging system", "submitterPrimaryDiagnosisId": "PD745301"}, {"followUp": [{"relapseType": null, "intervalOfFollowUp": 46, "submitterFollowUpId": "FO745302", "submitterTreatmentId": "TR745302", "diseaseStatusAtFollowUp": "Relapse or recurrence"}], "treatment": [{"chemotherapy": [{"drugName": "Tamoxifen"}], "treatmentType": ["Chemotherapy"], "treatmentDuration": 44, "responseToTreatment": "Disease progression", "submitterTreatmentId": "TR745302", "treatmentStartInterval": 82}], "ageAtDiagnosis": 20, "cancerTypeCode": "C34.8", "clinicalStageGroup": "Stage III", "clinicalTumourStagingSystem": "Ann Arbor staging system", "submitterPrimaryDiagnosisId": "PD745302"}], "submitterDonorId": "DO7453"}, "publication": {"doi": "10.1038/s41591-023-02650-10", "publication": "Nature"}, "specimen": {"tumourGrade": "Grade Group 3", "submitterSpecimenId": "SP745302", "tumourGradingSystem": "Gleason grade group system", "specimenAnatomicLocation": "C53", "submitterPrimaryDiagnosisId": "PD745301"}, "workflow": {"runId": "RI7453", "inputs": [{"analysisId": "00000000-0000-0000-0000-0000000007453", "analysisType": "sequencing_experiment"}], "sessionId": "SI7453", "genomeBuild": "GRCh38_hla_decoy_ebv", "workflowName": "BWA mem2 Alignment", "workflowVersion": "0.8", "workflowShortName": "BWAmem2Aln"}}, "file": {"name": "SP745312.bam", "md5sum": "99a812795e2c6cb4df2fcfe9c26981fe", "size": 125283, "data_type": "Aligned Reads", "index_file": {"object_id": "0dc8a919-fdd0-5c59-b2ea-c654f93279b9", "name": "SP745312.bam.bai", "file_type": "BAI", "md5sum": "4b3a3c832b21ef7f7278b071f2245169", "data_type": "Aligned Reads", "size": 27136, "dataCategory": "Sequencing Reads", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "dataCategory": "Sequencing Reads", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "repositories": [{"code": "song.overture", "organization": "Overture", "name": "Overture", "type": "S3", "country": "CA", "url": "http://song:8080"}], "donors": [{"donor_id": "663b8536-90a9-51d3-abda-695771e751d0", "submitter_donor_id": "DO7453", "gender": "Male", "specimens": [{"specimen_id": "0874380c-c470-5844-a4a4-5310ddbbac4b", "specimen_type": "Metastatic tumour - additional metastatic", "submitter_specimen_id": "SP745312", "samples": [{"sample_id": "0874380c-c470-5844-a4a4-5310ddbbac4b", "submitter_sample_id": "SP745312", "sample_type": "ctDNA", "matched_normal_submitter_sample_id": "SP745302"}], "tumour_normal_designation": "Tumour", "specimen_tissue_source": "Solid tissue"}]}], "dataCategory": "Sequencing Reads", "jbrowseCoordinates": "hg38:chr1:100000-200000"} \ No newline at end of file diff --git a/configurationFiles/elasticsearchConfigs/es-docs/22a0f109-77ac-5c09-b3e4-26a783e898c1.json b/configurationFiles/elasticsearchConfigs/es-docs/22a0f109-77ac-5c09-b3e4-26a783e898c1.json deleted file mode 100644 index a4616e92..00000000 --- a/configurationFiles/elasticsearchConfigs/es-docs/22a0f109-77ac-5c09-b3e4-26a783e898c1.json +++ /dev/null @@ -1 +0,0 @@ -{"object_id": "22a0f109-77ac-5c09-b3e4-26a783e898c1", "study_id": "demo", "data_type": "Aligned Reads", "file_type": "BAM", "file_access": "controlled", "analysis": {"analysis_id": "d99bcc91-7dfd-415b-9bcc-917dfdd15bee", "analysis_type": "quickStartSchema", "analysis_version": 1, "analysis_state": "PUBLISHED", "updated_at": 1720110980483, "first_published_at": 1720110980465, "published_at": 1720110980465, "experiment": {"model": "SEQUEL IIe", "platform": "PacBio", "sequencingDate": "2021-03-08T19:00:00.000Z", "sequencingCenter": "CGTA", "experimentalStrategy": "WGS"}, "analysisStateHistory": [{"initialState": "UNPUBLISHED", "updatedState": "PUBLISHED", "updatedAt": "2024-07-04T16:36:20.465757"}], "collaborator": [{"name": "AICR", "contactEmail": "raygarraty@aicr.ca"}], "createdAt": "2024-07-04T16:21:10.418976", "donor": {"primarySite": "Hematopoietic and reticuloendothelial systems", "vitalStatus": "Alive", "causeOfDeath": null, "survivalTime": null, "primaryDiagnosis": [{"followUp": [{"relapseType": null, "intervalOfFollowUp": 90, "submitterFollowUpId": "FO849001", "submitterTreatmentId": "TR849001", "diseaseStatusAtFollowUp": "Loco-regional progression"}], "treatment": [{"chemotherapy": [{"drugName": "Tamoxifen "}], "treatmentType": ["Chemotherapy", "Hormonal therapy"], "hormoneTherapy": [{"drugName": "Letrozole "}], "treatmentDuration": 72, "responseToTreatment": "Partial response", "submitterTreatmentId": "TR849001", "treatmentStartInterval": 9}], "ageAtDiagnosis": 78, "cancerTypeCode": "C88.3", "clinicalStageGroup": "Stage C", "clinicalTumourStagingSystem": "Binet staging system", "submitterPrimaryDiagnosisId": "PD849001"}], "submitterDonorId": "DO8490"}, "publication": {"doi": "10.1093/nar/gkae188", "publication": "NAR"}, "specimen": {"tumourGrade": "Grade III", "submitterSpecimenId": "SP849001", "tumourGradingSystem": "WHO grading system for CNS tumours", "specimenAnatomicLocation": "C42", "submitterPrimaryDiagnosisId": "PD849001"}, "workflow": {"runId": "RI8490", "inputs": [{"analysisId": "00000000-0000-0000-0000-0000000008490", "analysisType": "sequencing_experiment"}], "sessionId": "SI8490", "genomeBuild": "GRCh38_hla_decoy_ebv", "workflowName": "BWA mem2 Alignment", "workflowVersion": "0.8", "workflowShortName": "BWAmem2Aln"}}, "file": {"name": "SP849001.bam", "md5sum": "c1b6423c50b84e87453d5eb49c31c524", "size": 125266, "data_type": "Aligned Reads", "index_file": {"object_id": "b00c7461-46bb-57e3-918f-4592cb32df23", "name": "SP849001.bam.bai", "file_type": "BAI", "md5sum": "98bcf6ebd70311cb260e8555ce80466c", "data_type": "Aligned Reads", "size": 27280, "dataCategory": "Sequencing Reads", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "dataCategory": "Sequencing Reads", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "repositories": [{"code": "song.overture", "organization": "Overture", "name": "Overture", "type": "S3", "country": "CA", "url": "http://song:8080"}], "donors": [{"donor_id": "8a9d8e34-f9ce-5f5d-8b19-621e5c02ecba", "submitter_donor_id": "DO8490", "gender": "Male", "specimens": [{"specimen_id": "67b10bda-c3f5-5f6d-bce5-94e3e2e29d61", "specimen_type": "Normal - tissue adjacent to primary tumour", "submitter_specimen_id": "SP849001", "samples": [{"sample_id": "67b10bda-c3f5-5f6d-bce5-94e3e2e29d61", "submitter_sample_id": "SP849001", "sample_type": "Total DNA", "matched_normal_submitter_sample_id": null}], "tumour_normal_designation": "Normal", "specimen_tissue_source": "Intestine"}]}], "dataCategory": "Sequencing Reads", "jbrowseCoordinates": "hg38:chr1:100000-200000"} \ No newline at end of file diff --git a/configurationFiles/elasticsearchConfigs/es-docs/2c7b355a-c47b-5cd6-8268-f3ace739eef6.json b/configurationFiles/elasticsearchConfigs/es-docs/2c7b355a-c47b-5cd6-8268-f3ace739eef6.json deleted file mode 100644 index d348289a..00000000 --- a/configurationFiles/elasticsearchConfigs/es-docs/2c7b355a-c47b-5cd6-8268-f3ace739eef6.json +++ /dev/null @@ -1 +0,0 @@ -{"object_id": "2c7b355a-c47b-5cd6-8268-f3ace739eef6", "study_id": "demo", "data_type": "Raw SV Calls", "file_type": "VCF", "file_access": "controlled", "analysis": {"analysis_id": "d2f28fe6-7fef-4b44-b28f-e67fefcb447f", "analysis_type": "quickStartSchema", "analysis_version": 1, "analysis_state": "PUBLISHED", "updated_at": 1720111037628, "first_published_at": 1720111037616, "published_at": 1720111037616, "experiment": {"model": "SEQUEL IIe", "platform": "PacBio", "sequencingDate": "2021-03-08T19:00:00.000Z", "sequencingCenter": "CGTA", "experimentalStrategy": "WGS"}, "analysisStateHistory": [{"initialState": "UNPUBLISHED", "updatedState": "PUBLISHED", "updatedAt": "2024-07-04T16:37:17.61609"}], "collaborator": [{"name": "AICR", "contactEmail": "raygarraty@aicr.ca"}], "createdAt": "2024-07-04T16:21:19.167795", "donor": {"primarySite": "Bronchus and lung", "vitalStatus": "Deceased", "causeOfDeath": "Died of other reasons", "survivalTime": 1108, "primaryDiagnosis": [{"followUp": [{"relapseType": null, "intervalOfFollowUp": 92, "submitterFollowUpId": "FO945801", "submitterTreatmentId": "TR945801", "diseaseStatusAtFollowUp": "Relapse or recurrence"}], "treatment": [{"treatmentType": ["No treatment"], "submitterTreatmentId": "TR945801"}], "ageAtDiagnosis": 44, "cancerTypeCode": "C34.3", "clinicalStageGroup": "Stage IA2", "clinicalTumourStagingSystem": "FIGO staging system", "submitterPrimaryDiagnosisId": "PD945801"}, {"followUp": [{"relapseType": null, "intervalOfFollowUp": 33, "submitterFollowUpId": "FO945802", "submitterTreatmentId": "TR945802", "diseaseStatusAtFollowUp": "Relapse or recurrence"}], "treatment": [{"treatmentType": ["Hormonal therapy"], "hormoneTherapy": [{"drugName": "Exemestane "}], "treatmentDuration": 61, "responseToTreatment": "Complete response", "submitterTreatmentId": "TR945802", "treatmentStartInterval": 11}], "ageAtDiagnosis": 3, "cancerTypeCode": "C34.3", "clinicalStageGroup": "Stage IIIC", "clinicalTumourStagingSystem": "AJCC 7th edition", "submitterPrimaryDiagnosisId": "PD945802"}], "submitterDonorId": "DO9458"}, "publication": {"doi": "10.1093/nar/gkae188", "publication": "NAR"}, "specimen": {"tumourGrade": "Grade IV", "submitterSpecimenId": "SP945802", "tumourGradingSystem": "WHO grading system for CNS tumours", "specimenAnatomicLocation": "C77", "submitterPrimaryDiagnosisId": "PD945801"}, "workflow": {"runId": "RI9458", "inputs": [{"analysisType": "sequencing_alignment", "normalAnalysisId": "00000000-0000-0000-0000-0000000009458", "tumourAnalysisId": "00000000-0000-0000-0000-0000000009458"}], "sessionId": "SI9458", "genomeBuild": "GRCh38_hla_decoy_ebv", "workflowName": "Mutect2 Variant Calling", "workflowVersion": "0.1.1.1", "workflowShortName": "Mutect2Variant"}}, "file": {"name": "SP945802.snv.vcf.gz", "md5sum": "88ac07b88db7f194099614cf958906d5", "size": 17245, "data_type": "Raw SV Calls", "index_file": {"object_id": "8b593ddb-9c57-550d-ae66-8f5122e73de9", "name": "SP945802.snv.vcf.gz.tbi", "file_type": "TBI", "md5sum": "222c2bc2b6a00051183cc4630b3fb6f2", "data_type": "Raw SV Calls", "size": 146, "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "repositories": [{"code": "song.overture", "organization": "Overture", "name": "Overture", "type": "S3", "country": "CA", "url": "http://song:8080"}], "donors": [{"donor_id": "d9e8cd4c-48c8-5a56-9d87-8217370fc72d", "submitter_donor_id": "DO9458", "gender": "Female", "specimens": [{"specimen_id": "a06e50f0-834c-5519-b0aa-e288e5bab794", "specimen_type": "Normal", "submitter_specimen_id": "SP945802", "samples": [{"sample_id": "a06e50f0-834c-5519-b0aa-e288e5bab794", "submitter_sample_id": "SP945802", "sample_type": "Total DNA", "matched_normal_submitter_sample_id": null}], "tumour_normal_designation": "Normal", "specimen_tissue_source": "Blood derived - peripheral blood"}]}], "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"} \ No newline at end of file diff --git a/configurationFiles/elasticsearchConfigs/es-docs/38a0187c-203a-5669-83b8-d074e7362783.json b/configurationFiles/elasticsearchConfigs/es-docs/38a0187c-203a-5669-83b8-d074e7362783.json deleted file mode 100644 index 1e6b356f..00000000 --- a/configurationFiles/elasticsearchConfigs/es-docs/38a0187c-203a-5669-83b8-d074e7362783.json +++ /dev/null @@ -1 +0,0 @@ -{"object_id": "38a0187c-203a-5669-83b8-d074e7362783", "study_id": "demo", "data_type": "Raw InDel Calls", "file_type": "VCF", "file_access": "open", "analysis": {"analysis_id": "e64f132b-3020-48c9-8f13-2b302058c94d", "analysis_type": "quickStartSchema", "analysis_version": 1, "analysis_state": "PUBLISHED", "updated_at": 1720110312313, "first_published_at": 1720110312219, "published_at": 1720110312219, "experiment": {"model": "SEQUEL IIe", "platform": "PacBio", "sequencingDate": "2021-03-08T19:00:00.000Z", "sequencingCenter": "CGTA", "experimentalStrategy": "WXS"}, "analysisStateHistory": [{"initialState": "UNPUBLISHED", "updatedState": "PUBLISHED", "updatedAt": "2024-07-04T16:25:12.219162"}], "collaborator": [{"name": "MICR", "contactEmail": "susannorton@micr.ca"}], "createdAt": "2024-07-04T16:19:12.161284", "donor": {"primarySite": "Bronchus and lung", "vitalStatus": "Deceased", "causeOfDeath": "Died of other reasons", "survivalTime": 439, "primaryDiagnosis": [{"followUp": [{"relapseType": null, "intervalOfFollowUp": 50, "submitterFollowUpId": "FO011501", "submitterTreatmentId": "TR011501", "diseaseStatusAtFollowUp": "Partial remission"}], "treatment": [{"chemotherapy": [{"drugName": "Azacitidine "}], "treatmentType": ["Chemotherapy"], "treatmentDuration": 34, "responseToTreatment": "Minor response", "submitterTreatmentId": "TR011501", "treatmentStartInterval": 79}], "ageAtDiagnosis": 36, "cancerTypeCode": "C34.3", "clinicalStageGroup": "Stage III", "clinicalTumourStagingSystem": "AJCC 6th edition", "submitterPrimaryDiagnosisId": "PD011501"}, {"followUp": [{"relapseType": null, "intervalOfFollowUp": 33, "submitterFollowUpId": "FO011502", "submitterTreatmentId": "TR011502", "diseaseStatusAtFollowUp": "Relapse or recurrence"}], "treatment": [{"radiation": [{"anatomicalSiteIrradiated": "Body", "radiationTherapyModality": "Photon"}], "chemotherapy": [{"drugName": "Paclitaxel "}], "treatmentType": ["Chemotherapy", "Radiation therapy"], "treatmentDuration": 56, "responseToTreatment": "Complete response", "submitterTreatmentId": "TR011502", "treatmentStartInterval": 70}], "ageAtDiagnosis": 1, "cancerTypeCode": "C34.2", "clinicalStageGroup": "Stage IB", "clinicalTumourStagingSystem": "FIGO staging system", "submitterPrimaryDiagnosisId": "PD011502"}], "submitterDonorId": "DO0115"}, "publication": {"doi": "10.1093/nar/gkae188", "publication": "NAR"}, "specimen": {"tumourGrade": "G2", "submitterSpecimenId": "SP011501", "tumourGradingSystem": "Grading system for GNETs", "specimenAnatomicLocation": "C01", "submitterPrimaryDiagnosisId": "PD011501"}, "workflow": {"runId": "RI0115", "inputs": [{"analysisType": "sequencing_alignment", "normalAnalysisId": "00000000-0000-0000-0000-0000000000115", "tumourAnalysisId": "00000000-0000-0000-0000-0000000000115"}], "sessionId": "SI0115", "genomeBuild": "GRCh38_hla_decoy_ebv", "workflowName": "Sanger Variant Calling", "workflowVersion": "0.9.8", "workflowShortName": "SangerVariant"}}, "file": {"name": "SP011501.indel.vcf.gz", "md5sum": "a5e32b78bd52dc2cfe1cffcdaadcb335", "size": 17346, "data_type": "Raw InDel Calls", "index_file": {"object_id": "b2d7d5be-d3bd-5cdd-b4d0-924cf4236212", "name": "SP011501.indel.vcf.gz.tbi", "file_type": "TBI", "md5sum": "e4d3b0751f2824bac22f42147dd41fd8", "data_type": "Raw InDel Calls", "size": 144, "dataCategory": "Simple Nucleotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "dataCategory": "Simple Nucleotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "repositories": [{"code": "song.overture", "organization": "Overture", "name": "Overture", "type": "S3", "country": "CA", "url": "http://song:8080"}], "donors": [{"donor_id": "1a0cc916-465c-5b06-8eb7-c4fa438e496f", "submitter_donor_id": "DO0115", "gender": "Female", "specimens": [{"specimen_id": "e61a520b-56d9-541c-9265-10f2e5ecea8e", "specimen_type": "Normal - tissue adjacent to primary tumour", "submitter_specimen_id": "SP011501", "samples": [{"sample_id": "e61a520b-56d9-541c-9265-10f2e5ecea8e", "submitter_sample_id": "SP011501", "sample_type": "Total DNA", "matched_normal_submitter_sample_id": null}], "tumour_normal_designation": "Normal", "specimen_tissue_source": "Solid tissue"}]}], "dataCategory": "Simple Nucleotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"} \ No newline at end of file diff --git a/configurationFiles/elasticsearchConfigs/es-docs/41bde62d-e63e-5b4a-a8ea-58aa63b1e6e9.json b/configurationFiles/elasticsearchConfigs/es-docs/41bde62d-e63e-5b4a-a8ea-58aa63b1e6e9.json deleted file mode 100644 index 239abec4..00000000 --- a/configurationFiles/elasticsearchConfigs/es-docs/41bde62d-e63e-5b4a-a8ea-58aa63b1e6e9.json +++ /dev/null @@ -1 +0,0 @@ -{"object_id": "41bde62d-e63e-5b4a-a8ea-58aa63b1e6e9", "study_id": "demo", "data_type": "Raw InDel Calls", "file_type": "VCF", "file_access": "controlled", "analysis": {"analysis_id": "73fe3958-a60d-4a21-be39-58a60d5a214d", "analysis_type": "quickStartSchema", "analysis_version": 1, "analysis_state": "PUBLISHED", "updated_at": 1720110813710, "first_published_at": 1720110813703, "published_at": 1720110813703, "experiment": {"model": "PromethION", "platform": "ONT", "sequencingDate": "2022-12-12T19:00:00.000Z", "sequencingCenter": "GATC", "experimentalStrategy": "WXS"}, "analysisStateHistory": [{"initialState": "UNPUBLISHED", "updatedState": "PUBLISHED", "updatedAt": "2024-07-04T16:33:33.703455"}], "collaborator": [{"name": "OICR", "contactEmail": "sturedman@micr.ca"}], "createdAt": "2024-07-04T16:20:44.141154", "donor": {"primarySite": "Bronchus and lung", "vitalStatus": "Alive", "causeOfDeath": null, "survivalTime": null, "primaryDiagnosis": [{"followUp": [{"relapseType": null, "intervalOfFollowUp": 28, "submitterFollowUpId": "FO859001", "submitterTreatmentId": "TR859001", "diseaseStatusAtFollowUp": "Distant progression"}], "treatment": [{"radiation": [{"anatomicalSiteIrradiated": "Body", "radiationTherapyModality": "Proton"}], "treatmentType": ["Hormonal therapy", "Radiation therapy"], "hormoneTherapy": [{"drugName": "Anastrozole"}], "treatmentDuration": 30, "responseToTreatment": "Minor response", "submitterTreatmentId": "TR859001", "treatmentStartInterval": 58}], "ageAtDiagnosis": 63, "cancerTypeCode": "C34.2", "clinicalStageGroup": "Stage IIIC1", "clinicalTumourStagingSystem": "AJCC 6th edition", "submitterPrimaryDiagnosisId": "PD859001"}, {"followUp": [{"relapseType": null, "intervalOfFollowUp": 71, "submitterFollowUpId": "FO859002", "submitterTreatmentId": "TR859002", "diseaseStatusAtFollowUp": "Relapse or recurrence"}], "treatment": [{"chemotherapy": [{"drugName": "Paclitaxel"}], "treatmentType": ["Chemotherapy"], "treatmentDuration": 32, "responseToTreatment": "Stable disease", "submitterTreatmentId": "TR859002", "treatmentStartInterval": 59}], "ageAtDiagnosis": 14, "cancerTypeCode": "C34.2", "clinicalStageGroup": "Stage III", "clinicalTumourStagingSystem": "Durie-Salmon staging system", "submitterPrimaryDiagnosisId": "PD859002"}], "submitterDonorId": "DO8590"}, "publication": {"doi": "10.1038/s41591-023-02650-10", "publication": "Nature"}, "specimen": {"tumourGrade": "Grade Group 1", "submitterSpecimenId": "SP859001", "tumourGradingSystem": "Gleason grade group system", "specimenAnatomicLocation": "C87", "submitterPrimaryDiagnosisId": "PD859001"}, "workflow": {"runId": "RI8590", "inputs": [{"analysisType": "sequencing_alignment", "normalAnalysisId": "00000000-0000-0000-0000-0000000008590", "tumourAnalysisId": "00000000-0000-0000-0000-0000000008590"}], "sessionId": "SI8590", "genomeBuild": "GRCh38_hla_decoy_ebv", "workflowName": "Mutect2 Variant Calling", "workflowVersion": "0.1.1.1", "workflowShortName": "Mutect2Variant"}}, "file": {"name": "SP859001.indel.vcf.gz", "md5sum": "9ffbd86a4a5562e8bb686030f7314f5d", "size": 17380, "data_type": "Raw InDel Calls", "index_file": {"object_id": "a22f4c66-0f46-564b-b2ee-ea46cd18ad98", "name": "SP859001.indel.vcf.gz.tbi", "file_type": "TBI", "md5sum": "20de00567d1ae550f4b6ad894b817c12", "data_type": "Raw InDel Calls", "size": 150, "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "repositories": [{"code": "song.overture", "organization": "Overture", "name": "Overture", "type": "S3", "country": "CA", "url": "http://song:8080"}], "donors": [{"donor_id": "65019938-ce2c-5c63-8a40-715ef3c9a904", "submitter_donor_id": "DO8590", "gender": "Female", "specimens": [{"specimen_id": "a4f27813-933f-5b52-9834-03e8c311dc9d", "specimen_type": "Normal", "submitter_specimen_id": "SP859001", "samples": [{"sample_id": "a4f27813-933f-5b52-9834-03e8c311dc9d", "submitter_sample_id": "SP859001", "sample_type": "Total DNA", "matched_normal_submitter_sample_id": null}], "tumour_normal_designation": "Normal", "specimen_tissue_source": "Blood derived"}]}], "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"} \ No newline at end of file diff --git a/configurationFiles/elasticsearchConfigs/es-docs/44a53c0b-4622-5602-a958-338891712724.json b/configurationFiles/elasticsearchConfigs/es-docs/44a53c0b-4622-5602-a958-338891712724.json deleted file mode 100644 index 8060c838..00000000 --- a/configurationFiles/elasticsearchConfigs/es-docs/44a53c0b-4622-5602-a958-338891712724.json +++ /dev/null @@ -1 +0,0 @@ -{"object_id": "44a53c0b-4622-5602-a958-338891712724", "study_id": "demo", "data_type": "Raw SV Calls", "file_type": "VCF", "file_access": "controlled", "analysis": {"analysis_id": "72a383c6-2cbe-4278-a383-c62cbe72784a", "analysis_type": "quickStartSchema", "analysis_version": 1, "analysis_state": "PUBLISHED", "updated_at": 1720110522187, "first_published_at": 1720110522161, "published_at": 1720110522161, "experiment": {"model": "SEQUEL IIe", "platform": "PacBio", "sequencingDate": "2021-03-08T19:00:00.000Z", "sequencingCenter": "CGTA", "experimentalStrategy": "WXS"}, "analysisStateHistory": [{"initialState": "UNPUBLISHED", "updatedState": "PUBLISHED", "updatedAt": "2024-07-04T16:28:42.161777"}], "collaborator": [{"name": "MICR", "contactEmail": "susannorton@micr.ca"}], "createdAt": "2024-07-04T16:19:54.746322", "donor": {"primarySite": "Brain", "vitalStatus": "Deceased", "causeOfDeath": "Died of other reasons", "survivalTime": 216, "primaryDiagnosis": [{"followUp": [{"relapseType": null, "intervalOfFollowUp": 78, "submitterFollowUpId": "FO852501", "submitterTreatmentId": "TR852501", "diseaseStatusAtFollowUp": "Distant progression"}], "treatment": [{"radiation": [{"anatomicalSiteIrradiated": "Lung", "radiationTherapyModality": "Proton"}], "chemotherapy": [{"drugName": "Paclitaxel "}], "treatmentType": ["Chemotherapy", "Hormonal therapy", "Radiation therapy"], "hormoneTherapy": [{"drugName": "Anastrozole "}], "treatmentDuration": 78, "responseToTreatment": "Minor response", "submitterTreatmentId": "TR852501", "treatmentStartInterval": 15}], "ageAtDiagnosis": 59, "cancerTypeCode": "C71.1", "clinicalStageGroup": "Stage IVB", "clinicalTumourStagingSystem": "FIGO staging system", "submitterPrimaryDiagnosisId": "PD852501"}, {"followUp": [{"relapseType": null, "intervalOfFollowUp": 40, "submitterFollowUpId": "FO852502", "submitterTreatmentId": "TR852502", "diseaseStatusAtFollowUp": "Distant progression"}], "treatment": [{"chemotherapy": [{"drugName": "Tamoxifen "}], "treatmentType": ["Chemotherapy", "Hormonal therapy"], "hormoneTherapy": [{"drugName": "Anastrozole "}], "treatmentDuration": 86, "responseToTreatment": "Complete response", "submitterTreatmentId": "TR852502", "treatmentStartInterval": 8}], "ageAtDiagnosis": 32, "cancerTypeCode": "C71.7", "clinicalStageGroup": "Stage IIIB", "clinicalTumourStagingSystem": "Durie-Salmon staging system", "submitterPrimaryDiagnosisId": "PD852502"}], "submitterDonorId": "DO8525"}, "publication": {"doi": "10.1093/nar/gkae188", "publication": "NAR"}, "specimen": {"tumourGrade": "G2", "submitterSpecimenId": "SP852501", "tumourGradingSystem": "Three-tier grading system", "specimenAnatomicLocation": "C65", "submitterPrimaryDiagnosisId": "PD852501"}, "workflow": {"runId": "RI8525", "inputs": [{"analysisType": "sequencing_alignment", "normalAnalysisId": "00000000-0000-0000-0000-0000000008525", "tumourAnalysisId": "00000000-0000-0000-0000-0000000008525"}], "sessionId": "SI8525", "genomeBuild": "GRCh38_hla_decoy_ebv", "workflowName": "Mutect2 Variant Calling", "workflowVersion": "0.1.1.1", "workflowShortName": "Mutect2Variant"}}, "file": {"name": "SP852511.snv.vcf.gz", "md5sum": "3879f75773626af1ddf231684517cdff", "size": 17248, "data_type": "Raw SV Calls", "index_file": {"object_id": "900dd0e0-5f18-51c8-8dc6-a3b91b6acd9c", "name": "SP852511.snv.vcf.gz.tbi", "file_type": "TBI", "md5sum": "8211e43de0e47830a67b016265f21977", "data_type": "Raw SV Calls", "size": 146, "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "repositories": [{"code": "song.overture", "organization": "Overture", "name": "Overture", "type": "S3", "country": "CA", "url": "http://song:8080"}], "donors": [{"donor_id": "448815c8-cc3e-5149-9d81-5a6d369e743e", "submitter_donor_id": "DO8525", "gender": "Other", "specimens": [{"specimen_id": "f308e1d5-03ce-591f-87f0-1efd25c7ebe2", "specimen_type": "Tumour - unknown if derived from primary or metastatic", "submitter_specimen_id": "SP852511", "samples": [{"sample_id": "f308e1d5-03ce-591f-87f0-1efd25c7ebe2", "submitter_sample_id": "SP852511", "sample_type": "Amplified DNA", "matched_normal_submitter_sample_id": "SP852501"}], "tumour_normal_designation": "Tumour", "specimen_tissue_source": "Blood derived - bone marrow"}]}], "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"} \ No newline at end of file diff --git a/configurationFiles/elasticsearchConfigs/es-docs/4ec2c13a-e03d-516c-b393-ece343963eb9.json b/configurationFiles/elasticsearchConfigs/es-docs/4ec2c13a-e03d-516c-b393-ece343963eb9.json deleted file mode 100644 index 09f21d72..00000000 --- a/configurationFiles/elasticsearchConfigs/es-docs/4ec2c13a-e03d-516c-b393-ece343963eb9.json +++ /dev/null @@ -1 +0,0 @@ -{"object_id": "4ec2c13a-e03d-516c-b393-ece343963eb9", "study_id": "demo", "data_type": "Raw SV Calls", "file_type": "VCF", "file_access": "controlled", "analysis": {"analysis_id": "5c967063-19e2-4eec-9670-6319e28eecf0", "analysis_type": "quickStartSchema", "analysis_version": 1, "analysis_state": "PUBLISHED", "updated_at": 1720110927898, "first_published_at": 1720110927871, "published_at": 1720110927871, "experiment": {"model": "SEQUEL IIe", "platform": "PacBio", "sequencingDate": "2021-03-08T19:00:00.000Z", "sequencingCenter": "CGTA", "experimentalStrategy": "WXS"}, "analysisStateHistory": [{"initialState": "UNPUBLISHED", "updatedState": "PUBLISHED", "updatedAt": "2024-07-04T16:35:27.87161"}], "collaborator": [{"name": "AICR", "contactEmail": "raygarraty@aicr.ca"}], "createdAt": "2024-07-04T16:21:01.362111", "donor": {"primarySite": "Brain", "vitalStatus": "Alive", "causeOfDeath": null, "survivalTime": null, "primaryDiagnosis": [{"followUp": [{"relapseType": null, "intervalOfFollowUp": 5, "submitterFollowUpId": "FO933301", "submitterTreatmentId": "TR933301", "diseaseStatusAtFollowUp": "Stable"}], "treatment": [{"chemotherapy": [{"drugName": "Azacitidine "}], "treatmentType": ["Chemotherapy", "Hormonal therapy"], "hormoneTherapy": [{"drugName": "Exemestane "}], "treatmentDuration": 59, "responseToTreatment": "Complete response", "submitterTreatmentId": "TR933301", "treatmentStartInterval": 57}], "ageAtDiagnosis": 30, "cancerTypeCode": "C71.6", "clinicalStageGroup": "Stage I", "clinicalTumourStagingSystem": "Rai staging system", "submitterPrimaryDiagnosisId": "PD933301"}], "submitterDonorId": "DO9333"}, "publication": {"doi": "10.1093/nar/gkae188", "publication": "NAR"}, "specimen": {"tumourGrade": "Grade IV", "submitterSpecimenId": "SP933301", "tumourGradingSystem": "WHO grading system for CNS tumours", "specimenAnatomicLocation": "C15", "submitterPrimaryDiagnosisId": "PD933301"}, "workflow": {"runId": "RI9333", "inputs": [{"analysisType": "sequencing_alignment", "normalAnalysisId": "00000000-0000-0000-0000-0000000009333", "tumourAnalysisId": "00000000-0000-0000-0000-0000000009333"}], "sessionId": "SI9333", "genomeBuild": "GRCh38_hla_decoy_ebv", "workflowName": "Sanger Variant Calling", "workflowVersion": "0.9.8", "workflowShortName": "SangerVariant"}}, "file": {"name": "SP933311.snv.vcf.gz", "md5sum": "5d9afaaf221b44f17c0f12eb2b440f2a", "size": 17250, "data_type": "Raw SV Calls", "index_file": {"object_id": "782f544a-be42-5425-9649-44a7523800bc", "name": "SP933311.snv.vcf.gz.tbi", "file_type": "TBI", "md5sum": "f3459ce35d70fcf8dc7afe4da93e15af", "data_type": "Raw SV Calls", "size": 158, "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "repositories": [{"code": "song.overture", "organization": "Overture", "name": "Overture", "type": "S3", "country": "CA", "url": "http://song:8080"}], "donors": [{"donor_id": "fcd59878-cc3a-5223-8152-50942ca28bef", "submitter_donor_id": "DO9333", "gender": "Other", "specimens": [{"specimen_id": "9c73c39e-d72b-5771-9181-f0880ccf2006", "specimen_type": "Metastatic tumour - metastasis to distant location", "submitter_specimen_id": "SP933311", "samples": [{"sample_id": "9c73c39e-d72b-5771-9181-f0880ccf2006", "submitter_sample_id": "SP933311", "sample_type": "Total DNA", "matched_normal_submitter_sample_id": "SP933301"}], "tumour_normal_designation": "Tumour", "specimen_tissue_source": "Plasma"}]}], "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"} \ No newline at end of file diff --git a/configurationFiles/elasticsearchConfigs/es-docs/4fd0be6f-ce25-521a-9a54-1dbc2318ce05.json b/configurationFiles/elasticsearchConfigs/es-docs/4fd0be6f-ce25-521a-9a54-1dbc2318ce05.json deleted file mode 100644 index 53a91c34..00000000 --- a/configurationFiles/elasticsearchConfigs/es-docs/4fd0be6f-ce25-521a-9a54-1dbc2318ce05.json +++ /dev/null @@ -1 +0,0 @@ -{"object_id": "4fd0be6f-ce25-521a-9a54-1dbc2318ce05", "study_id": "demo", "data_type": "Raw InDel Calls", "file_type": "VCF", "file_access": "open", "analysis": {"analysis_id": "22286e7c-85f7-4aec-a86e-7c85f7eaecb2", "analysis_type": "quickStartSchema", "analysis_version": 1, "analysis_state": "PUBLISHED", "updated_at": 1720110341824, "first_published_at": 1720110341809, "published_at": 1720110341809, "experiment": {"model": "SEQUEL IIe", "platform": "PacBio", "sequencingDate": "2021-03-08T19:00:00.000Z", "sequencingCenter": "CGTA", "experimentalStrategy": "WXS"}, "analysisStateHistory": [{"initialState": "UNPUBLISHED", "updatedState": "PUBLISHED", "updatedAt": "2024-07-04T16:25:41.809441"}], "collaborator": [{"name": "MICR", "contactEmail": "susannorton@micr.ca"}], "createdAt": "2024-07-04T16:19:21.844701", "donor": {"primarySite": "Bronchus and lung", "vitalStatus": "Deceased", "causeOfDeath": "Died of other reasons", "survivalTime": 439, "primaryDiagnosis": [{"followUp": [{"relapseType": null, "intervalOfFollowUp": 50, "submitterFollowUpId": "FO011501", "submitterTreatmentId": "TR011501", "diseaseStatusAtFollowUp": "Partial remission"}], "treatment": [{"chemotherapy": [{"drugName": "Azacitidine "}], "treatmentType": ["Chemotherapy"], "treatmentDuration": 34, "responseToTreatment": "Minor response", "submitterTreatmentId": "TR011501", "treatmentStartInterval": 79}], "ageAtDiagnosis": 36, "cancerTypeCode": "C34.3", "clinicalStageGroup": "Stage III", "clinicalTumourStagingSystem": "AJCC 6th edition", "submitterPrimaryDiagnosisId": "PD011501"}, {"followUp": [{"relapseType": null, "intervalOfFollowUp": 33, "submitterFollowUpId": "FO011502", "submitterTreatmentId": "TR011502", "diseaseStatusAtFollowUp": "Relapse or recurrence"}], "treatment": [{"radiation": [{"anatomicalSiteIrradiated": "Body", "radiationTherapyModality": "Photon"}], "chemotherapy": [{"drugName": "Paclitaxel "}], "treatmentType": ["Chemotherapy", "Radiation therapy"], "treatmentDuration": 56, "responseToTreatment": "Complete response", "submitterTreatmentId": "TR011502", "treatmentStartInterval": 70}], "ageAtDiagnosis": 1, "cancerTypeCode": "C34.2", "clinicalStageGroup": "Stage IB", "clinicalTumourStagingSystem": "FIGO staging system", "submitterPrimaryDiagnosisId": "PD011502"}], "submitterDonorId": "DO0115"}, "publication": {"doi": "10.1093/nar/gkae188", "publication": "NAR"}, "specimen": {"tumourGrade": "G3", "submitterSpecimenId": "SP011501", "tumourGradingSystem": "Three-tier grading system", "specimenAnatomicLocation": "C14", "submitterPrimaryDiagnosisId": "PD011501"}, "workflow": {"runId": "RI0115", "inputs": [{"analysisType": "sequencing_alignment", "normalAnalysisId": "00000000-0000-0000-0000-0000000000115", "tumourAnalysisId": "00000000-0000-0000-0000-0000000000115"}], "sessionId": "SI0115", "genomeBuild": "GRCh38_hla_decoy_ebv", "workflowName": "Sanger Variant Calling", "workflowVersion": "0.9.8", "workflowShortName": "SangerVariant"}}, "file": {"name": "SP011511.indel.vcf.gz", "md5sum": "c445d6cd5e1aa1d7dec13096feae788c", "size": 17328, "data_type": "Raw InDel Calls", "index_file": {"object_id": "deaeaa56-c56d-54ee-ad75-f5b90bb7eda6", "name": "SP011511.indel.vcf.gz.tbi", "file_type": "TBI", "md5sum": "ae025b596b2fb562d33073338eb23a7d", "data_type": "Raw InDel Calls", "size": 148, "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "repositories": [{"code": "song.overture", "organization": "Overture", "name": "Overture", "type": "S3", "country": "CA", "url": "http://song:8080"}], "donors": [{"donor_id": "1a0cc916-465c-5b06-8eb7-c4fa438e496f", "submitter_donor_id": "DO0115", "gender": "Female", "specimens": [{"specimen_id": "89e3e128-6d1a-55cc-aae3-e62f5e2d4bdc", "specimen_type": "Primary tumour - adjacent to normal", "submitter_specimen_id": "SP011511", "samples": [{"sample_id": "89e3e128-6d1a-55cc-aae3-e62f5e2d4bdc", "submitter_sample_id": "SP011511", "sample_type": "Total DNA", "matched_normal_submitter_sample_id": "SP011501"}], "tumour_normal_designation": "Tumour", "specimen_tissue_source": "Blood derived - bone marrow"}]}], "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"} \ No newline at end of file diff --git a/configurationFiles/elasticsearchConfigs/es-docs/59291c9f-0b02-575a-85b7-501e54951e63.json b/configurationFiles/elasticsearchConfigs/es-docs/59291c9f-0b02-575a-85b7-501e54951e63.json deleted file mode 100644 index 0c64e659..00000000 --- a/configurationFiles/elasticsearchConfigs/es-docs/59291c9f-0b02-575a-85b7-501e54951e63.json +++ /dev/null @@ -1 +0,0 @@ -{"object_id": "59291c9f-0b02-575a-85b7-501e54951e63", "study_id": "demo", "data_type": "Raw InDel Calls", "file_type": "VCF", "file_access": "controlled", "analysis": {"analysis_id": "8e7fb5f1-21b7-40dc-bfb5-f121b790dcdc", "analysis_type": "quickStartSchema", "analysis_version": 1, "analysis_state": "PUBLISHED", "updated_at": 1720110624050, "first_published_at": 1720110624038, "published_at": 1720110624038, "experiment": {"model": "PromethION", "platform": "ONT", "sequencingDate": "2022-12-12T19:00:00.000Z", "sequencingCenter": "GATC", "experimentalStrategy": "WXS"}, "analysisStateHistory": [{"initialState": "UNPUBLISHED", "updatedState": "PUBLISHED", "updatedAt": "2024-07-04T16:30:24.038983"}], "collaborator": [{"name": "OICR", "contactEmail": "sturedman@micr.ca"}], "createdAt": "2024-07-04T16:20:13.553756", "donor": {"primarySite": "Bronchus and lung", "vitalStatus": "Deceased", "causeOfDeath": "Died of other reasons", "survivalTime": 1465, "primaryDiagnosis": [{"followUp": [{"relapseType": null, "intervalOfFollowUp": 81, "submitterFollowUpId": "FO919801", "submitterTreatmentId": "TR919801", "diseaseStatusAtFollowUp": "Distant progression"}], "treatment": [{"treatmentType": ["Hormonal therapy"], "hormoneTherapy": [{"drugName": "Anastrozole"}], "treatmentDuration": 84, "responseToTreatment": "Minor response", "submitterTreatmentId": "TR919801", "treatmentStartInterval": 86}], "ageAtDiagnosis": 43, "cancerTypeCode": "C34.0", "clinicalStageGroup": "Stage IB1", "clinicalTumourStagingSystem": "FIGO staging system", "submitterPrimaryDiagnosisId": "PD919801"}], "submitterDonorId": "DO9198"}, "publication": {"doi": "10.1038/s41591-023-02650-10", "publication": "Nature"}, "specimen": {"tumourGrade": "High grade", "submitterSpecimenId": "SP919801", "tumourGradingSystem": "Two-tier grading system", "specimenAnatomicLocation": "C76", "submitterPrimaryDiagnosisId": "PD919801"}, "workflow": {"runId": "RI9198", "inputs": [{"analysisType": "sequencing_alignment", "normalAnalysisId": "00000000-0000-0000-0000-0000000009198", "tumourAnalysisId": "00000000-0000-0000-0000-0000000009198"}], "sessionId": "SI9198", "genomeBuild": "GRCh38_hla_decoy_ebv", "workflowName": "Mutect2 Variant Calling", "workflowVersion": "0.1.1.1", "workflowShortName": "Mutect2Variant"}}, "file": {"name": "SP919801.indel.vcf.gz", "md5sum": "d4968ece01282590f24f6b90a97c5af3", "size": 17330, "data_type": "Raw InDel Calls", "index_file": {"object_id": "6ba7e370-9833-56b4-aba5-6d9562daa83d", "name": "SP919801.indel.vcf.gz.tbi", "file_type": "TBI", "md5sum": "c719518af10bce03d220bc56c11e970d", "data_type": "Raw InDel Calls", "size": 143, "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "repositories": [{"code": "song.overture", "organization": "Overture", "name": "Overture", "type": "S3", "country": "CA", "url": "http://song:8080"}], "donors": [{"donor_id": "4d1c2bd5-79cd-5448-bbb2-ada6ad4a5cb4", "submitter_donor_id": "DO9198", "gender": "Male", "specimens": [{"specimen_id": "bc6516db-9a44-5280-8fff-992ba7612b53", "specimen_type": "Normal - tissue adjacent to primary tumour", "submitter_specimen_id": "SP919801", "samples": [{"sample_id": "bc6516db-9a44-5280-8fff-992ba7612b53", "submitter_sample_id": "SP919801", "sample_type": "Amplified DNA", "matched_normal_submitter_sample_id": null}], "tumour_normal_designation": "Normal", "specimen_tissue_source": "Blood derived - bone marrow"}]}], "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"} \ No newline at end of file diff --git a/configurationFiles/elasticsearchConfigs/es-docs/5b431188-0ba3-53a2-88db-5b5a710d4a74.json b/configurationFiles/elasticsearchConfigs/es-docs/5b431188-0ba3-53a2-88db-5b5a710d4a74.json deleted file mode 100644 index 7185b856..00000000 --- a/configurationFiles/elasticsearchConfigs/es-docs/5b431188-0ba3-53a2-88db-5b5a710d4a74.json +++ /dev/null @@ -1 +0,0 @@ -{"object_id": "5b431188-0ba3-53a2-88db-5b5a710d4a74", "study_id": "demo", "data_type": "Raw SV Calls", "file_type": "VCF", "file_access": "controlled", "analysis": {"analysis_id": "fef58194-1dac-4c47-b581-941dacec474d", "analysis_type": "quickStartSchema", "analysis_version": 1, "analysis_state": "PUBLISHED", "updated_at": 1720110953744, "first_published_at": 1720110953705, "published_at": 1720110953705, "experiment": {"model": "SEQUEL IIe", "platform": "PacBio", "sequencingDate": "2021-03-08T19:00:00.000Z", "sequencingCenter": "CGTA", "experimentalStrategy": "WGS"}, "analysisStateHistory": [{"initialState": "UNPUBLISHED", "updatedState": "PUBLISHED", "updatedAt": "2024-07-04T16:35:53.705378"}], "collaborator": [{"name": "AICR", "contactEmail": "raygarraty@aicr.ca"}], "createdAt": "2024-07-04T16:21:06.280531", "donor": {"primarySite": "Brain", "vitalStatus": "Alive", "causeOfDeath": null, "survivalTime": null, "primaryDiagnosis": [{"followUp": [{"relapseType": null, "intervalOfFollowUp": 5, "submitterFollowUpId": "FO933301", "submitterTreatmentId": "TR933301", "diseaseStatusAtFollowUp": "Stable"}], "treatment": [{"chemotherapy": [{"drugName": "Azacitidine "}], "treatmentType": ["Chemotherapy", "Hormonal therapy"], "hormoneTherapy": [{"drugName": "Exemestane "}], "treatmentDuration": 59, "responseToTreatment": "Complete response", "submitterTreatmentId": "TR933301", "treatmentStartInterval": 57}], "ageAtDiagnosis": 30, "cancerTypeCode": "C71.6", "clinicalStageGroup": "Stage I", "clinicalTumourStagingSystem": "Rai staging system", "submitterPrimaryDiagnosisId": "PD933301"}], "submitterDonorId": "DO9333"}, "publication": {"doi": "10.1093/nar/gkae188", "publication": "NAR"}, "specimen": {"tumourGrade": "GX", "submitterSpecimenId": "SP933302", "tumourGradingSystem": "ISUP grading system", "specimenAnatomicLocation": "C66", "submitterPrimaryDiagnosisId": "PD933301"}, "workflow": {"runId": "RI9333", "inputs": [{"analysisType": "sequencing_alignment", "normalAnalysisId": "00000000-0000-0000-0000-0000000009333", "tumourAnalysisId": "00000000-0000-0000-0000-0000000009333"}], "sessionId": "SI9333", "genomeBuild": "GRCh38_hla_decoy_ebv", "workflowName": "Sanger Variant Calling", "workflowVersion": "0.9.8", "workflowShortName": "SangerVariant"}}, "file": {"name": "SP933312.snv.vcf.gz", "md5sum": "7a3d673c9f09e63b51a52ec5ce85f679", "size": 17247, "data_type": "Raw SV Calls", "index_file": {"object_id": "0f05867b-6b66-5e1f-b79e-2c489130d926", "name": "SP933312.snv.vcf.gz.tbi", "file_type": "TBI", "md5sum": "236a6fe3f791d3a505e786d730780658", "data_type": "Raw SV Calls", "size": 149, "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "repositories": [{"code": "song.overture", "organization": "Overture", "name": "Overture", "type": "S3", "country": "CA", "url": "http://song:8080"}], "donors": [{"donor_id": "fcd59878-cc3a-5223-8152-50942ca28bef", "submitter_donor_id": "DO9333", "gender": "Other", "specimens": [{"specimen_id": "de8ae449-e253-54fb-aef4-10804dfc55b1", "specimen_type": "Metastatic tumour - additional metastatic", "submitter_specimen_id": "SP933312", "samples": [{"sample_id": "de8ae449-e253-54fb-aef4-10804dfc55b1", "submitter_sample_id": "SP933312", "sample_type": "Amplified DNA", "matched_normal_submitter_sample_id": "SP933302"}], "tumour_normal_designation": "Tumour", "specimen_tissue_source": "Blood derived - bone marrow"}]}], "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"} \ No newline at end of file diff --git a/configurationFiles/elasticsearchConfigs/es-docs/603d285a-9070-51da-bb9d-d32b3429c9db.json b/configurationFiles/elasticsearchConfigs/es-docs/603d285a-9070-51da-bb9d-d32b3429c9db.json deleted file mode 100644 index f5b01c0e..00000000 --- a/configurationFiles/elasticsearchConfigs/es-docs/603d285a-9070-51da-bb9d-d32b3429c9db.json +++ /dev/null @@ -1 +0,0 @@ -{"object_id": "603d285a-9070-51da-bb9d-d32b3429c9db", "study_id": "demo", "data_type": "Aligned Reads", "file_type": "BAM", "file_access": "controlled", "analysis": {"analysis_id": "2d494116-3c5d-4069-8941-163c5d00695f", "analysis_type": "quickStartSchema", "analysis_version": 1, "analysis_state": "PUBLISHED", "updated_at": 1720111063251, "first_published_at": 1720111063232, "published_at": 1720111063232, "experiment": {"model": "SEQUEL IIe", "platform": "PacBio", "sequencingDate": "2021-03-08T19:00:00.000Z", "sequencingCenter": "CGTA", "experimentalStrategy": "WGS"}, "analysisStateHistory": [{"initialState": "UNPUBLISHED", "updatedState": "PUBLISHED", "updatedAt": "2024-07-04T16:37:43.232653"}], "collaborator": [{"name": "AICR", "contactEmail": "raygarraty@aicr.ca"}], "createdAt": "2024-07-04T16:21:23.326588", "donor": {"primarySite": "Hematopoietic and reticuloendothelial systems", "vitalStatus": "Alive", "causeOfDeath": null, "survivalTime": null, "primaryDiagnosis": [{"followUp": [{"relapseType": null, "intervalOfFollowUp": 90, "submitterFollowUpId": "FO849001", "submitterTreatmentId": "TR849001", "diseaseStatusAtFollowUp": "Loco-regional progression"}], "treatment": [{"chemotherapy": [{"drugName": "Tamoxifen "}], "treatmentType": ["Chemotherapy", "Hormonal therapy"], "hormoneTherapy": [{"drugName": "Letrozole "}], "treatmentDuration": 72, "responseToTreatment": "Partial response", "submitterTreatmentId": "TR849001", "treatmentStartInterval": 9}], "ageAtDiagnosis": 78, "cancerTypeCode": "C88.3", "clinicalStageGroup": "Stage C", "clinicalTumourStagingSystem": "Binet staging system", "submitterPrimaryDiagnosisId": "PD849001"}], "submitterDonorId": "DO8490"}, "publication": {"doi": "10.1093/nar/gkae188", "publication": "NAR"}, "specimen": {"tumourGrade": "GX", "submitterSpecimenId": "SP849001", "tumourGradingSystem": "Scarff-Bloom-Richardson grading system", "specimenAnatomicLocation": "C10", "submitterPrimaryDiagnosisId": "PD849001"}, "workflow": {"runId": "RI8490", "inputs": [{"analysisId": "00000000-0000-0000-0000-0000000008490", "analysisType": "sequencing_experiment"}], "sessionId": "SI8490", "genomeBuild": "GRCh38_hla_decoy_ebv", "workflowName": "BWA mem2 Alignment", "workflowVersion": "0.8", "workflowShortName": "BWAmem2Aln"}}, "file": {"name": "SP849011.bam", "md5sum": "6bd6da76fb11fd1d0c0be468776d4caa", "size": 125437, "data_type": "Aligned Reads", "index_file": {"object_id": "434c3dc4-5833-50eb-9cc1-1c6685fda47d", "name": "SP849011.bam.bai", "file_type": "BAI", "md5sum": "e7e432156b2418c599abe54b520d7f57", "data_type": "Aligned Reads", "size": 27160, "dataCategory": "Sequencing Reads", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "dataCategory": "Sequencing Reads", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "repositories": [{"code": "song.overture", "organization": "Overture", "name": "Overture", "type": "S3", "country": "CA", "url": "http://song:8080"}], "donors": [{"donor_id": "8a9d8e34-f9ce-5f5d-8b19-621e5c02ecba", "submitter_donor_id": "DO8490", "gender": "Male", "specimens": [{"specimen_id": "d413e7aa-ff78-5535-9903-8ae517a59263", "specimen_type": "Metastatic tumour - additional metastatic", "submitter_specimen_id": "SP849011", "samples": [{"sample_id": "d413e7aa-ff78-5535-9903-8ae517a59263", "submitter_sample_id": "SP849011", "sample_type": "Total DNA", "matched_normal_submitter_sample_id": "SP849001"}], "tumour_normal_designation": "Tumour", "specimen_tissue_source": "Lymph node"}]}], "dataCategory": "Sequencing Reads", "jbrowseCoordinates": "hg38:chr1:100000-200000"} \ No newline at end of file diff --git a/configurationFiles/elasticsearchConfigs/es-docs/726a01c6-a491-5213-9b4a-22a8d431337a.json b/configurationFiles/elasticsearchConfigs/es-docs/726a01c6-a491-5213-9b4a-22a8d431337a.json deleted file mode 100644 index d5d477ad..00000000 --- a/configurationFiles/elasticsearchConfigs/es-docs/726a01c6-a491-5213-9b4a-22a8d431337a.json +++ /dev/null @@ -1 +0,0 @@ -{"object_id": "726a01c6-a491-5213-9b4a-22a8d431337a", "study_id": "demo", "data_type": "Aligned Reads", "file_type": "CRAM", "file_access": "controlled", "analysis": {"analysis_id": "9a29ae5e-ad61-4979-a9ae-5ead613979ea", "analysis_type": "quickStartSchema", "analysis_version": 1, "analysis_state": "PUBLISHED", "updated_at": 1720110572681, "first_published_at": 1720110572672, "published_at": 1720110572672, "experiment": {"model": "SEQUEL IIe", "platform": "PacBio", "sequencingDate": "2021-03-08T19:00:00.000Z", "sequencingCenter": "CGTA", "experimentalStrategy": "WXS"}, "analysisStateHistory": [{"initialState": "UNPUBLISHED", "updatedState": "PUBLISHED", "updatedAt": "2024-07-04T16:29:32.67271"}], "collaborator": [{"name": "MICR", "contactEmail": "susannorton@micr.ca"}], "createdAt": "2024-07-04T16:20:04.433454", "donor": {"primarySite": "Hematopoietic and reticuloendothelial systems", "vitalStatus": "Deceased", "causeOfDeath": "Died of other reasons", "survivalTime": 1452, "primaryDiagnosis": [{"followUp": [{"relapseType": null, "intervalOfFollowUp": 67, "submitterFollowUpId": "FO864501", "submitterTreatmentId": "TR864501", "diseaseStatusAtFollowUp": "Partial remission"}], "treatment": [{"radiation": [{"anatomicalSiteIrradiated": "Abdomen", "radiationTherapyModality": "Photon"}], "chemotherapy": [{"drugName": "Tamoxifen "}], "treatmentType": ["Chemotherapy", "Radiation therapy"], "treatmentDuration": 32, "responseToTreatment": "Stable disease", "submitterTreatmentId": "TR864501", "treatmentStartInterval": 69}], "ageAtDiagnosis": 30, "cancerTypeCode": "C88.2", "clinicalStageGroup": "Stage IIIA", "clinicalTumourStagingSystem": "Durie-Salmon staging system", "submitterPrimaryDiagnosisId": "PD864501"}], "submitterDonorId": "DO8645"}, "publication": {"doi": "10.1093/nar/gkae188", "publication": "NAR"}, "specimen": {"tumourGrade": "GX", "submitterSpecimenId": "SP864501", "tumourGradingSystem": "FNCLCC grading system", "specimenAnatomicLocation": "C17", "submitterPrimaryDiagnosisId": "PD864501"}, "workflow": {"runId": "RI8645", "inputs": [{"analysisId": "00000000-0000-0000-0000-0000000008645", "analysisType": "sequencing_experiment"}], "sessionId": "SI8645", "genomeBuild": "GRCh38_hla_decoy_ebv", "workflowName": "Bowtie2 Alignment", "workflowVersion": "0.1.0", "workflowShortName": "Bowtie2Aln"}}, "file": {"name": "SP864511.cram", "md5sum": "a259d993349d3a1e285f47414146cda9", "size": 115987, "data_type": "Aligned Reads", "index_file": {"object_id": "2e53bb40-91a1-5d2b-ae3a-9a4d488c15ae", "name": "SP864511.cram.crai", "file_type": "CRAI", "md5sum": "ea7783f8c94e2623b163631f7542073c", "data_type": "Aligned Reads", "size": 52, "dataCategory": "Sequencing Reads", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "dataCategory": "Sequencing Reads", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "repositories": [{"code": "song.overture", "organization": "Overture", "name": "Overture", "type": "S3", "country": "CA", "url": "http://song:8080"}], "donors": [{"donor_id": "fbad60b4-4ab7-5932-b82a-d06ab5b2e864", "submitter_donor_id": "DO8645", "gender": "Other", "specimens": [{"specimen_id": "43fc5204-2711-5c8c-ae6e-37278ab82127", "specimen_type": "Metastatic tumour - additional metastatic", "submitter_specimen_id": "SP864511", "samples": [{"sample_id": "43fc5204-2711-5c8c-ae6e-37278ab82127", "submitter_sample_id": "SP864511", "sample_type": "Total DNA", "matched_normal_submitter_sample_id": "SP864501"}], "tumour_normal_designation": "Tumour", "specimen_tissue_source": "Plasma"}]}], "dataCategory": "Sequencing Reads", "jbrowseCoordinates": "hg38:chr1:100000-200000"} \ No newline at end of file diff --git a/configurationFiles/elasticsearchConfigs/es-docs/79f178e4-c033-59c5-82df-c460ec7b19d6.json b/configurationFiles/elasticsearchConfigs/es-docs/79f178e4-c033-59c5-82df-c460ec7b19d6.json deleted file mode 100644 index 53cde20e..00000000 --- a/configurationFiles/elasticsearchConfigs/es-docs/79f178e4-c033-59c5-82df-c460ec7b19d6.json +++ /dev/null @@ -1 +0,0 @@ -{"object_id": "79f178e4-c033-59c5-82df-c460ec7b19d6", "study_id": "demo", "data_type": "Aligned Reads", "file_type": "BAM", "file_access": "controlled", "analysis": {"analysis_id": "8fc67ce8-e665-4f48-867c-e8e6653f480b", "analysis_type": "quickStartSchema", "analysis_version": 1, "analysis_state": "PUBLISHED", "updated_at": 1720110434012, "first_published_at": 1720110434001, "published_at": 1720110434001, "experiment": {"model": "SEQUEL IIe", "platform": "PacBio", "sequencingDate": "2021-03-08T19:00:00.000Z", "sequencingCenter": "CGTA", "experimentalStrategy": "WGS"}, "analysisStateHistory": [{"initialState": "UNPUBLISHED", "updatedState": "PUBLISHED", "updatedAt": "2024-07-04T16:27:14.001951"}], "collaborator": [{"name": "MICR", "contactEmail": "susannorton@micr.ca"}], "createdAt": "2024-07-04T16:19:36.459655", "donor": {"primarySite": "Bronchus and lung", "vitalStatus": "Alive", "causeOfDeath": null, "survivalTime": null, "primaryDiagnosis": [{"followUp": [{"relapseType": null, "intervalOfFollowUp": 74, "submitterFollowUpId": "FO745301", "submitterTreatmentId": "TR745301", "diseaseStatusAtFollowUp": "Relapse or recurrence"}], "treatment": [{"treatmentType": ["Hormonal therapy"], "hormoneTherapy": [{"drugName": "Letrozole "}], "treatmentDuration": 32, "responseToTreatment": "Partial response", "submitterTreatmentId": "TR745301", "treatmentStartInterval": 38}], "ageAtDiagnosis": 30, "cancerTypeCode": "C34.3", "clinicalStageGroup": "Stage IB1", "clinicalTumourStagingSystem": "FIGO staging system", "submitterPrimaryDiagnosisId": "PD745301"}, {"followUp": [{"relapseType": null, "intervalOfFollowUp": 46, "submitterFollowUpId": "FO745302", "submitterTreatmentId": "TR745302", "diseaseStatusAtFollowUp": "Relapse or recurrence"}], "treatment": [{"chemotherapy": [{"drugName": "Tamoxifen "}], "treatmentType": ["Chemotherapy"], "treatmentDuration": 44, "responseToTreatment": "Disease progression", "submitterTreatmentId": "TR745302", "treatmentStartInterval": 82}], "ageAtDiagnosis": 20, "cancerTypeCode": "C34.8", "clinicalStageGroup": "Stage III", "clinicalTumourStagingSystem": "Ann Arbor staging system", "submitterPrimaryDiagnosisId": "PD745302"}], "submitterDonorId": "DO7453"}, "publication": {"doi": "10.1093/nar/gkae188", "publication": "NAR"}, "specimen": {"tumourGrade": "G1", "submitterSpecimenId": "SP745301", "tumourGradingSystem": "ISUP grading system", "specimenAnatomicLocation": "C60", "submitterPrimaryDiagnosisId": "PD745301"}, "workflow": {"runId": "RI7453", "inputs": [{"analysisId": "00000000-0000-0000-0000-0000000007453", "analysisType": "sequencing_experiment"}], "sessionId": "SI7453", "genomeBuild": "GRCh38_hla_decoy_ebv", "workflowName": "BWA mem2 Alignment", "workflowVersion": "0.8", "workflowShortName": "BWAmem2Aln"}}, "file": {"name": "SP745301.bam", "md5sum": "ae67942b1efbfcac4491401cf98d50b6", "size": 125502, "data_type": "Aligned Reads", "index_file": {"object_id": "329d1b22-a387-51ac-bc12-53625ea9ff80", "name": "SP745301.bam.bai", "file_type": "BAI", "md5sum": "5dbddafb5b591aee33fe53ef7db3d097", "data_type": "Aligned Reads", "size": 27232, "dataCategory": "Sequencing Reads", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "dataCategory": "Sequencing Reads", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "repositories": [{"code": "song.overture", "organization": "Overture", "name": "Overture", "type": "S3", "country": "CA", "url": "http://song:8080"}], "donors": [{"donor_id": "663b8536-90a9-51d3-abda-695771e751d0", "submitter_donor_id": "DO7453", "gender": "Male", "specimens": [{"specimen_id": "4050b184-081e-5c13-8c87-647d0a322219", "specimen_type": "Normal - tissue adjacent to primary tumour", "submitter_specimen_id": "SP745301", "samples": [{"sample_id": "4050b184-081e-5c13-8c87-647d0a322219", "submitter_sample_id": "SP745301", "sample_type": "Total DNA", "matched_normal_submitter_sample_id": null}], "tumour_normal_designation": "Normal", "specimen_tissue_source": "Blood derived - peripheral blood"}]}], "dataCategory": "Sequencing Reads", "jbrowseCoordinates": "hg38:chr1:100000-200000"} \ No newline at end of file diff --git a/configurationFiles/elasticsearchConfigs/es-docs/998f068b-0856-539e-86c3-a392e4ea171d.json b/configurationFiles/elasticsearchConfigs/es-docs/998f068b-0856-539e-86c3-a392e4ea171d.json deleted file mode 100644 index 560c1380..00000000 --- a/configurationFiles/elasticsearchConfigs/es-docs/998f068b-0856-539e-86c3-a392e4ea171d.json +++ /dev/null @@ -1 +0,0 @@ -{"object_id": "998f068b-0856-539e-86c3-a392e4ea171d", "study_id": "demo", "data_type": "Aligned Reads", "file_type": "BAM", "file_access": "controlled", "analysis": {"analysis_id": "276c39b3-77a0-45e5-ac39-b377a035e520", "analysis_type": "quickStartSchema", "analysis_version": 1, "analysis_state": "PUBLISHED", "updated_at": 1720110655160, "first_published_at": 1720110655131, "published_at": 1720110655131, "experiment": {"model": "PromethION", "platform": "ONT", "sequencingDate": "2022-12-12T19:00:00.000Z", "sequencingCenter": "GATC", "experimentalStrategy": "WGS"}, "analysisStateHistory": [{"initialState": "UNPUBLISHED", "updatedState": "PUBLISHED", "updatedAt": "2024-07-04T16:30:55.131045"}], "collaborator": [{"name": "OICR", "contactEmail": "sturedman@micr.ca"}], "createdAt": "2024-07-04T16:20:17.769103", "donor": {"primarySite": "Bronchus and lung", "vitalStatus": "Alive", "causeOfDeath": null, "survivalTime": null, "primaryDiagnosis": [{"followUp": [{"relapseType": null, "intervalOfFollowUp": 74, "submitterFollowUpId": "FO745301", "submitterTreatmentId": "TR745301", "diseaseStatusAtFollowUp": "Relapse or recurrence"}], "treatment": [{"treatmentType": ["Hormonal therapy"], "hormoneTherapy": [{"drugName": "Letrozole"}], "treatmentDuration": 32, "responseToTreatment": "Partial response", "submitterTreatmentId": "TR745301", "treatmentStartInterval": 38}], "ageAtDiagnosis": 30, "cancerTypeCode": "C34.3", "clinicalStageGroup": "Stage IB1", "clinicalTumourStagingSystem": "FIGO staging system", "submitterPrimaryDiagnosisId": "PD745301"}, {"followUp": [{"relapseType": null, "intervalOfFollowUp": 46, "submitterFollowUpId": "FO745302", "submitterTreatmentId": "TR745302", "diseaseStatusAtFollowUp": "Relapse or recurrence"}], "treatment": [{"chemotherapy": [{"drugName": "Tamoxifen"}], "treatmentType": ["Chemotherapy"], "treatmentDuration": 44, "responseToTreatment": "Disease progression", "submitterTreatmentId": "TR745302", "treatmentStartInterval": 82}], "ageAtDiagnosis": 20, "cancerTypeCode": "C34.8", "clinicalStageGroup": "Stage III", "clinicalTumourStagingSystem": "Ann Arbor staging system", "submitterPrimaryDiagnosisId": "PD745302"}], "submitterDonorId": "DO7453"}, "publication": {"doi": "10.1038/s41591-023-02650-10", "publication": "Nature"}, "specimen": {"tumourGrade": "Low", "submitterSpecimenId": "SP745302", "tumourGradingSystem": "Grading system for GISTs", "specimenAnatomicLocation": "C56", "submitterPrimaryDiagnosisId": "PD745301"}, "workflow": {"runId": "RI7453", "inputs": [{"analysisId": "00000000-0000-0000-0000-0000000007453", "analysisType": "sequencing_experiment"}], "sessionId": "SI7453", "genomeBuild": "GRCh38_hla_decoy_ebv", "workflowName": "BWA mem2 Alignment", "workflowVersion": "0.8", "workflowShortName": "BWAmem2Aln"}}, "file": {"name": "SP745302.bam", "md5sum": "50b5b6b50584e8afeb85e64f86dda864", "size": 125412, "data_type": "Aligned Reads", "index_file": {"object_id": "1bf7f1df-02ea-5937-833c-dfc72be8f55f", "name": "SP745302.bam.bai", "file_type": "BAI", "md5sum": "fea2626c58a5f79a9e1e51f6662dba8f", "data_type": "Aligned Reads", "size": 27160, "dataCategory": "Sequencing Reads", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "dataCategory": "Sequencing Reads", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "repositories": [{"code": "song.overture", "organization": "Overture", "name": "Overture", "type": "S3", "country": "CA", "url": "http://song:8080"}], "donors": [{"donor_id": "663b8536-90a9-51d3-abda-695771e751d0", "submitter_donor_id": "DO7453", "gender": "Male", "specimens": [{"specimen_id": "0e7b6871-ee82-58b3-b199-aaac9d8cbc1d", "specimen_type": "Normal - tissue adjacent to primary tumour", "submitter_specimen_id": "SP745302", "samples": [{"sample_id": "0e7b6871-ee82-58b3-b199-aaac9d8cbc1d", "submitter_sample_id": "SP745302", "sample_type": "ctDNA", "matched_normal_submitter_sample_id": null}], "tumour_normal_designation": "Normal", "specimen_tissue_source": "Blood derived"}]}], "dataCategory": "Sequencing Reads", "jbrowseCoordinates": "hg38:chr1:100000-200000"} \ No newline at end of file diff --git a/configurationFiles/elasticsearchConfigs/es-docs/9ec6bdd4-1265-5e98-ae1d-57f76abeb483.json b/configurationFiles/elasticsearchConfigs/es-docs/9ec6bdd4-1265-5e98-ae1d-57f76abeb483.json deleted file mode 100644 index 1d6c2fb7..00000000 --- a/configurationFiles/elasticsearchConfigs/es-docs/9ec6bdd4-1265-5e98-ae1d-57f76abeb483.json +++ /dev/null @@ -1 +0,0 @@ -{"object_id": "9ec6bdd4-1265-5e98-ae1d-57f76abeb483", "study_id": "demo", "data_type": "Aligned Reads", "file_type": "CRAM", "file_access": "controlled", "analysis": {"analysis_id": "f234f6be-62ac-4b36-b4f6-be62ac1b368c", "analysis_type": "quickStartSchema", "analysis_version": 1, "analysis_state": "PUBLISHED", "updated_at": 1720110756992, "first_published_at": 1720110756983, "published_at": 1720110756983, "experiment": {"model": "PromethION", "platform": "ONT", "sequencingDate": "2022-12-12T19:00:00.000Z", "sequencingCenter": "GATC", "experimentalStrategy": "WXS"}, "analysisStateHistory": [{"initialState": "UNPUBLISHED", "updatedState": "PUBLISHED", "updatedAt": "2024-07-04T16:32:36.983688"}], "collaborator": [{"name": "OICR", "contactEmail": "sturedman@micr.ca"}], "createdAt": "2024-07-04T16:20:35.395221", "donor": {"primarySite": "Brain", "vitalStatus": "Deceased", "causeOfDeath": "Died of cancer", "survivalTime": 1092, "primaryDiagnosis": [{"followUp": [{"relapseType": null, "intervalOfFollowUp": 95, "submitterFollowUpId": "FO923401", "submitterTreatmentId": "TR923401", "diseaseStatusAtFollowUp": "Relapse or recurrence"}], "treatment": [{"radiation": [{"anatomicalSiteIrradiated": "Neck", "radiationTherapyModality": "Heavy Ions"}], "chemotherapy": [{"drugName": "Azacitidine"}], "treatmentType": ["Chemotherapy", "Radiation therapy"], "treatmentDuration": 1, "responseToTreatment": "Partial response", "submitterTreatmentId": "TR923401", "treatmentStartInterval": 50}], "ageAtDiagnosis": 40, "cancerTypeCode": "C71.8", "clinicalStageGroup": "Stage I", "clinicalTumourStagingSystem": "Rai staging system", "submitterPrimaryDiagnosisId": "PD923401"}, {"followUp": [{"relapseType": null, "intervalOfFollowUp": 67, "submitterFollowUpId": "FO923402", "submitterTreatmentId": "TR923402", "diseaseStatusAtFollowUp": "No evidence of disease"}], "treatment": [{"chemotherapy": [{"drugName": "Tamoxifen"}], "treatmentType": ["Chemotherapy"], "treatmentDuration": 66, "responseToTreatment": "Complete response", "submitterTreatmentId": "TR923402", "treatmentStartInterval": 78}], "ageAtDiagnosis": 75, "cancerTypeCode": "C71.7", "clinicalStageGroup": "Stage II", "clinicalTumourStagingSystem": "St Jude staging system", "submitterPrimaryDiagnosisId": "PD923402"}], "submitterDonorId": "DO9234"}, "publication": {"doi": "10.1038/s41591-023-02650-10", "publication": "Nature"}, "specimen": {"tumourGrade": "Grade IV", "submitterSpecimenId": "SP923402", "tumourGradingSystem": "WHO grading system for CNS tumours", "specimenAnatomicLocation": "C46", "submitterPrimaryDiagnosisId": "PD923401"}, "workflow": {"runId": "RI9234", "inputs": [{"analysisId": "00000000-0000-0000-0000-0000000009234", "analysisType": "sequencing_experiment"}], "sessionId": "SI9234", "genomeBuild": "GRCh38_hla_decoy_ebv", "workflowName": "Bowtie2 Alignment", "workflowVersion": "0.1.0", "workflowShortName": "Bowtie2Aln"}}, "file": {"name": "SP923402.cram", "md5sum": "602f723b376324584d6b3b391f65a54c", "size": 115995, "data_type": "Aligned Reads", "index_file": {"object_id": "a2c664fb-6e1a-554f-9c40-351998586f24", "name": "SP923402.cram.crai", "file_type": "CRAI", "md5sum": "e8791a99c428c09f1ea9b6e2a1b6df0e", "data_type": "Aligned Reads", "size": 53, "dataCategory": "Sequencing Reads", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "dataCategory": "Sequencing Reads", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "repositories": [{"code": "song.overture", "organization": "Overture", "name": "Overture", "type": "S3", "country": "CA", "url": "http://song:8080"}], "donors": [{"donor_id": "986121a4-adf0-570b-8a4d-7ef5e63ad06a", "submitter_donor_id": "DO9234", "gender": "Male", "specimens": [{"specimen_id": "fec8a0bd-2b42-50c9-a39b-0f21b983acd6", "specimen_type": "Normal - tissue adjacent to primary tumour", "submitter_specimen_id": "SP923402", "samples": [{"sample_id": "fec8a0bd-2b42-50c9-a39b-0f21b983acd6", "submitter_sample_id": "SP923402", "sample_type": "Total DNA", "matched_normal_submitter_sample_id": null}], "tumour_normal_designation": "Normal", "specimen_tissue_source": "Blood derived"}]}], "dataCategory": "Sequencing Reads", "jbrowseCoordinates": "hg38:chr1:100000-200000"} \ No newline at end of file diff --git a/configurationFiles/elasticsearchConfigs/es-docs/a9e44028-6858-5e85-96eb-c57873da6658.json b/configurationFiles/elasticsearchConfigs/es-docs/a9e44028-6858-5e85-96eb-c57873da6658.json deleted file mode 100644 index e0aa5736..00000000 --- a/configurationFiles/elasticsearchConfigs/es-docs/a9e44028-6858-5e85-96eb-c57873da6658.json +++ /dev/null @@ -1 +0,0 @@ -{"object_id": "a9e44028-6858-5e85-96eb-c57873da6658", "study_id": "demo", "data_type": "Aligned Reads", "file_type": "CRAM", "file_access": "controlled", "analysis": {"analysis_id": "7b753de2-125e-497d-b53d-e2125e097d4e", "analysis_type": "quickStartSchema", "analysis_version": 1, "analysis_state": "PUBLISHED", "updated_at": 1720110547858, "first_published_at": 1720110547838, "published_at": 1720110547838, "experiment": {"model": "SEQUEL IIe", "platform": "PacBio", "sequencingDate": "2021-03-08T19:00:00.000Z", "sequencingCenter": "CGTA", "experimentalStrategy": "WXS"}, "analysisStateHistory": [{"initialState": "UNPUBLISHED", "updatedState": "PUBLISHED", "updatedAt": "2024-07-04T16:29:07.838421"}], "collaborator": [{"name": "MICR", "contactEmail": "susannorton@micr.ca"}], "createdAt": "2024-07-04T16:19:59.291713", "donor": {"primarySite": "Hematopoietic and reticuloendothelial systems", "vitalStatus": "Deceased", "causeOfDeath": "Died of other reasons", "survivalTime": 1452, "primaryDiagnosis": [{"followUp": [{"relapseType": null, "intervalOfFollowUp": 67, "submitterFollowUpId": "FO864501", "submitterTreatmentId": "TR864501", "diseaseStatusAtFollowUp": "Partial remission"}], "treatment": [{"radiation": [{"anatomicalSiteIrradiated": "Abdomen", "radiationTherapyModality": "Photon"}], "chemotherapy": [{"drugName": "Tamoxifen "}], "treatmentType": ["Chemotherapy", "Radiation therapy"], "treatmentDuration": 32, "responseToTreatment": "Stable disease", "submitterTreatmentId": "TR864501", "treatmentStartInterval": 69}], "ageAtDiagnosis": 30, "cancerTypeCode": "C88.2", "clinicalStageGroup": "Stage IIIA", "clinicalTumourStagingSystem": "Durie-Salmon staging system", "submitterPrimaryDiagnosisId": "PD864501"}], "submitterDonorId": "DO8645"}, "publication": {"doi": "10.1093/nar/gkae188", "publication": "NAR"}, "specimen": {"tumourGrade": "Grade Group 1", "submitterSpecimenId": "SP864501", "tumourGradingSystem": "Gleason grade group system", "specimenAnatomicLocation": "C38", "submitterPrimaryDiagnosisId": "PD864501"}, "workflow": {"runId": "RI8645", "inputs": [{"analysisId": "00000000-0000-0000-0000-0000000008645", "analysisType": "sequencing_experiment"}], "sessionId": "SI8645", "genomeBuild": "GRCh38_hla_decoy_ebv", "workflowName": "Bowtie2 Alignment", "workflowVersion": "0.1.0", "workflowShortName": "Bowtie2Aln"}}, "file": {"name": "SP864501.cram", "md5sum": "c852b26260bb6e80918e5b35f4a7c101", "size": 115973, "data_type": "Aligned Reads", "index_file": {"object_id": "1d1fe30b-191b-58ff-abb7-c9ea6ec83906", "name": "SP864501.cram.crai", "file_type": "CRAI", "md5sum": "8566392f47fcc703008a950393967efa", "data_type": "Aligned Reads", "size": 52, "dataCategory": "Sequencing Reads", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "dataCategory": "Sequencing Reads", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "repositories": [{"code": "song.overture", "organization": "Overture", "name": "Overture", "type": "S3", "country": "CA", "url": "http://song:8080"}], "donors": [{"donor_id": "fbad60b4-4ab7-5932-b82a-d06ab5b2e864", "submitter_donor_id": "DO8645", "gender": "Other", "specimens": [{"specimen_id": "b92cab89-9528-5a9c-9306-1ace47e4c686", "specimen_type": "Normal - tissue adjacent to primary tumour", "submitter_specimen_id": "SP864501", "samples": [{"sample_id": "b92cab89-9528-5a9c-9306-1ace47e4c686", "submitter_sample_id": "SP864501", "sample_type": "Total DNA", "matched_normal_submitter_sample_id": null}], "tumour_normal_designation": "Normal", "specimen_tissue_source": "Blood derived - bone marrow"}]}], "dataCategory": "Sequencing Reads", "jbrowseCoordinates": "hg38:chr1:100000-200000"} \ No newline at end of file diff --git a/configurationFiles/elasticsearchConfigs/es-docs/ae23ca2d-d8f8-5e05-bdac-c9e0ec1bd275.json b/configurationFiles/elasticsearchConfigs/es-docs/ae23ca2d-d8f8-5e05-bdac-c9e0ec1bd275.json deleted file mode 100644 index 0f129013..00000000 --- a/configurationFiles/elasticsearchConfigs/es-docs/ae23ca2d-d8f8-5e05-bdac-c9e0ec1bd275.json +++ /dev/null @@ -1 +0,0 @@ -{"object_id": "ae23ca2d-d8f8-5e05-bdac-c9e0ec1bd275", "study_id": "demo", "data_type": "Aligned Reads", "file_type": "CRAM", "file_access": "open", "analysis": {"analysis_id": "c0bd0c3c-287b-4832-bd0c-3c287bd83247", "analysis_type": "quickStartSchema", "analysis_version": 1, "analysis_state": "PUBLISHED", "updated_at": 1720110867317, "first_published_at": 1720110867309, "published_at": 1720110867309, "experiment": {"model": "SEQUEL IIe", "platform": "PacBio", "sequencingDate": "2021-03-08T19:00:00.000Z", "sequencingCenter": "CGTA", "experimentalStrategy": "WXS"}, "analysisStateHistory": [{"initialState": "UNPUBLISHED", "updatedState": "PUBLISHED", "updatedAt": "2024-07-04T16:34:27.309431"}], "collaborator": [{"name": "AICR", "contactEmail": "sturedman@micr.ca"}], "createdAt": "2024-07-04T16:20:52.858049", "donor": {"primarySite": "Bronchus and lung", "vitalStatus": "Deceased", "causeOfDeath": "Died of other reasons", "survivalTime": 1139, "primaryDiagnosis": [{"followUp": [{"relapseType": null, "intervalOfFollowUp": 86, "submitterFollowUpId": "FO410901", "submitterTreatmentId": "TR410901", "diseaseStatusAtFollowUp": "Stable"}], "treatment": [{"radiation": [{"anatomicalSiteIrradiated": "Thorax", "radiationTherapyModality": "Photon"}], "treatmentType": ["Hormonal therapy", "Radiation therapy"], "hormoneTherapy": [{"drugName": "Anastrozole "}], "treatmentDuration": 75, "responseToTreatment": "Disease progression", "submitterTreatmentId": "TR410901", "treatmentStartInterval": 2}], "ageAtDiagnosis": 77, "cancerTypeCode": "C34.2", "clinicalStageGroup": "Stage IA1", "clinicalTumourStagingSystem": "FIGO staging system", "submitterPrimaryDiagnosisId": "PD410901"}, {"followUp": [{"relapseType": null, "intervalOfFollowUp": 17, "submitterFollowUpId": "FO410902", "submitterTreatmentId": "TR410902", "diseaseStatusAtFollowUp": "Relapse or recurrence"}], "treatment": [{"chemotherapy": [{"drugName": "Paclitaxel "}], "treatmentType": ["Chemotherapy"], "treatmentDuration": 65, "responseToTreatment": "Disease progression", "submitterTreatmentId": "TR410902", "treatmentStartInterval": 97}], "ageAtDiagnosis": 43, "cancerTypeCode": "C34.8", "clinicalStageGroup": "Stage 0", "clinicalTumourStagingSystem": "Rai staging system", "submitterPrimaryDiagnosisId": "PD410902"}], "submitterDonorId": "DO4109"}, "publication": {"doi": "10.1093/nar/gkae188", "publication": "NAR"}, "specimen": {"tumourGrade": "GX", "submitterSpecimenId": "SP410901", "tumourGradingSystem": "Nuclear grading system for DCIS", "specimenAnatomicLocation": "C71", "submitterPrimaryDiagnosisId": "PD410901"}, "workflow": {"runId": "RI4109", "inputs": [{"analysisId": "00000000-0000-0000-0000-0000000004109", "analysisType": "sequencing_experiment"}], "sessionId": "SI4109", "genomeBuild": "GRCh38_hla_decoy_ebv", "workflowName": "BWA mem2 Alignment", "workflowVersion": "0.8", "workflowShortName": "BWAmem2Aln"}}, "file": {"name": "SP410911.cram", "md5sum": "7ecf7ab47df62450fedc0d365b33b76a", "size": 115958, "data_type": "Aligned Reads", "index_file": {"object_id": "8fcf286a-4f81-5c05-9cbd-d4096501779a", "name": "SP410911.cram.crai", "file_type": "CRAI", "md5sum": "3066b32d06be4ac1c5238346e8ad4270", "data_type": "Aligned Reads", "size": 53, "dataCategory": "Sequencing Reads", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "dataCategory": "Sequencing Reads", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "repositories": [{"code": "song.overture", "organization": "Overture", "name": "Overture", "type": "S3", "country": "CA", "url": "http://song:8080"}], "donors": [{"donor_id": "7893cbd1-b639-55ed-b1be-a7683b8d9964", "submitter_donor_id": "DO4109", "gender": "Female", "specimens": [{"specimen_id": "bd3bba0d-39f4-5d76-b183-1b9eb8fdc818", "specimen_type": "Primary tumour - additional new primary", "submitter_specimen_id": "SP410911", "samples": [{"sample_id": "bd3bba0d-39f4-5d76-b183-1b9eb8fdc818", "submitter_sample_id": "SP410911", "sample_type": "Amplified DNA", "matched_normal_submitter_sample_id": "SP410901"}], "tumour_normal_designation": "Tumour", "specimen_tissue_source": "Lymph node"}]}], "dataCategory": "Sequencing Reads", "jbrowseCoordinates": "hg38:chr1:100000-200000"} \ No newline at end of file diff --git a/configurationFiles/elasticsearchConfigs/es-docs/b08d8ad0-1dfc-5559-9233-b78091fff52f.json b/configurationFiles/elasticsearchConfigs/es-docs/b08d8ad0-1dfc-5559-9233-b78091fff52f.json deleted file mode 100644 index 73d97e05..00000000 --- a/configurationFiles/elasticsearchConfigs/es-docs/b08d8ad0-1dfc-5559-9233-b78091fff52f.json +++ /dev/null @@ -1 +0,0 @@ -{"object_id": "b08d8ad0-1dfc-5559-9233-b78091fff52f", "study_id": "demo", "data_type": "Raw SV Calls", "file_type": "VCF", "file_access": "controlled", "analysis": {"analysis_id": "7ce3580e-f934-4f77-a358-0ef9344f77b0", "analysis_type": "quickStartSchema", "analysis_version": 1, "analysis_state": "PUBLISHED", "updated_at": 1720110597919, "first_published_at": 1720110597910, "published_at": 1720110597910, "experiment": {"model": "PromethION", "platform": "ONT", "sequencingDate": "2022-12-12T19:00:00.000Z", "sequencingCenter": "GATC", "experimentalStrategy": "WXS"}, "analysisStateHistory": [{"initialState": "UNPUBLISHED", "updatedState": "PUBLISHED", "updatedAt": "2024-07-04T16:29:57.910636"}], "collaborator": [{"name": "OICR", "contactEmail": "sturedman@micr.ca"}], "createdAt": "2024-07-04T16:20:08.940577", "donor": {"primarySite": "Bronchus and lung", "vitalStatus": "Alive", "causeOfDeath": null, "survivalTime": null, "primaryDiagnosis": [{"followUp": [{"relapseType": null, "intervalOfFollowUp": 28, "submitterFollowUpId": "FO859001", "submitterTreatmentId": "TR859001", "diseaseStatusAtFollowUp": "Distant progression"}], "treatment": [{"radiation": [{"anatomicalSiteIrradiated": "Body", "radiationTherapyModality": "Proton"}], "treatmentType": ["Hormonal therapy", "Radiation therapy"], "hormoneTherapy": [{"drugName": "Anastrozole"}], "treatmentDuration": 30, "responseToTreatment": "Minor response", "submitterTreatmentId": "TR859001", "treatmentStartInterval": 58}], "ageAtDiagnosis": 63, "cancerTypeCode": "C34.2", "clinicalStageGroup": "Stage IIIC1", "clinicalTumourStagingSystem": "AJCC 6th edition", "submitterPrimaryDiagnosisId": "PD859001"}, {"followUp": [{"relapseType": null, "intervalOfFollowUp": 71, "submitterFollowUpId": "FO859002", "submitterTreatmentId": "TR859002", "diseaseStatusAtFollowUp": "Relapse or recurrence"}], "treatment": [{"chemotherapy": [{"drugName": "Paclitaxel"}], "treatmentType": ["Chemotherapy"], "treatmentDuration": 32, "responseToTreatment": "Stable disease", "submitterTreatmentId": "TR859002", "treatmentStartInterval": 59}], "ageAtDiagnosis": 14, "cancerTypeCode": "C34.2", "clinicalStageGroup": "Stage III", "clinicalTumourStagingSystem": "Durie-Salmon staging system", "submitterPrimaryDiagnosisId": "PD859002"}], "submitterDonorId": "DO8590"}, "publication": {"doi": "10.1038/s41591-023-02650-10", "publication": "Nature"}, "specimen": {"tumourGrade": "High grade", "submitterSpecimenId": "SP859001", "tumourGradingSystem": "Two-tier grading system", "specimenAnatomicLocation": "C21", "submitterPrimaryDiagnosisId": "PD859001"}, "workflow": {"runId": "RI8590", "inputs": [{"analysisType": "sequencing_alignment", "normalAnalysisId": "00000000-0000-0000-0000-0000000008590", "tumourAnalysisId": "00000000-0000-0000-0000-0000000008590"}], "sessionId": "SI8590", "genomeBuild": "GRCh38_hla_decoy_ebv", "workflowName": "Mutect2 Variant Calling", "workflowVersion": "0.1.1.1", "workflowShortName": "Mutect2Variant"}}, "file": {"name": "SP859011.snv.vcf.gz", "md5sum": "c5aa0b57090c2179430491ca652e5ef8", "size": 17246, "data_type": "Raw SV Calls", "index_file": {"object_id": "2216c52c-9890-5613-a831-3752d0a89f0d", "name": "SP859011.snv.vcf.gz.tbi", "file_type": "TBI", "md5sum": "a529e8896fcde6e3c1b9c50a72206571", "data_type": "Raw SV Calls", "size": 142, "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "repositories": [{"code": "song.overture", "organization": "Overture", "name": "Overture", "type": "S3", "country": "CA", "url": "http://song:8080"}], "donors": [{"donor_id": "65019938-ce2c-5c63-8a40-715ef3c9a904", "submitter_donor_id": "DO8590", "gender": "Female", "specimens": [{"specimen_id": "15760783-0b4b-5dd8-9fdc-dff1468276be", "specimen_type": "Primary tumour - additional new primary", "submitter_specimen_id": "SP859011", "samples": [{"sample_id": "15760783-0b4b-5dd8-9fdc-dff1468276be", "submitter_sample_id": "SP859011", "sample_type": "Total DNA", "matched_normal_submitter_sample_id": "SP859001"}], "tumour_normal_designation": "Tumour", "specimen_tissue_source": "Blood derived - peripheral blood"}]}], "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"} \ No newline at end of file diff --git a/configurationFiles/elasticsearchConfigs/es-docs/b2dec936-af54-5b2c-9ab9-7502b94191d0.json b/configurationFiles/elasticsearchConfigs/es-docs/b2dec936-af54-5b2c-9ab9-7502b94191d0.json deleted file mode 100644 index 8767979a..00000000 --- a/configurationFiles/elasticsearchConfigs/es-docs/b2dec936-af54-5b2c-9ab9-7502b94191d0.json +++ /dev/null @@ -1 +0,0 @@ -{"object_id": "b2dec936-af54-5b2c-9ab9-7502b94191d0", "study_id": "demo", "data_type": "Raw SV Calls", "file_type": "VCF", "file_access": "controlled", "analysis": {"analysis_id": "55a01148-c6b5-49fa-a011-48c6b5c9fa56", "analysis_type": "quickStartSchema", "analysis_version": 1, "analysis_state": "PUBLISHED", "updated_at": 1720111006406, "first_published_at": 1720111006396, "published_at": 1720111006396, "experiment": {"model": "SEQUEL IIe", "platform": "PacBio", "sequencingDate": "2021-03-08T19:00:00.000Z", "sequencingCenter": "CGTA", "experimentalStrategy": "WXS"}, "analysisStateHistory": [{"initialState": "UNPUBLISHED", "updatedState": "PUBLISHED", "updatedAt": "2024-07-04T16:36:46.396832"}], "collaborator": [{"name": "AICR", "contactEmail": "raygarraty@aicr.ca"}], "createdAt": "2024-07-04T16:21:14.732498", "donor": {"primarySite": "Brain", "vitalStatus": "Alive", "causeOfDeath": null, "survivalTime": null, "primaryDiagnosis": [{"followUp": [{"relapseType": null, "intervalOfFollowUp": 5, "submitterFollowUpId": "FO933301", "submitterTreatmentId": "TR933301", "diseaseStatusAtFollowUp": "Stable"}], "treatment": [{"chemotherapy": [{"drugName": "Azacitidine"}], "treatmentType": ["Chemotherapy", "Hormonal therapy"], "hormoneTherapy": [{"drugName": "Exemestane"}], "treatmentDuration": 59, "responseToTreatment": "Complete response", "submitterTreatmentId": "TR933301", "treatmentStartInterval": 57}], "ageAtDiagnosis": 30, "cancerTypeCode": "C71.6", "clinicalStageGroup": "Stage I", "clinicalTumourStagingSystem": "Rai staging system", "submitterPrimaryDiagnosisId": "PD933301"}], "submitterDonorId": "DO9333"}, "publication": {"doi": "10.1093/nar/gkae188", "publication": "NAR"}, "specimen": {"tumourGrade": "G1", "submitterSpecimenId": "SP933301", "tumourGradingSystem": "Grading system for GNETs", "specimenAnatomicLocation": "C55", "submitterPrimaryDiagnosisId": "PD933301"}, "workflow": {"runId": "RI9333", "inputs": [{"analysisType": "sequencing_alignment", "normalAnalysisId": "00000000-0000-0000-0000-0000000009333", "tumourAnalysisId": "00000000-0000-0000-0000-0000000009333"}], "sessionId": "SI9333", "genomeBuild": "GRCh38_hla_decoy_ebv", "workflowName": "Sanger Variant Calling", "workflowVersion": "0.9.8", "workflowShortName": "SangerVariant"}}, "file": {"name": "SP933301.snv.vcf.gz", "md5sum": "b1f642c5cdf743b068379a03939a2512", "size": 17248, "data_type": "Raw SV Calls", "index_file": {"object_id": "d52ad945-1f3b-54d9-b3c9-45a17c5db655", "name": "SP933301.snv.vcf.gz.tbi", "file_type": "TBI", "md5sum": "75f26b946ad64977b1148f08f33a26b3", "data_type": "Raw SV Calls", "size": 148, "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "repositories": [{"code": "song.overture", "organization": "Overture", "name": "Overture", "type": "S3", "country": "CA", "url": "http://song:8080"}], "donors": [{"donor_id": "fcd59878-cc3a-5223-8152-50942ca28bef", "submitter_donor_id": "DO9333", "gender": "Other", "specimens": [{"specimen_id": "5be056e8-45fd-561b-8a39-54f752c1638d", "specimen_type": "Normal", "submitter_specimen_id": "SP933301", "samples": [{"sample_id": "5be056e8-45fd-561b-8a39-54f752c1638d", "submitter_sample_id": "SP933301", "sample_type": "Total DNA", "matched_normal_submitter_sample_id": null}], "tumour_normal_designation": "Normal", "specimen_tissue_source": "Blood derived - bone marrow"}]}], "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"} \ No newline at end of file diff --git a/configurationFiles/elasticsearchConfigs/es-docs/b4b672be-f917-504b-b4e3-c4d6d580af06.json b/configurationFiles/elasticsearchConfigs/es-docs/b4b672be-f917-504b-b4e3-c4d6d580af06.json deleted file mode 100644 index 1d0050a6..00000000 --- a/configurationFiles/elasticsearchConfigs/es-docs/b4b672be-f917-504b-b4e3-c4d6d580af06.json +++ /dev/null @@ -1 +0,0 @@ -{"object_id": "b4b672be-f917-504b-b4e3-c4d6d580af06", "study_id": "demo", "data_type": "Raw SV Calls", "file_type": "VCF", "file_access": "controlled", "analysis": {"analysis_id": "76bf0d70-05c8-4551-bf0d-7005c8b551b2", "analysis_type": "quickStartSchema", "analysis_version": 1, "analysis_state": "PUBLISHED", "updated_at": 1720110487878, "first_published_at": 1720110487869, "published_at": 1720110487869, "experiment": {"model": "SEQUEL IIe", "platform": "PacBio", "sequencingDate": "2021-03-08T19:00:00.000Z", "sequencingCenter": "CGTA", "experimentalStrategy": "WXS"}, "analysisStateHistory": [{"initialState": "UNPUBLISHED", "updatedState": "PUBLISHED", "updatedAt": "2024-07-04T16:28:07.86992"}], "collaborator": [{"name": "MICR", "contactEmail": "susannorton@micr.ca"}], "createdAt": "2024-07-04T16:19:48.861959", "donor": {"primarySite": "Brain", "vitalStatus": "Deceased", "causeOfDeath": "Died of other reasons", "survivalTime": 216, "primaryDiagnosis": [{"followUp": [{"relapseType": null, "intervalOfFollowUp": 78, "submitterFollowUpId": "FO852501", "submitterTreatmentId": "TR852501", "diseaseStatusAtFollowUp": "Distant progression"}], "treatment": [{"radiation": [{"anatomicalSiteIrradiated": "Lung", "radiationTherapyModality": "Proton"}], "chemotherapy": [{"drugName": "Paclitaxel "}], "treatmentType": ["Chemotherapy", "Hormonal therapy", "Radiation therapy"], "hormoneTherapy": [{"drugName": "Anastrozole "}], "treatmentDuration": 78, "responseToTreatment": "Minor response", "submitterTreatmentId": "TR852501", "treatmentStartInterval": 15}], "ageAtDiagnosis": 59, "cancerTypeCode": "C71.1", "clinicalStageGroup": "Stage IVB", "clinicalTumourStagingSystem": "FIGO staging system", "submitterPrimaryDiagnosisId": "PD852501"}, {"followUp": [{"relapseType": null, "intervalOfFollowUp": 40, "submitterFollowUpId": "FO852502", "submitterTreatmentId": "TR852502", "diseaseStatusAtFollowUp": "Distant progression"}], "treatment": [{"chemotherapy": [{"drugName": "Tamoxifen "}], "treatmentType": ["Chemotherapy", "Hormonal therapy"], "hormoneTherapy": [{"drugName": "Anastrozole "}], "treatmentDuration": 86, "responseToTreatment": "Complete response", "submitterTreatmentId": "TR852502", "treatmentStartInterval": 8}], "ageAtDiagnosis": 32, "cancerTypeCode": "C71.7", "clinicalStageGroup": "Stage IIIB", "clinicalTumourStagingSystem": "Durie-Salmon staging system", "submitterPrimaryDiagnosisId": "PD852502"}], "submitterDonorId": "DO8525"}, "publication": {"doi": "10.1093/nar/gkae188", "publication": "NAR"}, "specimen": {"tumourGrade": "G1", "submitterSpecimenId": "SP852501", "tumourGradingSystem": "Scarff-Bloom-Richardson grading system", "specimenAnatomicLocation": "C84", "submitterPrimaryDiagnosisId": "PD852501"}, "workflow": {"runId": "RI8525", "inputs": [{"analysisType": "sequencing_alignment", "normalAnalysisId": "00000000-0000-0000-0000-0000000008525", "tumourAnalysisId": "00000000-0000-0000-0000-0000000008525"}], "sessionId": "SI8525", "genomeBuild": "GRCh38_hla_decoy_ebv", "workflowName": "Mutect2 Variant Calling", "workflowVersion": "0.1.1.1", "workflowShortName": "Mutect2Variant"}}, "file": {"name": "SP852501.snv.vcf.gz", "md5sum": "e6c73525fff2192be7df534ca6d8a8bb", "size": 17248, "data_type": "Raw SV Calls", "index_file": {"object_id": "86105e1b-0b7f-553f-8de5-6a7f28e4d183", "name": "SP852501.snv.vcf.gz.tbi", "file_type": "TBI", "md5sum": "f6386e770442a795016540f9ff6524b3", "data_type": "Raw SV Calls", "size": 141, "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "repositories": [{"code": "song.overture", "organization": "Overture", "name": "Overture", "type": "S3", "country": "CA", "url": "http://song:8080"}], "donors": [{"donor_id": "448815c8-cc3e-5149-9d81-5a6d369e743e", "submitter_donor_id": "DO8525", "gender": "Other", "specimens": [{"specimen_id": "97685422-143b-50d1-96fb-da5d4a5cc92e", "specimen_type": "Normal - tissue adjacent to primary tumour", "submitter_specimen_id": "SP852501", "samples": [{"sample_id": "97685422-143b-50d1-96fb-da5d4a5cc92e", "submitter_sample_id": "SP852501", "sample_type": "Amplified DNA", "matched_normal_submitter_sample_id": null}], "tumour_normal_designation": "Normal", "specimen_tissue_source": "Solid tissue"}]}], "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"} \ No newline at end of file diff --git a/configurationFiles/elasticsearchConfigs/es-docs/b8cdb477-995e-55cc-88ce-3e1f9b0de1d9.json b/configurationFiles/elasticsearchConfigs/es-docs/b8cdb477-995e-55cc-88ce-3e1f9b0de1d9.json deleted file mode 100644 index b07db4c2..00000000 --- a/configurationFiles/elasticsearchConfigs/es-docs/b8cdb477-995e-55cc-88ce-3e1f9b0de1d9.json +++ /dev/null @@ -1 +0,0 @@ -{"object_id": "b8cdb477-995e-55cc-88ce-3e1f9b0de1d9", "study_id": "demo", "data_type": "Raw InDel Calls", "file_type": "VCF", "file_access": "controlled", "analysis": {"analysis_id": "4c5510ec-48f7-4e73-9510-ec48f77e7373", "analysis_type": "quickStartSchema", "analysis_version": 1, "analysis_state": "PUBLISHED", "updated_at": 1720110788134, "first_published_at": 1720110788110, "published_at": 1720110788110, "experiment": {"model": "PromethION", "platform": "ONT", "sequencingDate": "2022-12-12T19:00:00.000Z", "sequencingCenter": "GATC", "experimentalStrategy": "WGS"}, "analysisStateHistory": [{"initialState": "UNPUBLISHED", "updatedState": "PUBLISHED", "updatedAt": "2024-07-04T16:33:08.110443"}], "collaborator": [{"name": "OICR", "contactEmail": "sturedman@micr.ca"}], "createdAt": "2024-07-04T16:20:39.829729", "donor": {"primarySite": "Hematopoietic and reticuloendothelial systems", "vitalStatus": "Deceased", "causeOfDeath": "Died of cancer", "survivalTime": 1057, "primaryDiagnosis": [{"followUp": [{"relapseType": null, "intervalOfFollowUp": 43, "submitterFollowUpId": "FO688101", "submitterTreatmentId": "TR688101", "diseaseStatusAtFollowUp": "Loco-regional progression"}], "treatment": [{"radiation": [{"anatomicalSiteIrradiated": "Pelvis", "radiationTherapyModality": "Photon"}], "treatmentType": ["Radiation therapy"], "treatmentDuration": 41, "responseToTreatment": "Disease progression", "submitterTreatmentId": "TR688101", "treatmentStartInterval": 56}], "ageAtDiagnosis": 42, "cancerTypeCode": "C88.0", "clinicalStageGroup": "Stage IIIB", "clinicalTumourStagingSystem": "Durie-Salmon staging system", "submitterPrimaryDiagnosisId": "PD688101"}, {"followUp": [{"relapseType": "Distant recurrence/metastasis", "intervalOfFollowUp": 22, "submitterFollowUpId": "FO688102", "submitterTreatmentId": "TR688102", "diseaseStatusAtFollowUp": "Progression NOS"}], "treatment": [{"radiation": [{"anatomicalSiteIrradiated": "Lower Limb", "radiationTherapyModality": "Electron"}], "treatmentType": ["Radiation therapy"], "treatmentDuration": 33, "responseToTreatment": "Stable disease", "submitterTreatmentId": "TR688102", "treatmentStartInterval": 82}], "ageAtDiagnosis": 62, "cancerTypeCode": "C88.3", "clinicalStageGroup": "Stage I", "clinicalTumourStagingSystem": "St Jude staging system", "submitterPrimaryDiagnosisId": "PD688102"}], "submitterDonorId": "DO6881"}, "publication": {"doi": "10.1038/s41591-023-02650-10", "publication": "Nature"}, "specimen": {"tumourGrade": "Low grade", "submitterSpecimenId": "SP688101", "tumourGradingSystem": "Two-tier grading system", "specimenAnatomicLocation": "C05", "submitterPrimaryDiagnosisId": "PD688101"}, "workflow": {"runId": "RI6881", "inputs": [{"analysisType": "sequencing_alignment", "normalAnalysisId": "00000000-0000-0000-0000-0000000006881", "tumourAnalysisId": "00000000-0000-0000-0000-0000000006881"}], "sessionId": "SI6881", "genomeBuild": "GRCh38_hla_decoy_ebv", "workflowName": "Mutect2 Variant Calling", "workflowVersion": "0.1.1.1", "workflowShortName": "Mutect2Variant"}}, "file": {"name": "SP688111.indel.vcf.gz", "md5sum": "4d42c0db3a1b64682bb2a992a7d90fce", "size": 17318, "data_type": "Raw InDel Calls", "index_file": {"object_id": "6b1decda-5b48-5e42-b499-28bad8aa5611", "name": "SP688111.indel.vcf.gz.tbi", "file_type": "TBI", "md5sum": "1a3370926a70960735c93f3ccc4e3fa8", "data_type": "Raw InDel Calls", "size": 142, "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "repositories": [{"code": "song.overture", "organization": "Overture", "name": "Overture", "type": "S3", "country": "CA", "url": "http://song:8080"}], "donors": [{"donor_id": "27c64193-35d4-5626-8ed9-74a3df052bc7", "submitter_donor_id": "DO6881", "gender": "Female", "specimens": [{"specimen_id": "67197300-99a1-590e-a7ca-df806340fe67", "specimen_type": "Metastatic tumour", "submitter_specimen_id": "SP688111", "samples": [{"sample_id": "67197300-99a1-590e-a7ca-df806340fe67", "submitter_sample_id": "SP688111", "sample_type": "Amplified DNA", "matched_normal_submitter_sample_id": "SP688101"}], "tumour_normal_designation": "Tumour", "specimen_tissue_source": "Blood derived"}]}], "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"} \ No newline at end of file diff --git a/configurationFiles/elasticsearchConfigs/es-docs/bba25936-6d51-5b24-be2c-6af6d462c434.json b/configurationFiles/elasticsearchConfigs/es-docs/bba25936-6d51-5b24-be2c-6af6d462c434.json deleted file mode 100644 index d27cd200..00000000 --- a/configurationFiles/elasticsearchConfigs/es-docs/bba25936-6d51-5b24-be2c-6af6d462c434.json +++ /dev/null @@ -1 +0,0 @@ -{"object_id": "bba25936-6d51-5b24-be2c-6af6d462c434", "study_id": "demo", "data_type": "Raw InDel Calls", "file_type": "VCF", "file_access": "controlled", "analysis": {"analysis_id": "4e5bec94-e864-49a3-9bec-94e86449a3cd", "analysis_type": "quickStartSchema", "analysis_version": 1, "analysis_state": "PUBLISHED", "updated_at": 1720111114276, "first_published_at": 1720111114252, "published_at": 1720111114252, "experiment": {"model": "SEQUEL IIe", "platform": "PacBio", "sequencingDate": "2021-03-08T19:00:00.000Z", "sequencingCenter": "CGTA", "experimentalStrategy": "WGS"}, "analysisStateHistory": [{"initialState": "UNPUBLISHED", "updatedState": "PUBLISHED", "updatedAt": "2024-07-04T16:38:34.252859"}], "collaborator": [{"name": "AICR", "contactEmail": "raygarraty@aicr.ca"}], "createdAt": "2024-07-04T16:21:32.201838", "donor": {"primarySite": "Bronchus and lung", "vitalStatus": "Deceased", "causeOfDeath": "Died of other reasons", "survivalTime": 1108, "primaryDiagnosis": [{"followUp": [{"relapseType": null, "intervalOfFollowUp": 92, "submitterFollowUpId": "FO945801", "submitterTreatmentId": "TR945801", "diseaseStatusAtFollowUp": "Relapse or recurrence"}], "treatment": [{"treatmentType": ["No treatment"], "submitterTreatmentId": "TR945801"}], "ageAtDiagnosis": 44, "cancerTypeCode": "C34.3", "clinicalStageGroup": "Stage IA2", "clinicalTumourStagingSystem": "FIGO staging system", "submitterPrimaryDiagnosisId": "PD945801"}, {"followUp": [{"relapseType": null, "intervalOfFollowUp": 33, "submitterFollowUpId": "FO945802", "submitterTreatmentId": "TR945802", "diseaseStatusAtFollowUp": "Relapse or recurrence"}], "treatment": [{"treatmentType": ["Hormonal therapy"], "hormoneTherapy": [{"drugName": "Exemestane "}], "treatmentDuration": 61, "responseToTreatment": "Complete response", "submitterTreatmentId": "TR945802", "treatmentStartInterval": 11}], "ageAtDiagnosis": 3, "cancerTypeCode": "C34.3", "clinicalStageGroup": "Stage IIIC", "clinicalTumourStagingSystem": "AJCC 7th edition", "submitterPrimaryDiagnosisId": "PD945802"}], "submitterDonorId": "DO9458"}, "publication": {"doi": "10.1093/nar/gkae188", "publication": "NAR"}, "specimen": {"tumourGrade": "G2", "submitterSpecimenId": "SP945802", "tumourGradingSystem": "ISUP grading system", "specimenAnatomicLocation": "C30", "submitterPrimaryDiagnosisId": "PD945801"}, "workflow": {"runId": "RI9458", "inputs": [{"analysisType": "sequencing_alignment", "normalAnalysisId": "00000000-0000-0000-0000-0000000009458", "tumourAnalysisId": "00000000-0000-0000-0000-0000000009458"}], "sessionId": "SI9458", "genomeBuild": "GRCh38_hla_decoy_ebv", "workflowName": "Mutect2 Variant Calling", "workflowVersion": "0.1.1.1", "workflowShortName": "Mutect2Variant"}}, "file": {"name": "SP945812.indel.vcf.gz", "md5sum": "ebec6c266ba376c11a97cca3a3180d49", "size": 17292, "data_type": "Raw InDel Calls", "index_file": {"object_id": "970c4b15-2ba3-5779-b0cb-f3c88ba3932b", "name": "SP945812.indel.vcf.gz.tbi", "file_type": "TBI", "md5sum": "51567d8aaa36ec2093f3f7c5293084e0", "data_type": "Raw InDel Calls", "size": 142, "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "repositories": [{"code": "song.overture", "organization": "Overture", "name": "Overture", "type": "S3", "country": "CA", "url": "http://song:8080"}], "donors": [{"donor_id": "d9e8cd4c-48c8-5a56-9d87-8217370fc72d", "submitter_donor_id": "DO9458", "gender": "Female", "specimens": [{"specimen_id": "305b0fde-efd3-54be-8d8f-fd37b6b976ec", "specimen_type": "Primary tumour - additional new primary", "submitter_specimen_id": "SP945812", "samples": [{"sample_id": "305b0fde-efd3-54be-8d8f-fd37b6b976ec", "submitter_sample_id": "SP945812", "sample_type": "Total DNA", "matched_normal_submitter_sample_id": "SP945802"}], "tumour_normal_designation": "Tumour", "specimen_tissue_source": "Blood derived - bone marrow"}]}], "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"} \ No newline at end of file diff --git a/configurationFiles/elasticsearchConfigs/es-docs/bf14635d-e43e-5dfd-b977-f2735e98f7e3.json b/configurationFiles/elasticsearchConfigs/es-docs/bf14635d-e43e-5dfd-b977-f2735e98f7e3.json deleted file mode 100644 index 7e05769a..00000000 --- a/configurationFiles/elasticsearchConfigs/es-docs/bf14635d-e43e-5dfd-b977-f2735e98f7e3.json +++ /dev/null @@ -1 +0,0 @@ -{"object_id": "bf14635d-e43e-5dfd-b977-f2735e98f7e3", "study_id": "demo", "data_type": "Raw InDel Calls", "file_type": "VCF", "file_access": "controlled", "analysis": {"analysis_id": "dce88d62-d3ba-4430-a88d-62d3bad430cd", "analysis_type": "quickStartSchema", "analysis_version": 1, "analysis_state": "PUBLISHED", "updated_at": 1720111088173, "first_published_at": 1720111088162, "published_at": 1720111088162, "experiment": {"model": "SEQUEL IIe", "platform": "PacBio", "sequencingDate": "2021-03-08T19:00:00.000Z", "sequencingCenter": "CGTA", "experimentalStrategy": "WGS"}, "analysisStateHistory": [{"initialState": "UNPUBLISHED", "updatedState": "PUBLISHED", "updatedAt": "2024-07-04T16:38:08.162907"}], "collaborator": [{"name": "AICR", "contactEmail": "raygarraty@aicr.ca"}], "createdAt": "2024-07-04T16:21:27.777779", "donor": {"primarySite": "Brain", "vitalStatus": "Alive", "causeOfDeath": null, "survivalTime": null, "primaryDiagnosis": [{"followUp": [{"relapseType": null, "intervalOfFollowUp": 5, "submitterFollowUpId": "FO933301", "submitterTreatmentId": "TR933301", "diseaseStatusAtFollowUp": "Stable"}], "treatment": [{"chemotherapy": [{"drugName": "Azacitidine "}], "treatmentType": ["Chemotherapy", "Hormonal therapy"], "hormoneTherapy": [{"drugName": "Exemestane "}], "treatmentDuration": 59, "responseToTreatment": "Complete response", "submitterTreatmentId": "TR933301", "treatmentStartInterval": 57}], "ageAtDiagnosis": 30, "cancerTypeCode": "C71.6", "clinicalStageGroup": "Stage I", "clinicalTumourStagingSystem": "Rai staging system", "submitterPrimaryDiagnosisId": "PD933301"}], "submitterDonorId": "DO9333"}, "publication": {"doi": "10.1093/nar/gkae188", "publication": "NAR"}, "specimen": {"tumourGrade": "GX", "submitterSpecimenId": "SP933302", "tumourGradingSystem": "Scarff-Bloom-Richardson grading system", "specimenAnatomicLocation": "C52", "submitterPrimaryDiagnosisId": "PD933301"}, "workflow": {"runId": "RI9333", "inputs": [{"analysisType": "sequencing_alignment", "normalAnalysisId": "00000000-0000-0000-0000-0000000009333", "tumourAnalysisId": "00000000-0000-0000-0000-0000000009333"}], "sessionId": "SI9333", "genomeBuild": "GRCh38_hla_decoy_ebv", "workflowName": "Sanger Variant Calling", "workflowVersion": "0.9.8", "workflowShortName": "SangerVariant"}}, "file": {"name": "SP933302.indel.vcf.gz", "md5sum": "51b47fe36f87185ab15fe84cfb4fcb81", "size": 17322, "data_type": "Raw InDel Calls", "index_file": {"object_id": "2cb8cdd1-3686-52ec-9b67-1c99d664a2e0", "name": "SP933302.indel.vcf.gz.tbi", "file_type": "TBI", "md5sum": "d5ad09fbcf9405daffbbf0d9ff38e2e6", "data_type": "Raw InDel Calls", "size": 144, "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "repositories": [{"code": "song.overture", "organization": "Overture", "name": "Overture", "type": "S3", "country": "CA", "url": "http://song:8080"}], "donors": [{"donor_id": "fcd59878-cc3a-5223-8152-50942ca28bef", "submitter_donor_id": "DO9333", "gender": "Other", "specimens": [{"specimen_id": "2cf7844e-a254-5148-bd4b-3bc7eba62a42", "specimen_type": "Normal", "submitter_specimen_id": "SP933302", "samples": [{"sample_id": "2cf7844e-a254-5148-bd4b-3bc7eba62a42", "submitter_sample_id": "SP933302", "sample_type": "Amplified DNA", "matched_normal_submitter_sample_id": null}], "tumour_normal_designation": "Normal", "specimen_tissue_source": "Blood derived"}]}], "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"} \ No newline at end of file diff --git a/configurationFiles/elasticsearchConfigs/es-docs/c0ecacdb-92c1-5e37-b949-24e9acfb50e2.json b/configurationFiles/elasticsearchConfigs/es-docs/c0ecacdb-92c1-5e37-b949-24e9acfb50e2.json deleted file mode 100644 index aac8eb09..00000000 --- a/configurationFiles/elasticsearchConfigs/es-docs/c0ecacdb-92c1-5e37-b949-24e9acfb50e2.json +++ /dev/null @@ -1 +0,0 @@ -{"object_id": "c0ecacdb-92c1-5e37-b949-24e9acfb50e2", "study_id": "demo", "data_type": "Raw InDel Calls", "file_type": "VCF", "file_access": "controlled", "analysis": {"analysis_id": "1ee9e37e-369d-4947-a9e3-7e369d19474b", "analysis_type": "quickStartSchema", "analysis_version": 1, "analysis_state": "PUBLISHED", "updated_at": 1720110375139, "first_published_at": 1720110375093, "published_at": 1720110375093, "experiment": {"model": "SEQUEL IIe", "platform": "PacBio", "sequencingDate": "2021-03-08T19:00:00.000Z", "sequencingCenter": "CGTA", "experimentalStrategy": "WXS"}, "analysisStateHistory": [{"initialState": "UNPUBLISHED", "updatedState": "PUBLISHED", "updatedAt": "2024-07-04T16:26:15.093123"}], "collaborator": [{"name": "MICR", "contactEmail": "susannorton@micr.ca"}], "createdAt": "2024-07-04T16:19:26.813659", "donor": {"primarySite": "Hematopoietic and reticuloendothelial systems", "vitalStatus": "Alive", "causeOfDeath": null, "survivalTime": null, "primaryDiagnosis": [{"followUp": [{"relapseType": null, "intervalOfFollowUp": 67, "submitterFollowUpId": "FO744301", "submitterTreatmentId": "TR744301", "diseaseStatusAtFollowUp": "Complete remission"}], "treatment": [{"chemotherapy": [{"drugName": "Azacitidine "}], "treatmentType": ["Chemotherapy"], "treatmentDuration": 70, "responseToTreatment": "Disease progression", "submitterTreatmentId": "TR744301", "treatmentStartInterval": 21}], "ageAtDiagnosis": 57, "cancerTypeCode": "C88.3", "clinicalStageGroup": "Stage IIC", "clinicalTumourStagingSystem": "AJCC 7th edition", "submitterPrimaryDiagnosisId": "PD744301"}], "submitterDonorId": "DO7443"}, "publication": {"doi": "10.1093/nar/gkae188", "publication": "NAR"}, "specimen": {"tumourGrade": "G2", "submitterSpecimenId": "SP744302", "tumourGradingSystem": "Three-tier grading system", "specimenAnatomicLocation": "C81", "submitterPrimaryDiagnosisId": "PD744301"}, "workflow": {"runId": "RI7443", "inputs": [{"analysisType": "sequencing_alignment", "normalAnalysisId": "00000000-0000-0000-0000-0000000007443", "tumourAnalysisId": "00000000-0000-0000-0000-0000000007443"}], "sessionId": "SI7443", "genomeBuild": "GRCh38_hla_decoy_ebv", "workflowName": "Mutect2 Variant Calling", "workflowVersion": "0.1.1.1", "workflowShortName": "Mutect2Variant"}}, "file": {"name": "SP744302.indel.vcf.gz", "md5sum": "df0fd6e0bd5e9a79f54e120bdbc82c5c", "size": 17314, "data_type": "Raw InDel Calls", "index_file": {"object_id": "798480ca-3919-5d8b-aa25-37f97115cfb5", "name": "SP744302.indel.vcf.gz.tbi", "file_type": "TBI", "md5sum": "f8329c8c667203d98fae606df0400232", "data_type": "Raw InDel Calls", "size": 150, "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "repositories": [{"code": "song.overture", "organization": "Overture", "name": "Overture", "type": "S3", "country": "CA", "url": "http://song:8080"}], "donors": [{"donor_id": "6ac5fc9e-88db-5837-9e57-3f048980ce90", "submitter_donor_id": "DO7443", "gender": "Male", "specimens": [{"specimen_id": "89bb25d4-3635-56b5-93b4-741891fa9577", "specimen_type": "Normal - tissue adjacent to primary tumour", "submitter_specimen_id": "SP744302", "samples": [{"sample_id": "89bb25d4-3635-56b5-93b4-741891fa9577", "submitter_sample_id": "SP744302", "sample_type": "ctDNA", "matched_normal_submitter_sample_id": null}], "tumour_normal_designation": "Normal", "specimen_tissue_source": "Intestine"}]}], "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"} diff --git a/configurationFiles/elasticsearchConfigs/es-docs/e3ef7c5a-244e-5323-acd0-94d66c2f0125.json b/configurationFiles/elasticsearchConfigs/es-docs/e3ef7c5a-244e-5323-acd0-94d66c2f0125.json deleted file mode 100644 index 8d764ecc..00000000 --- a/configurationFiles/elasticsearchConfigs/es-docs/e3ef7c5a-244e-5323-acd0-94d66c2f0125.json +++ /dev/null @@ -1 +0,0 @@ -{"object_id": "e3ef7c5a-244e-5323-acd0-94d66c2f0125", "study_id": "demo", "data_type": "Raw InDel Calls", "file_type": "VCF", "file_access": "controlled", "analysis": {"analysis_id": "ddb51c82-23c0-4565-b51c-8223c0356510", "analysis_type": "quickStartSchema", "analysis_version": 1, "analysis_state": "PUBLISHED", "updated_at": 1720110705748, "first_published_at": 1720110705727, "published_at": 1720110705727, "experiment": {"model": "PromethION", "platform": "ONT", "sequencingDate": "2022-12-12T19:00:00.000Z", "sequencingCenter": "GATC", "experimentalStrategy": "WGS"}, "analysisStateHistory": [{"initialState": "UNPUBLISHED", "updatedState": "PUBLISHED", "updatedAt": "2024-07-04T16:31:45.727741"}], "collaborator": [{"name": "OICR", "contactEmail": "sturedman@micr.ca"}], "createdAt": "2024-07-04T16:20:26.586857", "donor": {"primarySite": "Hematopoietic and reticuloendothelial systems", "vitalStatus": "Deceased", "causeOfDeath": "Died of cancer", "survivalTime": 1057, "primaryDiagnosis": [{"followUp": [{"relapseType": null, "intervalOfFollowUp": 43, "submitterFollowUpId": "FO688101", "submitterTreatmentId": "TR688101", "diseaseStatusAtFollowUp": "Loco-regional progression"}], "treatment": [{"radiation": [{"anatomicalSiteIrradiated": "Pelvis", "radiationTherapyModality": "Photon"}], "treatmentType": ["Radiation therapy"], "treatmentDuration": 41, "responseToTreatment": "Disease progression", "submitterTreatmentId": "TR688101", "treatmentStartInterval": 56}], "ageAtDiagnosis": 42, "cancerTypeCode": "C88.0", "clinicalStageGroup": "Stage IIIB", "clinicalTumourStagingSystem": "Durie-Salmon staging system", "submitterPrimaryDiagnosisId": "PD688101"}, {"followUp": [{"relapseType": "Distant recurrence/metastasis", "intervalOfFollowUp": 22, "submitterFollowUpId": "FO688102", "submitterTreatmentId": "TR688102", "diseaseStatusAtFollowUp": "Progression NOS"}], "treatment": [{"radiation": [{"anatomicalSiteIrradiated": "Lower Limb", "radiationTherapyModality": "Electron"}], "treatmentType": ["Radiation therapy"], "treatmentDuration": 33, "responseToTreatment": "Stable disease", "submitterTreatmentId": "TR688102", "treatmentStartInterval": 82}], "ageAtDiagnosis": 62, "cancerTypeCode": "C88.3", "clinicalStageGroup": "Stage I", "clinicalTumourStagingSystem": "St Jude staging system", "submitterPrimaryDiagnosisId": "PD688102"}], "submitterDonorId": "DO6881"}, "publication": {"doi": "10.1038/s41591-023-02650-10", "publication": "Nature"}, "specimen": {"tumourGrade": "G2", "submitterSpecimenId": "SP688101", "tumourGradingSystem": "Three-tier grading system", "specimenAnatomicLocation": "C61", "submitterPrimaryDiagnosisId": "PD688101"}, "workflow": {"runId": "RI6881", "inputs": [{"analysisType": "sequencing_alignment", "normalAnalysisId": "00000000-0000-0000-0000-0000000006881", "tumourAnalysisId": "00000000-0000-0000-0000-0000000006881"}], "sessionId": "SI6881", "genomeBuild": "GRCh38_hla_decoy_ebv", "workflowName": "Mutect2 Variant Calling", "workflowVersion": "0.1.1.1", "workflowShortName": "Mutect2Variant"}}, "file": {"name": "SP688101.indel.vcf.gz", "md5sum": "3a1b62929d0b9762fa72e5c7d99456b7", "size": 17360, "data_type": "Raw InDel Calls", "index_file": {"object_id": "3f037c6f-3b0e-58eb-8ebc-788ba82e466a", "name": "SP688101.indel.vcf.gz.tbi", "file_type": "TBI", "md5sum": "bf31495ee155fe79f785120c9b41130d", "data_type": "Raw InDel Calls", "size": 142, "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "repositories": [{"code": "song.overture", "organization": "Overture", "name": "Overture", "type": "S3", "country": "CA", "url": "http://song:8080"}], "donors": [{"donor_id": "27c64193-35d4-5626-8ed9-74a3df052bc7", "submitter_donor_id": "DO6881", "gender": "Female", "specimens": [{"specimen_id": "a749aac5-fd92-5e56-8c0e-5688026a5fe4", "specimen_type": "Normal", "submitter_specimen_id": "SP688101", "samples": [{"sample_id": "a749aac5-fd92-5e56-8c0e-5688026a5fe4", "submitter_sample_id": "SP688101", "sample_type": "Amplified DNA", "matched_normal_submitter_sample_id": null}], "tumour_normal_designation": "Normal", "specimen_tissue_source": "Blood derived - peripheral blood"}]}], "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"} \ No newline at end of file diff --git a/configurationFiles/elasticsearchConfigs/es-docs/e45bed7a-552d-5076-9507-405c51b2f196.json b/configurationFiles/elasticsearchConfigs/es-docs/e45bed7a-552d-5076-9507-405c51b2f196.json deleted file mode 100644 index 2def876e..00000000 --- a/configurationFiles/elasticsearchConfigs/es-docs/e45bed7a-552d-5076-9507-405c51b2f196.json +++ /dev/null @@ -1 +0,0 @@ -{"object_id": "e45bed7a-552d-5076-9507-405c51b2f196", "study_id": "demo", "data_type": "Aligned Reads", "file_type": "BAM", "file_access": "controlled", "analysis": {"analysis_id": "8c1c5dc1-131a-474f-9c5d-c1131aa74f3f", "analysis_type": "quickStartSchema", "analysis_version": 1, "analysis_state": "PUBLISHED", "updated_at": 1720110895235, "first_published_at": 1720110895024, "published_at": 1720110895024, "experiment": {"model": "SEQUEL IIe", "platform": "PacBio", "sequencingDate": "2021-03-08T19:00:00.000Z", "sequencingCenter": "CGTA", "experimentalStrategy": "WGS"}, "analysisStateHistory": [{"initialState": "UNPUBLISHED", "updatedState": "PUBLISHED", "updatedAt": "2024-07-04T16:34:55.024965"}], "collaborator": [{"name": "AICR", "contactEmail": "sturedman@micr.ca"}], "createdAt": "2024-07-04T16:20:57.14825", "donor": {"primarySite": "Bronchus and lung", "vitalStatus": "Alive", "causeOfDeath": null, "survivalTime": null, "primaryDiagnosis": [{"followUp": [{"relapseType": null, "intervalOfFollowUp": 72, "submitterFollowUpId": "FO787701", "submitterTreatmentId": "TR787701", "diseaseStatusAtFollowUp": "Distant progression"}], "treatment": [{"radiation": [{"anatomicalSiteIrradiated": "Body", "radiationTherapyModality": "Heavy Ions"}], "treatmentType": ["Hormonal therapy", "Radiation therapy"], "hormoneTherapy": [{"drugName": "Exemestane "}], "treatmentDuration": 43, "responseToTreatment": "Disease progression", "submitterTreatmentId": "TR787701", "treatmentStartInterval": 23}], "ageAtDiagnosis": 73, "cancerTypeCode": "C34.2", "clinicalStageGroup": "Stage I", "clinicalTumourStagingSystem": "Ann Arbor staging system", "submitterPrimaryDiagnosisId": "PD787701"}], "submitterDonorId": "DO7877"}, "publication": {"doi": "10.1093/nar/gkae188", "publication": "NAR"}, "specimen": {"tumourGrade": "GX", "submitterSpecimenId": "SP787701", "tumourGradingSystem": "Four-tier grading system", "specimenAnatomicLocation": "C17", "submitterPrimaryDiagnosisId": "PD787701"}, "workflow": {"runId": "RI7877", "inputs": [{"analysisId": "00000000-0000-0000-0000-0000000007877", "analysisType": "sequencing_experiment"}], "sessionId": "SI7877", "genomeBuild": "GRCh38_hla_decoy_ebv", "workflowName": "Bowtie2 Alignment", "workflowVersion": "0.1.0", "workflowShortName": "Bowtie2Aln"}}, "file": {"name": "SP787701.bam", "md5sum": "a420e75cf90ea41f20f79873357a44e0", "size": 125371, "data_type": "Aligned Reads", "index_file": {"object_id": "f99fe6f8-10b6-5989-ba33-92c7a3527476", "name": "SP787701.bam.bai", "file_type": "BAI", "md5sum": "261b232a0c997eb4972f9b5f7b29f840", "data_type": "Aligned Reads", "size": 27256, "dataCategory": "Sequencing Reads", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "dataCategory": "Sequencing Reads", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "repositories": [{"code": "song.overture", "organization": "Overture", "name": "Overture", "type": "S3", "country": "CA", "url": "http://song:8080"}], "donors": [{"donor_id": "032e868a-4a54-5364-a4e6-416df3cd56a4", "submitter_donor_id": "DO7877", "gender": "Other", "specimens": [{"specimen_id": "ad8fa2f0-8c3a-5166-9740-d0aaa69749b1", "specimen_type": "Normal", "submitter_specimen_id": "SP787701", "samples": [{"sample_id": "ad8fa2f0-8c3a-5166-9740-d0aaa69749b1", "submitter_sample_id": "SP787701", "sample_type": "ctDNA", "matched_normal_submitter_sample_id": null}], "tumour_normal_designation": "Normal", "specimen_tissue_source": "Blood derived - peripheral blood"}]}], "dataCategory": "Sequencing Reads", "jbrowseCoordinates": "hg38:chr1:100000-200000"} \ No newline at end of file diff --git a/configurationFiles/elasticsearchConfigs/es-docs/e9e7922a-a102-5381-be8f-b020e6045877.json b/configurationFiles/elasticsearchConfigs/es-docs/e9e7922a-a102-5381-be8f-b020e6045877.json deleted file mode 100644 index aa333140..00000000 --- a/configurationFiles/elasticsearchConfigs/es-docs/e9e7922a-a102-5381-be8f-b020e6045877.json +++ /dev/null @@ -1 +0,0 @@ -{"object_id": "e9e7922a-a102-5381-be8f-b020e6045877", "study_id": "demo", "data_type": "Raw InDel Calls", "file_type": "VCF", "file_access": "controlled", "analysis": {"analysis_id": "2320f88c-27fa-49ec-a0f8-8c27fa79eca3", "analysis_type": "quickStartSchema", "analysis_version": 1, "analysis_state": "PUBLISHED", "updated_at": 1720110680589, "first_published_at": 1720110680576, "published_at": 1720110680576, "experiment": {"model": "PromethION", "platform": "ONT", "sequencingDate": "2022-12-12T19:00:00.000Z", "sequencingCenter": "GATC", "experimentalStrategy": "WXS"}, "analysisStateHistory": [{"initialState": "UNPUBLISHED", "updatedState": "PUBLISHED", "updatedAt": "2024-07-04T16:31:20.57634"}], "collaborator": [{"name": "OICR", "contactEmail": "sturedman@micr.ca"}], "createdAt": "2024-07-04T16:20:22.006625", "donor": {"primarySite": "Bronchus and lung", "vitalStatus": "Deceased", "causeOfDeath": "Died of other reasons", "survivalTime": 1465, "primaryDiagnosis": [{"followUp": [{"relapseType": null, "intervalOfFollowUp": 81, "submitterFollowUpId": "FO919801", "submitterTreatmentId": "TR919801", "diseaseStatusAtFollowUp": "Distant progression"}], "treatment": [{"treatmentType": ["Hormonal therapy"], "hormoneTherapy": [{"drugName": "Anastrozole"}], "treatmentDuration": 84, "responseToTreatment": "Minor response", "submitterTreatmentId": "TR919801", "treatmentStartInterval": 86}], "ageAtDiagnosis": 43, "cancerTypeCode": "C34.0", "clinicalStageGroup": "Stage IB1", "clinicalTumourStagingSystem": "FIGO staging system", "submitterPrimaryDiagnosisId": "PD919801"}], "submitterDonorId": "DO9198"}, "publication": {"doi": "10.1038/s41591-023-02650-10", "publication": "Nature"}, "specimen": {"tumourGrade": "G3", "submitterSpecimenId": "SP919801", "tumourGradingSystem": "Scarff-Bloom-Richardson grading system", "specimenAnatomicLocation": "C10", "submitterPrimaryDiagnosisId": "PD919801"}, "workflow": {"runId": "RI9198", "inputs": [{"analysisType": "sequencing_alignment", "normalAnalysisId": "00000000-0000-0000-0000-0000000009198", "tumourAnalysisId": "00000000-0000-0000-0000-0000000009198"}], "sessionId": "SI9198", "genomeBuild": "GRCh38_hla_decoy_ebv", "workflowName": "Mutect2 Variant Calling", "workflowVersion": "0.1.1.1", "workflowShortName": "Mutect2Variant"}}, "file": {"name": "SP919811.indel.vcf.gz", "md5sum": "b32991cae3845c0b38ff42dc6179a5c1", "size": 17405, "data_type": "Raw InDel Calls", "index_file": {"object_id": "05dc857c-1a01-5a47-9bbb-ceddad8da90a", "name": "SP919811.indel.vcf.gz.tbi", "file_type": "TBI", "md5sum": "c0e92c3059a3dd763c72a1e633c08b4a", "data_type": "Raw InDel Calls", "size": 159, "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "repositories": [{"code": "song.overture", "organization": "Overture", "name": "Overture", "type": "S3", "country": "CA", "url": "http://song:8080"}], "donors": [{"donor_id": "4d1c2bd5-79cd-5448-bbb2-ada6ad4a5cb4", "submitter_donor_id": "DO9198", "gender": "Male", "specimens": [{"specimen_id": "f4e34423-3588-52b0-9c3d-6ba37b5302ce", "specimen_type": "Metastatic tumour - additional metastatic", "submitter_specimen_id": "SP919811", "samples": [{"sample_id": "f4e34423-3588-52b0-9c3d-6ba37b5302ce", "submitter_sample_id": "SP919811", "sample_type": "Amplified DNA", "matched_normal_submitter_sample_id": "SP919801"}], "tumour_normal_designation": "Tumour", "specimen_tissue_source": "Blood derived"}]}], "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"} \ No newline at end of file diff --git a/configurationFiles/elasticsearchConfigs/es-docs/fa6ed231-77fe-5b2b-8df4-f32f8d526208.json b/configurationFiles/elasticsearchConfigs/es-docs/fa6ed231-77fe-5b2b-8df4-f32f8d526208.json deleted file mode 100644 index 0277cd7b..00000000 --- a/configurationFiles/elasticsearchConfigs/es-docs/fa6ed231-77fe-5b2b-8df4-f32f8d526208.json +++ /dev/null @@ -1 +0,0 @@ -{"object_id": "fa6ed231-77fe-5b2b-8df4-f32f8d526208", "study_id": "demo", "data_type": "Raw InDel Calls", "file_type": "VCF", "file_access": "controlled", "analysis": {"analysis_id": "b110074f-4337-41b3-9007-4f433761b39f", "analysis_type": "quickStartSchema", "analysis_version": 1, "analysis_state": "PUBLISHED", "updated_at": 1720110406367, "first_published_at": 1720110406356, "published_at": 1720110406356, "experiment": {"model": "SEQUEL IIe", "platform": "PacBio", "sequencingDate": "2021-03-08T19:00:00.000Z", "sequencingCenter": "CGTA", "experimentalStrategy": "WXS"}, "analysisStateHistory": [{"initialState": "UNPUBLISHED", "updatedState": "PUBLISHED", "updatedAt": "2024-07-04T16:26:46.356908"}], "collaborator": [{"name": "MICR", "contactEmail": "susannorton@micr.ca"}], "createdAt": "2024-07-04T16:19:32.104094", "donor": {"primarySite": "Hematopoietic and reticuloendothelial systems", "vitalStatus": "Alive", "causeOfDeath": null, "survivalTime": null, "primaryDiagnosis": [{"followUp": [{"relapseType": null, "intervalOfFollowUp": 67, "submitterFollowUpId": "FO744301", "submitterTreatmentId": "TR744301", "diseaseStatusAtFollowUp": "Complete remission"}], "treatment": [{"chemotherapy": [{"drugName": "Azacitidine "}], "treatmentType": ["Chemotherapy"], "treatmentDuration": 70, "responseToTreatment": "Disease progression", "submitterTreatmentId": "TR744301", "treatmentStartInterval": 21}], "ageAtDiagnosis": 57, "cancerTypeCode": "C88.3", "clinicalStageGroup": "Stage IIC", "clinicalTumourStagingSystem": "AJCC 7th edition", "submitterPrimaryDiagnosisId": "PD744301"}], "submitterDonorId": "DO7443"}, "publication": {"doi": "10.1093/nar/gkae188", "publication": "NAR"}, "specimen": {"tumourGrade": "G1", "submitterSpecimenId": "SP744302", "tumourGradingSystem": "ISUP grading system", "specimenAnatomicLocation": "C47", "submitterPrimaryDiagnosisId": "PD744301"}, "workflow": {"runId": "RI7443", "inputs": [{"analysisType": "sequencing_alignment", "normalAnalysisId": "00000000-0000-0000-0000-0000000007443", "tumourAnalysisId": "00000000-0000-0000-0000-0000000007443"}], "sessionId": "SI7443", "genomeBuild": "GRCh38_hla_decoy_ebv", "workflowName": "Mutect2 Variant Calling", "workflowVersion": "0.1.1.1", "workflowShortName": "Mutect2Variant"}}, "file": {"name": "SP744312.indel.vcf.gz", "md5sum": "d713f83a36ff6d95a49268905b8a0206", "size": 17380, "data_type": "Raw InDel Calls", "index_file": {"object_id": "11fe277d-454b-51be-a6c8-9a890e2e332c", "name": "SP744312.indel.vcf.gz.tbi", "file_type": "TBI", "md5sum": "0fffe3a8969892bebfb92554748d1d60", "data_type": "Raw InDel Calls", "size": 151, "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "repositories": [{"code": "song.overture", "organization": "Overture", "name": "Overture", "type": "S3", "country": "CA", "url": "http://song:8080"}], "donors": [{"donor_id": "6ac5fc9e-88db-5837-9e57-3f048980ce90", "submitter_donor_id": "DO7443", "gender": "Male", "specimens": [{"specimen_id": "cf6006da-3fde-5945-afc4-635924a26800", "specimen_type": "Metastatic tumour - additional metastatic", "submitter_specimen_id": "SP744312", "samples": [{"sample_id": "cf6006da-3fde-5945-afc4-635924a26800", "submitter_sample_id": "SP744312", "sample_type": "ctDNA", "matched_normal_submitter_sample_id": "SP744302"}], "tumour_normal_designation": "Tumour", "specimen_tissue_source": "Blood derived"}]}], "dataCategory": "Simple Nucelotide Variation", "jbrowseCoordinates": "hg38:chr1:100000-200000"} \ No newline at end of file diff --git a/configurationFiles/elasticsearchConfigs/es-docs/ff7b8ca2-2b43-5503-b407-35dc8b0591b0.json b/configurationFiles/elasticsearchConfigs/es-docs/ff7b8ca2-2b43-5503-b407-35dc8b0591b0.json deleted file mode 100644 index 86e30a23..00000000 --- a/configurationFiles/elasticsearchConfigs/es-docs/ff7b8ca2-2b43-5503-b407-35dc8b0591b0.json +++ /dev/null @@ -1 +0,0 @@ -{"object_id": "ff7b8ca2-2b43-5503-b407-35dc8b0591b0", "study_id": "demo", "data_type": "Aligned Reads", "file_type": "BAM", "file_access": "controlled", "analysis": {"analysis_id": "d7fe62b5-3bab-47b0-be62-b53bab77b0e7", "analysis_type": "quickStartSchema", "analysis_version": 1, "analysis_state": "PUBLISHED", "updated_at": 1720110461116, "first_published_at": 1720110461106, "published_at": 1720110461106, "experiment": {"model": "SEQUEL IIe", "platform": "PacBio", "sequencingDate": "2021-03-08T19:00:00.000Z", "sequencingCenter": "CGTA", "experimentalStrategy": "WGS"}, "analysisStateHistory": [{"initialState": "UNPUBLISHED", "updatedState": "PUBLISHED", "updatedAt": "2024-07-04T16:27:41.106551"}], "collaborator": [{"name": "MICR", "contactEmail": "susannorton@micr.ca"}], "createdAt": "2024-07-04T16:19:40.628302", "donor": {"primarySite": "Bronchus and lung", "vitalStatus": "Alive", "causeOfDeath": null, "survivalTime": null, "primaryDiagnosis": [{"followUp": [{"relapseType": null, "intervalOfFollowUp": 74, "submitterFollowUpId": "FO745301", "submitterTreatmentId": "TR745301", "diseaseStatusAtFollowUp": "Relapse or recurrence"}], "treatment": [{"treatmentType": ["Hormonal therapy"], "hormoneTherapy": [{"drugName": "Letrozole "}], "treatmentDuration": 32, "responseToTreatment": "Partial response", "submitterTreatmentId": "TR745301", "treatmentStartInterval": 38}], "ageAtDiagnosis": 30, "cancerTypeCode": "C34.3", "clinicalStageGroup": "Stage IB1", "clinicalTumourStagingSystem": "FIGO staging system", "submitterPrimaryDiagnosisId": "PD745301"}, {"followUp": [{"relapseType": null, "intervalOfFollowUp": 46, "submitterFollowUpId": "FO745302", "submitterTreatmentId": "TR745302", "diseaseStatusAtFollowUp": "Relapse or recurrence"}], "treatment": [{"chemotherapy": [{"drugName": "Tamoxifen "}], "treatmentType": ["Chemotherapy"], "treatmentDuration": 44, "responseToTreatment": "Disease progression", "submitterTreatmentId": "TR745302", "treatmentStartInterval": 82}], "ageAtDiagnosis": 20, "cancerTypeCode": "C34.8", "clinicalStageGroup": "Stage III", "clinicalTumourStagingSystem": "Ann Arbor staging system", "submitterPrimaryDiagnosisId": "PD745302"}], "submitterDonorId": "DO7453"}, "publication": {"doi": "10.1093/nar/gkae188", "publication": "NAR"}, "specimen": {"tumourGrade": "G3", "submitterSpecimenId": "SP745301", "tumourGradingSystem": "Four-tier grading system", "specimenAnatomicLocation": "C11", "submitterPrimaryDiagnosisId": "PD745301"}, "workflow": {"runId": "RI7453", "inputs": [{"analysisId": "00000000-0000-0000-0000-0000000007453", "analysisType": "sequencing_experiment"}], "sessionId": "SI7453", "genomeBuild": "GRCh38_hla_decoy_ebv", "workflowName": "BWA mem2 Alignment", "workflowVersion": "0.8", "workflowShortName": "BWAmem2Aln"}}, "file": {"name": "SP745311.bam", "md5sum": "7df44e073f73923d05893764889039d2", "size": 125255, "data_type": "Aligned Reads", "index_file": {"object_id": "a36547ca-da4a-5591-a0fc-4e11e03a829c", "name": "SP745311.bam.bai", "file_type": "BAI", "md5sum": "dd2b54ec315db4ef29ffeec3777fc8a0", "data_type": "Aligned Reads", "size": 27160, "dataCategory": "Sequencing Reads", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "dataCategory": "Sequencing Reads", "jbrowseCoordinates": "hg38:chr1:100000-200000"}, "repositories": [{"code": "song.overture", "organization": "Overture", "name": "Overture", "type": "S3", "country": "CA", "url": "http://song:8080"}], "donors": [{"donor_id": "663b8536-90a9-51d3-abda-695771e751d0", "submitter_donor_id": "DO7453", "gender": "Male", "specimens": [{"specimen_id": "6473c26f-b273-5172-9bb0-7e95ea9f5020", "specimen_type": "Metastatic tumour", "submitter_specimen_id": "SP745311", "samples": [{"sample_id": "6473c26f-b273-5172-9bb0-7e95ea9f5020", "submitter_sample_id": "SP745311", "sample_type": "Total DNA", "matched_normal_submitter_sample_id": "SP745301"}], "tumour_normal_designation": "Tumour", "specimen_tissue_source": "Blood derived - peripheral blood"}]}], "dataCategory": "Sequencing Reads", "jbrowseCoordinates": "hg38:chr1:100000-200000"} \ No newline at end of file diff --git a/configurationFiles/elasticsearchConfigs/quickstart_index_template.json b/configurationFiles/elasticsearchConfigs/quickstart_index_template.json deleted file mode 100644 index 0ba386e5..00000000 --- a/configurationFiles/elasticsearchConfigs/quickstart_index_template.json +++ /dev/null @@ -1,238 +0,0 @@ -{ - "index_patterns": ["overture-*"], - "aliases": { - "file_centric": {} - }, - "mappings": { - "properties": { - "object_id": { "type": "keyword", "copy_to": ["file_autocomplete"] }, - "study_id": { "type": "keyword" }, - "data_type": { "type": "keyword" }, - "file_type": { "type": "keyword" }, - "file_access": { "type": "keyword" }, - "file_autocomplete": { - "type": "keyword", - "fields": { - "analyzed": { - "type": "text", - "analyzer": "autocomplete_analyzed", - "search_analyzer": "lowercase_keyword" - }, - "lowercase": { - "type": "text", - "analyzer": "lowercase_keyword" - }, - "prefix": { - "type": "text", - "analyzer": "autocomplete_prefix", - "search_analyzer": "lowercase_keyword" - } - } - }, - "analysis": { - "properties": { - "analysis_id": { "type": "keyword" }, - "analysis_type": { "type": "keyword" }, - "analysis_version": { "type": "integer" }, - "analysis_state": { "type": "keyword" }, - "updated_at": { "type": "date" }, - "first_published_at": { "type": "date" }, - "published_at": { "type": "date" }, - "experiment": { - "properties": { - "experimentalStrategy": { "type": "keyword" }, - "model": { "type": "keyword" }, - "platform": { "type": "keyword" }, - "sequencingCenter": { "type": "keyword" }, - "sequencingDate": { "type": "date" } - } - }, - "analysisStateHistory": { - "type": "nested", - "properties": { - "initialState": { "type": "keyword" }, - "updatedState": { "type": "keyword" }, - "updatedAt": { "type": "date" } - } - }, - "collaborator": { - "type": "nested", - "properties": { - "contactEmail": { "type": "keyword" }, - "name": { "type": "keyword" } - } - }, - "createdAt": { "type": "date" }, - "donor": { - "properties": { - "causeOfDeath": { "type": "keyword" }, - "primaryDiagnosis": { - "type": "nested", - "properties": { - "ageAtDiagnosis": { "type": "integer" }, - "cancerTypeCode": { "type": "keyword" }, - "clinicalStageGroup": { "type": "keyword" }, - "clinicalTumourStagingSystem": { "type": "keyword" }, - "followUp": { - "type": "nested", - "properties": { - "diseaseStatusAtFollowUp": { "type": "keyword" }, - "intervalOfFollowUp": { "type": "integer" }, - "relapseType": { "type": "keyword" }, - "submitterFollowUpId": { "type": "keyword" }, - "submitterTreatmentId": { "type": "keyword" } - } - }, - "submitterPrimaryDiagnosisId": { "type": "keyword" }, - "treatment": { - "type": "nested", - "properties": { - "chemotherapy": { - "type": "nested", - "properties": { - "drugName": { "type": "keyword" } - } - }, - "responseToTreatment": { "type": "keyword" }, - "submitterTreatmentId": { "type": "keyword" }, - "treatmentDuration": { "type": "integer" }, - "treatmentStartInterval": { "type": "integer" }, - "treatmentType": { "type": "keyword" } - } - } - } - }, - "primarySite": { "type": "keyword" }, - "submitterDonorId": { "type": "keyword" }, - "survivalTime": { "type": "integer" }, - "vitalStatus": { "type": "keyword" } - } - }, - "publication": { - "properties": { - "doi": { "type": "keyword" }, - "publication": { "type": "keyword" } - } - }, - "specimen": { - "properties": { - "specimenAnatomicLocation": { "type": "keyword" }, - "submitterPrimaryDiagnosisId": { "type": "keyword" }, - "submitterSpecimenId": { "type": "keyword" }, - "tumourGrade": { "type": "keyword" }, - "tumourGradingSystem": { "type": "keyword" } - } - }, - "workflow": { - "properties": { - "genomeBuild": { "type": "keyword" }, - "inputs": { - "type": "nested", - "properties": { - "analysisType": { "type": "keyword" }, - "normalAnalysisId": { "type": "keyword" }, - "tumourAnalysisId": { "type": "keyword" } - } - }, - "runId": { "type": "keyword" }, - "sessionId": { "type": "keyword" }, - "workflowName": { "type": "keyword" }, - "workflowShortName": { "type": "keyword" }, - "workflowVersion": { "type": "keyword" } - } - } - } - }, - "file": { - "properties": { - "name": { "type": "keyword" }, - "md5sum": { "type": "keyword" }, - "size": { "type": "integer" }, - "data_type": { "type": "keyword" }, - "index_file": { - "properties": { - "object_id": { "type": "keyword" }, - "name": { "type": "keyword" }, - "file_type": { "type": "keyword" }, - "md5sum": { "type": "keyword" }, - "data_type": { "type": "keyword" }, - "size": { "type": "integer" }, - "dataCategory": { "type": "keyword" }, - "jbrowseCoordinates": { "type": "keyword" } - } - }, - "dataCategory": { "type": "keyword" }, - "jbrowseCoordinates": { "type": "keyword" } - } - }, - "repositories": { - "type": "nested", - "properties": { - "code": { "type": "keyword" }, - "organization": { "type": "keyword" }, - "name": { "type": "keyword" }, - "type": { "type": "keyword" }, - "country": { "type": "keyword" }, - "url": { "type": "keyword" } - } - }, - "donors": { - "type": "nested", - "properties": { - "donor_id": { "type": "keyword" }, - "submitter_donor_id": { "type": "keyword" }, - "gender": { "type": "keyword" }, - "specimens": { - "type": "nested", - "properties": { - "specimen_id": { "type": "keyword" }, - "specimen_type": { "type": "keyword" }, - "submitter_specimen_id": { "type": "keyword" }, - "samples": { - "type": "nested", - "properties": { - "sample_id": { "type": "keyword" }, - "submitter_sample_id": { "type": "keyword" }, - "sample_type": { "type": "keyword" }, - "matched_normal_submitter_sample_id": { "type": "keyword" } - } - }, - "tumour_normal_designation": { "type": "keyword" }, - "specimen_tissue_source": { "type": "keyword" } - } - } - } - }, - "dataCategory": { "type": "keyword" }, - "jbrowseCoordinates": { "type": "keyword" } - } - }, - "settings": { - "analysis": { - "analyzer": { - "autocomplete_analyzed": { - "filter": ["lowercase", "edge_ngram"], - "tokenizer": "standard" - }, - "autocomplete_prefix": { - "filter": ["lowercase", "edge_ngram"], - "tokenizer": "keyword" - }, - "lowercase_keyword": { - "filter": ["lowercase"], - "tokenizer": "keyword" - } - }, - "filter": { - "edge_ngram": { - "max_gram": "20", - "min_gram": "1", - "side": "front", - "type": "edge_ngram" - } - } - }, - "index.max_result_window": 300000, - "index.number_of_shards": 3 - } -} diff --git a/configurationFiles/keycloakConfigs/keycloak-apikeys-1.0.1.jar b/configurationFiles/keycloakConfigs/keycloak-apikeys-1.0.1.jar deleted file mode 100644 index a157e694..00000000 Binary files a/configurationFiles/keycloakConfigs/keycloak-apikeys-1.0.1.jar and /dev/null differ diff --git a/configurationFiles/keycloakConfigs/myrealm-realm.json b/configurationFiles/keycloakConfigs/myrealm-realm.json deleted file mode 100644 index 4f1fd592..00000000 --- a/configurationFiles/keycloakConfigs/myrealm-realm.json +++ /dev/null @@ -1,1982 +0,0 @@ -{ - "id" : "b4227e2f-0b93-4820-871a-eada93058032", - "realm" : "myrealm", - "notBefore" : 0, - "defaultSignatureAlgorithm" : "RS256", - "revokeRefreshToken" : false, - "refreshTokenMaxReuse" : 0, - "accessTokenLifespan" : 3600, - "accessTokenLifespanForImplicitFlow" : 900, - "ssoSessionIdleTimeout" : 3600, - "ssoSessionMaxLifespan" : 36000, - "ssoSessionIdleTimeoutRememberMe" : 0, - "ssoSessionMaxLifespanRememberMe" : 0, - "offlineSessionIdleTimeout" : 2592000, - "offlineSessionMaxLifespanEnabled" : false, - "offlineSessionMaxLifespan" : 5184000, - "clientSessionIdleTimeout" : 0, - "clientSessionMaxLifespan" : 0, - "clientOfflineSessionIdleTimeout" : 0, - "clientOfflineSessionMaxLifespan" : 0, - "accessCodeLifespan" : 60, - "accessCodeLifespanUserAction" : 300, - "accessCodeLifespanLogin" : 1800, - "actionTokenGeneratedByAdminLifespan" : 43200, - "actionTokenGeneratedByUserLifespan" : 300, - "oauth2DeviceCodeLifespan" : 600, - "oauth2DevicePollingInterval" : 5, - "enabled" : true, - "sslRequired" : "external", - "registrationAllowed" : true, - "registrationEmailAsUsername" : false, - "rememberMe" : false, - "verifyEmail" : false, - "loginWithEmailAllowed" : true, - "duplicateEmailsAllowed" : false, - "resetPasswordAllowed" : false, - "editUsernameAllowed" : false, - "bruteForceProtected" : false, - "permanentLockout" : false, - "maxFailureWaitSeconds" : 900, - "minimumQuickLoginWaitSeconds" : 60, - "waitIncrementSeconds" : 60, - "quickLoginCheckMilliSeconds" : 1000, - "maxDeltaTimeSeconds" : 43200, - "failureFactor" : 30, - "roles" : { - "realm" : [ { - "id" : "55150a6d-487f-438d-bb78-8273342afbfc", - "name" : "offline_access", - "description" : "${role_offline-access}", - "composite" : false, - "clientRole" : false, - "containerId" : "b4227e2f-0b93-4820-871a-eada93058032", - "attributes" : { } - }, { - "id" : "38f9ce75-1682-425f-a492-52dba15ad4e3", - "name" : "ADMIN", - "description" : "", - "composite" : false, - "clientRole" : false, - "containerId" : "b4227e2f-0b93-4820-871a-eada93058032", - "attributes" : { } - }, { - "id" : "b0332d2c-fc13-4dd4-a741-dad72ad60ee0", - "name" : "uma_authorization", - "description" : "${role_uma_authorization}", - "composite" : false, - "clientRole" : false, - "containerId" : "b4227e2f-0b93-4820-871a-eada93058032", - "attributes" : { } - }, { - "id" : "87ab9b69-bc6f-42b0-8c86-fd19fd0ece42", - "name" : "default-roles-myrealm", - "description" : "${role_default-roles}", - "composite" : true, - "composites" : { - "realm" : [ "offline_access", "uma_authorization" ], - "client" : { - "account" : [ "manage-account", "view-profile" ] - } - }, - "clientRole" : false, - "containerId" : "b4227e2f-0b93-4820-871a-eada93058032", - "attributes" : { } - } ], - "client" : { - "realm-management" : [ { - "id" : "fc5157b3-a7b1-4fa5-b98a-194c2f01c1ff", - "name" : "query-clients", - "description" : "${role_query-clients}", - "composite" : false, - "clientRole" : true, - "containerId" : "05acca3b-a42f-44ca-9015-5af54b6335a0", - "attributes" : { } - }, { - "id" : "1e1cf9d0-490e-45f9-82f6-17db0b008e2c", - "name" : "view-events", - "description" : "${role_view-events}", - "composite" : false, - "clientRole" : true, - "containerId" : "05acca3b-a42f-44ca-9015-5af54b6335a0", - "attributes" : { } - }, { - "id" : "0c472f7b-9c75-46b5-86d5-032df1fcfa50", - "name" : "manage-realm", - "description" : "${role_manage-realm}", - "composite" : false, - "clientRole" : true, - "containerId" : "05acca3b-a42f-44ca-9015-5af54b6335a0", - "attributes" : { } - }, { - "id" : "36e84f62-20aa-496f-965d-84fb46a54d3d", - "name" : "view-users", - "description" : "${role_view-users}", - "composite" : true, - "composites" : { - "client" : { - "realm-management" : [ "query-users", "query-groups" ] - } - }, - "clientRole" : true, - "containerId" : "05acca3b-a42f-44ca-9015-5af54b6335a0", - "attributes" : { } - }, { - "id" : "7f06dabb-723e-48f0-b56f-6099576c2625", - "name" : "manage-events", - "description" : "${role_manage-events}", - "composite" : false, - "clientRole" : true, - "containerId" : "05acca3b-a42f-44ca-9015-5af54b6335a0", - "attributes" : { } - }, { - "id" : "81b3eed6-7a81-4269-af82-42650de43928", - "name" : "view-clients", - "description" : "${role_view-clients}", - "composite" : true, - "composites" : { - "client" : { - "realm-management" : [ "query-clients" ] - } - }, - "clientRole" : true, - "containerId" : "05acca3b-a42f-44ca-9015-5af54b6335a0", - "attributes" : { } - }, { - "id" : "697115e9-954b-4e5a-885c-25bc1c0009a3", - "name" : "manage-authorization", - "description" : "${role_manage-authorization}", - "composite" : false, - "clientRole" : true, - "containerId" : "05acca3b-a42f-44ca-9015-5af54b6335a0", - "attributes" : { } - }, { - "id" : "afe57081-7497-45f4-9a5a-562091d5e9f8", - "name" : "manage-identity-providers", - "description" : "${role_manage-identity-providers}", - "composite" : false, - "clientRole" : true, - "containerId" : "05acca3b-a42f-44ca-9015-5af54b6335a0", - "attributes" : { } - }, { - "id" : "83eae3c9-fd9c-47a9-813c-32201d7f0b99", - "name" : "query-realms", - "description" : "${role_query-realms}", - "composite" : false, - "clientRole" : true, - "containerId" : "05acca3b-a42f-44ca-9015-5af54b6335a0", - "attributes" : { } - }, { - "id" : "e6af4c93-3780-469e-a2da-86a89fccac11", - "name" : "view-identity-providers", - "description" : "${role_view-identity-providers}", - "composite" : false, - "clientRole" : true, - "containerId" : "05acca3b-a42f-44ca-9015-5af54b6335a0", - "attributes" : { } - }, { - "id" : "5fc10a91-5107-4363-bc14-d3acfad8525e", - "name" : "manage-clients", - "description" : "${role_manage-clients}", - "composite" : false, - "clientRole" : true, - "containerId" : "05acca3b-a42f-44ca-9015-5af54b6335a0", - "attributes" : { } - }, { - "id" : "8bb53c21-f800-46e8-bedb-6e57ce88f4e6", - "name" : "view-realm", - "description" : "${role_view-realm}", - "composite" : false, - "clientRole" : true, - "containerId" : "05acca3b-a42f-44ca-9015-5af54b6335a0", - "attributes" : { } - }, { - "id" : "e2b693fe-0022-46b7-b975-2727ace408fb", - "name" : "query-users", - "description" : "${role_query-users}", - "composite" : false, - "clientRole" : true, - "containerId" : "05acca3b-a42f-44ca-9015-5af54b6335a0", - "attributes" : { } - }, { - "id" : "249a235d-0be7-4f75-8710-d8274a394619", - "name" : "manage-users", - "description" : "${role_manage-users}", - "composite" : false, - "clientRole" : true, - "containerId" : "05acca3b-a42f-44ca-9015-5af54b6335a0", - "attributes" : { } - }, { - "id" : "097ab593-1532-469e-9ef1-4652a92d0468", - "name" : "query-groups", - "description" : "${role_query-groups}", - "composite" : false, - "clientRole" : true, - "containerId" : "05acca3b-a42f-44ca-9015-5af54b6335a0", - "attributes" : { } - }, { - "id" : "730cfec2-33ba-4199-90f1-2ecd3761ed82", - "name" : "create-client", - "description" : "${role_create-client}", - "composite" : false, - "clientRole" : true, - "containerId" : "05acca3b-a42f-44ca-9015-5af54b6335a0", - "attributes" : { } - }, { - "id" : "5e0e469c-96ca-4216-995b-d5eb9c6b889b", - "name" : "impersonation", - "description" : "${role_impersonation}", - "composite" : false, - "clientRole" : true, - "containerId" : "05acca3b-a42f-44ca-9015-5af54b6335a0", - "attributes" : { } - }, { - "id" : "dc5ad077-f1f3-46e2-b55c-7fd4afcbc868", - "name" : "realm-admin", - "description" : "${role_realm-admin}", - "composite" : true, - "composites" : { - "client" : { - "realm-management" : [ "query-clients", "view-events", "manage-realm", "view-users", "manage-events", "view-clients", "manage-authorization", "manage-identity-providers", "query-realms", "view-identity-providers", "manage-clients", "view-realm", "query-users", "manage-users", "query-groups", "create-client", "impersonation", "view-authorization" ] - } - }, - "clientRole" : true, - "containerId" : "05acca3b-a42f-44ca-9015-5af54b6335a0", - "attributes" : { } - }, { - "id" : "5325f1d2-e053-4b20-959c-08ee3c2dc29b", - "name" : "view-authorization", - "description" : "${role_view-authorization}", - "composite" : false, - "clientRole" : true, - "containerId" : "05acca3b-a42f-44ca-9015-5af54b6335a0", - "attributes" : { } - } ], - "webclient" : [ ], - "security-admin-console" : [ ], - "admin-cli" : [ ], - "account-console" : [ ], - "dms" : [ { - "id" : "64adfaf4-a828-4e86-b5df-3522bc3f73fb", - "name" : "uma_protection", - "composite" : false, - "clientRole" : true, - "containerId" : "478c9b3d-1d25-4c92-bd74-71d13496d046", - "attributes" : { } - } ], - "broker" : [ { - "id" : "4cc9442c-3848-43f5-b009-11af4f6a4bf9", - "name" : "read-token", - "description" : "${role_read-token}", - "composite" : false, - "clientRole" : true, - "containerId" : "16e760bb-2c0d-453b-b823-460913a22744", - "attributes" : { } - } ], - "account" : [ { - "id" : "8ebaccec-3448-4f0b-863e-06e450d800df", - "name" : "manage-account", - "description" : "${role_manage-account}", - "composite" : true, - "composites" : { - "client" : { - "account" : [ "manage-account-links" ] - } - }, - "clientRole" : true, - "containerId" : "601df4b2-0f47-4266-aed2-6702f0da7c59", - "attributes" : { } - }, { - "id" : "8cbeae7a-5939-499e-9ae6-addfc3052572", - "name" : "manage-account-links", - "description" : "${role_manage-account-links}", - "composite" : false, - "clientRole" : true, - "containerId" : "601df4b2-0f47-4266-aed2-6702f0da7c59", - "attributes" : { } - }, { - "id" : "bc0a2426-54b1-4aac-8ee0-5491ca5536da", - "name" : "delete-account", - "description" : "${role_delete-account}", - "composite" : false, - "clientRole" : true, - "containerId" : "601df4b2-0f47-4266-aed2-6702f0da7c59", - "attributes" : { } - }, { - "id" : "38125e01-359f-4010-aa2f-c4a47689465e", - "name" : "view-applications", - "description" : "${role_view-applications}", - "composite" : false, - "clientRole" : true, - "containerId" : "601df4b2-0f47-4266-aed2-6702f0da7c59", - "attributes" : { } - }, { - "id" : "64d12ccd-ec4b-486a-ada5-8b33fcf77730", - "name" : "view-consent", - "description" : "${role_view-consent}", - "composite" : false, - "clientRole" : true, - "containerId" : "601df4b2-0f47-4266-aed2-6702f0da7c59", - "attributes" : { } - }, { - "id" : "5af8bd59-9e5d-4d37-9975-1c69adb08623", - "name" : "manage-consent", - "description" : "${role_manage-consent}", - "composite" : true, - "composites" : { - "client" : { - "account" : [ "view-consent" ] - } - }, - "clientRole" : true, - "containerId" : "601df4b2-0f47-4266-aed2-6702f0da7c59", - "attributes" : { } - }, { - "id" : "9fd80d81-09c9-4c78-8df3-988129e28989", - "name" : "view-groups", - "description" : "${role_view-groups}", - "composite" : false, - "clientRole" : true, - "containerId" : "601df4b2-0f47-4266-aed2-6702f0da7c59", - "attributes" : { } - }, { - "id" : "a63682fb-9894-4d4b-899c-fade0779e3db", - "name" : "view-profile", - "description" : "${role_view-profile}", - "composite" : false, - "clientRole" : true, - "containerId" : "601df4b2-0f47-4266-aed2-6702f0da7c59", - "attributes" : { } - } ] - } - }, - "groups" : [ { - "id" : "c5de35e5-a449-4803-8034-600acde61ddb", - "name" : "ADMIN", - "path" : "/ADMIN", - "attributes" : { }, - "realmRoles" : [ ], - "clientRoles" : { }, - "subGroups" : [ ] - } ], - "defaultRole" : { - "id" : "87ab9b69-bc6f-42b0-8c86-fd19fd0ece42", - "name" : "default-roles-myrealm", - "description" : "${role_default-roles}", - "composite" : true, - "clientRole" : false, - "containerId" : "b4227e2f-0b93-4820-871a-eada93058032" - }, - "requiredCredentials" : [ "password" ], - "otpPolicyType" : "totp", - "otpPolicyAlgorithm" : "HmacSHA1", - "otpPolicyInitialCounter" : 0, - "otpPolicyDigits" : 6, - "otpPolicyLookAheadWindow" : 1, - "otpPolicyPeriod" : 30, - "otpPolicyCodeReusable" : false, - "otpSupportedApplications" : [ "totpAppMicrosoftAuthenticatorName", "totpAppGoogleName", "totpAppFreeOTPName" ], - "webAuthnPolicyRpEntityName" : "keycloak", - "webAuthnPolicySignatureAlgorithms" : [ "ES256" ], - "webAuthnPolicyRpId" : "", - "webAuthnPolicyAttestationConveyancePreference" : "not specified", - "webAuthnPolicyAuthenticatorAttachment" : "not specified", - "webAuthnPolicyRequireResidentKey" : "not specified", - "webAuthnPolicyUserVerificationRequirement" : "not specified", - "webAuthnPolicyCreateTimeout" : 0, - "webAuthnPolicyAvoidSameAuthenticatorRegister" : false, - "webAuthnPolicyAcceptableAaguids" : [ ], - "webAuthnPolicyPasswordlessRpEntityName" : "keycloak", - "webAuthnPolicyPasswordlessSignatureAlgorithms" : [ "ES256" ], - "webAuthnPolicyPasswordlessRpId" : "", - "webAuthnPolicyPasswordlessAttestationConveyancePreference" : "not specified", - "webAuthnPolicyPasswordlessAuthenticatorAttachment" : "not specified", - "webAuthnPolicyPasswordlessRequireResidentKey" : "not specified", - "webAuthnPolicyPasswordlessUserVerificationRequirement" : "not specified", - "webAuthnPolicyPasswordlessCreateTimeout" : 0, - "webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister" : false, - "webAuthnPolicyPasswordlessAcceptableAaguids" : [ ], - "scopeMappings" : [ { - "clientScope" : "offline_access", - "roles" : [ "offline_access" ] - } ], - "clientScopeMappings" : { - "account" : [ { - "client" : "account-console", - "roles" : [ "manage-account", "view-groups" ] - } ] - }, - "clients" : [ { - "id" : "601df4b2-0f47-4266-aed2-6702f0da7c59", - "clientId" : "account", - "name" : "${client_account}", - "rootUrl" : "${authBaseUrl}", - "baseUrl" : "/realms/myrealm/account/", - "surrogateAuthRequired" : false, - "enabled" : true, - "alwaysDisplayInConsole" : false, - "clientAuthenticatorType" : "client-secret", - "redirectUris" : [ "/realms/myrealm/account/*" ], - "webOrigins" : [ ], - "notBefore" : 0, - "bearerOnly" : false, - "consentRequired" : false, - "standardFlowEnabled" : true, - "implicitFlowEnabled" : false, - "directAccessGrantsEnabled" : false, - "serviceAccountsEnabled" : false, - "publicClient" : true, - "frontchannelLogout" : false, - "protocol" : "openid-connect", - "attributes" : { - "post.logout.redirect.uris" : "+" - }, - "authenticationFlowBindingOverrides" : { }, - "fullScopeAllowed" : false, - "nodeReRegistrationTimeout" : 0, - "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "email" ], - "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] - }, { - "id" : "46d9d0f5-0165-4f28-a3f9-4a0f00d5ea18", - "clientId" : "account-console", - "name" : "${client_account-console}", - "rootUrl" : "${authBaseUrl}", - "baseUrl" : "/realms/myrealm/account/", - "surrogateAuthRequired" : false, - "enabled" : true, - "alwaysDisplayInConsole" : false, - "clientAuthenticatorType" : "client-secret", - "redirectUris" : [ "/realms/myrealm/account/*" ], - "webOrigins" : [ ], - "notBefore" : 0, - "bearerOnly" : false, - "consentRequired" : false, - "standardFlowEnabled" : true, - "implicitFlowEnabled" : false, - "directAccessGrantsEnabled" : false, - "serviceAccountsEnabled" : false, - "publicClient" : true, - "frontchannelLogout" : false, - "protocol" : "openid-connect", - "attributes" : { - "post.logout.redirect.uris" : "+", - "pkce.code.challenge.method" : "S256" - }, - "authenticationFlowBindingOverrides" : { }, - "fullScopeAllowed" : false, - "nodeReRegistrationTimeout" : 0, - "protocolMappers" : [ { - "id" : "3a6f2608-6c13-4fbd-a2fa-57f8dcd1f68b", - "name" : "audience resolve", - "protocol" : "openid-connect", - "protocolMapper" : "oidc-audience-resolve-mapper", - "consentRequired" : false, - "config" : { } - } ], - "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "email" ], - "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] - }, { - "id" : "23ba58c4-e8ee-47d1-afdf-7e2aabffe9e5", - "clientId" : "admin-cli", - "name" : "${client_admin-cli}", - "surrogateAuthRequired" : false, - "enabled" : true, - "alwaysDisplayInConsole" : false, - "clientAuthenticatorType" : "client-secret", - "redirectUris" : [ ], - "webOrigins" : [ ], - "notBefore" : 0, - "bearerOnly" : false, - "consentRequired" : false, - "standardFlowEnabled" : false, - "implicitFlowEnabled" : false, - "directAccessGrantsEnabled" : true, - "serviceAccountsEnabled" : false, - "publicClient" : true, - "frontchannelLogout" : false, - "protocol" : "openid-connect", - "attributes" : { - "post.logout.redirect.uris" : "+" - }, - "authenticationFlowBindingOverrides" : { }, - "fullScopeAllowed" : false, - "nodeReRegistrationTimeout" : 0, - "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "email" ], - "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] - }, { - "id" : "16e760bb-2c0d-453b-b823-460913a22744", - "clientId" : "broker", - "name" : "${client_broker}", - "surrogateAuthRequired" : false, - "enabled" : true, - "alwaysDisplayInConsole" : false, - "clientAuthenticatorType" : "client-secret", - "redirectUris" : [ ], - "webOrigins" : [ ], - "notBefore" : 0, - "bearerOnly" : true, - "consentRequired" : false, - "standardFlowEnabled" : true, - "implicitFlowEnabled" : false, - "directAccessGrantsEnabled" : false, - "serviceAccountsEnabled" : false, - "publicClient" : false, - "frontchannelLogout" : false, - "protocol" : "openid-connect", - "attributes" : { - "post.logout.redirect.uris" : "+" - }, - "authenticationFlowBindingOverrides" : { }, - "fullScopeAllowed" : false, - "nodeReRegistrationTimeout" : 0, - "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "email" ], - "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] - }, { - "id" : "478c9b3d-1d25-4c92-bd74-71d13496d046", - "clientId" : "dms", - "name" : "Data Management Services ", - "description" : "Song, Score and Study IDs", - "rootUrl" : "", - "adminUrl" : "", - "baseUrl" : "", - "surrogateAuthRequired" : false, - "enabled" : true, - "alwaysDisplayInConsole" : false, - "clientAuthenticatorType" : "client-secret", - "secret" : "t016kqXfI648ORoIP5gepqCzqtsRjlcc", - "redirectUris" : [ "/*" ], - "webOrigins" : [ "/*" ], - "notBefore" : 0, - "bearerOnly" : false, - "consentRequired" : false, - "standardFlowEnabled" : true, - "implicitFlowEnabled" : false, - "directAccessGrantsEnabled" : true, - "serviceAccountsEnabled" : true, - "authorizationServicesEnabled" : true, - "publicClient" : false, - "frontchannelLogout" : true, - "protocol" : "openid-connect", - "attributes" : { - "oidc.ciba.grant.enabled" : "false", - "client.secret.creation.time" : "1718674923", - "backchannel.logout.session.required" : "true", - "post.logout.redirect.uris" : "+", - "oauth2.device.authorization.grant.enabled" : "false", - "backchannel.logout.revoke.offline.tokens" : "false" - }, - "authenticationFlowBindingOverrides" : { }, - "fullScopeAllowed" : true, - "nodeReRegistrationTimeout" : -1, - "protocolMappers" : [ { - "id" : "876c524c-34fc-40e1-977f-de56a8c702d2", - "name" : "Client Host", - "protocol" : "openid-connect", - "protocolMapper" : "oidc-usersessionmodel-note-mapper", - "consentRequired" : false, - "config" : { - "user.session.note" : "clientHost", - "userinfo.token.claim" : "true", - "id.token.claim" : "true", - "access.token.claim" : "true", - "claim.name" : "clientHost", - "jsonType.label" : "String" - } - }, { - "id" : "a5b87a49-e008-4167-bf30-cb47d999d118", - "name" : "Client IP Address", - "protocol" : "openid-connect", - "protocolMapper" : "oidc-usersessionmodel-note-mapper", - "consentRequired" : false, - "config" : { - "user.session.note" : "clientAddress", - "userinfo.token.claim" : "true", - "id.token.claim" : "true", - "access.token.claim" : "true", - "claim.name" : "clientAddress", - "jsonType.label" : "String" - } - }, { - "id" : "197ef9af-d7bd-4dc8-8193-ed4553eb8d87", - "name" : "Client ID", - "protocol" : "openid-connect", - "protocolMapper" : "oidc-usersessionmodel-note-mapper", - "consentRequired" : false, - "config" : { - "user.session.note" : "client_id", - "userinfo.token.claim" : "true", - "id.token.claim" : "true", - "access.token.claim" : "true", - "claim.name" : "client_id", - "jsonType.label" : "String" - } - } ], - "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "email" ], - "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ], - "authorizationSettings" : { - "allowRemoteResourceManagement" : true, - "policyEnforcementMode" : "PERMISSIVE", - "resources" : [ { - "name" : "song", - "ownerManagedAccess" : false, - "displayName" : "song", - "attributes" : { }, - "_id" : "1eaa231e-2bce-4d37-ad5c-8959eca3f663", - "uris" : [ ], - "scopes" : [ { - "name" : "READ" - }, { - "name" : "WRITE" - } ], - "icon_uri" : "" - }, { - "name" : "score", - "ownerManagedAccess" : false, - "displayName" : "score", - "attributes" : { }, - "_id" : "354ebfec-2fe9-4666-a3b3-d4ab29b39ff5", - "uris" : [ ], - "scopes" : [ { - "name" : "READ" - }, { - "name" : "WRITE" - } ], - "icon_uri" : "" - }, { - "name" : "demo", - "ownerManagedAccess" : false, - "displayName" : "demo", - "attributes" : { }, - "_id" : "a1910cc5-92ae-4550-82bd-a2a8c6df6423", - "uris" : [ ], - "scopes" : [ { - "name" : "READ" - }, { - "name" : "WRITE" - } ], - "icon_uri" : "" - } ], - "policies" : [ { - "id" : "b0cdae24-94f5-4373-b950-f20bb4b196ce", - "name" : "POLICY_ADMINGROUP", - "description" : "", - "type" : "group", - "logic" : "POSITIVE", - "decisionStrategy" : "UNANIMOUS", - "config" : { - "groups" : "[{\"path\":\"/ADMIN\",\"extendChildren\":false}]", - "groupsClaim" : "" - } - }, { - "id" : "b138c5f2-1f8e-4aa6-91da-5ec673eb92f9", - "name" : "PERMISSION_ADMINGROUP", - "description" : "", - "type" : "resource", - "logic" : "POSITIVE", - "decisionStrategy" : "AFFIRMATIVE", - "config" : { - "resources" : "[\"demo\",\"score\",\"song\"]", - "applyPolicies" : "[\"POLICY_ADMINGROUP\"]" - } - } ], - "scopes" : [ { - "id" : "82534205-6760-4a35-b9ed-08a4924693b6", - "name" : "READ", - "iconUri" : "" - }, { - "id" : "a1ad2a2d-abb7-4a49-b96f-b16b0e4b835a", - "name" : "WRITE", - "iconUri" : "" - } ], - "decisionStrategy" : "UNANIMOUS" - } - }, { - "id" : "05acca3b-a42f-44ca-9015-5af54b6335a0", - "clientId" : "realm-management", - "name" : "${client_realm-management}", - "surrogateAuthRequired" : false, - "enabled" : true, - "alwaysDisplayInConsole" : false, - "clientAuthenticatorType" : "client-secret", - "redirectUris" : [ ], - "webOrigins" : [ ], - "notBefore" : 0, - "bearerOnly" : true, - "consentRequired" : false, - "standardFlowEnabled" : true, - "implicitFlowEnabled" : false, - "directAccessGrantsEnabled" : false, - "serviceAccountsEnabled" : false, - "publicClient" : false, - "frontchannelLogout" : false, - "protocol" : "openid-connect", - "attributes" : { - "post.logout.redirect.uris" : "+" - }, - "authenticationFlowBindingOverrides" : { }, - "fullScopeAllowed" : false, - "nodeReRegistrationTimeout" : 0, - "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "email" ], - "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] - }, { - "id" : "3fcc7088-469e-48de-88cb-1f8800249e60", - "clientId" : "security-admin-console", - "name" : "${client_security-admin-console}", - "rootUrl" : "${authAdminUrl}", - "baseUrl" : "/admin/myrealm/console/", - "surrogateAuthRequired" : false, - "enabled" : true, - "alwaysDisplayInConsole" : false, - "clientAuthenticatorType" : "client-secret", - "redirectUris" : [ "/admin/myrealm/console/*" ], - "webOrigins" : [ "+" ], - "notBefore" : 0, - "bearerOnly" : false, - "consentRequired" : false, - "standardFlowEnabled" : true, - "implicitFlowEnabled" : false, - "directAccessGrantsEnabled" : false, - "serviceAccountsEnabled" : false, - "publicClient" : true, - "frontchannelLogout" : false, - "protocol" : "openid-connect", - "attributes" : { - "post.logout.redirect.uris" : "+", - "pkce.code.challenge.method" : "S256" - }, - "authenticationFlowBindingOverrides" : { }, - "fullScopeAllowed" : false, - "nodeReRegistrationTimeout" : 0, - "protocolMappers" : [ { - "id" : "71b820af-0ed7-482b-a8cd-04863b10d429", - "name" : "locale", - "protocol" : "openid-connect", - "protocolMapper" : "oidc-usermodel-attribute-mapper", - "consentRequired" : false, - "config" : { - "userinfo.token.claim" : "true", - "user.attribute" : "locale", - "id.token.claim" : "true", - "access.token.claim" : "true", - "claim.name" : "locale", - "jsonType.label" : "String" - } - } ], - "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "email" ], - "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] - }, { - "id" : "e8f6f77c-74a2-4b57-803b-5c0c9715c170", - "clientId" : "webclient", - "name" : "webclient", - "description" : "", - "rootUrl" : "", - "adminUrl" : "", - "baseUrl" : "", - "surrogateAuthRequired" : false, - "enabled" : true, - "alwaysDisplayInConsole" : false, - "clientAuthenticatorType" : "client-secret", - "secret" : "ikksyrYaKX07acf4hpGrpKWcUGaFkEdM", - "redirectUris" : [ "http://localhost:3000/api/auth/callback/keycloak", "http://localhost:3000/explorer" ], - "webOrigins" : [ "http://localhost:3000" ], - "notBefore" : 0, - "bearerOnly" : false, - "consentRequired" : false, - "standardFlowEnabled" : true, - "implicitFlowEnabled" : false, - "directAccessGrantsEnabled" : true, - "serviceAccountsEnabled" : false, - "publicClient" : false, - "frontchannelLogout" : true, - "protocol" : "openid-connect", - "attributes" : { - "client.secret.creation.time" : "1696010381", - "post.logout.redirect.uris" : "+", - "oauth2.device.authorization.grant.enabled" : "false", - "backchannel.logout.revoke.offline.tokens" : "false", - "use.refresh.tokens" : "true", - "oidc.ciba.grant.enabled" : "false", - "backchannel.logout.session.required" : "true", - "client_credentials.use_refresh_token" : "false", - "acr.loa.map" : "{}", - "require.pushed.authorization.requests" : "false", - "tls.client.certificate.bound.access.tokens" : "false", - "display.on.consent.screen" : "false", - "token.response.type.bearer.lower-case" : "false" - }, - "authenticationFlowBindingOverrides" : { }, - "fullScopeAllowed" : true, - "nodeReRegistrationTimeout" : -1, - "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "email" ], - "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] - } ], - "clientScopes" : [ { - "id" : "6896aee5-5d91-424d-a238-7adcc8d883b6", - "name" : "microprofile-jwt", - "description" : "Microprofile - JWT built-in scope", - "protocol" : "openid-connect", - "attributes" : { - "include.in.token.scope" : "true", - "display.on.consent.screen" : "false" - }, - "protocolMappers" : [ { - "id" : "f94d56d5-25a0-4315-8861-818decb0fe15", - "name" : "upn", - "protocol" : "openid-connect", - "protocolMapper" : "oidc-usermodel-attribute-mapper", - "consentRequired" : false, - "config" : { - "userinfo.token.claim" : "true", - "user.attribute" : "username", - "id.token.claim" : "true", - "access.token.claim" : "true", - "claim.name" : "upn", - "jsonType.label" : "String" - } - }, { - "id" : "dafeb681-a2da-4403-b391-3c164c37855a", - "name" : "groups", - "protocol" : "openid-connect", - "protocolMapper" : "oidc-usermodel-realm-role-mapper", - "consentRequired" : false, - "config" : { - "multivalued" : "true", - "userinfo.token.claim" : "true", - "user.attribute" : "foo", - "id.token.claim" : "true", - "access.token.claim" : "true", - "claim.name" : "groups", - "jsonType.label" : "String" - } - } ] - }, { - "id" : "db0ca862-d66b-4251-966c-7b7c3117553e", - "name" : "web-origins", - "description" : "OpenID Connect scope for add allowed web origins to the access token", - "protocol" : "openid-connect", - "attributes" : { - "include.in.token.scope" : "false", - "display.on.consent.screen" : "false", - "consent.screen.text" : "" - }, - "protocolMappers" : [ { - "id" : "f7fd9d03-b481-4d2e-aad8-5bc1bee34b6f", - "name" : "allowed web origins", - "protocol" : "openid-connect", - "protocolMapper" : "oidc-allowed-origins-mapper", - "consentRequired" : false, - "config" : { } - } ] - }, { - "id" : "e96af174-19fd-4423-9a25-62c292209c32", - "name" : "email", - "description" : "OpenID Connect built-in scope: email", - "protocol" : "openid-connect", - "attributes" : { - "include.in.token.scope" : "true", - "display.on.consent.screen" : "true", - "consent.screen.text" : "${emailScopeConsentText}" - }, - "protocolMappers" : [ { - "id" : "9716ad78-d384-40dc-b49f-061b85ffb16b", - "name" : "email", - "protocol" : "openid-connect", - "protocolMapper" : "oidc-usermodel-attribute-mapper", - "consentRequired" : false, - "config" : { - "userinfo.token.claim" : "true", - "user.attribute" : "email", - "id.token.claim" : "true", - "access.token.claim" : "true", - "claim.name" : "email", - "jsonType.label" : "String" - } - }, { - "id" : "c9624d47-67c8-4039-9c8a-7c59df9546f2", - "name" : "email verified", - "protocol" : "openid-connect", - "protocolMapper" : "oidc-usermodel-property-mapper", - "consentRequired" : false, - "config" : { - "userinfo.token.claim" : "true", - "user.attribute" : "emailVerified", - "id.token.claim" : "true", - "access.token.claim" : "true", - "claim.name" : "email_verified", - "jsonType.label" : "boolean" - } - } ] - }, { - "id" : "00f4e577-309a-4ded-b984-87f5131fb327", - "name" : "role_list", - "description" : "SAML role list", - "protocol" : "saml", - "attributes" : { - "consent.screen.text" : "${samlRoleListScopeConsentText}", - "display.on.consent.screen" : "true" - }, - "protocolMappers" : [ { - "id" : "744253d2-d5bd-4786-a55c-294689b11b1b", - "name" : "role list", - "protocol" : "saml", - "protocolMapper" : "saml-role-list-mapper", - "consentRequired" : false, - "config" : { - "single" : "false", - "attribute.nameformat" : "Basic", - "attribute.name" : "Role" - } - } ] - }, { - "id" : "2ee80b14-eb26-40a2-8a47-d3e1ec6f711d", - "name" : "profile", - "description" : "OpenID Connect built-in scope: profile", - "protocol" : "openid-connect", - "attributes" : { - "include.in.token.scope" : "true", - "display.on.consent.screen" : "true", - "consent.screen.text" : "${profileScopeConsentText}" - }, - "protocolMappers" : [ { - "id" : "b02e136a-4023-4940-b47d-c68d2cb0990c", - "name" : "gender", - "protocol" : "openid-connect", - "protocolMapper" : "oidc-usermodel-attribute-mapper", - "consentRequired" : false, - "config" : { - "userinfo.token.claim" : "true", - "user.attribute" : "gender", - "id.token.claim" : "true", - "access.token.claim" : "true", - "claim.name" : "gender", - "jsonType.label" : "String" - } - }, { - "id" : "d45005c5-3647-4890-b7b6-39ead108adc2", - "name" : "picture", - "protocol" : "openid-connect", - "protocolMapper" : "oidc-usermodel-attribute-mapper", - "consentRequired" : false, - "config" : { - "userinfo.token.claim" : "true", - "user.attribute" : "picture", - "id.token.claim" : "true", - "access.token.claim" : "true", - "claim.name" : "picture", - "jsonType.label" : "String" - } - }, { - "id" : "ab314612-542d-4f88-8225-2902ec21f1ec", - "name" : "nickname", - "protocol" : "openid-connect", - "protocolMapper" : "oidc-usermodel-attribute-mapper", - "consentRequired" : false, - "config" : { - "userinfo.token.claim" : "true", - "user.attribute" : "nickname", - "id.token.claim" : "true", - "access.token.claim" : "true", - "claim.name" : "nickname", - "jsonType.label" : "String" - } - }, { - "id" : "cb66f54d-457a-410b-b1ac-fbb0028732d3", - "name" : "locale", - "protocol" : "openid-connect", - "protocolMapper" : "oidc-usermodel-attribute-mapper", - "consentRequired" : false, - "config" : { - "userinfo.token.claim" : "true", - "user.attribute" : "locale", - "id.token.claim" : "true", - "access.token.claim" : "true", - "claim.name" : "locale", - "jsonType.label" : "String" - } - }, { - "id" : "7de083e7-b306-448f-bb0d-c68ef1d75de8", - "name" : "username", - "protocol" : "openid-connect", - "protocolMapper" : "oidc-usermodel-attribute-mapper", - "consentRequired" : false, - "config" : { - "userinfo.token.claim" : "true", - "user.attribute" : "username", - "id.token.claim" : "true", - "access.token.claim" : "true", - "claim.name" : "preferred_username", - "jsonType.label" : "String" - } - }, { - "id" : "18278c84-7039-4682-ae89-a4dbb85b0184", - "name" : "website", - "protocol" : "openid-connect", - "protocolMapper" : "oidc-usermodel-attribute-mapper", - "consentRequired" : false, - "config" : { - "userinfo.token.claim" : "true", - "user.attribute" : "website", - "id.token.claim" : "true", - "access.token.claim" : "true", - "claim.name" : "website", - "jsonType.label" : "String" - } - }, { - "id" : "de64ceb7-39e5-4ee1-98cb-8b5e013c8ceb", - "name" : "birthdate", - "protocol" : "openid-connect", - "protocolMapper" : "oidc-usermodel-attribute-mapper", - "consentRequired" : false, - "config" : { - "userinfo.token.claim" : "true", - "user.attribute" : "birthdate", - "id.token.claim" : "true", - "access.token.claim" : "true", - "claim.name" : "birthdate", - "jsonType.label" : "String" - } - }, { - "id" : "54e5ca9d-a39d-4929-abec-4b15a5743aad", - "name" : "full name", - "protocol" : "openid-connect", - "protocolMapper" : "oidc-full-name-mapper", - "consentRequired" : false, - "config" : { - "id.token.claim" : "true", - "access.token.claim" : "true", - "userinfo.token.claim" : "true" - } - }, { - "id" : "f1ac259e-e622-46d2-bba6-720adee1f082", - "name" : "updated at", - "protocol" : "openid-connect", - "protocolMapper" : "oidc-usermodel-attribute-mapper", - "consentRequired" : false, - "config" : { - "userinfo.token.claim" : "true", - "user.attribute" : "updatedAt", - "id.token.claim" : "true", - "access.token.claim" : "true", - "claim.name" : "updated_at", - "jsonType.label" : "long" - } - }, { - "id" : "eecdfc5d-077b-4845-ba70-c404edaa988d", - "name" : "family name", - "protocol" : "openid-connect", - "protocolMapper" : "oidc-usermodel-attribute-mapper", - "consentRequired" : false, - "config" : { - "userinfo.token.claim" : "true", - "user.attribute" : "lastName", - "id.token.claim" : "true", - "access.token.claim" : "true", - "claim.name" : "family_name", - "jsonType.label" : "String" - } - }, { - "id" : "29677acf-644d-4de6-a77d-bd492d14c747", - "name" : "middle name", - "protocol" : "openid-connect", - "protocolMapper" : "oidc-usermodel-attribute-mapper", - "consentRequired" : false, - "config" : { - "userinfo.token.claim" : "true", - "user.attribute" : "middleName", - "id.token.claim" : "true", - "access.token.claim" : "true", - "claim.name" : "middle_name", - "jsonType.label" : "String" - } - }, { - "id" : "25c8eb9b-d577-4d9c-94d8-0e3ae1700017", - "name" : "given name", - "protocol" : "openid-connect", - "protocolMapper" : "oidc-usermodel-attribute-mapper", - "consentRequired" : false, - "config" : { - "userinfo.token.claim" : "true", - "user.attribute" : "firstName", - "id.token.claim" : "true", - "access.token.claim" : "true", - "claim.name" : "given_name", - "jsonType.label" : "String" - } - }, { - "id" : "c576cf32-c382-4476-afa3-c0e4ccf310e3", - "name" : "profile", - "protocol" : "openid-connect", - "protocolMapper" : "oidc-usermodel-attribute-mapper", - "consentRequired" : false, - "config" : { - "userinfo.token.claim" : "true", - "user.attribute" : "profile", - "id.token.claim" : "true", - "access.token.claim" : "true", - "claim.name" : "profile", - "jsonType.label" : "String" - } - }, { - "id" : "36811e4f-1793-4f85-b537-6302f6b285d5", - "name" : "zoneinfo", - "protocol" : "openid-connect", - "protocolMapper" : "oidc-usermodel-attribute-mapper", - "consentRequired" : false, - "config" : { - "userinfo.token.claim" : "true", - "user.attribute" : "zoneinfo", - "id.token.claim" : "true", - "access.token.claim" : "true", - "claim.name" : "zoneinfo", - "jsonType.label" : "String" - } - } ] - }, { - "id" : "3c230c30-bb40-4250-9e9c-ab8de9aea417", - "name" : "offline_access", - "description" : "OpenID Connect built-in scope: offline_access", - "protocol" : "openid-connect", - "attributes" : { - "consent.screen.text" : "${offlineAccessScopeConsentText}", - "display.on.consent.screen" : "true" - } - }, { - "id" : "45d2de44-244a-4167-a5fc-1a50ea601d64", - "name" : "address", - "description" : "OpenID Connect built-in scope: address", - "protocol" : "openid-connect", - "attributes" : { - "include.in.token.scope" : "true", - "display.on.consent.screen" : "true", - "consent.screen.text" : "${addressScopeConsentText}" - }, - "protocolMappers" : [ { - "id" : "fa0646ca-0893-4b40-a1d1-b8bcc1a20769", - "name" : "address", - "protocol" : "openid-connect", - "protocolMapper" : "oidc-address-mapper", - "consentRequired" : false, - "config" : { - "user.attribute.formatted" : "formatted", - "user.attribute.country" : "country", - "user.attribute.postal_code" : "postal_code", - "userinfo.token.claim" : "true", - "user.attribute.street" : "street", - "id.token.claim" : "true", - "user.attribute.region" : "region", - "access.token.claim" : "true", - "user.attribute.locality" : "locality" - } - } ] - }, { - "id" : "d68a8101-3862-4381-814f-41d72ad2d759", - "name" : "phone", - "description" : "OpenID Connect built-in scope: phone", - "protocol" : "openid-connect", - "attributes" : { - "include.in.token.scope" : "true", - "display.on.consent.screen" : "true", - "consent.screen.text" : "${phoneScopeConsentText}" - }, - "protocolMappers" : [ { - "id" : "eccd4934-7602-400e-b2c7-0ab7af462db3", - "name" : "phone number", - "protocol" : "openid-connect", - "protocolMapper" : "oidc-usermodel-attribute-mapper", - "consentRequired" : false, - "config" : { - "userinfo.token.claim" : "true", - "user.attribute" : "phoneNumber", - "id.token.claim" : "true", - "access.token.claim" : "true", - "claim.name" : "phone_number", - "jsonType.label" : "String" - } - }, { - "id" : "5c3a9f01-3608-4261-a08b-1dc7a9bc7b51", - "name" : "phone number verified", - "protocol" : "openid-connect", - "protocolMapper" : "oidc-usermodel-attribute-mapper", - "consentRequired" : false, - "config" : { - "userinfo.token.claim" : "true", - "user.attribute" : "phoneNumberVerified", - "id.token.claim" : "true", - "access.token.claim" : "true", - "claim.name" : "phone_number_verified", - "jsonType.label" : "boolean" - } - } ] - }, { - "id" : "7b19085b-b3b1-4250-8dac-48a5a97f8d5b", - "name" : "acr", - "description" : "OpenID Connect scope for add acr (authentication context class reference) to the token", - "protocol" : "openid-connect", - "attributes" : { - "include.in.token.scope" : "false", - "display.on.consent.screen" : "false" - }, - "protocolMappers" : [ { - "id" : "954552e3-569d-4352-a4e9-ccff51b3cc7e", - "name" : "acr loa level", - "protocol" : "openid-connect", - "protocolMapper" : "oidc-acr-mapper", - "consentRequired" : false, - "config" : { - "id.token.claim" : "true", - "access.token.claim" : "true", - "userinfo.token.claim" : "true" - } - } ] - }, { - "id" : "37cef1a5-2600-4b1d-a69b-3bdd0d103a36", - "name" : "roles", - "description" : "OpenID Connect scope for add user roles to the access token", - "protocol" : "openid-connect", - "attributes" : { - "include.in.token.scope" : "false", - "display.on.consent.screen" : "true", - "consent.screen.text" : "${rolesScopeConsentText}" - }, - "protocolMappers" : [ { - "id" : "01cc6e37-f893-4eb6-b486-49c5abdebabd", - "name" : "audience resolve", - "protocol" : "openid-connect", - "protocolMapper" : "oidc-audience-resolve-mapper", - "consentRequired" : false, - "config" : { } - }, { - "id" : "1ee3b6de-4b2f-4b54-983e-c22a2e5d497b", - "name" : "realm roles", - "protocol" : "openid-connect", - "protocolMapper" : "oidc-usermodel-realm-role-mapper", - "consentRequired" : false, - "config" : { - "user.attribute" : "foo", - "access.token.claim" : "true", - "claim.name" : "realm_access.roles", - "jsonType.label" : "String", - "multivalued" : "true" - } - }, { - "id" : "2971369a-d7eb-4a7f-bbd8-48f693198bd7", - "name" : "client roles", - "protocol" : "openid-connect", - "protocolMapper" : "oidc-usermodel-client-role-mapper", - "consentRequired" : false, - "config" : { - "user.attribute" : "foo", - "access.token.claim" : "true", - "claim.name" : "resource_access.${client_id}.roles", - "jsonType.label" : "String", - "multivalued" : "true" - } - } ] - } ], - "defaultDefaultClientScopes" : [ "role_list", "profile", "email", "roles", "web-origins", "acr" ], - "defaultOptionalClientScopes" : [ "offline_access", "address", "phone", "microprofile-jwt" ], - "browserSecurityHeaders" : { - "contentSecurityPolicyReportOnly" : "", - "xContentTypeOptions" : "nosniff", - "referrerPolicy" : "no-referrer", - "xRobotsTag" : "none", - "xFrameOptions" : "SAMEORIGIN", - "contentSecurityPolicy" : "frame-src 'self'; frame-ancestors 'self'; object-src 'none';", - "xXSSProtection" : "1; mode=block", - "strictTransportSecurity" : "max-age=31536000; includeSubDomains" - }, - "smtpServer" : { }, - "eventsEnabled" : false, - "eventsListeners" : [ "jboss-logging" ], - "enabledEventTypes" : [ ], - "adminEventsEnabled" : false, - "adminEventsDetailsEnabled" : false, - "identityProviders" : [ ], - "identityProviderMappers" : [ ], - "components" : { - "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy" : [ { - "id" : "64009752-276e-43a0-b286-54b6e86e1e38", - "name" : "Allowed Client Scopes", - "providerId" : "allowed-client-templates", - "subType" : "anonymous", - "subComponents" : { }, - "config" : { - "allow-default-scopes" : [ "true" ] - } - }, { - "id" : "689ac444-a7e6-497a-a9ab-7c8d384bcf06", - "name" : "Consent Required", - "providerId" : "consent-required", - "subType" : "anonymous", - "subComponents" : { }, - "config" : { } - }, { - "id" : "4204bb0b-59bd-4bbd-9528-e0bdb0bea477", - "name" : "Allowed Protocol Mapper Types", - "providerId" : "allowed-protocol-mappers", - "subType" : "authenticated", - "subComponents" : { }, - "config" : { - "allowed-protocol-mapper-types" : [ "saml-user-attribute-mapper", "oidc-usermodel-property-mapper", "oidc-address-mapper", "oidc-full-name-mapper", "oidc-sha256-pairwise-sub-mapper", "saml-role-list-mapper", "saml-user-property-mapper", "oidc-usermodel-attribute-mapper" ] - } - }, { - "id" : "60e95445-5b19-456a-b4ab-f38d190a5692", - "name" : "Allowed Protocol Mapper Types", - "providerId" : "allowed-protocol-mappers", - "subType" : "anonymous", - "subComponents" : { }, - "config" : { - "allowed-protocol-mapper-types" : [ "saml-user-property-mapper", "oidc-address-mapper", "saml-role-list-mapper", "saml-user-attribute-mapper", "oidc-sha256-pairwise-sub-mapper", "oidc-usermodel-property-mapper", "oidc-full-name-mapper", "oidc-usermodel-attribute-mapper" ] - } - }, { - "id" : "a80fe473-48e2-4d14-a341-d90a0b92216a", - "name" : "Allowed Client Scopes", - "providerId" : "allowed-client-templates", - "subType" : "authenticated", - "subComponents" : { }, - "config" : { - "allow-default-scopes" : [ "true" ] - } - }, { - "id" : "56e5d0a2-354b-4e89-a45c-65f37bc6b9e6", - "name" : "Trusted Hosts", - "providerId" : "trusted-hosts", - "subType" : "anonymous", - "subComponents" : { }, - "config" : { - "host-sending-registration-request-must-match" : [ "true" ], - "client-uris-must-match" : [ "true" ] - } - }, { - "id" : "22ebd897-189f-4b8e-8dd7-62ad567e01fc", - "name" : "Max Clients Limit", - "providerId" : "max-clients", - "subType" : "anonymous", - "subComponents" : { }, - "config" : { - "max-clients" : [ "200" ] - } - }, { - "id" : "f0807c15-e127-49ed-9743-23ff6bf7b067", - "name" : "Full Scope Disabled", - "providerId" : "scope", - "subType" : "anonymous", - "subComponents" : { }, - "config" : { } - } ], - "org.keycloak.userprofile.UserProfileProvider" : [ { - "id" : "8221fdb5-e73e-4f2f-8dba-d28cfeb11329", - "providerId" : "declarative-user-profile", - "subComponents" : { }, - "config" : { } - } ], - "org.keycloak.keys.KeyProvider" : [ { - "id" : "73353bf5-70ce-4105-bbf0-4d580e746c6a", - "name" : "hmac-generated", - "providerId" : "hmac-generated", - "subComponents" : { }, - "config" : { - "kid" : [ "3e74502b-424c-4b7c-8266-d06259fc699e" ], - "secret" : [ "GEGoK7aaUQFf3GVrzwC6PSMlCUt8ksSoOpAQQzYaolGXvtujqlrRuMZKpHnsbpAOwNI-W4SvW23ryhALc9kvjg" ], - "priority" : [ "100" ], - "algorithm" : [ "HS256" ] - } - }, { - "id" : "a55565bb-b3de-47f7-92b8-b0b318d6c2de", - "name" : "rsa-enc-generated", - "providerId" : "rsa-enc-generated", - "subComponents" : { }, - "config" : { - "privateKey" : [ "MIIEpAIBAAKCAQEA15EWVTRgUZC8PMSee3yQ970bRB1qD1RnN2E+0pmMUhk7DGKybSfM0NtdT1qGVQy0a0L25/vwPKuDUkQqZghY7D4g2FSWq/T65lMBSpBY/behhhiVzAziePMmx/TQYnqbhxr+TvTinkphglCirFRgWOVDKM9/EEVeZFuvQmPQ/lD3sCbgecseskX/IeY/IYK4kcNYzQtuW/dIeGsYy2fIMxNq7ggaQ5w48OXdhfjmNHXh6Kdud2SFQRR9AAz31hYZ9UFaLaO252AtKXJOmGIgNIMhEfiUME1EcU08KZOzwQfVDMvFkajKc7B931ZwmLJwPnwnR4UfZk+XNmFh3FP9iQIDAQABAoIBAEfc/mz5QQLwFVDM22ifZlSwnl5ez/S8VoyHxsG+nqDf+Gdwn7r0Abu+5aSGsTG5QoxfjqBXxQb0xpquTtQlBD/9lkWILZK14M7X7R5GcORkS1zA5W9Y/EcGCG+wlae+6ApqXU1FJidO9KLU7uY0WspH49O/GMT72zPpvMuNKyccilT5vFjHeNBeCO6urAeVqlRE0atPKtuQPWSQtVVpJRo2yLURXYpMQCzkPyB0CYacrVyA3gsTATXZxud9tYYre3CGTuCfIc8/bwD+pgEVzoeFynH9XHwr6neOWoHyOhe+Mqwed2X0QJZ54kpwQN9LGmhEJY2gMsq0SNmI75qHbWECgYEA60kpCFQ8Ivxq2+500xP1QxPHuuOgBWcfBjvro5BlbzOEXBhXyNGzV/2OQDUtGGFfLhJ0lg34Xhc22UcpOZM/Al803NSRDNOPGQGjzqEOzGl2xfiT5jpP0V4l/3AxGS3j6pP5O8dPK20KHt73bx+ajc2RyVuDHJbQbdPOijRB3IMCgYEA6ouAgBjD7UbKD9XliEnmfPfyXGMVGSclZPT/Y4k0d+SEPmilgfVnZZPFVdTuLtAcL77I5BU7o9NnYScqdQF+HYnXoMstEfVuTHzC41UE92XyjgB2Cf6D+vR9u9SDjW2kNzd5KggUvY2CvdBw3vuH4dbThS12tekxISlfRdo7eAMCgYEAqNQ8Xz+iTzB0tQ+sQHHHwbQF03LWNkpClsSUVy+buWlsBnFpPC5M1EyasDP4AdCM7ZBMnAe2Oj3KG6rWR/wCcH9EfVkCJAQCYF0u32vuJHtgwLmX1tHsyD0YYuxsLrchHgfEBUME6hI5+uDfB5vT2QCzJZtGv1LwiH49bCoHQGUCgYEAwmIpdoCP6NeRYXxphgGRR6MKtyza8IS0Bi7SdoDg/jhirYJ3IPTs44+Lra4SVLPfmGZrAjTiv8zWUftuwZgiGIMENVwOF2MsLbH8pwHwYsWYN74EFhZc9aCpkAD5oj3rKmQMRBx8a/ibEYtt8C/Qlwg/N5HNX8hLEmvCbRcH0FcCgYAQAurHiGOJl19rNQsvGAGWjt2iw49mYxRdKhxbQAla34jUES7T6uL4DXsGIyeGrSqjRT6ZvfeifgnOV6sfec/Dz4kbSCbAL9YK4OlpkXyQL7VxYh3q2U35MCV5Yv7BH++X/hhURoKazQ5TlQsbOjsuBWm7eahj1sJIDaCRcoqGNg==" ], - "keyUse" : [ "ENC" ], - "certificate" : [ "MIICnTCCAYUCBgGK3IFC9zANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdteXJlYWxtMB4XDTIzMDkyODE1NTQzM1oXDTMzMDkyODE1NTYxM1owEjEQMA4GA1UEAwwHbXlyZWFsbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANeRFlU0YFGQvDzEnnt8kPe9G0Qdag9UZzdhPtKZjFIZOwxism0nzNDbXU9ahlUMtGtC9uf78Dyrg1JEKmYIWOw+INhUlqv0+uZTAUqQWP23oYYYlcwM4njzJsf00GJ6m4ca/k704p5KYYJQoqxUYFjlQyjPfxBFXmRbr0Jj0P5Q97Am4HnLHrJF/yHmPyGCuJHDWM0Lblv3SHhrGMtnyDMTau4IGkOcOPDl3YX45jR14einbndkhUEUfQAM99YWGfVBWi2jtudgLSlyTphiIDSDIRH4lDBNRHFNPCmTs8EH1QzLxZGoynOwfd9WcJiycD58J0eFH2ZPlzZhYdxT/YkCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAsM2x/4i8M3fZfolsxormrljwwdHmUe2H3pjO7QJfo/ZTgLvzR2QYwdvLNi7Gpk/7RVioygduLz1MBIa753wezP/3A5certZ8znChFJuR0xCvj+++M+3XCo1Ah8KUzBih3knw+aBaVvo8waYNqwoIKDW45kbcW6ohi+cernBgsdXNRYwpAMe96Ogi45REbPa4qaLiTKj7Ifi/tbrDdcelDEi2mpzEslbI/5Fi22+Agoc3GGufz6xSXVtvYGFVHiibSmVq7PcreYhVm89Ig21HI+mPb9y2kQzZuKqJ62wh82EtYzLIZTu+ATulI53rIclyV5gdW2K8B2hSmnGxI8a8Cw==" ], - "priority" : [ "100" ], - "algorithm" : [ "RSA-OAEP" ] - } - }, { - "id" : "24b11e9b-8efc-4e19-81cb-cae278512a9f", - "name" : "rsa-generated", - "providerId" : "rsa-generated", - "subComponents" : { }, - "config" : { - "privateKey" : [ "MIIEpAIBAAKCAQEAtPZ5ZeRS2744CMCHohZBbwEAgF0qu4BjAchNxWfSuyCCsa4LeyjkF/JOKqiOP522ULFlzEirfmntGYluxKNDr40JIMPBx6qnASZvT83mY9kbMkqeTuZ2nrRf9Z2o4aTBEyjWbKY2plWGML9WGUzOBUqMXxDc4/8FGFXzOZdmn2RItfD+hQM6F8RHWTE6P9+h4S/oPhqZ+4Ih3Jrk6BPG0Fv1u+9Dd7f7lptDaXALCEkuMqfwEwcpSUppkmErgGJ5Ujg3rtcbdFwgcr+cVaUkmZmSXn60JG0usiAO/d19DHa8CzETGlU4vaEvDm43h9ZpAOMIkoz8gos9IqYuBsYylQIDAQABAoIBACLfIDOvVPw9YqTlHP3yFffjFIqn6XUqX2nXhI0W3bfrouPEazf3gETRD5kO1CKULK7OEJTWKB37IZJ7Nlo0L/XjUq/6qRvl2brSAj85qTzyeFgvouQHazJYBenZ0NJyojYj93YGbZ+N+YbpSBkmAMlqPTSQllBlM0EmRvGBKGhsYtPljkb1Fc10zksNrEHZdyTXyiJpiXQpe/feRSVh64fORsREl/0CrjWOXgJoilerLInjdO6/UuEXnT+eY9ttJpGfXRjqdb4QzHHmkKb4HH6X3YMBvQX8NhS0EF9VGvzDVq2JZagwc97UDLKkKpFv82BydtwWx4zkcACBKZfFg/0CgYEA2qgbyJaK86vcrwlqzt2ykXmcPzeuueFpPRIYlKwZaoBS7hYJZBbjZq72/TU8oVvMEQH6sV9u1+dU7EBUJ64UEoQkShGd5deYTav5UD0fvjnCddz+rK9Z0K/nS9zeYc/eAYgSfNPAYd1zHfBfn2MTvBYuay4xy9CFLm/j7ePA8McCgYEA095Z0ZnU9UQ47TA20JXFVqguY0TnFYWIpN68Biv7o7ETVgti9WFNp5wpa/PkBGBXUzXoHW7Z+4wxe/UoNW2KOIgF959M0XbEN+niKIzcK3kxF2FDs926o/w3+FocJeGs6Mr/jGmGqzoaVSw6o3Z2KCzu996jE+riLiO0UpB13cMCgYBNy2PfMRiM64efyxTyNtRyh7b8kv4aakV8EfUm6Dg+uRtIVBTRRIdxoCyGGCvTKQrovjCIbPDN5iNDzvtiBsBjehpDNBNelB8++0G/t4+UqY4zSwZdQCIPapY7WoDQghl1qAkT2m7nItfzPfN3jNOXprirL4tN/Yl05SBOIisiPwKBgQDNXGTrSZSl9+7F2UoIfGO/T11HU2456ik8xbiyssdDL0xyxq6w8hP3NuLfhJOrukZqnYHTpbMcpBMC9+p1fyvPB+ngz0QCdIBVQhq4+3Ado2b2Jo0dNvrGIJ+P1qgZ/9k9/CYfz9l89uC3Vhuwfg6heoxXLjIcCDwcRPdwYB4fSQKBgQC+P05eo2IVMRtkWhGNBtYyWiWdC+3S52O10J5pwbn3DzYSFeVGGV3Mu2PWidI+26+0lKKrAgqoIuj5G/XKjBVx0g0diNR2AHOiu9bIlaSWiVTOpsb9xNRrrRQ8mcbe6d9YicyRhj6uVAI3cE2X44T4QV0Fq/j6ygepcVV6+TGtgA==" ], - "keyUse" : [ "SIG" ], - "certificate" : [ "MIICnTCCAYUCBgGK3IFB7TANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdteXJlYWxtMB4XDTIzMDkyODE1NTQzM1oXDTMzMDkyODE1NTYxM1owEjEQMA4GA1UEAwwHbXlyZWFsbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALT2eWXkUtu+OAjAh6IWQW8BAIBdKruAYwHITcVn0rsggrGuC3so5BfyTiqojj+dtlCxZcxIq35p7RmJbsSjQ6+NCSDDwceqpwEmb0/N5mPZGzJKnk7mdp60X/WdqOGkwRMo1mymNqZVhjC/VhlMzgVKjF8Q3OP/BRhV8zmXZp9kSLXw/oUDOhfER1kxOj/foeEv6D4amfuCIdya5OgTxtBb9bvvQ3e3+5abQ2lwCwhJLjKn8BMHKUlKaZJhK4BieVI4N67XG3RcIHK/nFWlJJmZkl5+tCRtLrIgDv3dfQx2vAsxExpVOL2hLw5uN4fWaQDjCJKM/IKLPSKmLgbGMpUCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAFzF4YARB1b6vba/9K11EreYaf07zO7xC0cr9eQCq2otkaHmWlpXzId/k/UUgVAO7SUOMYHaO4e2OlIJhUNHvURcTrGpPIoks+g5JThvlugFgwNOgUKLIoRiew80Q+jq43f4UHJGe9EE8TIyEKJPZWylqRJJIYzCJA55YSPGIziHeAIq80jYTpW3/QL7jwuRlzI1CGrFXfP5LB6tA2EKU9aIQ7GuJOSUxRGWFqOp7kvR3x/VewYJH7J/VuAt3CXNuQgX1gK1OOLbCUELo87opP/01CKSBrL3H59fGOOQqYJTvbowkgxRKtV+nG9HYCiEnSaGyyBAiWj8VgWsOGFF2ew==" ], - "priority" : [ "100" ] - } - }, { - "id" : "c55901db-a908-43e0-af7c-081843b0b092", - "name" : "aes-generated", - "providerId" : "aes-generated", - "subComponents" : { }, - "config" : { - "kid" : [ "7676e96f-9f72-4e4c-b768-ea16e9d9dafe" ], - "secret" : [ "hXFMxKJtJjXAs2XmlTOnXw" ], - "priority" : [ "100" ] - } - } ] - }, - "internationalizationEnabled" : false, - "supportedLocales" : [ ], - "authenticationFlows" : [ { - "id" : "c7d69cbe-8041-47f5-b9d3-6da167de223e", - "alias" : "Account verification options", - "description" : "Method with which to verity the existing account", - "providerId" : "basic-flow", - "topLevel" : false, - "builtIn" : true, - "authenticationExecutions" : [ { - "authenticator" : "idp-email-verification", - "authenticatorFlow" : false, - "requirement" : "ALTERNATIVE", - "priority" : 10, - "autheticatorFlow" : false, - "userSetupAllowed" : false - }, { - "authenticatorFlow" : true, - "requirement" : "ALTERNATIVE", - "priority" : 20, - "autheticatorFlow" : true, - "flowAlias" : "Verify Existing Account by Re-authentication", - "userSetupAllowed" : false - } ] - }, { - "id" : "70545ca0-25f6-4fda-a7a7-1bad57e14225", - "alias" : "Browser - Conditional OTP", - "description" : "Flow to determine if the OTP is required for the authentication", - "providerId" : "basic-flow", - "topLevel" : false, - "builtIn" : true, - "authenticationExecutions" : [ { - "authenticator" : "conditional-user-configured", - "authenticatorFlow" : false, - "requirement" : "REQUIRED", - "priority" : 10, - "autheticatorFlow" : false, - "userSetupAllowed" : false - }, { - "authenticator" : "auth-otp-form", - "authenticatorFlow" : false, - "requirement" : "REQUIRED", - "priority" : 20, - "autheticatorFlow" : false, - "userSetupAllowed" : false - } ] - }, { - "id" : "269ae920-f17e-42e0-b708-3f9b1e85fab1", - "alias" : "Direct Grant - Conditional OTP", - "description" : "Flow to determine if the OTP is required for the authentication", - "providerId" : "basic-flow", - "topLevel" : false, - "builtIn" : true, - "authenticationExecutions" : [ { - "authenticator" : "conditional-user-configured", - "authenticatorFlow" : false, - "requirement" : "REQUIRED", - "priority" : 10, - "autheticatorFlow" : false, - "userSetupAllowed" : false - }, { - "authenticator" : "direct-grant-validate-otp", - "authenticatorFlow" : false, - "requirement" : "REQUIRED", - "priority" : 20, - "autheticatorFlow" : false, - "userSetupAllowed" : false - } ] - }, { - "id" : "0d9fb4d5-0e11-4d83-8208-8d8c917692cc", - "alias" : "First broker login - Conditional OTP", - "description" : "Flow to determine if the OTP is required for the authentication", - "providerId" : "basic-flow", - "topLevel" : false, - "builtIn" : true, - "authenticationExecutions" : [ { - "authenticator" : "conditional-user-configured", - "authenticatorFlow" : false, - "requirement" : "REQUIRED", - "priority" : 10, - "autheticatorFlow" : false, - "userSetupAllowed" : false - }, { - "authenticator" : "auth-otp-form", - "authenticatorFlow" : false, - "requirement" : "REQUIRED", - "priority" : 20, - "autheticatorFlow" : false, - "userSetupAllowed" : false - } ] - }, { - "id" : "7c5af45a-74c3-471d-8fb3-032d91f81101", - "alias" : "Handle Existing Account", - "description" : "Handle what to do if there is existing account with same email/username like authenticated identity provider", - "providerId" : "basic-flow", - "topLevel" : false, - "builtIn" : true, - "authenticationExecutions" : [ { - "authenticator" : "idp-confirm-link", - "authenticatorFlow" : false, - "requirement" : "REQUIRED", - "priority" : 10, - "autheticatorFlow" : false, - "userSetupAllowed" : false - }, { - "authenticatorFlow" : true, - "requirement" : "REQUIRED", - "priority" : 20, - "autheticatorFlow" : true, - "flowAlias" : "Account verification options", - "userSetupAllowed" : false - } ] - }, { - "id" : "c3d188dd-38b8-4b23-a6d9-ddb4b8920651", - "alias" : "Reset - Conditional OTP", - "description" : "Flow to determine if the OTP should be reset or not. Set to REQUIRED to force.", - "providerId" : "basic-flow", - "topLevel" : false, - "builtIn" : true, - "authenticationExecutions" : [ { - "authenticator" : "conditional-user-configured", - "authenticatorFlow" : false, - "requirement" : "REQUIRED", - "priority" : 10, - "autheticatorFlow" : false, - "userSetupAllowed" : false - }, { - "authenticator" : "reset-otp", - "authenticatorFlow" : false, - "requirement" : "REQUIRED", - "priority" : 20, - "autheticatorFlow" : false, - "userSetupAllowed" : false - } ] - }, { - "id" : "799ec675-fe88-4c70-8395-c7dd6e93ccdd", - "alias" : "User creation or linking", - "description" : "Flow for the existing/non-existing user alternatives", - "providerId" : "basic-flow", - "topLevel" : false, - "builtIn" : true, - "authenticationExecutions" : [ { - "authenticatorConfig" : "create unique user config", - "authenticator" : "idp-create-user-if-unique", - "authenticatorFlow" : false, - "requirement" : "ALTERNATIVE", - "priority" : 10, - "autheticatorFlow" : false, - "userSetupAllowed" : false - }, { - "authenticatorFlow" : true, - "requirement" : "ALTERNATIVE", - "priority" : 20, - "autheticatorFlow" : true, - "flowAlias" : "Handle Existing Account", - "userSetupAllowed" : false - } ] - }, { - "id" : "b67f488b-af1c-4f7d-a167-8593d3424390", - "alias" : "Verify Existing Account by Re-authentication", - "description" : "Reauthentication of existing account", - "providerId" : "basic-flow", - "topLevel" : false, - "builtIn" : true, - "authenticationExecutions" : [ { - "authenticator" : "idp-username-password-form", - "authenticatorFlow" : false, - "requirement" : "REQUIRED", - "priority" : 10, - "autheticatorFlow" : false, - "userSetupAllowed" : false - }, { - "authenticatorFlow" : true, - "requirement" : "CONDITIONAL", - "priority" : 20, - "autheticatorFlow" : true, - "flowAlias" : "First broker login - Conditional OTP", - "userSetupAllowed" : false - } ] - }, { - "id" : "b2f2d03e-471f-4dcc-89a2-12edd5728007", - "alias" : "browser", - "description" : "browser based authentication", - "providerId" : "basic-flow", - "topLevel" : true, - "builtIn" : true, - "authenticationExecutions" : [ { - "authenticator" : "auth-cookie", - "authenticatorFlow" : false, - "requirement" : "ALTERNATIVE", - "priority" : 10, - "autheticatorFlow" : false, - "userSetupAllowed" : false - }, { - "authenticator" : "auth-spnego", - "authenticatorFlow" : false, - "requirement" : "DISABLED", - "priority" : 20, - "autheticatorFlow" : false, - "userSetupAllowed" : false - }, { - "authenticator" : "identity-provider-redirector", - "authenticatorFlow" : false, - "requirement" : "ALTERNATIVE", - "priority" : 25, - "autheticatorFlow" : false, - "userSetupAllowed" : false - }, { - "authenticatorFlow" : true, - "requirement" : "ALTERNATIVE", - "priority" : 30, - "autheticatorFlow" : true, - "flowAlias" : "forms", - "userSetupAllowed" : false - } ] - }, { - "id" : "4ef7b700-472a-4259-96d8-14185063336b", - "alias" : "clients", - "description" : "Base authentication for clients", - "providerId" : "client-flow", - "topLevel" : true, - "builtIn" : true, - "authenticationExecutions" : [ { - "authenticator" : "client-secret", - "authenticatorFlow" : false, - "requirement" : "ALTERNATIVE", - "priority" : 10, - "autheticatorFlow" : false, - "userSetupAllowed" : false - }, { - "authenticator" : "client-jwt", - "authenticatorFlow" : false, - "requirement" : "ALTERNATIVE", - "priority" : 20, - "autheticatorFlow" : false, - "userSetupAllowed" : false - }, { - "authenticator" : "client-secret-jwt", - "authenticatorFlow" : false, - "requirement" : "ALTERNATIVE", - "priority" : 30, - "autheticatorFlow" : false, - "userSetupAllowed" : false - }, { - "authenticator" : "client-x509", - "authenticatorFlow" : false, - "requirement" : "ALTERNATIVE", - "priority" : 40, - "autheticatorFlow" : false, - "userSetupAllowed" : false - } ] - }, { - "id" : "0899b39d-c961-493a-81c6-f3161923a476", - "alias" : "direct grant", - "description" : "OpenID Connect Resource Owner Grant", - "providerId" : "basic-flow", - "topLevel" : true, - "builtIn" : true, - "authenticationExecutions" : [ { - "authenticator" : "direct-grant-validate-username", - "authenticatorFlow" : false, - "requirement" : "REQUIRED", - "priority" : 10, - "autheticatorFlow" : false, - "userSetupAllowed" : false - }, { - "authenticator" : "direct-grant-validate-password", - "authenticatorFlow" : false, - "requirement" : "REQUIRED", - "priority" : 20, - "autheticatorFlow" : false, - "userSetupAllowed" : false - }, { - "authenticatorFlow" : true, - "requirement" : "CONDITIONAL", - "priority" : 30, - "autheticatorFlow" : true, - "flowAlias" : "Direct Grant - Conditional OTP", - "userSetupAllowed" : false - } ] - }, { - "id" : "7351f8b2-383d-4c25-aece-105aff101ba8", - "alias" : "docker auth", - "description" : "Used by Docker clients to authenticate against the IDP", - "providerId" : "basic-flow", - "topLevel" : true, - "builtIn" : true, - "authenticationExecutions" : [ { - "authenticator" : "docker-http-basic-authenticator", - "authenticatorFlow" : false, - "requirement" : "REQUIRED", - "priority" : 10, - "autheticatorFlow" : false, - "userSetupAllowed" : false - } ] - }, { - "id" : "866f40c4-7a10-40b4-9bb0-320938f25e47", - "alias" : "first broker login", - "description" : "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account", - "providerId" : "basic-flow", - "topLevel" : true, - "builtIn" : true, - "authenticationExecutions" : [ { - "authenticatorConfig" : "review profile config", - "authenticator" : "idp-review-profile", - "authenticatorFlow" : false, - "requirement" : "REQUIRED", - "priority" : 10, - "autheticatorFlow" : false, - "userSetupAllowed" : false - }, { - "authenticatorFlow" : true, - "requirement" : "REQUIRED", - "priority" : 20, - "autheticatorFlow" : true, - "flowAlias" : "User creation or linking", - "userSetupAllowed" : false - } ] - }, { - "id" : "5c6742df-ce47-4ebb-bf1d-816d9fb813f3", - "alias" : "forms", - "description" : "Username, password, otp and other auth forms.", - "providerId" : "basic-flow", - "topLevel" : false, - "builtIn" : true, - "authenticationExecutions" : [ { - "authenticator" : "auth-username-password-form", - "authenticatorFlow" : false, - "requirement" : "REQUIRED", - "priority" : 10, - "autheticatorFlow" : false, - "userSetupAllowed" : false - }, { - "authenticatorFlow" : true, - "requirement" : "CONDITIONAL", - "priority" : 20, - "autheticatorFlow" : true, - "flowAlias" : "Browser - Conditional OTP", - "userSetupAllowed" : false - } ] - }, { - "id" : "a609a901-382e-40a9-b837-d6ae1acf9add", - "alias" : "registration", - "description" : "registration flow", - "providerId" : "basic-flow", - "topLevel" : true, - "builtIn" : true, - "authenticationExecutions" : [ { - "authenticator" : "registration-page-form", - "authenticatorFlow" : true, - "requirement" : "REQUIRED", - "priority" : 10, - "autheticatorFlow" : true, - "flowAlias" : "registration form", - "userSetupAllowed" : false - } ] - }, { - "id" : "58c0329a-e16e-4412-bae6-3cfd009e662d", - "alias" : "registration form", - "description" : "registration form", - "providerId" : "form-flow", - "topLevel" : false, - "builtIn" : true, - "authenticationExecutions" : [ { - "authenticator" : "registration-user-creation", - "authenticatorFlow" : false, - "requirement" : "REQUIRED", - "priority" : 20, - "autheticatorFlow" : false, - "userSetupAllowed" : false - }, { - "authenticator" : "registration-profile-action", - "authenticatorFlow" : false, - "requirement" : "REQUIRED", - "priority" : 40, - "autheticatorFlow" : false, - "userSetupAllowed" : false - }, { - "authenticator" : "registration-password-action", - "authenticatorFlow" : false, - "requirement" : "REQUIRED", - "priority" : 50, - "autheticatorFlow" : false, - "userSetupAllowed" : false - }, { - "authenticator" : "registration-recaptcha-action", - "authenticatorFlow" : false, - "requirement" : "DISABLED", - "priority" : 60, - "autheticatorFlow" : false, - "userSetupAllowed" : false - } ] - }, { - "id" : "97c81f1a-fc4b-4c50-bbbb-e6fe40096ddf", - "alias" : "reset credentials", - "description" : "Reset credentials for a user if they forgot their password or something", - "providerId" : "basic-flow", - "topLevel" : true, - "builtIn" : true, - "authenticationExecutions" : [ { - "authenticator" : "reset-credentials-choose-user", - "authenticatorFlow" : false, - "requirement" : "REQUIRED", - "priority" : 10, - "autheticatorFlow" : false, - "userSetupAllowed" : false - }, { - "authenticator" : "reset-credential-email", - "authenticatorFlow" : false, - "requirement" : "REQUIRED", - "priority" : 20, - "autheticatorFlow" : false, - "userSetupAllowed" : false - }, { - "authenticator" : "reset-password", - "authenticatorFlow" : false, - "requirement" : "REQUIRED", - "priority" : 30, - "autheticatorFlow" : false, - "userSetupAllowed" : false - }, { - "authenticatorFlow" : true, - "requirement" : "CONDITIONAL", - "priority" : 40, - "autheticatorFlow" : true, - "flowAlias" : "Reset - Conditional OTP", - "userSetupAllowed" : false - } ] - }, { - "id" : "aed7672e-b59d-477c-9798-55f59b04ff9d", - "alias" : "saml ecp", - "description" : "SAML ECP Profile Authentication Flow", - "providerId" : "basic-flow", - "topLevel" : true, - "builtIn" : true, - "authenticationExecutions" : [ { - "authenticator" : "http-basic-authenticator", - "authenticatorFlow" : false, - "requirement" : "REQUIRED", - "priority" : 10, - "autheticatorFlow" : false, - "userSetupAllowed" : false - } ] - } ], - "authenticatorConfig" : [ { - "id" : "5ce31743-aee3-4684-842f-7f63a1ed9e37", - "alias" : "create unique user config", - "config" : { - "require.password.update.after.registration" : "false" - } - }, { - "id" : "44e63ced-c494-4a4d-8708-af0d492be5f8", - "alias" : "review profile config", - "config" : { - "update.profile.on.first.login" : "missing" - } - } ], - "requiredActions" : [ { - "alias" : "CONFIGURE_TOTP", - "name" : "Configure OTP", - "providerId" : "CONFIGURE_TOTP", - "enabled" : true, - "defaultAction" : false, - "priority" : 10, - "config" : { } - }, { - "alias" : "TERMS_AND_CONDITIONS", - "name" : "Terms and Conditions", - "providerId" : "TERMS_AND_CONDITIONS", - "enabled" : false, - "defaultAction" : false, - "priority" : 20, - "config" : { } - }, { - "alias" : "UPDATE_PASSWORD", - "name" : "Update Password", - "providerId" : "UPDATE_PASSWORD", - "enabled" : true, - "defaultAction" : false, - "priority" : 30, - "config" : { } - }, { - "alias" : "UPDATE_PROFILE", - "name" : "Update Profile", - "providerId" : "UPDATE_PROFILE", - "enabled" : true, - "defaultAction" : false, - "priority" : 40, - "config" : { } - }, { - "alias" : "VERIFY_EMAIL", - "name" : "Verify Email", - "providerId" : "VERIFY_EMAIL", - "enabled" : true, - "defaultAction" : false, - "priority" : 50, - "config" : { } - }, { - "alias" : "delete_account", - "name" : "Delete Account", - "providerId" : "delete_account", - "enabled" : false, - "defaultAction" : false, - "priority" : 60, - "config" : { } - }, { - "alias" : "webauthn-register", - "name" : "Webauthn Register", - "providerId" : "webauthn-register", - "enabled" : true, - "defaultAction" : false, - "priority" : 70, - "config" : { } - }, { - "alias" : "webauthn-register-passwordless", - "name" : "Webauthn Register Passwordless", - "providerId" : "webauthn-register-passwordless", - "enabled" : true, - "defaultAction" : false, - "priority" : 80, - "config" : { } - }, { - "alias" : "update_user_locale", - "name" : "Update User Locale", - "providerId" : "update_user_locale", - "enabled" : true, - "defaultAction" : false, - "priority" : 1000, - "config" : { } - } ], - "browserFlow" : "browser", - "registrationFlow" : "registration", - "directGrantFlow" : "direct grant", - "resetCredentialsFlow" : "reset credentials", - "clientAuthenticationFlow" : "clients", - "dockerAuthenticationFlow" : "docker auth", - "attributes" : { - "cibaBackchannelTokenDeliveryMode" : "poll", - "cibaAuthRequestedUserHint" : "login_hint", - "clientOfflineSessionMaxLifespan" : "0", - "oauth2DevicePollingInterval" : "5", - "clientSessionIdleTimeout" : "0", - "actionTokenGeneratedByUserLifespan-execute-actions" : "", - "actionTokenGeneratedByUserLifespan-verify-email" : "", - "clientOfflineSessionIdleTimeout" : "0", - "actionTokenGeneratedByUserLifespan-reset-credentials" : "", - "cibaInterval" : "5", - "realmReusableOtpCode" : "false", - "cibaExpiresIn" : "120", - "oauth2DeviceCodeLifespan" : "600", - "actionTokenGeneratedByUserLifespan-idp-verify-account-via-email" : "", - "parRequestUriLifespan" : "60", - "clientSessionMaxLifespan" : "0", - "shortVerificationUri" : "" - }, - "keycloakVersion" : "22.0.5", - "userManagedAccessAllowed" : false, - "clientProfiles" : { - "profiles" : [ ] - }, - "clientPolicies" : { - "policies" : [ ] - } -} \ No newline at end of file diff --git a/configurationFiles/keycloakConfigs/myrealm-users-0.json b/configurationFiles/keycloakConfigs/myrealm-users-0.json deleted file mode 100644 index c48848af..00000000 --- a/configurationFiles/keycloakConfigs/myrealm-users-0.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "realm" : "myrealm", - "users" : [ { - "id" : "6e0f30a6-e18e-45e9-ad75-8dc8171988b8", - "createdTimestamp" : 1718675261866, - "username" : "admin", - "enabled" : true, - "totp" : false, - "emailVerified" : true, - "firstName" : "admin", - "lastName" : "example", - "email" : "admin@example.com", - "attributes" : { - "api-keys" : [ "{\"name\":\"F4C094A60BA88FB3F42BB9D20D75931286549D7F3C2E448F62D81CE20237B9BC\",\"scope\":[\"score.READ\",\"score.WRITE\",\"song.READ\",\"song.WRITE\"],\"expiryDate\":1830297599000,\"issueDate\":1701960265122,\"isRevoked\":false,\"description\":\"System wide ApiKey\"}" ] - }, - "credentials" : [ { - "id" : "0c249566-bd35-42dd-8e13-fa8b94d432e7", - "type" : "password", - "userLabel" : "My password", - "createdDate" : 1718675312626, - "secretData" : "{\"value\":\"bObvXU4FOF8JDDloamU4Th0+weRiJ6A/UEx3NlweKxM=\",\"salt\":\"k8hhIcgGIFLPp+FyxyACmA==\",\"additionalParameters\":{}}", - "credentialData" : "{\"hashIterations\":27500,\"algorithm\":\"pbkdf2-sha256\",\"additionalParameters\":{}}" - } ], - "disableableCredentialTypes" : [ ], - "requiredActions" : [ ], - "realmRoles" : [ "default-roles-myrealm" ], - "notBefore" : 0, - "groups" : [ "/ADMIN" ] - }, { - "id" : "7255599f-7826-458a-aaa7-ced54e8610e0", - "createdTimestamp" : 1718674923677, - "username" : "service-account-dms", - "enabled" : true, - "totp" : false, - "emailVerified" : false, - "serviceAccountClientId" : "dms", - "credentials" : [ ], - "disableableCredentialTypes" : [ ], - "requiredActions" : [ ], - "realmRoles" : [ "default-roles-myrealm" ], - "clientRoles" : { - "dms" : [ "uma_protection" ] - }, - "notBefore" : 0, - "groups" : [ ] - } ] -} \ No newline at end of file diff --git a/data/datatable1.csv b/data/datatable1.csv new file mode 100644 index 00000000..a552eae4 --- /dev/null +++ b/data/datatable1.csv @@ -0,0 +1,52 @@ +donor_id,gender,primary_site,vital_status,diagnosis_id,age_at_diagnosis,cancer_type,staging_system,stage,specimen_id,specimen_type,tissue_source,sample_id,sample_type,treatment_id,treatment_type,treatment_start,treatment_duration,treatment_response,drug_name,followup_id,followup_interval,disease_status +DO0599,Female,Trachea,Alive,PD059901,50,C34.2,Binet staging system,Stage A,SP059902,Normal - tissue adjacent to primary tumour,Blood derived - bone marrow,SP059902,Total DNA,TR059901,Chemotherapy,58,52,Complete response,Tamoxifen,FO059901,45,Stable +DO0600,Male,Brain,Alive,PD059902,45,C71.0,AJCC 8th edition,Stage II,SP059903,Primary tumour,Solid tissue,SP059903,Total RNA,TR059902,Radiation therapy,30,45,Partial response,None,FO059902,60,Stable +DO0601,Female,Breast,Alive,PD059903,62,C50.1,AJCC 8th edition,Stage IIA,SP059904,Primary tumour,Solid tissue,SP059904,Total DNA,TR059903,Chemotherapy,45,90,Complete response,Doxorubicin,FO059903,90,Complete remission +DO0602,Male,Prostate gland,Alive,PD059904,71,C61,Gleason grade group system,Grade Group 2,SP059905,Primary tumour,Solid tissue,SP059905,Total DNA,TR059904,Hormonal therapy,15,180,Partial response,Leuprolide,FO059904,120,Stable +DO0603,Female,Ovary,Deceased,PD059905,58,C56,FIGO staging system,Stage IIIC,SP059906,Primary tumour,Solid tissue,SP059906,Total DNA,TR059905,Chemotherapy,20,120,Disease progression,Carboplatin,FO059905,150,Progression NOS +DO0604,Male,Lung,Alive,PD059906,67,C34.1,AJCC 8th edition,Stage IIIA,SP059907,Primary tumour,Solid tissue,SP059907,Total DNA,TR059906,Chemotherapy,40,60,Partial response,Cisplatin,FO059906,80,Stable +DO0605,Female,Thyroid gland,Alive,PD059907,43,C73,AJCC 8th edition,Stage I,SP059908,Primary tumour,Solid tissue,SP059908,Total DNA,TR059907,Surgery,10,1,Complete response,None,FO059907,180,No evidence of disease +DO0606,Male,Colon,Alive,PD059908,59,C18.2,AJCC 8th edition,Stage IIB,SP059909,Primary tumour,Solid tissue,SP059909,Total DNA,TR059908,Chemotherapy,25,84,Complete response,FOLFOX,FO059908,120,Stable +DO0607,Female,Pancreas,Deceased,PD059909,64,C25.0,AJCC 8th edition,Stage IV,SP059910,Primary tumour,Solid tissue,SP059910,Total DNA,TR059909,Chemotherapy,15,45,Disease progression,Gemcitabine,FO059909,60,Progression NOS +DO0608,Male,Liver,Alive,PD059910,55,C22.0,AJCC 8th edition,Stage II,SP059911,Primary tumour,Solid tissue,SP059911,Total DNA,TR059910,Surgery,5,1,Complete response,None,FO059910,90,Stable +DO0609,Female,Cervix uteri,Alive,PD059911,48,C53.0,FIGO staging system,Stage IB,SP059912,Primary tumour,Solid tissue,SP059912,Total DNA,TR059911,Radiation therapy,20,40,Complete response,None,FO059911,150,No evidence of disease +DO0610,Male,Bladder,Alive,PD059912,72,C67.0,AJCC 8th edition,Stage I,SP059913,Primary tumour,Solid tissue,SP059913,Total DNA,TR059912,Surgery,0,1,Complete response,None,FO059912,120,Stable +DO0611,Female,Breast,Alive,PD059913,51,C50.2,AJCC 8th edition,Stage IIA,SP059914,Primary tumour,Solid tissue,SP059914,Total DNA,TR059913,Chemotherapy,30,120,Complete response,Paclitaxel,FO059913,180,Complete remission +DO0612,Male,Prostate gland,Alive,PD059914,68,C61,Gleason grade group system,Grade Group 3,SP059915,Primary tumour,Solid tissue,SP059915,Total DNA,TR059914,Hormonal therapy,10,240,Partial response,Enzalutamide,FO059914,150,Stable +DO0613,Female,Ovary,Deceased,PD059915,61,C56,FIGO staging system,Stage IV,SP059916,Primary tumour,Solid tissue,SP059916,Total DNA,TR059915,Chemotherapy,25,90,Disease progression,Paclitaxel,FO059915,120,Progression NOS +DO0614,Male,Kidney,Alive,PD059916,57,C64.9,AJCC 8th edition,Stage II,SP059917,Primary tumour,Solid tissue,SP059917,Total DNA,TR059916,Surgery,15,1,Complete response,None,FO059916,90,No evidence of disease +DO0615,Female,Thyroid gland,Alive,PD059917,39,C73,AJCC 8th edition,Stage I,SP059918,Primary tumour,Solid tissue,SP059918,Total DNA,TR059917,Surgery,5,1,Complete response,None,FO059917,240,Stable +DO0616,Male,Stomach,Deceased,PD059918,70,C16.0,AJCC 8th edition,Stage IIIB,SP059919,Primary tumour,Solid tissue,SP059919,Total DNA,TR059918,Chemotherapy,20,60,Partial response,FLOT,FO059918,90,Progression NOS +DO0617,Female,Lung,Alive,PD059919,63,C34.3,AJCC 8th edition,Stage IIB,SP059920,Primary tumour,Solid tissue,SP059920,Total DNA,TR059919,Chemotherapy,35,75,Complete response,Pemetrexed,FO059919,120,Stable +DO0618,Male,Brain,Deceased,PD059920,52,C71.2,AJCC 8th edition,Stage IV,SP059921,Primary tumour,Solid tissue,SP059921,Total DNA,TR059920,Radiation therapy,15,30,Disease progression,None,FO059920,45,Progression NOS +DO0619,Female,Breast,Alive,PD059921,47,C50.4,AJCC 8th edition,Stage I,SP059922,Primary tumour,Solid tissue,SP059922,Total DNA,TR059921,Surgery,0,1,Complete response,None,FO059921,180,No evidence of disease +DO0620,Male,Colon,Alive,PD059922,66,C18.7,AJCC 8th edition,Stage IIIA,SP059923,Primary tumour,Solid tissue,SP059923,Total DNA,TR059922,Chemotherapy,25,120,Partial response,CAPOX,FO059922,150,Stable +DO0621,Female,Pancreas,Deceased,PD059923,69,C25.1,AJCC 8th edition,Stage IV,SP059924,Primary tumour,Solid tissue,SP059924,Total DNA,TR059923,Chemotherapy,10,60,Disease progression,FOLFIRINOX,FO059923,75,Progression NOS +DO0622,Male,Liver,Alive,PD059924,58,C22.0,AJCC 8th edition,Stage II,SP059925,Primary tumour,Solid tissue,SP059925,Total DNA,TR059924,Surgery,5,1,Complete response,None,FO059924,120,Stable +DO0623,Female,Cervix uteri,Alive,PD059925,44,C53.1,FIGO staging system,Stage IIA,SP059926,Primary tumour,Solid tissue,SP059926,Total DNA,TR059925,Radiation therapy,20,45,Complete response,None,FO059925,180,No evidence of disease +DO0624,Male,Bladder,Alive,PD059926,73,C67.1,AJCC 8th edition,Stage I,SP059927,Primary tumour,Solid tissue,SP059927,Total DNA,TR059926,Surgery,0,1,Complete response,None,FO059926,90,Stable +DO0625,Female,Breast,Alive,PD059927,54,C50.1,AJCC 8th edition,Stage IIB,SP059928,Primary tumour,Solid tissue,SP059928,Total DNA,TR059927,Chemotherapy,30,90,Complete response,AC-T,FO059927,150,Complete remission +DO0626,Male,Prostate gland,Alive,PD059928,65,C61,Gleason grade group system,Grade Group 2,SP059929,Primary tumour,Solid tissue,SP059929,Total DNA,TR059928,Hormonal therapy,15,180,Partial response,Abiraterone,FO059928,120,Stable +DO0627,Female,Ovary,Deceased,PD059929,60,C56,FIGO staging system,Stage IIIC,SP059930,Primary tumour,Solid tissue,SP059930,Total DNA,TR059929,Chemotherapy,25,120,Disease progression,Carboplatin,FO059929,90,Progression NOS +DO0628,Male,Kidney,Alive,PD059930,56,C64.9,AJCC 8th edition,Stage I,SP059931,Primary tumour,Solid tissue,SP059931,Total DNA,TR059930,Surgery,10,1,Complete response,None,FO059930,180,No evidence of disease +DO0629,Female,Thyroid gland,Alive,PD059931,41,C73,AJCC 8th edition,Stage I,SP059932,Primary tumour,Solid tissue,SP059932,Total DNA,TR059931,Surgery,5,1,Complete response,None,FO059931,240,Stable +DO0630,Male,Stomach,Deceased,PD059932,71,C16.3,AJCC 8th edition,Stage IV,SP059933,Primary tumour,Solid tissue,SP059933,Total DNA,TR059932,Chemotherapy,20,45,Disease progression,FLOT,FO059932,60,Progression NOS +DO0631,Female,Lung,Alive,PD059933,62,C34.1,AJCC 8th edition,Stage IIIA,SP059934,Primary tumour,Solid tissue,SP059934,Total DNA,TR059933,Chemotherapy,35,60,Partial response,Cisplatin,FO059933,120,Stable +DO0632,Male,Brain,Deceased,PD059934,53,C71.6,AJCC 8th edition,Stage IV,SP059935,Primary tumour,Solid tissue,SP059935,Total DNA,TR059934,Radiation therapy,15,30,Disease progression,None,FO059934,45,Progression NOS +DO0633,Female,Breast,Alive,PD059935,49,C50.2,AJCC 8th edition,Stage I,SP059936,Primary tumour,Solid tissue,SP059936,Total DNA,TR059935,Surgery,0,1,Complete response,None,FO059935,180,No evidence of disease +DO0634,Male,Colon,Alive,PD059936,67,C18.5,AJCC 8th edition,Stage IIIB,SP059937,Primary tumour,Solid tissue,SP059937,Total DNA,TR059936,Chemotherapy,25,120,Partial response,FOLFOX,FO059936,150,Stable +DO0635,Female,Pancreas,Deceased,PD059937,68,C25.2,AJCC 8th edition,Stage IV,SP059938,Primary tumour,Solid tissue,SP059938,Total DNA,TR059937,Chemotherapy,10,45,Disease progression,Gemcitabine,FO059937,60,Progression NOS +DO0636,Male,Liver,Alive,PD059938,57,C22.0,AJCC 8th edition,Stage II,SP059939,Primary tumour,Solid tissue,SP059939,Total DNA,TR059938,Surgery,5,1,Complete response,None,FO059938,120,Stable +DO0637,Female,Cervix uteri,Alive,PD059939,46,C53.0,FIGO staging system,Stage IB,SP059940,Primary tumour,Solid tissue,SP059940,Total DNA,TR059939,Radiation therapy,20,40,Complete response,None,FO059939,180,No evidence of disease +DO0638,Male,Bladder,Alive,PD059940,74,C67.2,AJCC 8th edition,Stage I,SP059941,Primary tumour,Solid tissue,SP059941,Total DNA,TR059940,Surgery,0,1,Complete response,None,FO059940,90,Stable +DO0639,Female,Breast,Alive,PD059941,52,C50.3,AJCC 8th edition,Stage IIA,SP059942,Primary tumour,Solid tissue,SP059942,Total DNA,TR059941,Chemotherapy,30,90,Complete response,TC,FO059941,150,Complete remission +DO0640,Male,Prostate gland,Alive,PD059942,69,C61,Gleason grade group system,Grade Group 3,SP059943,Primary tumour,Solid tissue,SP059943,Total DNA,TR059942,Hormonal therapy,15,240,Partial response,Enzalutamide,FO059942,120,Stable +DO0641,Female,Ovary,Deceased,PD059943,59,C56,FIGO staging system,Stage IV,SP059944,Primary tumour,Solid tissue,SP059944,Total DNA,TR059943,Chemotherapy,25,90,Disease progression,Paclitaxel,FO059943,75,Progression NOS +DO0642,Male,Kidney,Alive,PD059944,55,C64.9,AJCC 8th edition,Stage II,SP059945,Primary tumour,Solid tissue,SP059945,Total DNA,TR059944,Surgery,10,1,Complete response,None,FO059944,180,No evidence of disease +DO0643,Female,Thyroid gland,Alive,PD059945,40,C73,AJCC 8th edition,Stage I,SP059946,Primary tumour,Solid tissue,SP059946,Total DNA,TR059945,Surgery,5,1,Complete response,None,FO059945,240,Stable +DO0644,Male,Stomach,Deceased,PD059946,72,C16.4,AJCC 8th edition,Stage IIIB,SP059947,Primary tumour,Solid tissue,SP059947,Total DNA,TR059946,Chemotherapy,20,60,Disease progression,FLOT,FO059946,90,Progression NOS +DO0645,Female,Lung,Alive,PD059947,61,C34.3,AJCC 8th edition,Stage IIB,SP059948,Primary tumour,Solid tissue,SP059948,Total DNA,TR059947,Chemotherapy,35,75,Partial response,Pemetrexed,FO059947,120,Stable +DO0646,Male,Brain,Deceased,PD059948,54,C71.2,AJCC 8th edition,Stage IV,SP059949,Primary tumour,Solid tissue,SP059949,Total DNA,TR059948,Radiation therapy,15,30,Disease progression,None,FO059948,45,Progression NOS +DO0647,Female,Breast,Alive,PD059949,48,C50.4,AJCC 8th edition,Stage I,SP059950,Primary tumour,Solid tissue,SP059950,Total DNA,TR059949,Surgery,0,1,Complete response,None,FO059949,180,No evidence of disease +DO0648,Male,Colon,Alive,PD059950,65,C18.7,AJCC 8th edition,Stage IIIA,SP059951,Primary tumour,Solid tissue,SP059951,Total DNA,TR059950,Chemotherapy,25,120,Complete response,CAPOX,FO059950,150,Stable +DO0649,Female,Pancreas,Deceased,PD059951,70,C25.1,AJCC 8th edition,Stage IV,SP059952,Primary tumour,Solid tissue,SP059952,Total DNA,TR059951,Chemotherapy,10,60,Disease progression,FOLFIRINOX,FO059951,75,Progression NOS \ No newline at end of file diff --git a/data/document.json b/data/document.json new file mode 100644 index 00000000..fbea83e9 --- /dev/null +++ b/data/document.json @@ -0,0 +1,47 @@ +{ + "data": { + "gender": "Female", + "donor_id": "DO0603", + "vital_status": "Deceased", + "diagnosis": [ + { + "stage": "Stage IIIC", + "donor_id": "DO0603", + "cancer_type": "C56", + "diagnosis_id": "PD059905", + "primary_site": "Ovary", + "staging_system": "FIGO staging system", + "age_at_diagnosis": 58, + "followup": [ + { + "followup_id": "FO059905", + "diagnosis_id": "PD059905", + "disease_status": "Progression NOS", + "followup_interval": 150 + } + ], + "specimen": [ + { + "sample_id": "SP059906", + "sample_type": "Total DNA", + "specimen_id": "SP059906", + "diagnosis_id": "PD059905", + "specimen_type": "Primary tumour", + "tissue_source": "Solid tissue" + } + ], + "treatment": [ + { + "drug_name": "Carboplatin", + "diagnosis_id": "PD059905", + "treatment_id": "TR059905", + "treatment_type": "Chemotherapy", + "treatment_start": 20, + "treatment_duration": 120, + "treatment_response": "Disease progression" + } + ] + } + ] + } +} diff --git a/guideMaterials/dataSubmission/SP059902.snv.vcf.gz b/data/fileData/SP059902.snv.vcf.gz similarity index 100% rename from guideMaterials/dataSubmission/SP059902.snv.vcf.gz rename to data/fileData/SP059902.snv.vcf.gz diff --git a/guideMaterials/dataSubmission/SP059902.snv.vcf.gz.tbi b/data/fileData/SP059902.snv.vcf.gz.tbi similarity index 100% rename from guideMaterials/dataSubmission/SP059902.snv.vcf.gz.tbi rename to data/fileData/SP059902.snv.vcf.gz.tbi diff --git a/data/fileData/file-metadata.json b/data/fileData/file-metadata.json new file mode 100644 index 00000000..cf31c685 --- /dev/null +++ b/data/fileData/file-metadata.json @@ -0,0 +1,51 @@ +{ + "studyId": "demo", + "analysisType": { + "name": "MyNewSchema" + }, + "files": [ + { + "dataType": "Raw SV Calls", + "fileName": "SP059902.snv.vcf.gz", + "fileSize": 17246, + "fileMd5sum": "94b790078d8e98ad08ffc42389e2fa68", + "fileAccess": "open", + "fileType": "VCF", + "info": { + "dataCategory": "Simple Nucelotide Variation", + "jbrowseCoordinates": "hg38:chr1:100000-200000" + } + }, + { + "dataType": "Raw SV Calls", + "fileName": "SP059902.snv.vcf.gz.tbi", + "fileSize": 141, + "fileMd5sum": "f5cca6ace25d076d1f76cebf4ce3defd", + "fileAccess": "open", + "fileType": "TBI", + "info": { + "dataCategory": "Simple Nucelotide Variation", + "jbrowseCoordinates": "hg38:chr1:100000-200000" + } + } + ], + "workflow": { + "workflowName": "Mutect2 Variant Calling", + "workflowShortName": "Mutect2Variant", + "workflowVersion": "0.1.1.1", + "inputs": [ + { + "analysisType": "sequencing_alignment", + "analysisId": "00000000-0000-0000-0000-0000000000599" + } + ], + "runId": "RI0599", + "sessionId": "SI0599" + }, + "experiment": { + "platform": "PacBio", + "experimentalStrategy": "WXS", + "sequencingCenter": "CGTA", + "sequencingDate": "2021-03-08T19:00:00.000Z" + } +} diff --git a/data/readme.md b/data/readme.md new file mode 100644 index 00000000..60034696 --- /dev/null +++ b/data/readme.md @@ -0,0 +1,25 @@ +# Data Folder + +This folder is for storing data files used in your project. Below are guidelines +for optimal data management: + +## File Format + +- The composer supports configurable delimiters, but CSV (Comma-Separated + Values) is the recommended format for tabular data +- Include headers in your CSV files for clear column identification your + elasticsearch index mapping should match these field names + +## Data Security + +- If storing sensitive data, add your data files to `.gitignore` before + committing to GitHub +- If pushing data files to github review them for any personally identifiable + information (PII) before committing + +## Dataset Size + +- Use representative sample datasets of approximately 500 records for + development and testing +- No strict minimum or maximum size limits exist beyond Docker and Elasticsearch + resource constraints diff --git a/data/sampleData.csv b/data/sampleData.csv new file mode 100644 index 00000000..5a11655b --- /dev/null +++ b/data/sampleData.csv @@ -0,0 +1,29 @@ +Name,Profile,Ranking +Linda Xiang,Bioinformatician, +Hardeep Nahal,Bioinformatician, +Jon Eubank,Software Developer, +Ann Catton,Software Developer, +Andres Melani,PhD Student, +Ciaran Schutte,Software Developer, +Brandon Chan,Business Analyst, +Alexis Li,Software Developer, +Samantha Rich,Software Developer, +Henrich Feher,Cloud Systems Architect, +Bhavik Bhagat,Business Analyst, +Justin Richardsson,Software Developer, +Rakesh Mistry,Software Developer, +Yelizar Alturmessov,DevOps Engineer, +Dan DeMaria,Software Developer, +Edmund Su,Bioinformatician, +James Lopez,Software Developer, +Jochen Weile,Data Scientist, +Robin Haw,Program Manager, +Ryan Seeto,Data Scientists, +Leonardo Rivera,Software Developer, +Patrick Dos Santos,Senior UI/UX designer, +Mitchell Shiell,Outreach Coordinator, +Azher Ali Mohammed,Software Developer, +Sunnie Kapar,Software Developer, +Tony Yu,Masters Student, +Patrick Dos Santos, UI/UX Designer, +Mitchell Shiell, Product Manager \ No newline at end of file diff --git a/data/segmentedData/diagnosis.csv b/data/segmentedData/diagnosis.csv new file mode 100644 index 00000000..6f481d03 --- /dev/null +++ b/data/segmentedData/diagnosis.csv @@ -0,0 +1,52 @@ +diagnosis_id,donor_id,primary_site,age_at_diagnosis,cancer_type,staging_system,stage +PD059901,DO0599,Trachea,50,C34.2,Binet staging system,Stage A +PD059902,DO0600,Brain,45,C71.0,AJCC 8th edition,Stage II +PD059903,DO0601,Breast,62,C50.1,AJCC 8th edition,Stage IIA +PD059904,DO0602,Prostate gland,71,C61,Gleason grade group system,Grade Group 2 +PD059905,DO0603,Ovary,58,C56,FIGO staging system,Stage IIIC +PD059906,DO0604,Lung,67,C34.1,AJCC 8th edition,Stage IIIA +PD059907,DO0605,Thyroid gland,43,C73,AJCC 8th edition,Stage I +PD059908,DO0606,Colon,59,C18.2,AJCC 8th edition,Stage IIB +PD059909,DO0607,Pancreas,64,C25.0,AJCC 8th edition,Stage IV +PD059910,DO0608,Liver,55,C22.0,AJCC 8th edition,Stage II +PD059911,DO0609,Cervix uteri,48,C53.0,FIGO staging system,Stage IB +PD059912,DO0610,Bladder,72,C67.0,AJCC 8th edition,Stage I +PD059913,DO0611,Breast,51,C50.2,AJCC 8th edition,Stage IIA +PD059914,DO0612,Prostate gland,68,C61,Gleason grade group system,Grade Group 3 +PD059915,DO0613,Ovary,61,C56,FIGO staging system,Stage IV +PD059916,DO0614,Kidney,57,C64.9,AJCC 8th edition,Stage II +PD059917,DO0615,Thyroid gland,39,C73,AJCC 8th edition,Stage I +PD059918,DO0616,Stomach,70,C16.0,AJCC 8th edition,Stage IIIB +PD059919,DO0617,Lung,63,C34.3,AJCC 8th edition,Stage IIB +PD059920,DO0618,Brain,52,C71.2,AJCC 8th edition,Stage IV +PD059921,DO0619,Breast,47,C50.4,AJCC 8th edition,Stage I +PD059922,DO0620,Colon,66,C18.7,AJCC 8th edition,Stage IIIA +PD059923,DO0621,Pancreas,69,C25.1,AJCC 8th edition,Stage IV +PD059924,DO0622,Liver,58,C22.0,AJCC 8th edition,Stage II +PD059925,DO0623,Cervix uteri,44,C53.1,FIGO staging system,Stage IIA +PD059926,DO0624,Bladder,73,C67.1,AJCC 8th edition,Stage I +PD059927,DO0625,Breast,54,C50.1,AJCC 8th edition,Stage IIB +PD059928,DO0626,Prostate gland,65,C61,Gleason grade group system,Grade Group 2 +PD059929,DO0627,Ovary,60,C56,FIGO staging system,Stage IIIC +PD059930,DO0628,Kidney,56,C64.9,AJCC 8th edition,Stage I +PD059931,DO0629,Thyroid gland,41,C73,AJCC 8th edition,Stage I +PD059932,DO0630,Stomach,71,C16.3,AJCC 8th edition,Stage IV +PD059933,DO0631,Lung,62,C34.1,AJCC 8th edition,Stage IIIA +PD059934,DO0632,Brain,53,C71.6,AJCC 8th edition,Stage IV +PD059935,DO0633,Breast,49,C50.2,AJCC 8th edition,Stage I +PD059936,DO0634,Colon,67,C18.5,AJCC 8th edition,Stage IIIB +PD059937,DO0635,Pancreas,68,C25.2,AJCC 8th edition,Stage IV +PD059938,DO0636,Liver,57,C22.0,AJCC 8th edition,Stage II +PD059939,DO0637,Cervix uteri,46,C53.0,FIGO staging system,Stage IB +PD059940,DO0638,Bladder,74,C67.2,AJCC 8th edition,Stage I +PD059941,DO0639,Breast,52,C50.3,AJCC 8th edition,Stage IIA +PD059942,DO0640,Prostate gland,69,C61,Gleason grade group system,Grade Group 3 +PD059943,DO0641,Ovary,59,C56,FIGO staging system,Stage IV +PD059944,DO0642,Kidney,55,C64.9,AJCC 8th edition,Stage II +PD059945,DO0643,Thyroid gland,40,C73,AJCC 8th edition,Stage I +PD059946,DO0644,Stomach,72,C16.4,AJCC 8th edition,Stage IIIB +PD059947,DO0645,Lung,61,C34.3,AJCC 8th edition,Stage IIB +PD059948,DO0646,Brain,54,C71.2,AJCC 8th edition,Stage IV +PD059949,DO0647,Breast,48,C50.4,AJCC 8th edition,Stage I +PD059950,DO0648,Colon,65,C18.7,AJCC 8th edition,Stage IIIA +PD059951,DO0649,Pancreas,70,C25.1,AJCC 8th edition,Stage IV \ No newline at end of file diff --git a/data/segmentedData/donor.csv b/data/segmentedData/donor.csv new file mode 100644 index 00000000..d9a49655 --- /dev/null +++ b/data/segmentedData/donor.csv @@ -0,0 +1,52 @@ +donor_id,gender,vital_status +DO0599,Female,Alive +DO0600,Male,Alive +DO0601,Female,Alive +DO0602,Male,Alive +DO0603,Female,Deceased +DO0604,Male,Alive +DO0605,Female,Alive +DO0606,Male,Alive +DO0607,Female,Deceased +DO0608,Male,Alive +DO0609,Female,Alive +DO0610,Male,Alive +DO0611,Female,Alive +DO0612,Male,Alive +DO0613,Female,Deceased +DO0614,Male,Alive +DO0615,Female,Alive +DO0616,Male,Deceased +DO0617,Female,Alive +DO0618,Male,Deceased +DO0619,Female,Alive +DO0620,Male,Alive +DO0621,Female,Deceased +DO0622,Male,Alive +DO0623,Female,Alive +DO0624,Male,Alive +DO0625,Female,Alive +DO0626,Male,Alive +DO0627,Female,Deceased +DO0628,Male,Alive +DO0629,Female,Alive +DO0630,Male,Deceased +DO0631,Female,Alive +DO0632,Male,Deceased +DO0633,Female,Alive +DO0634,Male,Alive +DO0635,Female,Deceased +DO0636,Male,Alive +DO0637,Female,Alive +DO0638,Male,Alive +DO0639,Female,Alive +DO0640,Male,Alive +DO0641,Female,Deceased +DO0642,Male,Alive +DO0643,Female,Alive +DO0644,Male,Deceased +DO0645,Female,Alive +DO0646,Male,Deceased +DO0647,Female,Alive +DO0648,Male,Alive +DO0649,Female,Deceased \ No newline at end of file diff --git a/data/segmentedData/followup.csv b/data/segmentedData/followup.csv new file mode 100644 index 00000000..de0ec1aa --- /dev/null +++ b/data/segmentedData/followup.csv @@ -0,0 +1,52 @@ +treatment_id,followup_id,followup_interval,disease_status +TR059951,FO059901,45,Stable +TR059950,FO059902,60,Stable +TR059949,FO059903,90,Complete remission +TR059948,FO059904,120,Stable +TR059947,FO059905,150,Progression NOS +TR059946,FO059906,80,Stable +TR059945,FO059907,180,No evidence of disease +TR059944,FO059908,120,Stable +TR059943,FO059909,60,Progression NOS +TR059942,FO059910,90,Stable +TR059941,FO059911,150,No evidence of disease +TR059940,FO059912,120,Stable +TR059939,FO059913,180,Complete remission +TR059938,FO059914,150,Stable +TR059937,FO059915,120,Progression NOS +TR059936,FO059916,90,No evidence of disease +TR059935,FO059917,240,Stable +TR059934,FO059918,90,Progression NOS +TR059933,FO059919,120,Stable +TR059932,FO059920,45,Progression NOS +TR059931,FO059921,180,No evidence of disease +TR059930,FO059922,150,Stable +TR059929,FO059923,75,Progression NOS +TR059928,FO059924,120,Stable +TR059927,FO059925,180,No evidence of disease +TR059926,FO059926,90,Stable +TR059925,FO059927,150,Complete remission +TR059924,FO059928,120,Stable +TR059923,FO059929,90,Progression NOS +TR059922,FO059930,180,No evidence of disease +TR059921,FO059931,240,Stable +TR059920,FO059932,60,Progression NOS +TR059919,FO059933,120,Stable +TR059918,FO059934,45,Progression NOS +TR059917,FO059935,180,No evidence of disease +TR059916,FO059936,150,Stable +TR059915,FO059937,60,Progression NOS +TR059914,FO059938,120,Stable +TR059913,FO059939,180,No evidence of disease +TR059912,FO059940,90,Stable +TR059911,FO059941,150,Complete remission +TR059910,FO059942,120,Stable +TR059909,FO059943,75,Progression NOS +TR059908,FO059944,180,No evidence of disease +TR059907,FO059945,240,Stable +TR059906,FO059946,90,Progression NOS +TR059905,FO059947,120,Stable +TR059904,FO059948,45,Progression NOS +TR059903,FO059949,180,No evidence of disease +TR059902,FO059950,150,Stable +TR059901,FO059951,75,Progression NOS \ No newline at end of file diff --git a/data/segmentedData/treatment.csv b/data/segmentedData/treatment.csv new file mode 100644 index 00000000..b8dcda32 --- /dev/null +++ b/data/segmentedData/treatment.csv @@ -0,0 +1,52 @@ +donor_id,treatment_id,treatment_type,treatment_start,treatment_duration,treatment_response +DO0649,TR059901,Chemotherapy,58,52,Complete response +DO0648,TR059902,Radiation therapy,30,45,Partial response +DO0647,TR059903,Chemotherapy,45,90,Complete response +DO0646,TR059904,Hormonal therapy,15,180,Partial response +DO0645,TR059905,Chemotherapy,20,120,Disease progression +DO0644,TR059906,Chemotherapy,40,60,Partial response +DO0643,TR059907,Surgery,10,1,Complete response +DO0642,TR059908,Chemotherapy,25,84,Complete response +DO0641,TR059909,Chemotherapy,15,45,Disease progression +DO0640,TR059910,Surgery,5,1,Complete response +DO0639,TR059911,Radiation therapy,20,40,Complete response +DO0638,TR059912,Surgery,0,1,Complete response +DO0637,TR059913,Chemotherapy,30,120,Complete response +DO0636,TR059914,Hormonal therapy,10,240,Partial response +DO0635,TR059915,Chemotherapy,25,90,Disease progression +DO0634,TR059916,Surgery,15,1,Complete response +DO0633,TR059917,Surgery,5,1,Complete response +DO0632,TR059918,Chemotherapy,20,60,Partial response +DO0631,TR059919,Chemotherapy,35,75,Complete response +DO0630,TR059920,Radiation therapy,15,30,Disease progression +DO0629,TR059921,Surgery,0,1,Complete response +DO0628,TR059922,Chemotherapy,25,120,Partial response +DO0627,TR059923,Chemotherapy,10,60,Disease progression +DO0626,TR059924,Surgery,5,1,Complete response +DO0625,TR059925,Radiation therapy,20,45,Complete response +DO0624,TR059926,Surgery,0,1,Complete response +DO0623,TR059927,Chemotherapy,30,90,Complete responsea +DO0622,TR059928,Hormonal therapy,15,180,Partial response +DO0621,TR059929,Chemotherapy,25,120,Disease progression +DO0620,TR059930,Surgery,10,1,Complete response +DO0619,TR059931,Surgery,5,1,Complete response +DO0618,TR059932,Chemotherapy,20,45,Disease progression +DO0617,TR059933,Chemotherapy,35,60,Partial response +DO0616,TR059934,Radiation therapy,15,30,Disease progression +DO0615,TR059935,Surgery,0,1,Complete response +DO0614,TR059936,Chemotherapy,25,120,Partial response +DO0613,TR059937,Chemotherapy,10,45,Disease progression +DO0612,TR059938,Surgery,5,1,Complete response +DO0611,TR059939,Radiation therapy,20,40,Complete response +DO0610,TR059940,Surgery,0,1,Complete response +DO0609,TR059941,Chemotherapy,30,90,Complete response +DO0608,TR059942,Hormonal therapy,15,240,Partial response +DO0607,TR059943,Chemotherapy,25,90,Disease progression +DO0606,TR059944,Surgery,10,1,Complete response +DO0605,TR059945,Surgery,5,1,Complete response +DO0604,TR059946,Chemotherapy,20,60,Disease progression +DO0603,TR059947,Chemotherapy,35,75,Partial response +DO0602,TR059948,Radiation therapy,15,30,Disease progression +DO0601,TR059949,Surgery,0,1,Complete response +DO0600,TR059950,Chemotherapy,25,120,Complete response +DO0599,TR059951,Chemotherapy,10,60,Disease progression \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 3c405f50..1026775c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,251 +1,525 @@ services: + # ================================================================================== # + # This compose breaks down data portal deployment into three phased steps such that # + # teams can systematically verify requirements and user workflows while minimizing # + # technical overhead. The conductor service below manages all deployments using # + # scripts to automate general setup and configuration. # + # ================================================================================== # conductor: - profiles: ["platform", "songDev", "scoreDev", "maestroDev", "arrangerDev", "stageDev"] + profiles: ["phase1", "phase2", "phase3", "stageDev", "default"] image: alpine/curl:8.8.0 container_name: conductor ports: - - "9204:9204" + - "9204:9204" volumes: - - ./persistentStorage/data-keycloak-db:/keycloak/db-folder-init - - ./persistentStorage/data-song-db:/song/db-folder-init - - ./configurationFiles/elasticsearchConfigs/quickstart_index_template.json:/usr/share/elasticsearch/config/quickstart_index_template.json - - ./configurationFiles/elasticsearchConfigs/es-docs:/es-docs - - ./conductorScripts:/scripts - - ./health:/health + - ./data:/data + - ./apps/conductor/volumes/health:/health + - ./apps/composer/:/composer + - ./apps/conductor/:/conductor environment: - - PROFILE=${PROFILE:-platform} + # Global Configuration + PROFILE: ${PROFILE:-default} + DEBUG: false + # Elasticsearch Index Configuration + # Dynamic indices are configured with a count and indexed variables + ES_INDEX_COUNT: 1 + # First index + ES_INDEX_0_NAME: datatable1-index + ES_INDEX_0_TEMPLATE_FILE: conductor/configs/elasticsearchConfigs/datatable1-mapping.json + ES_INDEX_0_TEMPLATE_NAME: datatable1-index + ES_INDEX_0_ALIAS_NAME: datatable1_centric + # Second index + # ES_INDEX_1_NAME: file-index + # ES_INDEX_1_TEMPLATE_FILE: conductor/configs/elasticsearchConfigs/file_data_index_template.json + # ES_INDEX_1_TEMPLATE_NAME: file_template + # ES_INDEX_1_ALIAS_NAME: file_centric + # Arranger Services Configuration + # Dynamically configurable number of Arranger instances + ARRANGER_COUNT: 1 + ARRANGER_0_URL: http://arranger-datatable1:5050 + ARRANGER_1_URL: http://arranger-datatable2:5051 + # ARRANGER_2_URL: http://arranger-datatable3:5052 + # Add more ARRANGER_X_URL as needed, matching ARRANGER_COUNT + # ARRANGER_X_URL: http://arranger-x:505X + # Service Connections + ES_USER: elastic + ES_PASS: myelasticpassword + ES_URL: http://elasticsearch:9200 + STAGE_URL: http://stage:3000 + LECTERN_URL: http://lectern:3031 + LYRIC_URL: http://lyric:3030 + SONG_URL: http://song:8080 + SCORE_URL: http://score:8087 + MAESTRO_URL: http://maestro:11235 + OBJECT_STORAGE_URL: http://minio:9000 command: > sh -c ' set -e - echo "Profile is set to: $PROFILE" - case "$PROFILE" in - platform) - echo "Running platform deployment..." - chmod +x scripts/deployments/platform.sh - scripts/deployments/platform.sh - ;; - stageDev) - echo "Running Stage development environment..." - chmod +x scripts/deployments/stageDev.sh - scripts/deployments/stageDev.sh - ;; - arrangerDev) - echo "Running Arranger development environment..." - chmod +x scripts/deployments/arrangerDev.sh - scripts/deployments/arrangerDev.sh - ;; - maestroDev) - echo "Running Maestro development environment..." - chmod +x scripts/deployments/maestroDev.sh - scripts/deployments/maestroDev.sh - ;; - songDev) - echo "Running Song development environment..." - chmod +x scripts/deployments/songDev.sh - scripts/deployments/songDev.sh - ;; - scoreDev) - echo "Running Score development environment..." - chmod +x scripts/deployments/scoreDev.sh - scripts/deployments/scoreDev.sh - ;; - *) - echo "Invalid profile: $PROFILE. Available options are [platform, songDev, scoreDev, maestroDev, arrangerDev, stageDev]." - exit 1 - ;; - esac + echo "Profile is set to: $PROFILE" + case "$PROFILE" in + "phase1") + echo "Running phase1 deployment..." + chmod +x conductor/scripts/deployments/phase1.sh + conductor/scripts/deployments/phase1.sh + ;; + "phase2") + echo "Running phase2 deployment..." + chmod +x conductor/scripts/deployments/phase2.sh + conductor/scripts/deployments/phase2.sh + ;; + "phase3") + echo "Running phase3 deployment ..." + chmod +x conductor/scripts/deployments/phase3.sh + conductor/scripts/deployments/phase3.sh + ;; + "stageDev") + echo "Running Stage Dev deployment..." + chmod +x conductor/scripts/deployments/stageDev.sh + conductor/scripts/deployments/stageDev.sh + ;; + *) + echo "Invalid profile specified." + exit 1 + ;; + esac exit 0 ' healthcheck: - test: ["CMD", "test", "-f", "/health/conductor_health"] + test: ["CMD", "test", "-f", "conductor/volumes/health/conductor_health"] interval: 5s timeout: 40s retries: 100 start_period: 30s + networks: + - conductor-network - # ================================================================================== - # OAuth (KeyCloak) - # ================================================================================== - - # ====================================== - # Keycloak Database - # -------------------------------------- - # Pre-populated with a system wide API key: 68fb42b4-f1ed-4e8c-beab-3724b99fe528, required for Songs SCORE_ACCESSTOKEN env variable - # Documentation Link: https://www.overture.bio/documentation/guides/deployment/oauth/#setting-up-the-keycloak-database - # -------------------------------------- - keycloak-db: - profiles: ["platform", "songDev" , "scoreDev" ,"maestroDev", "stageDev"] - depends_on: - - conductor - image: postgres:14 + # ================================================================================== # + # ================================================================================== # + # phase1: # + # Search & Discovery # + # ================================================================================== # + # phase1 focuses on how you want your data displayed in the front-end portal. # + # Here you want to figure out how many data tables (Arrangers) you want and how you # + # want them configured. This is also a good time to do any theming of your portal. # + # through Stage. # + # ================================================================================== # + + # --------------------------------------------------------------------------------------# + # Elasticsearch # + # --------------------------------------------------------------------------------------# + # A search and analytics engine used to help query massive datatables. # + # Documentation Link: # + # https://www.elastic.co/guide/en/elasticsearch/reference/7.17/elasticsearch-intro.html # + # --------------------------------------------------------------------------------------# + elasticsearch: + profiles: ["phase1", "phase2", "phase3", "stageDev", "default"] + image: docker.elastic.co/elasticsearch/elasticsearch:7.17.27 + container_name: elasticsearch platform: linux/amd64 - container_name: keycloak-db + ports: + - "9200:9200" environment: - POSTGRES_USER: admin - POSTGRES_PASSWORD: admin123 - POSTGRES_DB: keycloakDb + discovery.type: single-node + cluster.name: workflow.elasticsearch + ES_JAVA_OPTS: -Xms512m -Xmx2048m + ES_USER: elastic + ELASTIC_PASSWORD: myelasticpassword + xpack.security.enabled: "true" + logging: + driver: "json-file" + options: + max-size: "50m" + max-file: "10" volumes: - - ./persistentStorage/data-keycloak-db:/var/lib/postgresql/data + - elasticsearch-data:/usr/share/configs/elasticsearch/data healthcheck: - test: ["CMD-SHELL", "pg_isready -U admin -d keycloakDb"] - interval: 20s + test: + "curl --silent --fail localhost:9200/_cluster/health?wait_for_status=yellow&timeout=50s || + exit 1" + interval: 10s timeout: 10s - retries: 10 - start_period: 20s - - # ========================== - # Keycloak - # ========================== - # Authorization and authentication service - # Documentation Link: https://www.overture.bio/documentation/guides/deployment/oauth/#setting-up-keycloak - # -------------------------------------- - keycloak: - profiles: ["platform", "songDev", "scoreDev", "maestroDev", "stageDev"] - image: quay.io/keycloak/keycloak:22.0 - container_name: keycloak + retries: 5 + start_period: 25s + networks: + - conductor-network + + # ------------------------------------------------------------------------------------# + # Arranger-Server for our tabular data # + # ------------------------------------------------------------------------------------# + # Search API generation with compatible search UI components # + # Documentation Link: https://docs.overture.bio/docs/core-software/Arranger/overview # + # ------------------------------------------------------------------------------------# + arranger-datatable1: + profiles: ["phase1", "phase2", "phase3", "stageDev", "default"] + image: ghcr.io/overture-stack/arranger-server:3.0.0-beta.36 + container_name: arranger-datatable1 platform: linux/amd64 depends_on: - keycloak-db: + conductor: condition: service_healthy ports: - - "8180:8080" + - "5050:5050" + volumes: + - ./apps/conductor/configs/arrangerConfigs/datatable1:/app/modules/server/configs environment: - # Postgres Variables - KC_DB: postgres - KC_DB_USERNAME: admin - KC_DB_PASSWORD: admin123 - KC_DB_URL: jdbc:postgresql://keycloak-db:5432/keycloakDb - # Keycloak Variables - KEYCLOAK_ADMIN: admin - KEYCLOAK_ADMIN_PASSWORD: admin123 - KC_HOSTNAME: localhost - KC_HEALTH_ENABLED: true + # Elasticsearch Variables + ES_HOST: http://elasticsearch:9200 + ES_USER: elastic + ES_PASS: myelasticpassword + ES_ARRANGER_SET_INDEX: data_arranger_set + # Arranger Variables (Port required) + PORT: 5050 + DEBUG: false + ENABLE_LOGS: false + networks: + - conductor-network + + arranger-datatable2: + profiles: ["phase1", "phase2", "phase3", "stageDev", "default"] + image: ghcr.io/overture-stack/arranger-server:3.0.0-beta.36 + container_name: arranger-datatable2 + platform: linux/amd64 + depends_on: + conductor: + condition: service_healthy + ports: + - "5051:5051" # Use unique ports for each Arranger instance volumes: - - ./configurationFiles/keycloakConfigs/keycloak-apikeys-1.0.1.jar:/opt/keycloak/providers/keycloak-apikeys.jar - - ./configurationFiles/keycloakConfigs/myrealm-realm.json:/opt/keycloak/data/import/myrealm-realm.json - - ./configurationFiles/keycloakConfigs/myrealm-users-0.json:/opt/keycloak/data/import/myrealm-users-0.json - command: > - start-dev - --import-realm - --hostname-port=8180 - - # ================================================================================== - # File Management (Song, Score, Kafka, Minio) - # ================================================================================== - - # ====================================== - # Kafka - # ====================================== - # Messaging system for Song and Maestro, used to orchestrate asynchronous communication, job execution, queuing, and processing. - # Documentation Link: https://www.overture.bio/documentation/guides/deployment/datamanagement/#running-kafka - # -------------------------------------- - kafka: - profiles: ["platform", "maestroDev"] - image: confluentinc/cp-kafka:7.6.1 - container_name: kafka - platform: linux/amd64 - ports: - - "9092:9092" - - "29092:29092" - volumes: - - ./conductorScripts/services/kafkaSetup.sh:/scripts/kafkaSetup.sh - environment: - # Core Kafka Configuration - KAFKA_PROCESS_ROLES: broker,controller - KAFKA_NODE_ID: 1 - KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092,EXTERNAL://localhost:29092 - KAFKA_LISTENERS: PLAINTEXT://kafka:9092,EXTERNAL://0.0.0.0:29092,CONTROLLER://kafka:9093 - KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,EXTERNAL:PLAINTEXT,CONTROLLER:PLAINTEXT - KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT - KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka:9093 - KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER - # Storage Configuration - KAFKA_LOG_DIRS: /var/lib/kafka/data - KAFKA_LOG_RETENTION_HOURS: 168 # 7 days - KAFKA_LOG_RETENTION_BYTES: -1 # Unlimited size - # Topic Configuration - KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1 - KAFKA_AUTO_CREATE_TOPICS_ENABLE: false - KAFKA_NUM_PARTITIONS: 1 - KAFKA_DEFAULT_REPLICATION_FACTOR: 1 - KAFKA_MIN_INSYNC_REPLICAS: 1 - # Performance Tuning - KAFKA_MESSAGE_MAX_BYTES: 5242880 # 5MB max message size - KAFKA_REPLICA_FETCH_MAX_BYTES: 5242880 - # Logging Configuration - KAFKA_LOG4J_LOGGERS: "kafka.controller=INFO,kafka.producer.async.DefaultEventHandler=INFO,state.change.logger=INFO" - KAFKA_LOG4J_ROOT_LOGLEVEL: INFO - # Cluster Configuration - CLUSTER_ID: "q1Sh-9_ISia_zwGINzRvyQ" - command: > - sh -c ' - echo "Setting up Kafka..." - chmod +x /scripts/kafkaSetup.sh - /scripts/kafkaSetup.sh & - - # Start Kafka broker - /etc/confluent/docker/run - ' - healthcheck: - test: - - "CMD-SHELL" - - > - /bin/kafka-topics --bootstrap-server kafka:9092 --list - interval: 10s - timeout: 5s - retries: 10 + - ./apps/conductor/configs/arrangerConfigs/datatable2:/app/modules/server/configs # Point to the relevant generated config + environment: + # Elasticsearch Variables + ES_HOST: http://elasticsearch:9200 + ES_USER: elastic + ES_PASS: myelasticpassword + ES_ARRANGER_SET_INDEX: datatable2_arranger_set + # Arranger Variables + PORT: 5051 # Required + DEBUG: false + ENABLE_LOGS: false + networks: + - conductor-network - # ====================================== - # Song Database - # ====================================== - # Postgres database populated with 30 pre-published analyses (metadata files) - # Documentation Link: https://www.overture.bio/documentation/guides/deployment/datamanagement/#running-song - # -------------------------------------- - song-db: - profiles: ["platform", "songDev", "scoreDev", "maestroDev"] + # arranger-datatable3: + # profiles: ["phase1", "phase2", "phase3", "stageDev", "default"] + # image: ghcr.io/overture-stack/arranger-server:3.0.0-beta.36 + # container_name: arranger-datatable3 + # platform: linux/amd64 + # depends_on: + # conductor: + # condition: service_healthy + # ports: + # - "5052:5052" # Use unique ports for each Arranger instance + # volumes: + # - ./apps/conductor/configs/arrangerConfigs/datatable3:/app/modules/server/configs # Point to the relevant generated config + # environment: + # # Elasticsearch Variables + # ES_HOST: http://elasticsearch:9200 + # ES_USER: elastic + # ES_PASS: myelasticpassword + # ES_ARRANGER_SET_INDEX: datatable3_arranger_set + # # Arranger Variables + # PORT: 5052 # Required + # DEBUG: false + # ENABLE_LOGS: false + # networks: + # - conductor-network + + # ------------------------------------------------------------------------------------# + # Stage # + # ------------------------------------------------------------------------------------# + # The react-based, front end UI scaffolding for Overture # + # Documentation Link: https://docs.overture.bio/docs/core-software/Stage/overview # + # ------------------------------------------------------------------------------------# + stage: + profiles: ["phase1", "phase2", "phase3", "default"] + image: stageimage:1.0 + container_name: stage + pull_policy: never + platform: linux/arm64/v8 depends_on: - - conductor - image: postgres:11.1 - container_name: song-db + conductor: + condition: service_healthy + ports: + - "3000:3000" + environment: + # Stage Variables + NEXTAUTH_URL: http://localhost:3000/api/auth + NEXT_PUBLIC_LAB_NAME: Overture Prelude Portal + NEXT_PUBLIC_ADMIN_EMAIL: example@example.com + NEXT_PUBLIC_DEBUG: false + NEXT_PUBLIC_SHOW_MOBILE_WARNING: true + NEXT_PUBLIC_ENABLE_DOWNLOADS: true + # Datatable1 Arranger Variables + NEXT_PUBLIC_ARRANGER_DATATABLE_1_API: http://arranger-datatable1:5050 + NEXT_PUBLIC_ARRANGER_DATATABLE_1_DOCUMENT_TYPE: file + NEXT_PUBLIC_ARRANGER_DATATABLE_1_INDEX: datatable1_centric + # Datatable2 Arranger Variables + NEXT_PUBLIC_ARRANGER_DATATABLE_2_API: http://arranger-datatable2:5051 + NEXT_PUBLIC_ARRANGER_DATATABLE_2_DOCUMENT_TYPE: file + NEXT_PUBLIC_ARRANGER_DATATABLE_2_INDEX: datatable2_centric + # Datatable2 Arranger Variables + NEXT_PUBLIC_ARRANGER_DATATABLE_3_API: http://arranger-datatable3:5052 + NEXT_PUBLIC_ARRANGER_DATATABLE_3_DOCUMENT_TYPE: file + NEXT_PUBLIC_ARRANGER_DATATABLE_3_INDEX: datatable3_centric + # Using localhost for client-side requests + NEXT_PUBLIC_SONG_API: http://song:8080 + NEXT_PUBLIC_SCORE_API: http://score:8087 + NEXT_PUBLIC_LYRIC_API: http://lyric:3030 + NEXT_PUBLIC_LECTERN_API: http://lectern:3031 + # Auth Variables + NEXTAUTH_SECRET: your-secure-secret-here + # System Alerts + NEXT_PUBLIC_SYSTEM_ALERTS: '[{"level":"info","title":"API Documentation Available","message":"Swagger documentation for Song, Lyric, Lectern, and Score APIs is now available in the Documentation section.","dismissable":true,"id":"api-docs-available"}]' + # CORS Configuration + NEXT_PUBLIC_CORS_ENABLED: "true" + NEXT_PUBLIC_CORS_ALLOWED_ORIGINS: "*" + # File Arranger Variables + NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_API: http://arranger-molecular:5060 + NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_DOCUMENT_TYPE: file + NEXT_PUBLIC_ARRANGER_MOLECULAR_DATA_INDEX: file_centric + NEXT_PUBLIC_ARRANGER_MANIFEST_COLUMNS: repositories.code, analysis.analysis_id, object_id, study_id, file.name, file.size, file.md5sum, file_access, analysis.experiment.acknowledgements.strategy, file.data_type, analysis.experiment.data.sequence_length + volumes: + - stage-data:/usr/src/public/static/dms_user_assets + networks: + - conductor-network + + # ================================================================================== # + # ================================================================================== # + # phase2: # + # Tabular data storage & submission # + # ================================================================================== # + # Here we will focus on implementing our back-end tabular data management services # + # which will include the addition of Lyric, Lectern, LyricDb (Postgres) and a # + # LecternDb (MongoDb). # + # ================================================================================== # + + # -----------------------------------------------------------------------------------# + # Lectern # + # -----------------------------------------------------------------------------------# + # Schema manager that validates and stores collections of data dictionaries. # + # Documentation Link: https://docs.overture.bio/docs/under-development/lectern/ # + # -----------------------------------------------------------------------------------# + lectern: + profiles: ["phase2", "phase3", "default"] + image: ghcr.io/overture-stack/lectern:2.0.0-beta.3 + container_name: lectern platform: linux/amd64 - ports: - - "5433:5432" + depends_on: + lectern-db: + condition: service_healthy + ports: + - "3031:3031" environment: - POSTGRES_USER: admin - POSTGRES_PASSWORD: admin123 - POSTGRES_DB: songDb + PORT: 3031 + OPENAPI_PATH: /api-docs + MONGO_HOST: lectern-db + MONGO_PORT: 27017 + MONGO_DB: lectern + MONGO_USER: admin + MONGO_PASS: admin123 + AUTH_ENABLED: false + VAULT_ENABLED: false + networks: + - conductor-network + + # -----------------------------------------------------------------------------------# + # LecternDb # + # -----------------------------------------------------------------------------------# + # Database used by Lectern to store its schemas. # + # -----------------------------------------------------------------------------------# + lectern-db: + profiles: ["phase2", "phase3", "default"] + image: bitnami/mongodb:4.0 + container_name: lectern-db + platform: linux/amd64 + ports: + - 27017:27017 volumes: - - ./persistentStorage/data-song-db:/var/lib/postgresql/data + - lectern-db-data:/bitnami + environment: + MONGODB_USERNAME: admin + MONGODB_PASSWORD: admin123 + MONGODB_DATABASE: lectern + MONGODB_ROOT_PASSWORD: admin123 healthcheck: - test: ["CMD-SHELL", "pg_isready -U admin -d songDb"] + test: + [ + "CMD", + "mongo", + "--authenticationDatabase", + "admin", + "-u", + "root", + "-p", + "admin123", + "--eval", + "db.adminCommand('ping')", + ] + interval: 10s + timeout: 10s + retries: 5 + start_period: 40s + networks: + - conductor-network + + # -----------------------------------------------------------------------------------# + # Lryic # + # -----------------------------------------------------------------------------------# + # Submit, validate, and manage structured data according to predefined schemas. # + # Documentation Link: https://docs.overture.bio/docs/under-development/lyric/ # + # -----------------------------------------------------------------------------------# + lyric: + profiles: ["phase2", "phase3", "default"] + image: ghcr.io/overture-stack/lyric:0.6.0 + container_name: lyric + platform: linux/amd64 + depends_on: + lyric-db: + condition: service_healthy + lectern: + condition: service_started + ports: + - "3030:3030" + environment: + PORT: 3030 + DB_HOST: lyric-db + DB_PORT: 5432 + DB_NAME: lyricDb + DB_USER: admin + DB_PASSWORD: admin123 + LECTERN_URL: http://lectern:3031 + LOG_LEVEL: debug + AUDIT_ENABLED: false + ID_USELOCAL: true + UPLOAD_LIMIT: "100mb" + PLURALIZE_SCHEMAS_ENABLED: false + networks: + - conductor-network + + # -----------------------------------------------------------------------------------# + # LyricDb # + # -----------------------------------------------------------------------------------# + # Database used by Lyric to store its tabular data. # + # -----------------------------------------------------------------------------------# + lyric-db: + profiles: ["phase2", phase3, "default"] + image: postgres:15-alpine + container_name: lyric-db + platform: linux/amd64 + ports: + - 5434:5432 + environment: + POSTGRES_PASSWORD: admin123 + POSTGRES_USER: admin + POSTGRES_DB: lyricDb + healthcheck: + test: ["CMD-SHELL", "pg_isready -U admin -d lyricDb"] interval: 20s timeout: 10s retries: 10 start_period: 20s - - # ====================================== - # Song - # ====================================== - # Metadata management service with a customizable and automated submission validation system - # Documentation Link: https://www.overture.bio/documentation/guides/deployment/datamanagement/#running-song - # -------------------------------------- - song: - profiles: ["platform", "scoreDev", "maestroDev"] - image: ghcr.io/overture-stack/song-server:5.2.0 - container_name: song + volumes: + - lyric-db-data:/var/lib/postgresql/data + networks: + - conductor-network + + # -----------------------------------------------------------------------------------# + # Maestro # + # -----------------------------------------------------------------------------------# + # Indexs data into Elasticsearch on publication # + # Documentation Link: https://docs.overture.bio/docs/core-software/Maestro/overview # + # Organization === study # + # id === analysisId # + # -----------------------------------------------------------------------------------# + maestro: + profiles: ["phase2", phase3, "default"] + image: ghcr.io/overture-stack/maestro:e868d03 + container_name: maestro platform: linux/amd64 depends_on: - keycloak: + lectern: condition: service_started - kafka: + conductor: condition: service_healthy + ports: + - "11235:11235" + environment: + # Maestro Base Variables + MAESTRO_FAILURELOG_ENABLED: true + MAESTRO_FAILURELOG_DIR: app/logs/maestro + MAESTRO_LOGGING_LEVEL_ROOT: INFO + MAESTRO_DISABLEEVENTINDEXING: true + # Repository Configuration - Lyric + MAESTRO_REPOSITORIES_0_BASE_URL: http://lyric:3030 + # in the old world we added these to each document in elasticsearch, + MAESTRO_REPOSITORIES_0_CODE: lyric.overture + MAESTRO_REPOSITORIES_0_NAME: Overture Lyric + MAESTRO_REPOSITORIES_0_PAGINATION_SIZE: 50 + MAESTRO_REPOSITORIES_0_INDEX_NAME: datatable1-index + MAESTRO_REPOSITORIES_0_TYPE: LYRIC + MAESTRO_REPOSITORIES_0_LYRIC_VALID_DATA_ONLY: true + MAESTRO_REPOSITORIES_0_LYRIC_CATEGORY_ID: 1 + # Elasticsearch Settings (Required) + MAESTRO_ELASTICSEARCH_NODES: http://elasticsearch:9200 + MAESTRO_ELASTICSEARCH_VERSION: 7 + MAESTRO_ELASTICSEARCH_CLIENT_BASICAUTH_ENABLED: true + MAESTRO_ELASTICSEARCH_CLIENT_BASICAUTH_USER: elastic + MAESTRO_ELASTICSEARCH_CLIENT_BASICAUTH_PASSWORD: myelasticpassword + MAESTRO_ELASTICSEARCH_CLIENT_RETRY_MAX_ATTEMPTS: 3 + MAESTRO_ELASTICSEARCH_CLIENT_RETRY_WAIT_DURATION_MILLIS: 500 + MAESTRO_ELASTICSEARCH_CLIENT_DOCS_PER_BULK_REQ_MAX: 5000 + MAESTRO_ELASTICSEARCH_CLIENT_CONNECTION_TIMEOUT: 5000 + # Repository Configuration - Song + MAESTRO_REPOSITORIES_1_BASE_URL: http://song:8080 + MAESTRO_REPOSITORIES_1_CODE: song.overture + MAESTRO_REPOSITORIES_1_NAME: Overture Song + MAESTRO_REPOSITORIES_1_PAGINATION_SIZE: 50 + MAESTRO_REPOSITORIES_1_INDEX_NAME: file-index + MAESTRO_REPOSITORIES_1_TYPE: SONG + MAESTRO_REPOSITORIES_1_SONG_INDEXABLE_STUDY_STATES: PUBLISHED + MAESTRO_REPOSITORIES_1_SONG_ANALYSIS_CENTRIC_ENABLED: true + MAESTRO_REPOSITORIES_1_SONG_ORGANIZATION: OICR + MAESTRO_REPOSITORIES_1_SONG_COUNTRY: CA + volumes: + - maestro-data:/app/app-data + networks: + - conductor-network + + # ================================================================================== # + # ================================================================================== # + # phase3: # + # File data storage & submission # + # ================================================================================== # + # Here we will focus on implementing our back-end file management services which # + # will include the addition of Song, Score, SongDb (Postgres) and an Object # + # Storage provider (Minio). # + # ================================================================================== # + + # ---------------------------------------------------------------------------------- # + # Song # + # ---------------------------------------------------------------------------------- # + # Catalog and manage metadata associated to file data # + # Documentation Link: https://docs.overture.bio/docs/core-software/Song/overview # + # ---------------------------------------------------------------------------------- # + song: + profiles: ["phase3", "default"] + image: ghcr.io/overture-stack/song-server:a81a8e48 + container_name: song + platform: linux/amd64 + depends_on: song-db: condition: service_healthy ports: - "8080:8080" environment: # Spring Variables - SPRING_PROFILES_ACTIVE: prod,secure,kafka + SPRING_PROFILES_ACTIVE: dev, noSecurityDev + # Swagger/OpenAPI Configuration + SPRING_MVC_CORS_ENABLED: "true" + SPRING_MVC_CORS_ALLOWED-ORIGINS: "*" + SPRING_MVC_CORS_ALLOWED-METHODS: "GET,POST,PUT,DELETE,PATCH,OPTIONS" + SPRING_MVC_CORS_ALLOWED-HEADERS: "*" + SPRING_MVC_CORS_ALLOW-CREDENTIALS: "true" # Flyway variables SPRING_FLYWAY_ENABLED: true # Song Variables @@ -253,82 +527,91 @@ services: SCHEMAS_ENFORCELATEST: true # Score Variables SCORE_URL: http://score:8087 - SCORE_ACCESSTOKEN: 68fb42b4-f1ed-4e8c-beab-3724b99fe528 - # Keycloak Variables - AUTH_SERVER_PROVIDER: keycloak - AUTH_SERVER_CLIENTID: dms - AUTH_SERVER_CLIENTSECRET: t016kqXfI648ORoIP5gepqCzqtsRjlcc - AUTH_SERVER_TOKENNAME: apiKey - AUTH_SERVER_KEYCLOAK_HOST: http://keycloak:8080 - AUTH_SERVER_KEYCLOAK_REALM: myrealm - AUTH_SERVER_SCOPE_STUDY_PREFIX: STUDY. - AUTH_SERVER_SCOPE_STUDY_SUFFIX: .WRITE - AUTH_SERVER_SCOPE_SYSTEM: song.WRITE - SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_JWK_SET_URI: http://keycloak:8080/realms/myrealm/protocol/openid-connect/certs - AUTH_SERVER_INTROSPECTIONURI: http://keycloak:8080/realms/myrealm/apikey/check_api_key/ # Postgres Variables SPRING_DATASOURCE_URL: jdbc:postgresql://song-db:5432/songDb?stringtype=unspecified SPRING_DATASOURCE_USERNAME: admin SPRING_DATASOURCE_PASSWORD: admin123 - # Kafka Variables - SPRING_KAFKA_BOOTSTRAPSERVERS: kafka:9092 - SPRING_KAFKA_TEMPLATE_DEFAULTTOPIC: song-analysis # Swagger Variable SWAGGER_ALTERNATEURL: /swagger-api - - # ====================================== - # Minio - # ====================================== - # High-performance open-source object storage provider - # Used here for local object storage found at persistentStorage/data-minio - # data-minio contains 60 data files linked to the pre-populated analyses in the song-db. This folder is passed into the image on startup - # Documentation Link: https://www.overture.bio/documentation/guides/deployment/datamanagement/#setting-up-object-storage - # -------------------------------------- - minio: - profiles: ["platform", "scoreDev", "songDev", "maestroDev"] - image: minio/minio:RELEASE.2018-05-11T00-29-24Z - container_name: minio + networks: + - conductor-network + + song-client: + profiles: ["phase3", "default"] + image: ghcr.io/overture-stack/song-client:d7e5cb61 + container_name: song-client + platform: linux/amd64 + depends_on: + conductor: + condition: service_healthy + volumes: + - ./data:/data + - ./output:/output + environment: + ACCESSTOKEN: 68fb42b4-f1ed-4e8c-beab-3724b99fe528 + CLIENT_STUDY_ID: demo + CLIENT_SERVER_URL: http://song:8080 + networks: + - conductor-network + command: tail -f /dev/null + + # -----------------------------------------------------------------------------------# + # SongDb # + # -----------------------------------------------------------------------------------# + # Database used by Lyric to store its tabular data. # + # -----------------------------------------------------------------------------------# + song-db: + profiles: ["phase3", "default"] + depends_on: + - conductor + image: postgres:11.1 + container_name: song-db platform: linux/amd64 ports: - - 9000:9000 + - "5433:5432" environment: - MINIO_ACCESS_KEY: admin - MINIO_SECRET_KEY: admin123 - command: server /data - volumes: - - ./persistentStorage/data-minio:/data + POSTGRES_USER: admin + POSTGRES_PASSWORD: admin123 + POSTGRES_DB: songDb + user: postgres:postgres healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"] - interval: 30s - timeout: 20s - retries: 3 - - # ====================================== - # Score - # ====================================== - # File transfer microservice - # Documentation Link: https://www.overture.bio/documentation/guides/deployment/datamanagement/#running-score - # -------------------------------------- + test: ["CMD-SHELL", "pg_isready -U admin -d songDb"] + interval: 20s + timeout: 10s + retries: 10 + start_period: 20s + volumes: + - song-db-data:/var/lib/postgresql/data + networks: + - conductor-network + + # -----------------------------------------------------------------------------------# + # Score # + # -----------------------------------------------------------------------------------# + # Transfer file data to and from any S3 object storage. # + # Documentation Link: https://docs.overture.bio/docs/core-software/Score/overview # + # -----------------------------------------------------------------------------------# score: - profiles: ["platform", "songDev", "maestroDev"] - image: ghcr.io/overture-stack/score-server:5.11.0 + profiles: ["phase3", "default"] + image: ghcr.io/overture-stack/score-server:6c4a3a3c container_name: score platform: linux/amd64 depends_on: - keycloak: - condition: service_started + minio: + condition: service_healthy ports: - "8087:8087" environment: # Spring Variables - SPRING_PROFILES_ACTIVE: default,collaboratory,prod,secure,jwt + SPRING_PROFILES_ACTIVE: noSecurityDev, s3 SERVER_PORT: 8087 # Song Variable METADATA_URL: http://song:8080 # Score Variables SERVER_SSL_ENABLED: "false" # Object Storage Variables - S3_ENDPOINT: http://host.docker.internal:9000 + S3_ENDPOINT: http://minio:9000 + S3_PRESIGNEDURL_BASEURL: http://localhost:9000 S3_ACCESSKEY: admin S3_SECRETKEY: admin123 S3_SIGV4ENABLED: true @@ -338,177 +621,94 @@ services: BUCKET_NAME_STATE: state UPLOAD_PARTSIZE: 1073741824 UPLOAD_CONNECTION_TIMEOUT: 1200000 - # Keycloak Variables - AUTH_SERVER_PROVIDER: keycloak - AUTH_SERVER_CLIENTID: dms - AUTH_SERVER_CLIENTSECRET: t016kqXfI648ORoIP5gepqCzqtsRjlcc - AUTH_SERVER_TOKENNAME: apiKey - AUTH_SERVER_KEYCLOAK_HOST: http://keycloak:8080 - AUTH_SERVER_KEYCLOAK_REALM: myrealm - AUTH_SERVER_SCOPE_STUDY_PREFIX: STUDY. - AUTH_SERVER_SCOPE_DOWNLOAD_SUFFIX: .READ - AUTH_SERVER_SCOPE_DOWNLOAD_SYSTEM: score.READ - AUTH_SERVER_SCOPE_UPLOAD_SYSTEM: score.WRITE - AUTH_SERVER_SCOPE_UPLOAD_SUFFIX: .WRITE - AUTH_SERVER_URL: http://keycloak:8080/realms/myrealm/apikey/check_api_key/ - AUTH_JWT_PUBLICKEYURL: http://keycloak:8080/oauth/token/public_key - SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_JWK_SET_URI: http://keycloak:8080/realms/myrealm/protocol/openid-connect/certs - - # ================================================================================== - # E. Search (Elasticsearch, Maestro, Arranger) - # ================================================================================== - - # ====================================== - # Elasticsearch - # ====================================== - # Search and analytics engine used to help query massive datasets flexibly and efficiently. - # Documentation Link: https://www.overture.bio/documentation/guides/deployment/dataportal/#setting-up-elasticsearch - # -------------------------------------- - elasticsearch: - profiles: ["platform", "stageDev", "arrangerDev", "maestroDev"] - image: docker.elastic.co/elasticsearch/elasticsearch:7.17.1 - container_name: elasticsearch - platform: linux/amd64 - ports: - - "9200:9200" - environment: - discovery.type: single-node - cluster.name: workflow.elasticsearch - ES_JAVA_OPTS: -Xms512m -Xmx2048m - ELASTIC_PASSWORD: myelasticpassword - xpack.security.enabled: "true" - MANAGE_INDEX_TEMPLATES: "true" - NETWORK_HOST: http://localhost:9200 - logging: - driver: "json-file" - options: - max-size: "50m" - max-file: "10" - healthcheck: - test: "curl --silent --fail localhost:9200/_cluster/health?wait_for_status=yellow&timeout=50s || exit 1" - interval: 10s - timeout: 10s - retries: 5 - start_period: 25s + networks: + - conductor-network - # ====================================== - # Maestro - # ====================================== - # Indexing service that transforms metadata in Song into Elasticsearch documents - # Documentation Link: https://www.overture.bio/documentation/guides/deployment/dataportal/#running-maestro - # -------------------------------------- - maestro: - profiles: ["platform"] - image: ghcr.io/overture-stack/maestro:4.3.0 - container_name: maestro + score-client: + profiles: ["phase3", "default"] + image: ghcr.io/overture-stack/score:6c4a3a3c + container_name: score-client platform: linux/amd64 depends_on: - song: - condition: service_started - kafka: - condition: service_started conductor: condition: service_healthy + volumes: + - ./data:/data + - ./output:/output + environment: + ACCESSTOKEN: 68fb42b4-f1ed-4e8c-beab-3724b99fe528 + STORAGE_URL: http://score:8087 + METADATA_URL: http://song:8080 + networks: + - conductor-network + command: tail -f /dev/null + + # -----------------------------------------------------------------------------------# + # Minio # + # -----------------------------------------------------------------------------------# + # A locally deployed open source S3-compatible object storage # + # Documentation Link: # + # http://docs.overture.bio/guides/deployment-guide/data-management-&-storage # + # -----------------------------------------------------------------------------------# + minio: + profiles: ["phase3", "default"] + image: minio/minio:RELEASE.2018-05-11T00-29-24Z + container_name: minio + platform: linux/amd64 ports: - - "11235:11235" + - 9000:9000 environment: - # Maestro Variables - MAESTRO_FAILURELOG_ENABLED: true - MAESTRO_FAILURELOG_DIR: app/logs/maestro - MAESTRO_LOGGING_LEVEL_ROOT: INFO - MAESTRO_NOTIFICATIONS_SLACK_ENABLED: false - # Song Variables - MAESTRO_REPOSITORIES_0_CODE: song.overture - MAESTRO_REPOSITORIES_0_URL: http://song:8080 - MAESTRO_REPOSITORIES_0_NAME: Overture - MAESTRO_REPOSITORIES_0_ORGANIZATION: OICR - MAESTRO_REPOSITORIES_0_COUNTRY: CA - # Elasticsearch Variables - MAESTRO_ELASTICSEARCH_CLUSTER_NODES: http://elasticsearch:9200 - MAESTRO_ELASTICSEARCH_CLIENT_BASICAUTH_USER: elastic - MAESTRO_ELASTICSEARCH_CLIENT_BASICAUTH_PASSWORD: myelasticpassword - MAESTRO_ELASTICSEARCH_CLIENT_TRUSTSELFSIGNCERT: true - MAESTRO_ELASTICSEARCH_INDEXES_ANALYSISCENTRIC_ENABLED: false - MAESTRO_ELASTICSEARCH_INDEXES_FILECENTRIC_ENABLED: true - MAESTRO_ELASTICSEARCH_INDEXES_FILECENTRIC_NAME: overture-quickstart-index - MAESTRO_ELASTICSEARCH_INDEXES_FILECENTRIC_ALIAS: file_centric - MAESTRO_ELASTICSEARCH_CLIENT_BASICAUTH_ENABLED: true - MANAGEMENT_HEALTH_ELASTICSEARCH_ENABLED: false - # Spring Variables - SPRING_MVC_ASYNC_REQUESTTIMEOUT: -1 - SPRINGDOC_SWAGGERUI_PATH: /swagger-api - # Kafka Variables - SPRING_CLOUD_STREAM_KAFKA_BINDER_BROKERS: kafka:9092 - SPRING_CLOUD_STREAM_BINDINGS_SONGINPUT_DESTINATION: song-analysis - - # ====================================== - # Arranger-Server - # ====================================== - # Search API generation with compatible search UI components - # Documentation Link: https://www.overture.bio/documentation/guides/deployment/dataportal/#running-arranger - # -------------------------------------- - arranger-server: - profiles: ["platform", "stageDev"] - image: ghcr.io/overture-stack/arranger-server:3.0.0-beta.33 - container_name: arranger-server + MINIO_ACCESS_KEY: admin + MINIO_SECRET_KEY: admin123 + command: server /data + volumes: + - ./apps/conductor/volumes/data-minio:/data + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"] + interval: 30s + timeout: 20s + retries: 3 + networks: + - conductor-network + + # ------------------------------------------------------------------------------------# + # Arranger-Server for our file data # + # ------------------------------------------------------------------------------------# + # Search API generation with compatible search UI components # + # Documentation Link: https://docs.overture.bio/docs/core-software/Arranger/overview # + # ------------------------------------------------------------------------------------# + arranger-molecular: + profiles: ["phase3", "stageDev", "default"] + image: ghcr.io/overture-stack/arranger-server:3.0.0-beta.36 + container_name: arranger-molecular platform: linux/amd64 depends_on: conductor: condition: service_healthy ports: - - "5050:5050" + - "5060:5060" volumes: - - ./configurationFiles/arrangerConfigs/base.json:/app/modules/server/configs/base.json - - ./configurationFiles/arrangerConfigs/extended.json:/app/modules/server/configs/extended.json - - ./configurationFiles/arrangerConfigs/facets.json:/app/modules/server/configs/facets.json - - ./configurationFiles/arrangerConfigs/matchbox.json:/app/modules/server/configs/matchbox.json - - ./configurationFiles/arrangerConfigs/table.json:/app/modules/server/configs/table.json + - ./apps/conductor/configs/arrangerConfigs/fileDataConfigs:/app/modules/server/configs environment: - # Arranger Variables - ENABLE_LOGS: false # Elasticsearch Variables ES_HOST: http://elasticsearch:9200 ES_USER: elastic ES_PASS: myelasticpassword - - # ================================================================================== - # F. Discovery (Stage) - # ================================================================================== - - # ====================================== - # Stage - # ====================================== - # The react-based, front end portal UI for Overture - # Documentation Link: https://www.overture.bio/documentation/guides/deployment/dataportal/#setting-up-stage - # -------------------------------------- - stage: - profiles: ["platform", "arrangerDev"] - image: ghcr.io/overture-stack/stage:a211593 - container_name: stage - platform: linux/amd64 - depends_on: - conductor: - condition: service_healthy - ports: - - "3000:3000" - environment: - # Stage Variables - NEXTAUTH_URL: http://localhost:3000/api/auth - NEXT_PUBLIC_LAB_NAME: Overture QuickStart Portal - NEXT_PUBLIC_ADMIN_EMAIL: contact@overture.bio - NEXT_PUBLIC_DEBUG: true - NEXT_PUBLIC_SHOW_MOBILE_WARNING: true - # Keycloak Variables - NEXT_PUBLIC_AUTH_PROVIDER: keycloak - ACCESSTOKEN_ENCRYPTION_SECRET: super_secret - SESSION_ENCRYPTION_SECRET: this_is_a_super_secret_secret - NEXT_PUBLIC_KEYCLOAK_HOST: http://keycloak:8080 - NEXT_PUBLIC_KEYCLOAK_REALM: myrealm - NEXT_PUBLIC_KEYCLOAK_CLIENT_ID: webclient - KEYCLOAK_CLIENT_SECRET: ikksyrYaKX07acf4hpGrpKWcUGaFkEdM - NEXT_PUBLIC_KEYCLOAK_PERMISSION_AUDIENCE: dms + ES_ARRANGER_SET_INDEX: file_arranger_set # Arranger Variables - NEXT_PUBLIC_ARRANGER_DOCUMENT_TYPE: file - NEXT_PUBLIC_ARRANGER_INDEX: file_centric - NEXT_PUBLIC_ARRANGER_API_URL: http://arranger-server:5050 - NEXT_PUBLIC_ARRANGER_MANIFEST_COLUMNS: repositories.code, analysis.analysis_id, object_id, study_id, file_type, file.name, file.size, file.md5sum, file.index_file.object_id, donors.donor_id, donors.specimens.samples.sample_id + PORT: 5060 + DEBUG: false + ENABLE_LOGS: false + networks: + - conductor-network + +volumes: + elasticsearch-data: + stage-data: + maestro-data: + song-db-data: + lyric-db-data: + lectern-db-data: +networks: + conductor-network: + driver: bridge diff --git a/docs b/docs new file mode 120000 index 00000000..9465a649 --- /dev/null +++ b/docs @@ -0,0 +1 @@ +./apps/stage/public/docs \ No newline at end of file diff --git a/guideMaterials/dataAdministration/ES-analysisCentric-document.json b/guideMaterials/dataAdministration/ES-analysisCentric-document.json deleted file mode 100644 index 03fa01b5..00000000 --- a/guideMaterials/dataAdministration/ES-analysisCentric-document.json +++ /dev/null @@ -1,226 +0,0 @@ - -{ - "analysis_id": "70d78670-618f-4257-9786-70618fb2578b", - "analysis_type": "quickStartSchema", - "analysis_version": 1, - "analysis_state": "PUBLISHED", - "updated_at": 1719708298753, - "published_at": 1719789481510, - "first_published_at": 1719708298744, - "study_id": "demo", - "donors": [ - { - "donor_id": "1a0cc916-465c-5b06-8eb7-c4fa438e496f", - "submitter_donor_id": "DO0115", - "gender": "Female", - "specimens": [ - { - "specimen_id": "89e3e128-6d1a-55cc-aae3-e62f5e2d4bdc", - "specimen_type": "Primary tumour - adjacent to normal", - "submitter_specimen_id": "SP011511", - "samples": [ - { - "sample_id": "89e3e128-6d1a-55cc-aae3-e62f5e2d4bdc", - "submitter_sample_id": "SP011511", - "sample_type": "Total DNA", - "matched_normal_submitter_sample_id": "SP011501" - } - ], - "tumour_normal_designation": "Tumour", - "specimen_tissue_source": "Blood derived - bone marrow" - } - ] - } - ], - "files": [ - { - "object_id": "b78e0e71-8177-5e49-9b2b-025dd58f7f7b", - "name": "SP011511.indel.vcf.gz", - "size": 17328, - "file_type": "VCF", - "md5_sum": "c445d6cd5e1aa1d7dec13096feae788c", - "file_access": "open", - "data_type": "Raw InDel Calls", - "dataCategory": "Simple Nucelotide Variation", - "jbrowseCoordinates": "hg38:chr1:100000-200000" - }, - { - "object_id": "b9582e12-03ed-57c1-a29b-40291fc64dc7", - "name": "SP011511.indel.vcf.gz.tbi", - "size": 148, - "file_type": "TBI", - "md5_sum": "ae025b596b2fb562d33073338eb23a7d", - "file_access": "open", - "data_type": "Raw InDel Calls", - "dataCategory": "Simple Nucelotide Variation", - "jbrowseCoordinates": "hg38:chr1:100000-200000" - } - ], - "repositories": [ - { - "code": "song.overture", - "organization": "Overture", - "name": "Overture", - "type": "S3", - "country": "CA", - "url": "http://song:8080" - } - ], - "experiment": { - "experimentalStrategy": "WXS", - "model": "SEQUEL IIe", - "platform": "PacBio", - "sequencingCenter": "CGTA", - "sequencingDate": "2021-03-08T19:00:00.000Z" - }, - "analysisStateHistory": [ - { - "initialState": "UNPUBLISHED", - "updatedState": "PUBLISHED", - "updatedAt": "2024-06-30T00:44:58.744865" - }, - { - "initialState": "PUBLISHED", - "updatedState": "PUBLISHED", - "updatedAt": "2024-06-30T01:47:36.807659" - }, - { - "initialState": "PUBLISHED", - "updatedState": "PUBLISHED", - "updatedAt": "2024-06-30T02:20:10.703175" - }, - { - "initialState": "PUBLISHED", - "updatedState": "PUBLISHED", - "updatedAt": "2024-06-30T22:12:42.925452" - }, - { - "initialState": "PUBLISHED", - "updatedState": "PUBLISHED", - "updatedAt": "2024-06-30T23:03:31.126799" - }, - { - "initialState": "PUBLISHED", - "updatedState": "PUBLISHED", - "updatedAt": "2024-06-30T23:11:28.179691" - }, - { - "initialState": "PUBLISHED", - "updatedState": "PUBLISHED", - "updatedAt": "2024-06-30T23:18:01.510626" - } - ], - "collaborator": [ - { - "contactEmail": "susannorton@micr.ca", - "name": "MICR" - } - ], - "createdAt": "2024-06-30T00:40:08.565416", - "donor": { - "causeOfDeath": "Died of other reasons", - "primaryDiagnosis": [ - { - "ageAtDiagnosis": 36, - "cancerTypeCode": "C34.3", - "clinicalStageGroup": "Stage III", - "clinicalTumourStagingSystem": "AJCC 6th edition", - "followUp": [ - { - "diseaseStatusAtFollowUp": "Partial remission", - "intervalOfFollowUp": 50, - "relapseType": null, - "submitterFollowUpId": "FO011501", - "submitterTreatmentId": "TR011501" - } - ], - "submitterPrimaryDiagnosisId": "PD011501", - "treatment": [ - { - "chemotherapy": [ - { - "drugName": "Azacitidine " - } - ], - "responseToTreatment": "Minor response", - "submitterTreatmentId": "TR011501", - "treatmentDuration": 34, - "treatmentStartInterval": 79, - "treatmentType": [ - "Chemotherapy" - ] - } - ] - }, - { - "ageAtDiagnosis": 1, - "cancerTypeCode": "C34.2", - "clinicalStageGroup": "Stage IB", - "clinicalTumourStagingSystem": "FIGO staging system", - "followUp": [ - { - "diseaseStatusAtFollowUp": "Relapse or recurrence", - "intervalOfFollowUp": 33, - "relapseType": null, - "submitterFollowUpId": "FO011502", - "submitterTreatmentId": "TR011502" - } - ], - "submitterPrimaryDiagnosisId": "PD011502", - "treatment": [ - { - "chemotherapy": [ - { - "drugName": "Paclitaxel " - } - ], - "radiation": [ - { - "anatomicalSiteIrradiated": "Body", - "radiationTherapyModality": "Photon" - } - ], - "responseToTreatment": "Complete response", - "submitterTreatmentId": "TR011502", - "treatmentDuration": 56, - "treatmentStartInterval": 70, - "treatmentType": [ - "Chemotherapy", - "Radiation therapy" - ] - } - ] - } - ], - "primarySite": "Bronchus and lung", - "submitterDonorId": "DO0115", - "survivalTime": 439, - "vitalStatus": "Deceased" - }, - "publication": { - "doi": "10.1093/nar/gkae188", - "publication": "NAR" - }, - "specimen": { - "specimenAnatomicLocation": "C14", - "submitterPrimaryDiagnosisId": "PD011501", - "submitterSpecimenId": "SP011501", - "tumourGrade": "G3", - "tumourGradingSystem": "Three-tier grading system" - }, - "workflow": { - "genomeBuild": "GRCh38_hla_decoy_ebv", - "inputs": [ - { - "analysisType": "sequencing_alignment", - "normalAnalysisId": "00000000-0000-0000-0000-0000000000115", - "tumourAnalysisId": "00000000-0000-0000-0000-0000000000115" - } - ], - "runId": "RI0115", - "sessionId": "SI0115", - "workflowName": "Sanger Variant Calling", - "workflowShortName": "SangerVariant", - "workflowVersion": "0.9.8" - } - } \ No newline at end of file diff --git a/guideMaterials/dataAdministration/ES-fileCentric-document.json b/guideMaterials/dataAdministration/ES-fileCentric-document.json deleted file mode 100644 index ac2e67ca..00000000 --- a/guideMaterials/dataAdministration/ES-fileCentric-document.json +++ /dev/null @@ -1,218 +0,0 @@ - -{ - "file": { - "size": 17346, - "md5sum": "a5e32b78bd52dc2cfe1cffcdaadcb335", - "dataCategory": "Simple Nucleotide Variation", - "name": "SP011501.indel.vcf.gz", - "data_type": "Raw InDel Calls", - "jbrowseCoordinates": "hg38:chr1:100000-200000", - "index_file": { - "size": 144, - "file_type": "TBI", - "md5sum": "e4d3b0751f2824bac22f42147dd41fd8", - "dataCategory": "Simple Nucleotide Variation", - "name": "SP011501.indel.vcf.gz.tbi", - "data_type": "Raw InDel Calls", - "jbrowseCoordinates": "hg38:chr1:100000-200000", - "object_id": "30697525-1033-543c-a86b-1ab428c7e8d5" - } - }, - "repositories": [ - { - "code": "song.overture", - "organization": "Overture", - "name": "Overture", - "type": "S3", - "country": "CA", - "url": "http://song:8080" - } - ], - "file_type": "VCF", - "dataCategory": "Simple Nucleotide Variation", - "data_type": "Raw InDel Calls", - "donors": [ - { - "gender": "Female", - "specimens": [ - { - "specimen_id": "e61a520b-56d9-541c-9265-10f2e5ecea8e", - "submitter_specimen_id": "SP011501", - "specimen_type": "Normal - tissue adjacent to primary tumour", - "specimen_tissue_source": "Solid tissue", - "tumour_normal_designation": "Normal", - "samples": [ - { - "submitter_sample_id": "SP011501", - "matched_normal_submitter_sample_id": null, - "sample_id": "e61a520b-56d9-541c-9265-10f2e5ecea8e", - "sample_type": "Total DNA" - } - ] - } - ], - "donor_id": "1a0cc916-465c-5b06-8eb7-c4fa438e496f", - "submitter_donor_id": "DO0115" - } - ], - "jbrowseCoordinates": "hg38:chr1:100000-200000", - "study_id": "demo", - "file_access": "open", - "analysis": { - "workflow": { - "genomeBuild": "GRCh38_hla_decoy_ebv", - "inputs": [ - { - "tumourAnalysisId": "00000000-0000-0000-0000-0000000000115", - "normalAnalysisId": "00000000-0000-0000-0000-0000000000115", - "analysisType": "sequencing_alignment" - } - ], - "workflowShortName": "SangerVariant", - "workflowName": "Sanger Variant Calling", - "runId": "RI0115", - "sessionId": "SI0115", - "workflowVersion": "0.9.8" - }, - "analysis_type": "quickStartSchema", - "analysis_version": 1, - "analysis_state": "PUBLISHED", - "analysis_id": "b5543647-f97a-491e-9436-47f97ac91e69", - "collaborator": [ - { - "contactEmail": "susannorton@micr.ca", - "name": "MICR" - } - ], - "createdAt": "2024-06-30T00:40:01.427321", - "analysisStateHistory": [ - { - "updatedState": "PUBLISHED", - "initialState": "UNPUBLISHED", - "updatedAt": "2024-06-30T00:44:34.697139" - }, - { - "updatedState": "PUBLISHED", - "initialState": "PUBLISHED", - "updatedAt": "2024-06-30T01:47:29.192658" - }, - { - "updatedState": "PUBLISHED", - "initialState": "PUBLISHED", - "updatedAt": "2024-06-30T02:20:04.716056" - }, - { - "updatedState": "PUBLISHED", - "initialState": "PUBLISHED", - "updatedAt": "2024-06-30T22:12:32.930015" - }, - { - "updatedState": "PUBLISHED", - "initialState": "PUBLISHED", - "updatedAt": "2024-06-30T23:03:25.674125" - } - ], - "donor": { - "primarySite": "Bronchus and lung", - "submitterDonorId": "DO0115", - "survivalTime": 439, - "causeOfDeath": "Died of other reasons", - "primaryDiagnosis": [ - { - "cancerTypeCode": "C34.3", - "followUp": [ - { - "submitterFollowUpId": "FO011501", - "relapseType": null, - "submitterTreatmentId": "TR011501", - "diseaseStatusAtFollowUp": "Partial remission", - "intervalOfFollowUp": 50 - } - ], - "treatment": [ - { - "responseToTreatment": "Minor response", - "treatmentType": [ - "Chemotherapy" - ], - "treatmentDuration": 34, - "submitterTreatmentId": "TR011501", - "chemotherapy": [ - { - "drugName": "Azacitidine " - } - ], - "treatmentStartInterval": 79 - } - ], - "clinicalTumourStagingSystem": "AJCC 6th edition", - "ageAtDiagnosis": 36, - "submitterPrimaryDiagnosisId": "PD011501", - "clinicalStageGroup": "Stage III" - }, - { - "cancerTypeCode": "C34.2", - "followUp": [ - { - "submitterFollowUpId": "FO011502", - "relapseType": null, - "submitterTreatmentId": "TR011502", - "diseaseStatusAtFollowUp": "Relapse or recurrence", - "intervalOfFollowUp": 33 - } - ], - "treatment": [ - { - "responseToTreatment": "Complete response", - "treatmentType": [ - "Chemotherapy", - "Radiation therapy" - ], - "radiation": [ - { - "radiationTherapyModality": "Photon", - "anatomicalSiteIrradiated": "Body" - } - ], - "treatmentDuration": 56, - "submitterTreatmentId": "TR011502", - "chemotherapy": [ - { - "drugName": "Paclitaxel " - } - ], - "treatmentStartInterval": 70 - } - ], - "clinicalTumourStagingSystem": "FIGO staging system", - "ageAtDiagnosis": 1, - "submitterPrimaryDiagnosisId": "PD011502", - "clinicalStageGroup": "Stage IB" - } - ], - "vitalStatus": "Deceased" - }, - "updated_at": 1719708274766, - "experiment": { - "model": "SEQUEL IIe", - "sequencingDate": "2021-03-08T19:00:00.000Z", - "experimentalStrategy": "WXS", - "platform": "PacBio", - "sequencingCenter": "CGTA" - }, - "publication": { - "publication": "NAR", - "doi": "10.1093/nar/gkae188" - }, - "specimen": { - "tumourGrade": "G2", - "submitterSpecimenId": "SP011501", - "submitterPrimaryDiagnosisId": "PD011501", - "tumourGradingSystem": "Grading system for GNETs", - "specimenAnatomicLocation": "C01" - }, - "first_published_at": 1719708274697, - "published_at": 1719788605674 - }, - "object_id": "5b3bf92a-8f57-54b9-9ab9-6dcf34a0dc78" - } \ No newline at end of file diff --git a/guideMaterials/dataAdministration/ES-index-template.json b/guideMaterials/dataAdministration/ES-index-template.json deleted file mode 100644 index 571f6172..00000000 --- a/guideMaterials/dataAdministration/ES-index-template.json +++ /dev/null @@ -1,238 +0,0 @@ -{ - "index_patterns": ["overture-*"], - "aliases": { - "file_centric": {} - }, - "mappings": { - "properties": { - "object_id": { "type": "keyword", "copy_to": ["file_autocomplete"] }, - "study_id": { "type": "keyword" }, - "data_type": { "type": "keyword" }, - "file_type": { "type": "keyword" }, - "file_access": { "type": "keyword" }, - "file_autocomplete": { - "type": "keyword", - "fields": { - "analyzed": { - "type": "text", - "analyzer": "autocomplete_analyzed", - "search_analyzer": "lowercase_keyword" - }, - "lowercase": { - "type": "text", - "analyzer": "lowercase_keyword" - }, - "prefix": { - "type": "text", - "analyzer": "autocomplete_prefix", - "search_analyzer": "lowercase_keyword" - } - } - }, - "analysis": { - "properties": { - "analysis_id": { "type": "keyword" }, - "analysis_type": { "type": "keyword" }, - "analysis_version": { "type": "integer" }, - "analysis_state": { "type": "keyword" }, - "updated_at": { "type": "date" }, - "first_published_at": { "type": "date" }, - "published_at": { "type": "date" }, - "experiment": { - "properties": { - "experimentalStrategy": { "type": "keyword" }, - "model": { "type": "keyword" }, - "platform": { "type": "keyword" }, - "sequencingCenter": { "type": "keyword" }, - "sequencingDate": { "type": "date" } - } - }, - "analysisStateHistory": { - "type": "nested", - "properties": { - "initialState": { "type": "keyword" }, - "updatedState": { "type": "keyword" }, - "updatedAt": { "type": "date" } - } - }, - "collaborator": { - "type": "nested", - "properties": { - "contactEmail": { "type": "keyword" }, - "name": { "type": "keyword" } - } - }, - "createdAt": { "type": "date" }, - "donor": { - "properties": { - "causeOfDeath": { "type": "keyword" }, - "primaryDiagnosis": { - "type": "nested", - "properties": { - "ageAtDiagnosis": { "type": "integer" }, - "cancerTypeCode": { "type": "keyword" }, - "clinicalStageGroup": { "type": "keyword" }, - "clinicalTumourStagingSystem": { "type": "keyword" }, - "followUp": { - "type": "nested", - "properties": { - "diseaseStatusAtFollowUp": { "type": "keyword" }, - "intervalOfFollowUp": { "type": "integer" }, - "relapseType": { "type": "keyword" }, - "submitterFollowUpId": { "type": "keyword" }, - "submitterTreatmentId": { "type": "keyword" } - } - }, - "submitterPrimaryDiagnosisId": { "type": "keyword" }, - "treatment": { - "type": "nested", - "properties": { - "chemotherapy": { - "type": "nested", - "properties": { - "drugName": { "type": "keyword" } - } - }, - "responseToTreatment": { "type": "keyword" }, - "submitterTreatmentId": { "type": "keyword" }, - "treatmentDuration": { "type": "integer" }, - "treatmentStartInterval": { "type": "integer" }, - "treatmentType": { "type": "keyword" } - } - } - } - }, - "primarySite": { "type": "keyword" }, - "submitterDonorId": { "type": "keyword" }, - "survivalTime": { "type": "integer" }, - "vitalStatus": { "type": "keyword" } - } - }, - "publication": { - "properties": { - "doi": { "type": "keyword" }, - "publication": { "type": "keyword" } - } - }, - "specimen": { - "properties": { - "specimenAnatomicLocation": { "type": "keyword" }, - "submitterPrimaryDiagnosisId": { "type": "keyword" }, - "submitterSpecimenId": { "type": "keyword" }, - "tumourGrade": { "type": "keyword" }, - "tumourGradingSystem": { "type": "keyword" } - } - }, - "workflow": { - "properties": { - "genomeBuild": { "type": "keyword" }, - "inputs": { - "type": "nested", - "properties": { - "analysisType": { "type": "keyword" }, - "normalAnalysisId": { "type": "keyword" }, - "tumourAnalysisId": { "type": "keyword" } - } - }, - "runId": { "type": "keyword" }, - "sessionId": { "type": "keyword" }, - "workflowName": { "type": "keyword" }, - "workflowShortName": { "type": "keyword" }, - "workflowVersion": { "type": "keyword" } - } - } - } - }, - "file": { - "properties": { - "name": { "type": "keyword" }, - "md5sum": { "type": "keyword" }, - "size": { "type": "integer" }, - "data_type": { "type": "keyword" }, - "index_file": { - "properties": { - "object_id": { "type": "keyword" }, - "name": { "type": "keyword" }, - "file_type": { "type": "keyword" }, - "md5sum": { "type": "keyword" }, - "data_type": { "type": "keyword" }, - "size": { "type": "integer" }, - "dataCategory": { "type": "keyword" }, - "jbrowseCoordinates": { "type": "keyword" } - } - }, - "dataCategory": { "type": "keyword" }, - "jbrowseCoordinates": { "type": "keyword" } - } - }, - "repositories": { - "type": "nested", - "properties": { - "code": { "type": "keyword" }, - "organization": { "type": "keyword" }, - "name": { "type": "keyword" }, - "type": { "type": "keyword" }, - "country": { "type": "keyword" }, - "url": { "type": "keyword" } - } - }, - "donors": { - "type": "nested", - "properties": { - "donor_id": { "type": "keyword" }, - "submitter_donor_id": { "type": "keyword" }, - "gender": { "type": "keyword" }, - "specimens": { - "type": "nested", - "properties": { - "specimen_id": { "type": "keyword" }, - "specimen_type": { "type": "keyword" }, - "submitter_specimen_id": { "type": "keyword" }, - "samples": { - "type": "nested", - "properties": { - "sample_id": { "type": "keyword" }, - "submitter_sample_id": { "type": "keyword" }, - "sample_type": { "type": "keyword" }, - "matched_normal_submitter_sample_id": { "type": "keyword" } - } - }, - "tumour_normal_designation": { "type": "keyword" }, - "specimen_tissue_source": { "type": "keyword" } - } - } - } - }, - "dataCategory": { "type": "keyword" }, - "jbrowseCoordinates": { "type": "keyword" } - } - }, - "settings": { - "analysis": { - "analyzer": { - "autocomplete_analyzed": { - "filter": ["lowercase", "edge_ngram"], - "tokenizer": "standard" - }, - "autocomplete_prefix": { - "filter": ["lowercase", "edge_ngram"], - "tokenizer": "keyword" - }, - "lowercase_keyword": { - "filter": ["lowercase"], - "tokenizer": "keyword" - } - }, - "filter": { - "edge_ngram": { - "max_gram": "20", - "min_gram": "1", - "side": "front", - "type": "edge_ngram" - } - } - }, - "index.max_result_window": 300000, - "index.number_of_shards": 3 - } -} \ No newline at end of file diff --git a/guideMaterials/dataAdministration/SONG-schema.json b/guideMaterials/dataAdministration/SONG-schema.json deleted file mode 100644 index 12e79ba0..00000000 --- a/guideMaterials/dataAdministration/SONG-schema.json +++ /dev/null @@ -1,677 +0,0 @@ -{ - "name": "quickStartSchema", - "schema": { - "type": "object", - "required": ["donor", "specimen", "workflow", "experiment"], - "properties": { - "workflow": { - "propertyNames": { - "enum": ["workflowName", "workflowShortName", "workflowVersion", "genomeBuild", "inputs","sessionId","runId"] - }, - "required": ["workflowName", "genomeBuild", "inputs"], - "type": "object", - "properties": { - "workflowName": { - "type": "string", - "pattern": "^[a-zA-Z][a-zA-Z0-9 _\\-]+[a-zA-Z0-9]+$" - }, - "workflowShortName": { - "type": "string", - "pattern": "^[a-zA-Z][a-zA-Z0-9_\\-]+[a-zA-Z0-9]+$" - }, - "workflowVersion": { - "type": "string" - }, - "genomeBuild": { - "type": "string", - "enum": ["GRCh37", "GRCh38_hla_decoy_ebv", "GRCh38_Verily_v1"] - }, - "inputs": { - "type": "array", - "items": { - "type": "object", - "properties": { - "tumourAnalysisId": { - "type": "string", - "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{13}$" - }, - "normalAnalysisId": { - "type": "string", - "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{13}$" - }, - "analysisType": { - "type": "string" - } - } - }, - "minItems": 1, - "maxItems": 2 - }, - "runId": { - "type": "string" - }, - "sessionId": { - "type": "string", - "pattern": "SI[0-9]{4}" - } - } - }, - "experiment": { - "propertyNames": { - "enum": [ - "platform", - "experimentalStrategy", - "model", - "sequencingCenter", - "sequencingDate" - ] - }, - "required": ["platform", "experimentalStrategy"], - "type": "object", - "properties": { - "platform": { - "type": ["string", "null"] - }, - "experimentalStrategy": { - "type": ["string", "null"] - }, - "model": { - "type": ["string", "null"] - }, - "sequencingCenter": { - "type": ["string", "null"] - }, - "sequencingDate": { - "type": ["string", "null"], - "pattern": "^(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(.[0-9]+)?(Z|[+-](?:2[0-3]|[01][0-9]):[0-5][0-9])?$" - } - } - }, - "donor": { - "type": "object", - "propertyNames": { - "enum": [ - "submitterDonorId", - "primarySite", - "vitalStatus", - "survivalTime", - "causeOfDeath", - "primaryDiagnosis" - ] - }, - "required": ["submitterDonorId", "primarySite", "vitalStatus", "primaryDiagnosis"], - "properties": { - "submitterDonorId": { - "type": "string" - }, - "primarySite": { - "type": "string", - "enum": [ - "Accessory sinuses", - "Adrenal gland", - "Base of tongue", - "Bladder", - "Bones, joints and articular cartilage of limbs", - "Bones, joints and articular cartilage of other and unspecified sites", - "Brain", - "Breast", - "Bronchus and lung", - "Cervix uteri", - "Colon", - "Connective, subcutaneous and other soft tissues", - "Corpus uteri", - "Esophagus", - "Eye and adnexa", - "Floor of mouth", - "Gallbladder", - "Gum", - "Heart, mediastinum, and pleura", - "Hematopoietic and reticuloendothelial systems", - "Hypopharynx", - "Kidney", - "Larynx", - "Lip", - "Liver and intrahepatic bile ducts", - "Lymph nodes", - "Meninges", - "Nasal cavity and middle ear", - "Nasopharynx", - "Oropharynx", - "Other and ill-defined digestive organs", - "Other and ill-defined sites", - "Other and ill-defined sites in lip, oral cavity and pharynx", - "Other and ill-defined sites within respiratory system and intrathoracic organs", - "Other and unspecified female genital organs", - "Other and unspecified major salivary glands", - "Other and unspecified male genital organs", - "Other and unspecified parts of biliary tract", - "Other and unspecified parts of mouth", - "Other and unspecified parts of tongue", - "Other and unspecified urinary organs", - "Other endocrine glands and related structures", - "Ovary", - "Palate", - "Pancreas", - "Parotid gland", - "Penis", - "Peripheral nerves and autonomic nervous system", - "Placenta", - "Prostate gland", - "Pyriform sinus", - "Rectosigmoid junction", - "Rectum", - "Renal pelvis", - "Retroperitoneum and peritoneum", - "Skin", - "Small intestine", - "Spinal cord, cranial nerves, and other parts of central nervous system", - "Stomach", - "Testis", - "Thymus", - "Thyroid gland", - "Tonsil", - "Trachea", - "Ureter", - "Uterus, NOS", - "Vagina", - "Vulva" - ] - }, - "vitalStatus": { - "type": "string", - "enum": ["Alive", "Deceased"] - }, - "survivalTime": { - "type": ["null", "integer"], - "minimum": 0 - }, - "causeOfDeath": { - "type": ["null", "string"], - "enum": ["Died of cancer", "Died of other reasons", "Unknown", null] - }, - "primaryDiagnosis": { - "type": "array", - "minItems": 1, - "items": { - "type": "object", - "propertyNames": { - "enum": [ - "submitterPrimaryDiagnosisId", - "ageAtDiagnosis", - "cancerTypeCode", - "clinicalTumourStagingSystem", - "clinicalStageGroup", - "treatment", - "followUp" - ] - }, - "required": ["submitterPrimaryDiagnosisId", "ageAtDiagnosis", "cancerTypeCode"], - "properties": { - "submitterPrimaryDiagnosisId": { - "type": "string" - }, - "ageAtDiagnosis": { - "type": "integer", - "minimum": 0 - }, - "cancerTypeCode": { - "type": "string", - "pattern": "^[C|D][0-9]{2}(.[0-9]{1,3}[A-Z]{0,1})?$" - }, - "clinicalTumourStagingSystem": { - "type": "string", - "enum": [ - "AJCC 8th edition", - "AJCC 7th edition", - "AJCC 6th edition", - "Ann Arbor staging system", - "Binet staging system", - "Durie-Salmon staging system", - "FIGO staging system", - "Lugano staging system", - "Rai staging system", - "Revised International staging system (RISS)", - "St Jude staging system" - ] - }, - "clinicalStageGroup": { - "type": "string", - "enum": [ - "Occult Carcinoma", - "Stage 0", - "Stage 0a", - "Stage 0is", - "Stage 1", - "Stage 1A", - "Stage 1B", - "Stage A", - "Stage B", - "Stage C", - "Stage I", - "Stage IA", - "Stage IA1", - "Stage IA2", - "Stage IA3", - "Stage IAB", - "Stage IAE", - "Stage IAES", - "Stage IAS", - "Stage IB", - "Stage IB1", - "Stage IB2", - "Stage IBE", - "Stage IBES", - "Stage IBS", - "Stage IC", - "Stage IE", - "Stage IEA", - "Stage IEB", - "Stage IES", - "Stage II", - "Stage II bulky", - "Stage IIA", - "Stage IIA1", - "Stage IIA2", - "Stage IIAE", - "Stage IIAES", - "Stage IIAS", - "Stage IIB", - "Stage IIBE", - "Stage IIBES", - "Stage IIBS", - "Stage IIC", - "Stage IIE", - "Stage IIEA", - "Stage IIEB", - "Stage IIES", - "Stage III", - "Stage IIIA", - "Stage IIIA1", - "Stage IIIA2", - "Stage IIIAE", - "Stage IIIAES", - "Stage IIIAS", - "Stage IIIB", - "Stage IIIBE", - "Stage IIIBES", - "Stage IIIBS", - "Stage IIIC", - "Stage IIIC1", - "Stage IIIC2", - "Stage IIID", - "Stage IIIE", - "Stage IIIES", - "Stage IIIS", - "Stage IIS", - "Stage IS", - "Stage IV", - "Stage IVA", - "Stage IVA1", - "Stage IVA2", - "Stage IVAE", - "Stage IVAES", - "Stage IVAS", - "Stage IVB", - "Stage IVBE", - "Stage IVBES", - "Stage IVBS", - "Stage IVC", - "Stage IVE", - "Stage IVES", - "Stage IVS", - "Cannot be assessed" - ] - }, - "followUp": { - "type": "array", - "items": { - "type": "object", - "propertyNames": { - "enum": [ - "submitterFollowUpId", - "intervalOfFollowUp", - "diseaseStatusAtFollowUp", - "relapseType", - "submitterTreatmentId" - ] - }, - "required": [ - "submitterFollowUpId", - "intervalOfFollowUp", - "diseaseStatusAtFollowUp" - ], - "properties": { - "submitterFollowUpId": { - "type": "string" - }, - "submitterTreatmentId": { - "type": "string" - }, - "intervalOfFollowUp": { - "type": "integer", - "minimum": 0 - }, - "diseaseStatusAtFollowUp": { - "type": "string", - "enum": [ - "Complete remission", - "Distant progression", - "Loco-regional progression", - "No evidence of disease", - "Partial remission", - "Progression NOS", - "Relapse or recurrence", - "Stable" - ] - }, - "relapseType": { - "type": ["string", "null"], - "enum": [ - "Distant recurrence/metastasis", - "Local recurrence", - "Local recurrence and distant metastasis", - "Progression (liquid tumours)", - null - ] - } - } - } - }, - "treatment": { - "type": "array", - "items": { - "type": "object", - "propertyNames": { - "enum": [ - "submitterTreatmentId", - "treatmentType", - "treatmentStartInterval", - "treatmentDuration", - "responseToTreatment", - "chemotherapy", - "hormoneTherapy", - "radiation" - ] - }, - "required": ["submitterTreatmentId", "treatmentType"], - "properties": { - "submitterTreatmentId": { - "type": "string" - }, - "treatmentType": { - "type": "array", - "items": { - "type": "string", - "enum": [ - "Ablation", - "Bone marrow transplant", - "Chemotherapy", - "Endoscopic therapy", - "Hormonal therapy", - "No treatment", - "Other targeting molecular therapy", - "Photodynamic therapy", - "Radiation therapy", - "Stem cell transplant", - "Surgery" - ] - } - }, - "treatmentStartInterval": { - "type": "integer", - "minimum": 0 - }, - "treatmentDuration": { - "type": "integer", - "minimum": 0 - }, - "responseToTreatment": { - "type": "string", - "enum": [ - "Complete response", - "Disease progression", - "NED", - "Minor response", - "Partial response", - "Stable disease" - ] - }, - "chemotherapy": { - "type": "array", - "items": { - "type": "object", - "propertyNames": { - "enum": ["drugName"] - }, - "required": ["drugName"], - "properties": { - "drugName": { - "type": "string" - } - } - } - }, - "hormoneTherapy": { - "type": "array", - "items": { - "type": "object", - "propertyNames": { - "enum": ["drugName"] - }, - "required": ["drugName"], - "properties": { - "drugName": { - "type": "string" - } - } - } - }, - "radiation": { - "type": "array", - "items": { - "type": "object", - "propertyNames": { - "enum": ["radiationTherapyModality", "anatomicalSiteIrradiated"] - }, - "required": ["radiationTherapyModality", "anatomicalSiteIrradiated"], - "properties": { - "radiationTherapyModality": { - "type": "string", - "enum": ["Electron", "Heavy Ions", "Photon", "Proton"] - }, - "anatomicalSiteIrradiated": { - "type": "string", - "enum": [ - "Abdomen", - "Body", - "Brain", - "Chest", - "Head", - "Liver", - "Lower Limb", - "Lung", - "Neck", - "Pelvis", - "Skin", - "Spine", - "Thorax", - "Upper Limb" - ] - } - } - } - } - }, - "allOf": [ - { - "if": { - "properties": { - "treatmentType": { - "contains": { - "const": "Chemotherapy" - } - } - } - }, - "then": { - "required": ["chemotherapy"] - } - }, - { - "if": { - "properties": { - "treatmentType": { - "contains": { - "const": "Radiation therapy" - } - } - } - }, - "then": { - "required": ["radiation"] - } - }, - { - "if": { - "properties": { - "treatmentType": { - "contains": { - "const": "Hormonal therapy" - } - } - } - }, - "then": { - "required": ["hormoneTherapy"] - } - } - ] - } - } - } - } - } - }, - "if": { - "properties": { - "vitalStatus": { - "const": "Deceased" - } - } - }, - "then": { - "required": ["causeOfDeath", "survivalTime"] - } - }, - "specimen": { - "type": "object", - "propertyNames": { - "enum": [ - "submitterSpecimenId", - "submitterPrimaryDiagnosisId", - "specimenAnatomicLocation", - "tumourGradingSystem", - "tumourGrade" - ] - }, - "required": [ - "submitterSpecimenId", - "submitterPrimaryDiagnosisId", - "specimenAnatomicLocation" - ], - "properties": { - "submitterSpecimenId": { - "type": "string" - }, - "submitterPrimaryDiagnosisId": { - "type": "string" - }, - "specimenAnatomicLocation": { - "type": "string", - "pattern": "^[C][0-9]{2}(.[0-9]{1})?$" - }, - "tumourGradingSystem": { - "type": "string", - "enum": [ - "FNCLCC grading system", - "Four-tier grading system", - "Gleason grade group system", - "Grading system for GISTs", - "Grading system for GNETs", - "ISUP grading system", - "Nuclear grading system for DCIS", - "Scarff-Bloom-Richardson grading system", - "Three-tier grading system", - "Two-tier grading system", - "WHO grading system for CNS tumours" - ] - }, - "tumourGrade": { - "type": "string", - "enum": [ - "Low grade", - "High grade", - "GX", - "G1", - "G2", - "G3", - "G4", - "Low", - "High", - "Grade I", - "Grade II", - "Grade III", - "Grade IV", - "Grade Group 1", - "Grade Group 2", - "Grade Group 3", - "Grade Group 4", - "Grade Group 5" - ] - } - } - }, - "publication": { - "type": "object", - "propertyNames": { - "enum": ["publication", "doi"] - }, - "properties": { - "publication": { - "type": ["string", "null"] - }, - "doi": { - "type": ["string", "null"] - } - } - }, - "collaborator": { - "type": "array", - "items": { - "type": "object", - "propertyNames": { - "enum": [ - "name", - "contactEmail" - ] - }, - "required": [ - "name" - ], - "properties": { - "name": { - "type": "string" - }, - "contactEmail": { - "type": [ - "string", - "null" - ], - "pattern": "^\\S+@\\S+\\.\\S+$" - } - } - } - } - } - } -} \ No newline at end of file diff --git a/guideMaterials/dataDownload/.gitkeep b/guideMaterials/dataDownload/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/guideMaterials/dataSubmission/SP059902.vcf.corrected.json b/guideMaterials/dataSubmission/SP059902.vcf.corrected.json deleted file mode 100644 index f0a7f46c..00000000 --- a/guideMaterials/dataSubmission/SP059902.vcf.corrected.json +++ /dev/null @@ -1,129 +0,0 @@ -{ - "studyId": "demo", - "analysisType": { - "name": "quickStartSchema" - }, - "collaborator": [ - { - "name": "IICR", - "contactEmail": "dataSubmitter@example.com" - } - ], - "samples": [ - { - "submitterSampleId": "SP059902", - "sampleType": "Total DNA", - "matchedNormalSubmitterSampleId": null, - "specimen": { - "submitterSpecimenId": "SP059902", - "specimenType": "Normal - tissue adjacent to primary tumour", - "tumourNormalDesignation": "Normal", - "specimenTissueSource": "Blood derived - bone marrow" - }, - "donor": { - "submitterDonorId": "DO0599", - "gender": "Female" - } - } - ], - "files": [ - { - "dataType": "Raw SV Calls", - "fileName": "SP059902.snv.vcf.gz", - "fileSize": 17246, - "fileMd5sum": "94b790078d8e98ad08ffc42389e2fa68", - "fileAccess": "open", - "fileType": "VCF", - "info": { - "dataCategory": "Simple Nucelotide Variation", - "jbrowseCoordinates": "hg38:chr1:100000-200000" - } - }, - { - "dataType": "Raw SV Calls", - "fileName": "SP059902.snv.vcf.gz.tbi", - "fileSize": 141, - "fileMd5sum": "f5cca6ace25d076d1f76cebf4ce3defd", - "fileAccess": "open", - "fileType": "TBI", - "info": { - "dataCategory": "Simple Nucelotide Variation", - "jbrowseCoordinates": "hg38:chr1:100000-200000" - } - } - ], - "specimen": { - "submitterPrimaryDiagnosisId": "PD059901", - "submitterSpecimenId": "SP059902", - "specimenAnatomicLocation": "C31", - "tumourGradingSystem": "Nuclear grading system for DCIS", - "tumourGrade": "G1" - }, - "donor": { - "submitterDonorId": "DO0599", - "primarySite": "Trachea", - "vitalStatus": "Alive", - "survivalTime": null, - "causeOfDeath": null, - "primaryDiagnosis": [ - { - "submitterPrimaryDiagnosisId": "PD059901", - "ageAtDiagnosis": 50, - "cancerTypeCode": "C34.2", - "clinicalTumourStagingSystem": "Binet staging system", - "clinicalStageGroup": "Stage A", - "treatment": [ - { - "submitterTreatmentId": "TR059901", - "treatmentType": [ - "Chemotherapy" - ], - "treatmentStartInterval": 58, - "treatmentDuration": 52, - "responseToTreatment": "Complete response", - "chemotherapy": [ - { - "drugName": "Tamoxifen " - } - ] - } - ], - "followUp": [ - { - "submitterFollowUpId": "FO059901", - "submitterTreatmentId": "TR059901", - "intervalOfFollowUp": 45, - "diseaseStatusAtFollowUp": "Stable", - "relapseType": null - } - ] - } - ] - }, - "experiment": { - "platform": "PacBio", - "experimentalStrategy": "WXS", - "model": "SEQUEL IIe", - "sequencingCenter": "CGTA", - "sequencingDate": "2021-03-08T19:00:00.000Z" - }, - "workflow": { - "workflowName": "Mutect2 Variant Calling", - "workflowShortName": "Mutect2Variant", - "workflowVersion": "0.1.1.1", - "genomeBuild": "GRCh38_hla_decoy_ebv", - "inputs": [ - { - "analysisType": "sequencing_alignment", - "tumourAnalysisId": "00000000-0000-0000-0000-0000000000599", - "normalAnalysisId": "00000000-0000-0000-0000-0000000000599" - } - ], - "runId": "RI0599", - "sessionId": "SI0599" - }, - "publication": { - "publication": "NAR", - "doi": "10.1093/nar/gkae188" - } -} diff --git a/guideMaterials/dataSubmission/SP059902.vcf.json b/guideMaterials/dataSubmission/SP059902.vcf.json deleted file mode 100644 index 65468ab2..00000000 --- a/guideMaterials/dataSubmission/SP059902.vcf.json +++ /dev/null @@ -1,128 +0,0 @@ -{ - "studyId": "demo", - "analysisType": { - "name": "quickStartSchema" - }, - "collaborator": [ - { - "contactEmail": "dataSubmitter@example.com" - } - ], - "samples": [ - { - "submitterSampleId": "SP059902", - "sampleType": "Total DNA", - "matchedNormalSubmitterSampleId": null, - "specimen": { - "submitterSpecimenId": "SP059902", - "specimenType": "Normal - tissue adjacent to primary tumour", - "tumourNormalDesignation": "Normal", - "specimenTissueSource": "Blood derived - bone marrow" - }, - "donor": { - "submitterDonorId": "DO0599", - "gender": "Female" - } - } - ], - "files": [ - { - "dataType": "Raw SV Calls", - "fileName": "SP059902.snv.vcf.gz", - "fileSize": 17246, - "fileMd5sum": "94b790078d8e98ad08ffc42389e2fa68", - "fileAccess": "open", - "fileType": "VCF", - "info": { - "dataCategory": "Simple Nucelotide Variation", - "jbrowseCoordinates": "hg38:chr1:100000-200000" - } - }, - { - "dataType": "Raw SV Calls", - "fileName": "SP059902.snv.vcf.gz.tbi", - "fileSize": 141, - "fileMd5sum": "f5cca6ace25d076d1f76cebf4ce3defd", - "fileAccess": "open", - "fileType": "TBI", - "info": { - "dataCategory": "Simple Nucelotide Variation", - "jbrowseCoordinates": "hg38:chr1:100000-200000" - } - } - ], - "specimen": { - "submitterPrimaryDiagnosisId": "PD059901", - "submitterSpecimenId": "SP059902", - "specimenAnatomicLocation": "C31", - "tumourGradingSystem": "Nuclear grading system for DCIS", - "tumourGrade": "G1" - }, - "donor": { - "submitterDonorId": "DO0599", - "primarySite": "Windpipe", - "vitalStatus": "Alive", - "survivalTime": null, - "causeOfDeath": null, - "primaryDiagnosis": [ - { - "submitterPrimaryDiagnosisId": "PD059901", - "ageAtDiagnosis": 50, - "cancerTypeCode": "C34.2", - "clinicalTumourStagingSystem": "Binet staging system", - "clinicalStageGroup": "Stage A", - "treatment": [ - { - "submitterTreatmentId": "TR059901", - "treatmentType": [ - "Chemotherapy" - ], - "treatmentStartInterval": 58, - "treatmentDuration": 52, - "responseToTreatment": "Complete response", - "chemotherapy": [ - { - "drugName": "Tamoxifen " - } - ] - } - ], - "followUp": [ - { - "submitterFollowUpId": "FO059901", - "submitterTreatmentId": "TR059901", - "intervalOfFollowUp": 45, - "diseaseStatusAtFollowUp": "Stable", - "relapseType": null - } - ] - } - ] - }, - "experiment": { - "platform": "PacBio", - "experimentalStrategy": "WXS", - "model": "SEQUEL IIe", - "sequencingCenter": "CGTA", - "sequencingDate": "2021-03-08T19:00:00.000Z" - }, - "workflow": { - "workflowName": "Mutect2 Variant Calling", - "workflowShortName": "Mutect2Variant", - "workflowVersion": "0.1.1.1", - "genomeBuild": "GRCh38_hla_decoy_ebv", - "inputs": [ - { - "analysisType": "sequencing_alignment", - "tumourAnalysisId": "00000000-0000-0000-0000-0000000000599", - "normalAnalysisId": "00000000-0000-0000-0000-0000000000599" - } - ], - "runId": "RI0599", - "sessionId": "SI0599" - }, - "publication": { - "publication": "NAR", - "doi": "10.1093/nar/gkae188" - } -} diff --git a/make.bat b/make.bat deleted file mode 100644 index 9e86a98a..00000000 --- a/make.bat +++ /dev/null @@ -1,51 +0,0 @@ -@echo off -setlocal enabledelayedexpansion - -if "%1"=="" goto help - -if "%1"=="platform" ( - set PROFILE=platform - goto run -) -if "%1"=="stageDev" ( - set PROFILE=stageDev - goto run -) -if "%1"=="arrangerDev" ( - set PROFILE=arrangerDev - goto run -) -if "%1"=="maestroDev" ( - set PROFILE=maestroDev - goto run -) -if "%1"=="songDev" ( - set PROFILE=songDev - goto run -) -if "%1"=="scoreDev" ( - set PROFILE=scoreDev - goto run -) -if "%1"=="down" ( - set PROFILE=platfrom - docker compose down - goto :eof -) - -goto help - -:run -docker compose --profile %PROFILE% up --attach conductor -goto :eof - -:help -echo Usage: build.bat [target] -echo Available targets: -echo platform -echo stageDev -echo arrangerDev -echo maestroDev -echo songDev -echo scoreDev -echo down diff --git a/persistentStorage/data-keycloak-db/PG_VERSION b/persistentStorage/data-keycloak-db/PG_VERSION deleted file mode 100644 index 8351c193..00000000 --- a/persistentStorage/data-keycloak-db/PG_VERSION +++ /dev/null @@ -1 +0,0 @@ -14 diff --git a/persistentStorage/data-keycloak-db/base/1/112 b/persistentStorage/data-keycloak-db/base/1/112 deleted file mode 100644 index 21db5147..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/112 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/113 b/persistentStorage/data-keycloak-db/base/1/113 deleted file mode 100644 index 3f06e2f0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/113 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/1247 b/persistentStorage/data-keycloak-db/base/1/1247 deleted file mode 100644 index cac034f9..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/1247 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/1247_fsm b/persistentStorage/data-keycloak-db/base/1/1247_fsm deleted file mode 100644 index 0e4086fb..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/1247_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/1247_vm b/persistentStorage/data-keycloak-db/base/1/1247_vm deleted file mode 100644 index 708f4aed..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/1247_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/1249 b/persistentStorage/data-keycloak-db/base/1/1249 deleted file mode 100644 index aec85207..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/1249 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/1249_fsm b/persistentStorage/data-keycloak-db/base/1/1249_fsm deleted file mode 100644 index 1f8868d0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/1249_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/1249_vm b/persistentStorage/data-keycloak-db/base/1/1249_vm deleted file mode 100644 index ec0b2516..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/1249_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/1255 b/persistentStorage/data-keycloak-db/base/1/1255 deleted file mode 100644 index ad8eae9d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/1255 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/1255_fsm b/persistentStorage/data-keycloak-db/base/1/1255_fsm deleted file mode 100644 index b730b34d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/1255_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/1255_vm b/persistentStorage/data-keycloak-db/base/1/1255_vm deleted file mode 100644 index 32919fdd..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/1255_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/1259 b/persistentStorage/data-keycloak-db/base/1/1259 deleted file mode 100644 index c8b79d6d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/1259 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/1259_fsm b/persistentStorage/data-keycloak-db/base/1/1259_fsm deleted file mode 100644 index 3d17e637..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/1259_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/1259_vm b/persistentStorage/data-keycloak-db/base/1/1259_vm deleted file mode 100644 index 5c2e63f0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/1259_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/13598 b/persistentStorage/data-keycloak-db/base/1/13598 deleted file mode 100644 index f536b0d2..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/13598 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/13598_fsm b/persistentStorage/data-keycloak-db/base/1/13598_fsm deleted file mode 100644 index dc87bf49..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/13598_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/13598_vm b/persistentStorage/data-keycloak-db/base/1/13598_vm deleted file mode 100644 index 17ee883c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/13598_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/13601 b/persistentStorage/data-keycloak-db/base/1/13601 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/13602 b/persistentStorage/data-keycloak-db/base/1/13602 deleted file mode 100644 index 752d0764..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/13602 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/13603 b/persistentStorage/data-keycloak-db/base/1/13603 deleted file mode 100644 index 239fb781..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/13603 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/13603_fsm b/persistentStorage/data-keycloak-db/base/1/13603_fsm deleted file mode 100644 index ce7c26eb..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/13603_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/13603_vm b/persistentStorage/data-keycloak-db/base/1/13603_vm deleted file mode 100644 index f1a19f83..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/13603_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/13606 b/persistentStorage/data-keycloak-db/base/1/13606 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/13607 b/persistentStorage/data-keycloak-db/base/1/13607 deleted file mode 100644 index a34d8cfe..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/13607 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/13608 b/persistentStorage/data-keycloak-db/base/1/13608 deleted file mode 100644 index 257e1065..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/13608 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/13608_fsm b/persistentStorage/data-keycloak-db/base/1/13608_fsm deleted file mode 100644 index d388044f..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/13608_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/13608_vm b/persistentStorage/data-keycloak-db/base/1/13608_vm deleted file mode 100644 index 5f1cf8d0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/13608_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/13611 b/persistentStorage/data-keycloak-db/base/1/13611 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/13612 b/persistentStorage/data-keycloak-db/base/1/13612 deleted file mode 100644 index 28970355..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/13612 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/13613 b/persistentStorage/data-keycloak-db/base/1/13613 deleted file mode 100644 index 2b4c488c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/13613 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/13613_fsm b/persistentStorage/data-keycloak-db/base/1/13613_fsm deleted file mode 100644 index a836ddf7..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/13613_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/13613_vm b/persistentStorage/data-keycloak-db/base/1/13613_vm deleted file mode 100644 index be95e308..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/13613_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/13616 b/persistentStorage/data-keycloak-db/base/1/13616 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/13617 b/persistentStorage/data-keycloak-db/base/1/13617 deleted file mode 100644 index 572afc12..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/13617 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/1417 b/persistentStorage/data-keycloak-db/base/1/1417 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/1418 b/persistentStorage/data-keycloak-db/base/1/1418 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/174 b/persistentStorage/data-keycloak-db/base/1/174 deleted file mode 100644 index 6312b18f..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/174 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/175 b/persistentStorage/data-keycloak-db/base/1/175 deleted file mode 100644 index 0f504d0b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/175 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2187 b/persistentStorage/data-keycloak-db/base/1/2187 deleted file mode 100644 index 6ea4d227..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2187 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2224 b/persistentStorage/data-keycloak-db/base/1/2224 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/2228 b/persistentStorage/data-keycloak-db/base/1/2228 deleted file mode 100644 index da192ed0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2228 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2328 b/persistentStorage/data-keycloak-db/base/1/2328 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/2336 b/persistentStorage/data-keycloak-db/base/1/2336 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/2337 b/persistentStorage/data-keycloak-db/base/1/2337 deleted file mode 100644 index d6111abe..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2337 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2579 b/persistentStorage/data-keycloak-db/base/1/2579 deleted file mode 100644 index 1659ed5e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2579 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2600 b/persistentStorage/data-keycloak-db/base/1/2600 deleted file mode 100644 index 827b5c23..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2600 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2600_fsm b/persistentStorage/data-keycloak-db/base/1/2600_fsm deleted file mode 100644 index 3f8f4089..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2600_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2600_vm b/persistentStorage/data-keycloak-db/base/1/2600_vm deleted file mode 100644 index b01cf52e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2600_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2601 b/persistentStorage/data-keycloak-db/base/1/2601 deleted file mode 100644 index d8001c8c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2601 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2601_fsm b/persistentStorage/data-keycloak-db/base/1/2601_fsm deleted file mode 100644 index d388044f..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2601_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2601_vm b/persistentStorage/data-keycloak-db/base/1/2601_vm deleted file mode 100644 index 0c4e3626..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2601_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2602 b/persistentStorage/data-keycloak-db/base/1/2602 deleted file mode 100644 index 4a27b0a3..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2602 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2602_fsm b/persistentStorage/data-keycloak-db/base/1/2602_fsm deleted file mode 100644 index 23170d85..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2602_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2602_vm b/persistentStorage/data-keycloak-db/base/1/2602_vm deleted file mode 100644 index 3f263ec7..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2602_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2603 b/persistentStorage/data-keycloak-db/base/1/2603 deleted file mode 100644 index d511af56..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2603 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2603_fsm b/persistentStorage/data-keycloak-db/base/1/2603_fsm deleted file mode 100644 index 949bd18f..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2603_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2603_vm b/persistentStorage/data-keycloak-db/base/1/2603_vm deleted file mode 100644 index 24766c7b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2603_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2604 b/persistentStorage/data-keycloak-db/base/1/2604 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/2605 b/persistentStorage/data-keycloak-db/base/1/2605 deleted file mode 100644 index 287bf968..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2605 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2605_fsm b/persistentStorage/data-keycloak-db/base/1/2605_fsm deleted file mode 100644 index c7723da0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2605_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2605_vm b/persistentStorage/data-keycloak-db/base/1/2605_vm deleted file mode 100644 index 577f6fb5..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2605_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2606 b/persistentStorage/data-keycloak-db/base/1/2606 deleted file mode 100644 index 93ca2f3d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2606 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2606_fsm b/persistentStorage/data-keycloak-db/base/1/2606_fsm deleted file mode 100644 index 37bfa7e7..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2606_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2606_vm b/persistentStorage/data-keycloak-db/base/1/2606_vm deleted file mode 100644 index 8ad5bbc4..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2606_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2607 b/persistentStorage/data-keycloak-db/base/1/2607 deleted file mode 100644 index bfad49ae..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2607 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2607_fsm b/persistentStorage/data-keycloak-db/base/1/2607_fsm deleted file mode 100644 index 80ac8b14..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2607_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2607_vm b/persistentStorage/data-keycloak-db/base/1/2607_vm deleted file mode 100644 index 4af50662..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2607_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2608 b/persistentStorage/data-keycloak-db/base/1/2608 deleted file mode 100644 index 43fb1416..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2608 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2608_fsm b/persistentStorage/data-keycloak-db/base/1/2608_fsm deleted file mode 100644 index 8e746db5..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2608_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2608_vm b/persistentStorage/data-keycloak-db/base/1/2608_vm deleted file mode 100644 index ae30bb8a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2608_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2609 b/persistentStorage/data-keycloak-db/base/1/2609 deleted file mode 100644 index 8bddfc4c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2609 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2609_fsm b/persistentStorage/data-keycloak-db/base/1/2609_fsm deleted file mode 100644 index adbf4b7d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2609_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2609_vm b/persistentStorage/data-keycloak-db/base/1/2609_vm deleted file mode 100644 index 66957e84..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2609_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2610 b/persistentStorage/data-keycloak-db/base/1/2610 deleted file mode 100644 index b659a82f..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2610 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2610_fsm b/persistentStorage/data-keycloak-db/base/1/2610_fsm deleted file mode 100644 index 39a3e893..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2610_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2610_vm b/persistentStorage/data-keycloak-db/base/1/2610_vm deleted file mode 100644 index 404ddf51..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2610_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2611 b/persistentStorage/data-keycloak-db/base/1/2611 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/2612 b/persistentStorage/data-keycloak-db/base/1/2612 deleted file mode 100644 index 09d3db9a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2612 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2612_fsm b/persistentStorage/data-keycloak-db/base/1/2612_fsm deleted file mode 100644 index 877976ac..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2612_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2612_vm b/persistentStorage/data-keycloak-db/base/1/2612_vm deleted file mode 100644 index fb040308..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2612_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2613 b/persistentStorage/data-keycloak-db/base/1/2613 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/2615 b/persistentStorage/data-keycloak-db/base/1/2615 deleted file mode 100644 index 8db70da0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2615 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2615_fsm b/persistentStorage/data-keycloak-db/base/1/2615_fsm deleted file mode 100644 index d041693e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2615_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2615_vm b/persistentStorage/data-keycloak-db/base/1/2615_vm deleted file mode 100644 index 2be5d8fe..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2615_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2616 b/persistentStorage/data-keycloak-db/base/1/2616 deleted file mode 100644 index 0d60d797..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2616 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2616_fsm b/persistentStorage/data-keycloak-db/base/1/2616_fsm deleted file mode 100644 index cb924c95..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2616_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2616_vm b/persistentStorage/data-keycloak-db/base/1/2616_vm deleted file mode 100644 index 32b43b65..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2616_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2617 b/persistentStorage/data-keycloak-db/base/1/2617 deleted file mode 100644 index 86965511..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2617 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2617_fsm b/persistentStorage/data-keycloak-db/base/1/2617_fsm deleted file mode 100644 index 84060f4b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2617_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2617_vm b/persistentStorage/data-keycloak-db/base/1/2617_vm deleted file mode 100644 index a6a45cc3..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2617_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2618 b/persistentStorage/data-keycloak-db/base/1/2618 deleted file mode 100644 index 2893aa34..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2618 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2618_fsm b/persistentStorage/data-keycloak-db/base/1/2618_fsm deleted file mode 100644 index b92d2da4..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2618_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2618_vm b/persistentStorage/data-keycloak-db/base/1/2618_vm deleted file mode 100644 index 0fd8ac1c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2618_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2619 b/persistentStorage/data-keycloak-db/base/1/2619 deleted file mode 100644 index 7acc667a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2619 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2619_fsm b/persistentStorage/data-keycloak-db/base/1/2619_fsm deleted file mode 100644 index ee863db4..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2619_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2619_vm b/persistentStorage/data-keycloak-db/base/1/2619_vm deleted file mode 100644 index 6d85b37c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2619_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2620 b/persistentStorage/data-keycloak-db/base/1/2620 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/2650 b/persistentStorage/data-keycloak-db/base/1/2650 deleted file mode 100644 index 7627c51a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2650 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2651 b/persistentStorage/data-keycloak-db/base/1/2651 deleted file mode 100644 index f9c68ee5..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2651 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2652 b/persistentStorage/data-keycloak-db/base/1/2652 deleted file mode 100644 index 7b6c2f24..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2652 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2653 b/persistentStorage/data-keycloak-db/base/1/2653 deleted file mode 100644 index 541d5f4a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2653 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2654 b/persistentStorage/data-keycloak-db/base/1/2654 deleted file mode 100644 index 29ad199a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2654 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2655 b/persistentStorage/data-keycloak-db/base/1/2655 deleted file mode 100644 index b4acab68..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2655 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2656 b/persistentStorage/data-keycloak-db/base/1/2656 deleted file mode 100644 index 9e5e1b0c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2656 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2657 b/persistentStorage/data-keycloak-db/base/1/2657 deleted file mode 100644 index 0d2b3a8d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2657 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2658 b/persistentStorage/data-keycloak-db/base/1/2658 deleted file mode 100644 index 6dbe3957..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2658 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2659 b/persistentStorage/data-keycloak-db/base/1/2659 deleted file mode 100644 index cf685c39..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2659 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2660 b/persistentStorage/data-keycloak-db/base/1/2660 deleted file mode 100644 index 59c279a1..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2660 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2661 b/persistentStorage/data-keycloak-db/base/1/2661 deleted file mode 100644 index 040e9976..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2661 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2662 b/persistentStorage/data-keycloak-db/base/1/2662 deleted file mode 100644 index 1d56660e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2662 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2663 b/persistentStorage/data-keycloak-db/base/1/2663 deleted file mode 100644 index 259eebed..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2663 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2664 b/persistentStorage/data-keycloak-db/base/1/2664 deleted file mode 100644 index b7c14dee..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2664 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2665 b/persistentStorage/data-keycloak-db/base/1/2665 deleted file mode 100644 index 1af33b9e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2665 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2666 b/persistentStorage/data-keycloak-db/base/1/2666 deleted file mode 100644 index 5c05ac8b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2666 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2667 b/persistentStorage/data-keycloak-db/base/1/2667 deleted file mode 100644 index ad8282f5..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2667 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2668 b/persistentStorage/data-keycloak-db/base/1/2668 deleted file mode 100644 index 1ceedaaf..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2668 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2669 b/persistentStorage/data-keycloak-db/base/1/2669 deleted file mode 100644 index 865bb062..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2669 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2670 b/persistentStorage/data-keycloak-db/base/1/2670 deleted file mode 100644 index 01be7b00..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2670 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2673 b/persistentStorage/data-keycloak-db/base/1/2673 deleted file mode 100644 index 106411b0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2673 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2673_fsm b/persistentStorage/data-keycloak-db/base/1/2673_fsm deleted file mode 100644 index 2c8d238d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2673_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2674 b/persistentStorage/data-keycloak-db/base/1/2674 deleted file mode 100644 index e5cc937a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2674 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2674_fsm b/persistentStorage/data-keycloak-db/base/1/2674_fsm deleted file mode 100644 index ed74869b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2674_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2675 b/persistentStorage/data-keycloak-db/base/1/2675 deleted file mode 100644 index 4c2d5263..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2675 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2678 b/persistentStorage/data-keycloak-db/base/1/2678 deleted file mode 100644 index 1b959664..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2678 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2679 b/persistentStorage/data-keycloak-db/base/1/2679 deleted file mode 100644 index afd22d69..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2679 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2680 b/persistentStorage/data-keycloak-db/base/1/2680 deleted file mode 100644 index abc5412a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2680 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2681 b/persistentStorage/data-keycloak-db/base/1/2681 deleted file mode 100644 index 11f4836a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2681 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2682 b/persistentStorage/data-keycloak-db/base/1/2682 deleted file mode 100644 index a17584c1..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2682 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2683 b/persistentStorage/data-keycloak-db/base/1/2683 deleted file mode 100644 index ef3053d1..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2683 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2684 b/persistentStorage/data-keycloak-db/base/1/2684 deleted file mode 100644 index 0e7d9c11..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2684 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2685 b/persistentStorage/data-keycloak-db/base/1/2685 deleted file mode 100644 index e131ea4c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2685 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2686 b/persistentStorage/data-keycloak-db/base/1/2686 deleted file mode 100644 index 832bcb9a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2686 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2687 b/persistentStorage/data-keycloak-db/base/1/2687 deleted file mode 100644 index 189fd41e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2687 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2688 b/persistentStorage/data-keycloak-db/base/1/2688 deleted file mode 100644 index 6ebe3e7e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2688 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2689 b/persistentStorage/data-keycloak-db/base/1/2689 deleted file mode 100644 index daa83a39..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2689 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2690 b/persistentStorage/data-keycloak-db/base/1/2690 deleted file mode 100644 index 0806b469..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2690 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2691 b/persistentStorage/data-keycloak-db/base/1/2691 deleted file mode 100644 index 9cd87042..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2691 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2692 b/persistentStorage/data-keycloak-db/base/1/2692 deleted file mode 100644 index 7296dcf7..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2692 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2693 b/persistentStorage/data-keycloak-db/base/1/2693 deleted file mode 100644 index 8084e6e0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2693 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2696 b/persistentStorage/data-keycloak-db/base/1/2696 deleted file mode 100644 index f7393f47..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2696 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2699 b/persistentStorage/data-keycloak-db/base/1/2699 deleted file mode 100644 index cb458c10..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2699 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2701 b/persistentStorage/data-keycloak-db/base/1/2701 deleted file mode 100644 index c18ab55d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2701 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2702 b/persistentStorage/data-keycloak-db/base/1/2702 deleted file mode 100644 index 91ddfc9a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2702 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2703 b/persistentStorage/data-keycloak-db/base/1/2703 deleted file mode 100644 index 11d15164..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2703 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2704 b/persistentStorage/data-keycloak-db/base/1/2704 deleted file mode 100644 index 886285ff..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2704 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2753 b/persistentStorage/data-keycloak-db/base/1/2753 deleted file mode 100644 index 3c16dff6..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2753 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2753_fsm b/persistentStorage/data-keycloak-db/base/1/2753_fsm deleted file mode 100644 index 642bce3b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2753_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2753_vm b/persistentStorage/data-keycloak-db/base/1/2753_vm deleted file mode 100644 index 928f7e31..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2753_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2754 b/persistentStorage/data-keycloak-db/base/1/2754 deleted file mode 100644 index 1cbd156e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2754 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2755 b/persistentStorage/data-keycloak-db/base/1/2755 deleted file mode 100644 index 0fc8e919..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2755 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2756 b/persistentStorage/data-keycloak-db/base/1/2756 deleted file mode 100644 index 5d355e2a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2756 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2757 b/persistentStorage/data-keycloak-db/base/1/2757 deleted file mode 100644 index 6f40a7fb..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2757 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2830 b/persistentStorage/data-keycloak-db/base/1/2830 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/2831 b/persistentStorage/data-keycloak-db/base/1/2831 deleted file mode 100644 index e4ad5c17..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2831 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2832 b/persistentStorage/data-keycloak-db/base/1/2832 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/2833 b/persistentStorage/data-keycloak-db/base/1/2833 deleted file mode 100644 index b97afa32..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2833 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2834 b/persistentStorage/data-keycloak-db/base/1/2834 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/2835 b/persistentStorage/data-keycloak-db/base/1/2835 deleted file mode 100644 index 6aa119f3..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2835 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2836 b/persistentStorage/data-keycloak-db/base/1/2836 deleted file mode 100644 index c688f81c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2836 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2836_fsm b/persistentStorage/data-keycloak-db/base/1/2836_fsm deleted file mode 100644 index 4066e1ec..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2836_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2836_vm b/persistentStorage/data-keycloak-db/base/1/2836_vm deleted file mode 100644 index d2ba922d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2836_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2837 b/persistentStorage/data-keycloak-db/base/1/2837 deleted file mode 100644 index ed7a191d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2837 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2838 b/persistentStorage/data-keycloak-db/base/1/2838 deleted file mode 100644 index 4cb35492..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2838 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2838_fsm b/persistentStorage/data-keycloak-db/base/1/2838_fsm deleted file mode 100644 index 4cc16309..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2838_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2838_vm b/persistentStorage/data-keycloak-db/base/1/2838_vm deleted file mode 100644 index c02f1ce0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2838_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2839 b/persistentStorage/data-keycloak-db/base/1/2839 deleted file mode 100644 index 518516dd..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2839 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2840 b/persistentStorage/data-keycloak-db/base/1/2840 deleted file mode 100644 index ea1cef46..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2840 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2840_fsm b/persistentStorage/data-keycloak-db/base/1/2840_fsm deleted file mode 100644 index 49de3921..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2840_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2840_vm b/persistentStorage/data-keycloak-db/base/1/2840_vm deleted file mode 100644 index 7033e055..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2840_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2841 b/persistentStorage/data-keycloak-db/base/1/2841 deleted file mode 100644 index a0776384..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2841 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/2995 b/persistentStorage/data-keycloak-db/base/1/2995 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/2996 b/persistentStorage/data-keycloak-db/base/1/2996 deleted file mode 100644 index 35f2758f..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/2996 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3079 b/persistentStorage/data-keycloak-db/base/1/3079 deleted file mode 100644 index 08f2b014..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3079 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3079_fsm b/persistentStorage/data-keycloak-db/base/1/3079_fsm deleted file mode 100644 index 7732d22b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3079_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3079_vm b/persistentStorage/data-keycloak-db/base/1/3079_vm deleted file mode 100644 index e2bfe1e5..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3079_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3080 b/persistentStorage/data-keycloak-db/base/1/3080 deleted file mode 100644 index 77890e90..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3080 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3081 b/persistentStorage/data-keycloak-db/base/1/3081 deleted file mode 100644 index c9e8c6e7..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3081 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3085 b/persistentStorage/data-keycloak-db/base/1/3085 deleted file mode 100644 index d83ce3e2..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3085 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3118 b/persistentStorage/data-keycloak-db/base/1/3118 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/3119 b/persistentStorage/data-keycloak-db/base/1/3119 deleted file mode 100644 index c0d08b7e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3119 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3164 b/persistentStorage/data-keycloak-db/base/1/3164 deleted file mode 100644 index b8d5a33f..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3164 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3256 b/persistentStorage/data-keycloak-db/base/1/3256 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/3257 b/persistentStorage/data-keycloak-db/base/1/3257 deleted file mode 100644 index 85937d28..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3257 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3258 b/persistentStorage/data-keycloak-db/base/1/3258 deleted file mode 100644 index 5f252a3c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3258 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3350 b/persistentStorage/data-keycloak-db/base/1/3350 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/3351 b/persistentStorage/data-keycloak-db/base/1/3351 deleted file mode 100644 index 0aecbb30..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3351 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3379 b/persistentStorage/data-keycloak-db/base/1/3379 deleted file mode 100644 index 3992c116..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3379 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3380 b/persistentStorage/data-keycloak-db/base/1/3380 deleted file mode 100644 index 8f72126d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3380 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3381 b/persistentStorage/data-keycloak-db/base/1/3381 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/3394 b/persistentStorage/data-keycloak-db/base/1/3394 deleted file mode 100644 index 7fa1e11b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3394 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3394_fsm b/persistentStorage/data-keycloak-db/base/1/3394_fsm deleted file mode 100644 index f8d6070c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3394_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3394_vm b/persistentStorage/data-keycloak-db/base/1/3394_vm deleted file mode 100644 index 5db2a120..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3394_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3395 b/persistentStorage/data-keycloak-db/base/1/3395 deleted file mode 100644 index fa7b9d72..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3395 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3429 b/persistentStorage/data-keycloak-db/base/1/3429 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/3430 b/persistentStorage/data-keycloak-db/base/1/3430 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/3431 b/persistentStorage/data-keycloak-db/base/1/3431 deleted file mode 100644 index 553b503b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3431 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3433 b/persistentStorage/data-keycloak-db/base/1/3433 deleted file mode 100644 index 9b9eb9ce..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3433 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3439 b/persistentStorage/data-keycloak-db/base/1/3439 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/3440 b/persistentStorage/data-keycloak-db/base/1/3440 deleted file mode 100644 index 47135494..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3440 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3455 b/persistentStorage/data-keycloak-db/base/1/3455 deleted file mode 100644 index a7d2f24e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3455 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3456 b/persistentStorage/data-keycloak-db/base/1/3456 deleted file mode 100644 index e3460d9d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3456 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3456_fsm b/persistentStorage/data-keycloak-db/base/1/3456_fsm deleted file mode 100644 index fc8f8b80..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3456_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3456_vm b/persistentStorage/data-keycloak-db/base/1/3456_vm deleted file mode 100644 index 89d107bd..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3456_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3466 b/persistentStorage/data-keycloak-db/base/1/3466 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/3467 b/persistentStorage/data-keycloak-db/base/1/3467 deleted file mode 100644 index 68eab7b6..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3467 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3468 b/persistentStorage/data-keycloak-db/base/1/3468 deleted file mode 100644 index 63a8f7cd..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3468 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3501 b/persistentStorage/data-keycloak-db/base/1/3501 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/3502 b/persistentStorage/data-keycloak-db/base/1/3502 deleted file mode 100644 index 7676fd82..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3502 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3503 b/persistentStorage/data-keycloak-db/base/1/3503 deleted file mode 100644 index 22146019..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3503 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3534 b/persistentStorage/data-keycloak-db/base/1/3534 deleted file mode 100644 index 9a307a42..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3534 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3541 b/persistentStorage/data-keycloak-db/base/1/3541 deleted file mode 100644 index 40869ad3..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3541 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3541_fsm b/persistentStorage/data-keycloak-db/base/1/3541_fsm deleted file mode 100644 index a3a2de4d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3541_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3541_vm b/persistentStorage/data-keycloak-db/base/1/3541_vm deleted file mode 100644 index bd8c84af..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3541_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3542 b/persistentStorage/data-keycloak-db/base/1/3542 deleted file mode 100644 index ee21b6ae..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3542 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3574 b/persistentStorage/data-keycloak-db/base/1/3574 deleted file mode 100644 index 418bbca1..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3574 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3575 b/persistentStorage/data-keycloak-db/base/1/3575 deleted file mode 100644 index 6addf868..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3575 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3576 b/persistentStorage/data-keycloak-db/base/1/3576 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/3596 b/persistentStorage/data-keycloak-db/base/1/3596 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/3597 b/persistentStorage/data-keycloak-db/base/1/3597 deleted file mode 100644 index 71d2820e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3597 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3598 b/persistentStorage/data-keycloak-db/base/1/3598 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/3599 b/persistentStorage/data-keycloak-db/base/1/3599 deleted file mode 100644 index 507ca587..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3599 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3600 b/persistentStorage/data-keycloak-db/base/1/3600 deleted file mode 100644 index 41c62c58..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3600 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3600_fsm b/persistentStorage/data-keycloak-db/base/1/3600_fsm deleted file mode 100644 index cebec199..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3600_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3600_vm b/persistentStorage/data-keycloak-db/base/1/3600_vm deleted file mode 100644 index e611f185..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3600_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3601 b/persistentStorage/data-keycloak-db/base/1/3601 deleted file mode 100644 index 04c846ec..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3601 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3601_fsm b/persistentStorage/data-keycloak-db/base/1/3601_fsm deleted file mode 100644 index 7732d22b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3601_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3601_vm b/persistentStorage/data-keycloak-db/base/1/3601_vm deleted file mode 100644 index e63f9b2d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3601_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3602 b/persistentStorage/data-keycloak-db/base/1/3602 deleted file mode 100644 index e77e1ad5..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3602 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3602_fsm b/persistentStorage/data-keycloak-db/base/1/3602_fsm deleted file mode 100644 index d7897de2..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3602_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3602_vm b/persistentStorage/data-keycloak-db/base/1/3602_vm deleted file mode 100644 index 23986f7e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3602_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3603 b/persistentStorage/data-keycloak-db/base/1/3603 deleted file mode 100644 index 57062b10..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3603 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3603_fsm b/persistentStorage/data-keycloak-db/base/1/3603_fsm deleted file mode 100644 index c28dd4fa..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3603_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3603_vm b/persistentStorage/data-keycloak-db/base/1/3603_vm deleted file mode 100644 index b5dac618..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3603_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3604 b/persistentStorage/data-keycloak-db/base/1/3604 deleted file mode 100644 index 4a979b17..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3604 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3605 b/persistentStorage/data-keycloak-db/base/1/3605 deleted file mode 100644 index 7e7c31ca..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3605 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3606 b/persistentStorage/data-keycloak-db/base/1/3606 deleted file mode 100644 index de60e2ff..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3606 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3607 b/persistentStorage/data-keycloak-db/base/1/3607 deleted file mode 100644 index ff537351..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3607 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3608 b/persistentStorage/data-keycloak-db/base/1/3608 deleted file mode 100644 index bf99099a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3608 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3609 b/persistentStorage/data-keycloak-db/base/1/3609 deleted file mode 100644 index aca244c6..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3609 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3712 b/persistentStorage/data-keycloak-db/base/1/3712 deleted file mode 100644 index e4e2c033..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3712 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3764 b/persistentStorage/data-keycloak-db/base/1/3764 deleted file mode 100644 index da4bd39c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3764 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3764_fsm b/persistentStorage/data-keycloak-db/base/1/3764_fsm deleted file mode 100644 index f64db4df..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3764_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3764_vm b/persistentStorage/data-keycloak-db/base/1/3764_vm deleted file mode 100644 index 3930bc12..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3764_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3766 b/persistentStorage/data-keycloak-db/base/1/3766 deleted file mode 100644 index 44d0b7de..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3766 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3767 b/persistentStorage/data-keycloak-db/base/1/3767 deleted file mode 100644 index b8e981f8..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3767 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/3997 b/persistentStorage/data-keycloak-db/base/1/3997 deleted file mode 100644 index fd6175ff..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/3997 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/4143 b/persistentStorage/data-keycloak-db/base/1/4143 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/4144 b/persistentStorage/data-keycloak-db/base/1/4144 deleted file mode 100644 index a3569d11..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/4144 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/4145 b/persistentStorage/data-keycloak-db/base/1/4145 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/4146 b/persistentStorage/data-keycloak-db/base/1/4146 deleted file mode 100644 index 3397d87e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/4146 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/4147 b/persistentStorage/data-keycloak-db/base/1/4147 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/4148 b/persistentStorage/data-keycloak-db/base/1/4148 deleted file mode 100644 index 6e10fc5e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/4148 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/4149 b/persistentStorage/data-keycloak-db/base/1/4149 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/4150 b/persistentStorage/data-keycloak-db/base/1/4150 deleted file mode 100644 index a0ea1cc0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/4150 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/4151 b/persistentStorage/data-keycloak-db/base/1/4151 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/4152 b/persistentStorage/data-keycloak-db/base/1/4152 deleted file mode 100644 index 4179f382..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/4152 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/4153 b/persistentStorage/data-keycloak-db/base/1/4153 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/4154 b/persistentStorage/data-keycloak-db/base/1/4154 deleted file mode 100644 index a5e44b4f..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/4154 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/4155 b/persistentStorage/data-keycloak-db/base/1/4155 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/4156 b/persistentStorage/data-keycloak-db/base/1/4156 deleted file mode 100644 index e3a35c68..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/4156 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/4157 b/persistentStorage/data-keycloak-db/base/1/4157 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/4158 b/persistentStorage/data-keycloak-db/base/1/4158 deleted file mode 100644 index 3de62cdf..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/4158 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/4159 b/persistentStorage/data-keycloak-db/base/1/4159 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/4160 b/persistentStorage/data-keycloak-db/base/1/4160 deleted file mode 100644 index b17f909c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/4160 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/4163 b/persistentStorage/data-keycloak-db/base/1/4163 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/4164 b/persistentStorage/data-keycloak-db/base/1/4164 deleted file mode 100644 index 2e798538..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/4164 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/4165 b/persistentStorage/data-keycloak-db/base/1/4165 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/4166 b/persistentStorage/data-keycloak-db/base/1/4166 deleted file mode 100644 index 9e74293a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/4166 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/4167 b/persistentStorage/data-keycloak-db/base/1/4167 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/4168 b/persistentStorage/data-keycloak-db/base/1/4168 deleted file mode 100644 index a032ccae..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/4168 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/4169 b/persistentStorage/data-keycloak-db/base/1/4169 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/4170 b/persistentStorage/data-keycloak-db/base/1/4170 deleted file mode 100644 index c75cf673..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/4170 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/4171 b/persistentStorage/data-keycloak-db/base/1/4171 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/4172 b/persistentStorage/data-keycloak-db/base/1/4172 deleted file mode 100644 index f9cb0379..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/4172 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/4173 b/persistentStorage/data-keycloak-db/base/1/4173 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/4174 b/persistentStorage/data-keycloak-db/base/1/4174 deleted file mode 100644 index deb4a11b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/4174 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/5002 b/persistentStorage/data-keycloak-db/base/1/5002 deleted file mode 100644 index 32af7a1e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/5002 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/548 b/persistentStorage/data-keycloak-db/base/1/548 deleted file mode 100644 index 9f219478..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/548 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/549 b/persistentStorage/data-keycloak-db/base/1/549 deleted file mode 100644 index 68efb3f3..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/549 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/6102 b/persistentStorage/data-keycloak-db/base/1/6102 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/6104 b/persistentStorage/data-keycloak-db/base/1/6104 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/6106 b/persistentStorage/data-keycloak-db/base/1/6106 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/6110 b/persistentStorage/data-keycloak-db/base/1/6110 deleted file mode 100644 index 536b80d3..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/6110 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/6111 b/persistentStorage/data-keycloak-db/base/1/6111 deleted file mode 100644 index 3d22c94f..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/6111 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/6112 b/persistentStorage/data-keycloak-db/base/1/6112 deleted file mode 100644 index 9e47d5c5..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/6112 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/6113 b/persistentStorage/data-keycloak-db/base/1/6113 deleted file mode 100644 index 4e57f5be..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/6113 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/6117 b/persistentStorage/data-keycloak-db/base/1/6117 deleted file mode 100644 index 296b14e8..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/6117 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/6175 b/persistentStorage/data-keycloak-db/base/1/6175 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/6176 b/persistentStorage/data-keycloak-db/base/1/6176 deleted file mode 100644 index 45c76f44..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/6176 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/826 b/persistentStorage/data-keycloak-db/base/1/826 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/1/827 b/persistentStorage/data-keycloak-db/base/1/827 deleted file mode 100644 index 86db9fe6..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/827 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/828 b/persistentStorage/data-keycloak-db/base/1/828 deleted file mode 100644 index 4a522991..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/828 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/1/PG_VERSION b/persistentStorage/data-keycloak-db/base/1/PG_VERSION deleted file mode 100644 index 8351c193..00000000 --- a/persistentStorage/data-keycloak-db/base/1/PG_VERSION +++ /dev/null @@ -1 +0,0 @@ -14 diff --git a/persistentStorage/data-keycloak-db/base/1/pg_filenode.map b/persistentStorage/data-keycloak-db/base/1/pg_filenode.map deleted file mode 100644 index 193d78f3..00000000 Binary files a/persistentStorage/data-keycloak-db/base/1/pg_filenode.map and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/112 b/persistentStorage/data-keycloak-db/base/13779/112 deleted file mode 100644 index 21db5147..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/112 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/113 b/persistentStorage/data-keycloak-db/base/13779/113 deleted file mode 100644 index 3f06e2f0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/113 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/1247 b/persistentStorage/data-keycloak-db/base/13779/1247 deleted file mode 100644 index cac034f9..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/1247 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/1247_fsm b/persistentStorage/data-keycloak-db/base/13779/1247_fsm deleted file mode 100644 index 0e4086fb..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/1247_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/1247_vm b/persistentStorage/data-keycloak-db/base/13779/1247_vm deleted file mode 100644 index 708f4aed..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/1247_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/1249 b/persistentStorage/data-keycloak-db/base/13779/1249 deleted file mode 100644 index aec85207..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/1249 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/1249_fsm b/persistentStorage/data-keycloak-db/base/13779/1249_fsm deleted file mode 100644 index 1f8868d0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/1249_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/1249_vm b/persistentStorage/data-keycloak-db/base/13779/1249_vm deleted file mode 100644 index ec0b2516..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/1249_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/1255 b/persistentStorage/data-keycloak-db/base/13779/1255 deleted file mode 100644 index ad8eae9d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/1255 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/1255_fsm b/persistentStorage/data-keycloak-db/base/13779/1255_fsm deleted file mode 100644 index b730b34d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/1255_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/1255_vm b/persistentStorage/data-keycloak-db/base/13779/1255_vm deleted file mode 100644 index 32919fdd..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/1255_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/1259 b/persistentStorage/data-keycloak-db/base/13779/1259 deleted file mode 100644 index ebb36d64..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/1259 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/1259_fsm b/persistentStorage/data-keycloak-db/base/13779/1259_fsm deleted file mode 100644 index 3d17e637..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/1259_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/1259_vm b/persistentStorage/data-keycloak-db/base/13779/1259_vm deleted file mode 100644 index 5c2e63f0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/1259_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/13598 b/persistentStorage/data-keycloak-db/base/13779/13598 deleted file mode 100644 index f536b0d2..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/13598 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/13598_fsm b/persistentStorage/data-keycloak-db/base/13779/13598_fsm deleted file mode 100644 index dc87bf49..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/13598_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/13598_vm b/persistentStorage/data-keycloak-db/base/13779/13598_vm deleted file mode 100644 index 17ee883c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/13598_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/13601 b/persistentStorage/data-keycloak-db/base/13779/13601 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/13602 b/persistentStorage/data-keycloak-db/base/13779/13602 deleted file mode 100644 index 752d0764..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/13602 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/13603 b/persistentStorage/data-keycloak-db/base/13779/13603 deleted file mode 100644 index 239fb781..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/13603 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/13603_fsm b/persistentStorage/data-keycloak-db/base/13779/13603_fsm deleted file mode 100644 index ce7c26eb..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/13603_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/13603_vm b/persistentStorage/data-keycloak-db/base/13779/13603_vm deleted file mode 100644 index f1a19f83..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/13603_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/13606 b/persistentStorage/data-keycloak-db/base/13779/13606 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/13607 b/persistentStorage/data-keycloak-db/base/13779/13607 deleted file mode 100644 index a34d8cfe..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/13607 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/13608 b/persistentStorage/data-keycloak-db/base/13779/13608 deleted file mode 100644 index 257e1065..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/13608 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/13608_fsm b/persistentStorage/data-keycloak-db/base/13779/13608_fsm deleted file mode 100644 index d388044f..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/13608_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/13608_vm b/persistentStorage/data-keycloak-db/base/13779/13608_vm deleted file mode 100644 index 5f1cf8d0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/13608_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/13611 b/persistentStorage/data-keycloak-db/base/13779/13611 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/13612 b/persistentStorage/data-keycloak-db/base/13779/13612 deleted file mode 100644 index 28970355..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/13612 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/13613 b/persistentStorage/data-keycloak-db/base/13779/13613 deleted file mode 100644 index 2b4c488c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/13613 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/13613_fsm b/persistentStorage/data-keycloak-db/base/13779/13613_fsm deleted file mode 100644 index a836ddf7..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/13613_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/13613_vm b/persistentStorage/data-keycloak-db/base/13779/13613_vm deleted file mode 100644 index be95e308..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/13613_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/13616 b/persistentStorage/data-keycloak-db/base/13779/13616 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/13617 b/persistentStorage/data-keycloak-db/base/13779/13617 deleted file mode 100644 index 572afc12..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/13617 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/1417 b/persistentStorage/data-keycloak-db/base/13779/1417 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/1418 b/persistentStorage/data-keycloak-db/base/13779/1418 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/174 b/persistentStorage/data-keycloak-db/base/13779/174 deleted file mode 100644 index 6312b18f..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/174 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/175 b/persistentStorage/data-keycloak-db/base/13779/175 deleted file mode 100644 index 0f504d0b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/175 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2187 b/persistentStorage/data-keycloak-db/base/13779/2187 deleted file mode 100644 index 6ea4d227..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2187 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2224 b/persistentStorage/data-keycloak-db/base/13779/2224 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/2228 b/persistentStorage/data-keycloak-db/base/13779/2228 deleted file mode 100644 index da192ed0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2228 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2328 b/persistentStorage/data-keycloak-db/base/13779/2328 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/2336 b/persistentStorage/data-keycloak-db/base/13779/2336 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/2337 b/persistentStorage/data-keycloak-db/base/13779/2337 deleted file mode 100644 index d6111abe..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2337 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2579 b/persistentStorage/data-keycloak-db/base/13779/2579 deleted file mode 100644 index 1659ed5e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2579 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2600 b/persistentStorage/data-keycloak-db/base/13779/2600 deleted file mode 100644 index 827b5c23..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2600 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2600_fsm b/persistentStorage/data-keycloak-db/base/13779/2600_fsm deleted file mode 100644 index 3f8f4089..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2600_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2600_vm b/persistentStorage/data-keycloak-db/base/13779/2600_vm deleted file mode 100644 index b01cf52e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2600_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2601 b/persistentStorage/data-keycloak-db/base/13779/2601 deleted file mode 100644 index d8001c8c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2601 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2601_fsm b/persistentStorage/data-keycloak-db/base/13779/2601_fsm deleted file mode 100644 index d388044f..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2601_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2601_vm b/persistentStorage/data-keycloak-db/base/13779/2601_vm deleted file mode 100644 index 0c4e3626..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2601_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2602 b/persistentStorage/data-keycloak-db/base/13779/2602 deleted file mode 100644 index 4a27b0a3..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2602 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2602_fsm b/persistentStorage/data-keycloak-db/base/13779/2602_fsm deleted file mode 100644 index 23170d85..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2602_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2602_vm b/persistentStorage/data-keycloak-db/base/13779/2602_vm deleted file mode 100644 index 3f263ec7..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2602_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2603 b/persistentStorage/data-keycloak-db/base/13779/2603 deleted file mode 100644 index d511af56..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2603 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2603_fsm b/persistentStorage/data-keycloak-db/base/13779/2603_fsm deleted file mode 100644 index 949bd18f..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2603_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2603_vm b/persistentStorage/data-keycloak-db/base/13779/2603_vm deleted file mode 100644 index 24766c7b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2603_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2604 b/persistentStorage/data-keycloak-db/base/13779/2604 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/2605 b/persistentStorage/data-keycloak-db/base/13779/2605 deleted file mode 100644 index 287bf968..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2605 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2605_fsm b/persistentStorage/data-keycloak-db/base/13779/2605_fsm deleted file mode 100644 index c7723da0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2605_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2605_vm b/persistentStorage/data-keycloak-db/base/13779/2605_vm deleted file mode 100644 index 577f6fb5..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2605_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2606 b/persistentStorage/data-keycloak-db/base/13779/2606 deleted file mode 100644 index 93ca2f3d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2606 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2606_fsm b/persistentStorage/data-keycloak-db/base/13779/2606_fsm deleted file mode 100644 index 37bfa7e7..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2606_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2606_vm b/persistentStorage/data-keycloak-db/base/13779/2606_vm deleted file mode 100644 index 8ad5bbc4..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2606_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2607 b/persistentStorage/data-keycloak-db/base/13779/2607 deleted file mode 100644 index bfad49ae..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2607 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2607_fsm b/persistentStorage/data-keycloak-db/base/13779/2607_fsm deleted file mode 100644 index 80ac8b14..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2607_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2607_vm b/persistentStorage/data-keycloak-db/base/13779/2607_vm deleted file mode 100644 index 4af50662..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2607_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2608 b/persistentStorage/data-keycloak-db/base/13779/2608 deleted file mode 100644 index 43fb1416..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2608 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2608_fsm b/persistentStorage/data-keycloak-db/base/13779/2608_fsm deleted file mode 100644 index 8e746db5..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2608_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2608_vm b/persistentStorage/data-keycloak-db/base/13779/2608_vm deleted file mode 100644 index ae30bb8a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2608_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2609 b/persistentStorage/data-keycloak-db/base/13779/2609 deleted file mode 100644 index 8bddfc4c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2609 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2609_fsm b/persistentStorage/data-keycloak-db/base/13779/2609_fsm deleted file mode 100644 index adbf4b7d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2609_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2609_vm b/persistentStorage/data-keycloak-db/base/13779/2609_vm deleted file mode 100644 index 66957e84..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2609_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2610 b/persistentStorage/data-keycloak-db/base/13779/2610 deleted file mode 100644 index b659a82f..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2610 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2610_fsm b/persistentStorage/data-keycloak-db/base/13779/2610_fsm deleted file mode 100644 index 39a3e893..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2610_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2610_vm b/persistentStorage/data-keycloak-db/base/13779/2610_vm deleted file mode 100644 index 404ddf51..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2610_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2611 b/persistentStorage/data-keycloak-db/base/13779/2611 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/2612 b/persistentStorage/data-keycloak-db/base/13779/2612 deleted file mode 100644 index 09d3db9a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2612 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2612_fsm b/persistentStorage/data-keycloak-db/base/13779/2612_fsm deleted file mode 100644 index 877976ac..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2612_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2612_vm b/persistentStorage/data-keycloak-db/base/13779/2612_vm deleted file mode 100644 index fb040308..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2612_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2613 b/persistentStorage/data-keycloak-db/base/13779/2613 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/2615 b/persistentStorage/data-keycloak-db/base/13779/2615 deleted file mode 100644 index 8db70da0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2615 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2615_fsm b/persistentStorage/data-keycloak-db/base/13779/2615_fsm deleted file mode 100644 index d041693e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2615_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2615_vm b/persistentStorage/data-keycloak-db/base/13779/2615_vm deleted file mode 100644 index 2be5d8fe..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2615_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2616 b/persistentStorage/data-keycloak-db/base/13779/2616 deleted file mode 100644 index 0d60d797..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2616 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2616_fsm b/persistentStorage/data-keycloak-db/base/13779/2616_fsm deleted file mode 100644 index cb924c95..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2616_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2616_vm b/persistentStorage/data-keycloak-db/base/13779/2616_vm deleted file mode 100644 index 32b43b65..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2616_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2617 b/persistentStorage/data-keycloak-db/base/13779/2617 deleted file mode 100644 index 86965511..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2617 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2617_fsm b/persistentStorage/data-keycloak-db/base/13779/2617_fsm deleted file mode 100644 index 84060f4b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2617_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2617_vm b/persistentStorage/data-keycloak-db/base/13779/2617_vm deleted file mode 100644 index a6a45cc3..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2617_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2618 b/persistentStorage/data-keycloak-db/base/13779/2618 deleted file mode 100644 index 2893aa34..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2618 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2618_fsm b/persistentStorage/data-keycloak-db/base/13779/2618_fsm deleted file mode 100644 index b92d2da4..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2618_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2618_vm b/persistentStorage/data-keycloak-db/base/13779/2618_vm deleted file mode 100644 index 0fd8ac1c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2618_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2619 b/persistentStorage/data-keycloak-db/base/13779/2619 deleted file mode 100644 index 7acc667a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2619 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2619_fsm b/persistentStorage/data-keycloak-db/base/13779/2619_fsm deleted file mode 100644 index ee863db4..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2619_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2619_vm b/persistentStorage/data-keycloak-db/base/13779/2619_vm deleted file mode 100644 index 6d85b37c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2619_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2620 b/persistentStorage/data-keycloak-db/base/13779/2620 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/2650 b/persistentStorage/data-keycloak-db/base/13779/2650 deleted file mode 100644 index 7627c51a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2650 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2651 b/persistentStorage/data-keycloak-db/base/13779/2651 deleted file mode 100644 index f9c68ee5..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2651 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2652 b/persistentStorage/data-keycloak-db/base/13779/2652 deleted file mode 100644 index 7b6c2f24..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2652 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2653 b/persistentStorage/data-keycloak-db/base/13779/2653 deleted file mode 100644 index 541d5f4a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2653 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2654 b/persistentStorage/data-keycloak-db/base/13779/2654 deleted file mode 100644 index 29ad199a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2654 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2655 b/persistentStorage/data-keycloak-db/base/13779/2655 deleted file mode 100644 index b4acab68..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2655 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2656 b/persistentStorage/data-keycloak-db/base/13779/2656 deleted file mode 100644 index 9e5e1b0c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2656 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2657 b/persistentStorage/data-keycloak-db/base/13779/2657 deleted file mode 100644 index 0d2b3a8d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2657 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2658 b/persistentStorage/data-keycloak-db/base/13779/2658 deleted file mode 100644 index 6dbe3957..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2658 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2659 b/persistentStorage/data-keycloak-db/base/13779/2659 deleted file mode 100644 index cf685c39..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2659 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2660 b/persistentStorage/data-keycloak-db/base/13779/2660 deleted file mode 100644 index 59c279a1..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2660 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2661 b/persistentStorage/data-keycloak-db/base/13779/2661 deleted file mode 100644 index 040e9976..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2661 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2662 b/persistentStorage/data-keycloak-db/base/13779/2662 deleted file mode 100644 index 1d56660e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2662 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2663 b/persistentStorage/data-keycloak-db/base/13779/2663 deleted file mode 100644 index 259eebed..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2663 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2664 b/persistentStorage/data-keycloak-db/base/13779/2664 deleted file mode 100644 index b7c14dee..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2664 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2665 b/persistentStorage/data-keycloak-db/base/13779/2665 deleted file mode 100644 index 1af33b9e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2665 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2666 b/persistentStorage/data-keycloak-db/base/13779/2666 deleted file mode 100644 index 5c05ac8b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2666 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2667 b/persistentStorage/data-keycloak-db/base/13779/2667 deleted file mode 100644 index ad8282f5..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2667 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2668 b/persistentStorage/data-keycloak-db/base/13779/2668 deleted file mode 100644 index 1ceedaaf..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2668 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2669 b/persistentStorage/data-keycloak-db/base/13779/2669 deleted file mode 100644 index 865bb062..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2669 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2670 b/persistentStorage/data-keycloak-db/base/13779/2670 deleted file mode 100644 index 01be7b00..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2670 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2673 b/persistentStorage/data-keycloak-db/base/13779/2673 deleted file mode 100644 index 106411b0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2673 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2673_fsm b/persistentStorage/data-keycloak-db/base/13779/2673_fsm deleted file mode 100644 index 2c8d238d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2673_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2674 b/persistentStorage/data-keycloak-db/base/13779/2674 deleted file mode 100644 index e5cc937a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2674 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2674_fsm b/persistentStorage/data-keycloak-db/base/13779/2674_fsm deleted file mode 100644 index ed74869b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2674_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2675 b/persistentStorage/data-keycloak-db/base/13779/2675 deleted file mode 100644 index 4c2d5263..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2675 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2678 b/persistentStorage/data-keycloak-db/base/13779/2678 deleted file mode 100644 index 1b959664..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2678 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2679 b/persistentStorage/data-keycloak-db/base/13779/2679 deleted file mode 100644 index afd22d69..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2679 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2680 b/persistentStorage/data-keycloak-db/base/13779/2680 deleted file mode 100644 index abc5412a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2680 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2681 b/persistentStorage/data-keycloak-db/base/13779/2681 deleted file mode 100644 index 11f4836a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2681 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2682 b/persistentStorage/data-keycloak-db/base/13779/2682 deleted file mode 100644 index a17584c1..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2682 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2683 b/persistentStorage/data-keycloak-db/base/13779/2683 deleted file mode 100644 index ef3053d1..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2683 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2684 b/persistentStorage/data-keycloak-db/base/13779/2684 deleted file mode 100644 index 0e7d9c11..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2684 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2685 b/persistentStorage/data-keycloak-db/base/13779/2685 deleted file mode 100644 index e131ea4c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2685 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2686 b/persistentStorage/data-keycloak-db/base/13779/2686 deleted file mode 100644 index 832bcb9a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2686 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2687 b/persistentStorage/data-keycloak-db/base/13779/2687 deleted file mode 100644 index 189fd41e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2687 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2688 b/persistentStorage/data-keycloak-db/base/13779/2688 deleted file mode 100644 index 6ebe3e7e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2688 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2689 b/persistentStorage/data-keycloak-db/base/13779/2689 deleted file mode 100644 index daa83a39..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2689 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2690 b/persistentStorage/data-keycloak-db/base/13779/2690 deleted file mode 100644 index 0806b469..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2690 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2691 b/persistentStorage/data-keycloak-db/base/13779/2691 deleted file mode 100644 index 9cd87042..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2691 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2692 b/persistentStorage/data-keycloak-db/base/13779/2692 deleted file mode 100644 index 7296dcf7..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2692 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2693 b/persistentStorage/data-keycloak-db/base/13779/2693 deleted file mode 100644 index 8084e6e0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2693 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2696 b/persistentStorage/data-keycloak-db/base/13779/2696 deleted file mode 100644 index f7393f47..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2696 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2699 b/persistentStorage/data-keycloak-db/base/13779/2699 deleted file mode 100644 index cb458c10..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2699 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2701 b/persistentStorage/data-keycloak-db/base/13779/2701 deleted file mode 100644 index c18ab55d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2701 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2702 b/persistentStorage/data-keycloak-db/base/13779/2702 deleted file mode 100644 index 91ddfc9a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2702 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2703 b/persistentStorage/data-keycloak-db/base/13779/2703 deleted file mode 100644 index 11d15164..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2703 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2704 b/persistentStorage/data-keycloak-db/base/13779/2704 deleted file mode 100644 index 886285ff..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2704 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2753 b/persistentStorage/data-keycloak-db/base/13779/2753 deleted file mode 100644 index 3c16dff6..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2753 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2753_fsm b/persistentStorage/data-keycloak-db/base/13779/2753_fsm deleted file mode 100644 index 642bce3b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2753_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2753_vm b/persistentStorage/data-keycloak-db/base/13779/2753_vm deleted file mode 100644 index 928f7e31..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2753_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2754 b/persistentStorage/data-keycloak-db/base/13779/2754 deleted file mode 100644 index 1cbd156e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2754 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2755 b/persistentStorage/data-keycloak-db/base/13779/2755 deleted file mode 100644 index 0fc8e919..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2755 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2756 b/persistentStorage/data-keycloak-db/base/13779/2756 deleted file mode 100644 index 5d355e2a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2756 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2757 b/persistentStorage/data-keycloak-db/base/13779/2757 deleted file mode 100644 index 6f40a7fb..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2757 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2830 b/persistentStorage/data-keycloak-db/base/13779/2830 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/2831 b/persistentStorage/data-keycloak-db/base/13779/2831 deleted file mode 100644 index e4ad5c17..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2831 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2832 b/persistentStorage/data-keycloak-db/base/13779/2832 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/2833 b/persistentStorage/data-keycloak-db/base/13779/2833 deleted file mode 100644 index b97afa32..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2833 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2834 b/persistentStorage/data-keycloak-db/base/13779/2834 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/2835 b/persistentStorage/data-keycloak-db/base/13779/2835 deleted file mode 100644 index 6aa119f3..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2835 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2836 b/persistentStorage/data-keycloak-db/base/13779/2836 deleted file mode 100644 index c688f81c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2836 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2836_fsm b/persistentStorage/data-keycloak-db/base/13779/2836_fsm deleted file mode 100644 index 4066e1ec..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2836_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2836_vm b/persistentStorage/data-keycloak-db/base/13779/2836_vm deleted file mode 100644 index d2ba922d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2836_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2837 b/persistentStorage/data-keycloak-db/base/13779/2837 deleted file mode 100644 index ed7a191d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2837 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2838 b/persistentStorage/data-keycloak-db/base/13779/2838 deleted file mode 100644 index 4cb35492..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2838 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2838_fsm b/persistentStorage/data-keycloak-db/base/13779/2838_fsm deleted file mode 100644 index 4cc16309..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2838_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2838_vm b/persistentStorage/data-keycloak-db/base/13779/2838_vm deleted file mode 100644 index c02f1ce0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2838_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2839 b/persistentStorage/data-keycloak-db/base/13779/2839 deleted file mode 100644 index 518516dd..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2839 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2840 b/persistentStorage/data-keycloak-db/base/13779/2840 deleted file mode 100644 index ea1cef46..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2840 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2840_fsm b/persistentStorage/data-keycloak-db/base/13779/2840_fsm deleted file mode 100644 index 49de3921..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2840_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2840_vm b/persistentStorage/data-keycloak-db/base/13779/2840_vm deleted file mode 100644 index 7033e055..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2840_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2841 b/persistentStorage/data-keycloak-db/base/13779/2841 deleted file mode 100644 index a0776384..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2841 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/2995 b/persistentStorage/data-keycloak-db/base/13779/2995 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/2996 b/persistentStorage/data-keycloak-db/base/13779/2996 deleted file mode 100644 index 35f2758f..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/2996 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3079 b/persistentStorage/data-keycloak-db/base/13779/3079 deleted file mode 100644 index 08f2b014..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3079 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3079_fsm b/persistentStorage/data-keycloak-db/base/13779/3079_fsm deleted file mode 100644 index 7732d22b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3079_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3079_vm b/persistentStorage/data-keycloak-db/base/13779/3079_vm deleted file mode 100644 index e2bfe1e5..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3079_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3080 b/persistentStorage/data-keycloak-db/base/13779/3080 deleted file mode 100644 index 77890e90..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3080 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3081 b/persistentStorage/data-keycloak-db/base/13779/3081 deleted file mode 100644 index c9e8c6e7..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3081 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3085 b/persistentStorage/data-keycloak-db/base/13779/3085 deleted file mode 100644 index d83ce3e2..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3085 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3118 b/persistentStorage/data-keycloak-db/base/13779/3118 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/3119 b/persistentStorage/data-keycloak-db/base/13779/3119 deleted file mode 100644 index c0d08b7e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3119 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3164 b/persistentStorage/data-keycloak-db/base/13779/3164 deleted file mode 100644 index b8d5a33f..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3164 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3256 b/persistentStorage/data-keycloak-db/base/13779/3256 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/3257 b/persistentStorage/data-keycloak-db/base/13779/3257 deleted file mode 100644 index 85937d28..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3257 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3258 b/persistentStorage/data-keycloak-db/base/13779/3258 deleted file mode 100644 index 5f252a3c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3258 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3350 b/persistentStorage/data-keycloak-db/base/13779/3350 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/3351 b/persistentStorage/data-keycloak-db/base/13779/3351 deleted file mode 100644 index 0aecbb30..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3351 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3379 b/persistentStorage/data-keycloak-db/base/13779/3379 deleted file mode 100644 index 3992c116..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3379 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3380 b/persistentStorage/data-keycloak-db/base/13779/3380 deleted file mode 100644 index 8f72126d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3380 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3381 b/persistentStorage/data-keycloak-db/base/13779/3381 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/3394 b/persistentStorage/data-keycloak-db/base/13779/3394 deleted file mode 100644 index 7fa1e11b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3394 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3394_fsm b/persistentStorage/data-keycloak-db/base/13779/3394_fsm deleted file mode 100644 index f8d6070c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3394_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3394_vm b/persistentStorage/data-keycloak-db/base/13779/3394_vm deleted file mode 100644 index 5db2a120..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3394_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3395 b/persistentStorage/data-keycloak-db/base/13779/3395 deleted file mode 100644 index fa7b9d72..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3395 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3429 b/persistentStorage/data-keycloak-db/base/13779/3429 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/3430 b/persistentStorage/data-keycloak-db/base/13779/3430 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/3431 b/persistentStorage/data-keycloak-db/base/13779/3431 deleted file mode 100644 index 553b503b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3431 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3433 b/persistentStorage/data-keycloak-db/base/13779/3433 deleted file mode 100644 index 9b9eb9ce..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3433 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3439 b/persistentStorage/data-keycloak-db/base/13779/3439 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/3440 b/persistentStorage/data-keycloak-db/base/13779/3440 deleted file mode 100644 index 47135494..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3440 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3455 b/persistentStorage/data-keycloak-db/base/13779/3455 deleted file mode 100644 index a7d2f24e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3455 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3456 b/persistentStorage/data-keycloak-db/base/13779/3456 deleted file mode 100644 index e3460d9d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3456 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3456_fsm b/persistentStorage/data-keycloak-db/base/13779/3456_fsm deleted file mode 100644 index fc8f8b80..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3456_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3456_vm b/persistentStorage/data-keycloak-db/base/13779/3456_vm deleted file mode 100644 index 89d107bd..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3456_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3466 b/persistentStorage/data-keycloak-db/base/13779/3466 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/3467 b/persistentStorage/data-keycloak-db/base/13779/3467 deleted file mode 100644 index 68eab7b6..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3467 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3468 b/persistentStorage/data-keycloak-db/base/13779/3468 deleted file mode 100644 index 63a8f7cd..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3468 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3501 b/persistentStorage/data-keycloak-db/base/13779/3501 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/3502 b/persistentStorage/data-keycloak-db/base/13779/3502 deleted file mode 100644 index 7676fd82..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3502 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3503 b/persistentStorage/data-keycloak-db/base/13779/3503 deleted file mode 100644 index 22146019..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3503 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3534 b/persistentStorage/data-keycloak-db/base/13779/3534 deleted file mode 100644 index 9a307a42..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3534 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3541 b/persistentStorage/data-keycloak-db/base/13779/3541 deleted file mode 100644 index 40869ad3..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3541 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3541_fsm b/persistentStorage/data-keycloak-db/base/13779/3541_fsm deleted file mode 100644 index a3a2de4d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3541_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3541_vm b/persistentStorage/data-keycloak-db/base/13779/3541_vm deleted file mode 100644 index bd8c84af..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3541_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3542 b/persistentStorage/data-keycloak-db/base/13779/3542 deleted file mode 100644 index ee21b6ae..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3542 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3574 b/persistentStorage/data-keycloak-db/base/13779/3574 deleted file mode 100644 index 418bbca1..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3574 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3575 b/persistentStorage/data-keycloak-db/base/13779/3575 deleted file mode 100644 index 6addf868..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3575 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3576 b/persistentStorage/data-keycloak-db/base/13779/3576 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/3596 b/persistentStorage/data-keycloak-db/base/13779/3596 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/3597 b/persistentStorage/data-keycloak-db/base/13779/3597 deleted file mode 100644 index 71d2820e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3597 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3598 b/persistentStorage/data-keycloak-db/base/13779/3598 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/3599 b/persistentStorage/data-keycloak-db/base/13779/3599 deleted file mode 100644 index 507ca587..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3599 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3600 b/persistentStorage/data-keycloak-db/base/13779/3600 deleted file mode 100644 index 41c62c58..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3600 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3600_fsm b/persistentStorage/data-keycloak-db/base/13779/3600_fsm deleted file mode 100644 index cebec199..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3600_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3600_vm b/persistentStorage/data-keycloak-db/base/13779/3600_vm deleted file mode 100644 index e611f185..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3600_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3601 b/persistentStorage/data-keycloak-db/base/13779/3601 deleted file mode 100644 index 04c846ec..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3601 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3601_fsm b/persistentStorage/data-keycloak-db/base/13779/3601_fsm deleted file mode 100644 index 7732d22b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3601_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3601_vm b/persistentStorage/data-keycloak-db/base/13779/3601_vm deleted file mode 100644 index e63f9b2d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3601_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3602 b/persistentStorage/data-keycloak-db/base/13779/3602 deleted file mode 100644 index e77e1ad5..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3602 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3602_fsm b/persistentStorage/data-keycloak-db/base/13779/3602_fsm deleted file mode 100644 index d7897de2..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3602_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3602_vm b/persistentStorage/data-keycloak-db/base/13779/3602_vm deleted file mode 100644 index 23986f7e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3602_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3603 b/persistentStorage/data-keycloak-db/base/13779/3603 deleted file mode 100644 index 57062b10..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3603 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3603_fsm b/persistentStorage/data-keycloak-db/base/13779/3603_fsm deleted file mode 100644 index c28dd4fa..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3603_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3603_vm b/persistentStorage/data-keycloak-db/base/13779/3603_vm deleted file mode 100644 index b5dac618..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3603_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3604 b/persistentStorage/data-keycloak-db/base/13779/3604 deleted file mode 100644 index 4a979b17..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3604 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3605 b/persistentStorage/data-keycloak-db/base/13779/3605 deleted file mode 100644 index 7e7c31ca..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3605 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3606 b/persistentStorage/data-keycloak-db/base/13779/3606 deleted file mode 100644 index de60e2ff..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3606 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3607 b/persistentStorage/data-keycloak-db/base/13779/3607 deleted file mode 100644 index ff537351..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3607 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3608 b/persistentStorage/data-keycloak-db/base/13779/3608 deleted file mode 100644 index bf99099a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3608 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3609 b/persistentStorage/data-keycloak-db/base/13779/3609 deleted file mode 100644 index aca244c6..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3609 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3712 b/persistentStorage/data-keycloak-db/base/13779/3712 deleted file mode 100644 index e4e2c033..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3712 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3764 b/persistentStorage/data-keycloak-db/base/13779/3764 deleted file mode 100644 index da4bd39c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3764 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3764_fsm b/persistentStorage/data-keycloak-db/base/13779/3764_fsm deleted file mode 100644 index f64db4df..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3764_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3764_vm b/persistentStorage/data-keycloak-db/base/13779/3764_vm deleted file mode 100644 index 3930bc12..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3764_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3766 b/persistentStorage/data-keycloak-db/base/13779/3766 deleted file mode 100644 index 44d0b7de..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3766 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3767 b/persistentStorage/data-keycloak-db/base/13779/3767 deleted file mode 100644 index b8e981f8..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3767 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/3997 b/persistentStorage/data-keycloak-db/base/13779/3997 deleted file mode 100644 index fd6175ff..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/3997 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/4143 b/persistentStorage/data-keycloak-db/base/13779/4143 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/4144 b/persistentStorage/data-keycloak-db/base/13779/4144 deleted file mode 100644 index a3569d11..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/4144 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/4145 b/persistentStorage/data-keycloak-db/base/13779/4145 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/4146 b/persistentStorage/data-keycloak-db/base/13779/4146 deleted file mode 100644 index 3397d87e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/4146 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/4147 b/persistentStorage/data-keycloak-db/base/13779/4147 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/4148 b/persistentStorage/data-keycloak-db/base/13779/4148 deleted file mode 100644 index 6e10fc5e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/4148 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/4149 b/persistentStorage/data-keycloak-db/base/13779/4149 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/4150 b/persistentStorage/data-keycloak-db/base/13779/4150 deleted file mode 100644 index a0ea1cc0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/4150 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/4151 b/persistentStorage/data-keycloak-db/base/13779/4151 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/4152 b/persistentStorage/data-keycloak-db/base/13779/4152 deleted file mode 100644 index 4179f382..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/4152 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/4153 b/persistentStorage/data-keycloak-db/base/13779/4153 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/4154 b/persistentStorage/data-keycloak-db/base/13779/4154 deleted file mode 100644 index a5e44b4f..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/4154 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/4155 b/persistentStorage/data-keycloak-db/base/13779/4155 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/4156 b/persistentStorage/data-keycloak-db/base/13779/4156 deleted file mode 100644 index e3a35c68..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/4156 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/4157 b/persistentStorage/data-keycloak-db/base/13779/4157 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/4158 b/persistentStorage/data-keycloak-db/base/13779/4158 deleted file mode 100644 index 3de62cdf..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/4158 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/4159 b/persistentStorage/data-keycloak-db/base/13779/4159 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/4160 b/persistentStorage/data-keycloak-db/base/13779/4160 deleted file mode 100644 index b17f909c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/4160 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/4163 b/persistentStorage/data-keycloak-db/base/13779/4163 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/4164 b/persistentStorage/data-keycloak-db/base/13779/4164 deleted file mode 100644 index 2e798538..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/4164 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/4165 b/persistentStorage/data-keycloak-db/base/13779/4165 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/4166 b/persistentStorage/data-keycloak-db/base/13779/4166 deleted file mode 100644 index 9e74293a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/4166 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/4167 b/persistentStorage/data-keycloak-db/base/13779/4167 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/4168 b/persistentStorage/data-keycloak-db/base/13779/4168 deleted file mode 100644 index a032ccae..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/4168 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/4169 b/persistentStorage/data-keycloak-db/base/13779/4169 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/4170 b/persistentStorage/data-keycloak-db/base/13779/4170 deleted file mode 100644 index c75cf673..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/4170 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/4171 b/persistentStorage/data-keycloak-db/base/13779/4171 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/4172 b/persistentStorage/data-keycloak-db/base/13779/4172 deleted file mode 100644 index f9cb0379..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/4172 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/4173 b/persistentStorage/data-keycloak-db/base/13779/4173 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/4174 b/persistentStorage/data-keycloak-db/base/13779/4174 deleted file mode 100644 index deb4a11b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/4174 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/5002 b/persistentStorage/data-keycloak-db/base/13779/5002 deleted file mode 100644 index 32af7a1e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/5002 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/548 b/persistentStorage/data-keycloak-db/base/13779/548 deleted file mode 100644 index 9f219478..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/548 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/549 b/persistentStorage/data-keycloak-db/base/13779/549 deleted file mode 100644 index 68efb3f3..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/549 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/6102 b/persistentStorage/data-keycloak-db/base/13779/6102 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/6104 b/persistentStorage/data-keycloak-db/base/13779/6104 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/6106 b/persistentStorage/data-keycloak-db/base/13779/6106 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/6110 b/persistentStorage/data-keycloak-db/base/13779/6110 deleted file mode 100644 index 536b80d3..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/6110 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/6111 b/persistentStorage/data-keycloak-db/base/13779/6111 deleted file mode 100644 index 3d22c94f..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/6111 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/6112 b/persistentStorage/data-keycloak-db/base/13779/6112 deleted file mode 100644 index 9e47d5c5..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/6112 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/6113 b/persistentStorage/data-keycloak-db/base/13779/6113 deleted file mode 100644 index 4e57f5be..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/6113 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/6117 b/persistentStorage/data-keycloak-db/base/13779/6117 deleted file mode 100644 index 296b14e8..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/6117 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/6175 b/persistentStorage/data-keycloak-db/base/13779/6175 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/6176 b/persistentStorage/data-keycloak-db/base/13779/6176 deleted file mode 100644 index 45c76f44..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/6176 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/826 b/persistentStorage/data-keycloak-db/base/13779/826 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13779/827 b/persistentStorage/data-keycloak-db/base/13779/827 deleted file mode 100644 index 86db9fe6..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/827 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/828 b/persistentStorage/data-keycloak-db/base/13779/828 deleted file mode 100644 index 4a522991..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/828 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13779/PG_VERSION b/persistentStorage/data-keycloak-db/base/13779/PG_VERSION deleted file mode 100644 index 8351c193..00000000 --- a/persistentStorage/data-keycloak-db/base/13779/PG_VERSION +++ /dev/null @@ -1 +0,0 @@ -14 diff --git a/persistentStorage/data-keycloak-db/base/13779/pg_filenode.map b/persistentStorage/data-keycloak-db/base/13779/pg_filenode.map deleted file mode 100644 index 193d78f3..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13779/pg_filenode.map and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/112 b/persistentStorage/data-keycloak-db/base/13780/112 deleted file mode 100644 index 21db5147..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/112 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/113 b/persistentStorage/data-keycloak-db/base/13780/113 deleted file mode 100644 index 3f06e2f0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/113 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/1247 b/persistentStorage/data-keycloak-db/base/13780/1247 deleted file mode 100644 index cac034f9..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/1247 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/1247_fsm b/persistentStorage/data-keycloak-db/base/13780/1247_fsm deleted file mode 100644 index 0e4086fb..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/1247_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/1247_vm b/persistentStorage/data-keycloak-db/base/13780/1247_vm deleted file mode 100644 index 708f4aed..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/1247_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/1249 b/persistentStorage/data-keycloak-db/base/13780/1249 deleted file mode 100644 index aec85207..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/1249 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/1249_fsm b/persistentStorage/data-keycloak-db/base/13780/1249_fsm deleted file mode 100644 index 1f8868d0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/1249_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/1249_vm b/persistentStorage/data-keycloak-db/base/13780/1249_vm deleted file mode 100644 index ec0b2516..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/1249_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/1255 b/persistentStorage/data-keycloak-db/base/13780/1255 deleted file mode 100644 index ad8eae9d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/1255 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/1255_fsm b/persistentStorage/data-keycloak-db/base/13780/1255_fsm deleted file mode 100644 index b730b34d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/1255_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/1255_vm b/persistentStorage/data-keycloak-db/base/13780/1255_vm deleted file mode 100644 index 32919fdd..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/1255_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/1259 b/persistentStorage/data-keycloak-db/base/13780/1259 deleted file mode 100644 index c8b79d6d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/1259 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/1259_fsm b/persistentStorage/data-keycloak-db/base/13780/1259_fsm deleted file mode 100644 index 3d17e637..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/1259_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/1259_vm b/persistentStorage/data-keycloak-db/base/13780/1259_vm deleted file mode 100644 index 5c2e63f0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/1259_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/13598 b/persistentStorage/data-keycloak-db/base/13780/13598 deleted file mode 100644 index f536b0d2..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/13598 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/13598_fsm b/persistentStorage/data-keycloak-db/base/13780/13598_fsm deleted file mode 100644 index dc87bf49..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/13598_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/13598_vm b/persistentStorage/data-keycloak-db/base/13780/13598_vm deleted file mode 100644 index 17ee883c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/13598_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/13601 b/persistentStorage/data-keycloak-db/base/13780/13601 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/13602 b/persistentStorage/data-keycloak-db/base/13780/13602 deleted file mode 100644 index 752d0764..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/13602 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/13603 b/persistentStorage/data-keycloak-db/base/13780/13603 deleted file mode 100644 index 239fb781..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/13603 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/13603_fsm b/persistentStorage/data-keycloak-db/base/13780/13603_fsm deleted file mode 100644 index ce7c26eb..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/13603_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/13603_vm b/persistentStorage/data-keycloak-db/base/13780/13603_vm deleted file mode 100644 index f1a19f83..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/13603_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/13606 b/persistentStorage/data-keycloak-db/base/13780/13606 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/13607 b/persistentStorage/data-keycloak-db/base/13780/13607 deleted file mode 100644 index a34d8cfe..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/13607 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/13608 b/persistentStorage/data-keycloak-db/base/13780/13608 deleted file mode 100644 index 257e1065..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/13608 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/13608_fsm b/persistentStorage/data-keycloak-db/base/13780/13608_fsm deleted file mode 100644 index d388044f..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/13608_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/13608_vm b/persistentStorage/data-keycloak-db/base/13780/13608_vm deleted file mode 100644 index 5f1cf8d0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/13608_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/13611 b/persistentStorage/data-keycloak-db/base/13780/13611 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/13612 b/persistentStorage/data-keycloak-db/base/13780/13612 deleted file mode 100644 index 28970355..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/13612 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/13613 b/persistentStorage/data-keycloak-db/base/13780/13613 deleted file mode 100644 index 2b4c488c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/13613 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/13613_fsm b/persistentStorage/data-keycloak-db/base/13780/13613_fsm deleted file mode 100644 index a836ddf7..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/13613_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/13613_vm b/persistentStorage/data-keycloak-db/base/13780/13613_vm deleted file mode 100644 index be95e308..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/13613_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/13616 b/persistentStorage/data-keycloak-db/base/13780/13616 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/13617 b/persistentStorage/data-keycloak-db/base/13780/13617 deleted file mode 100644 index 572afc12..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/13617 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/1417 b/persistentStorage/data-keycloak-db/base/13780/1417 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/1418 b/persistentStorage/data-keycloak-db/base/13780/1418 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/174 b/persistentStorage/data-keycloak-db/base/13780/174 deleted file mode 100644 index 6312b18f..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/174 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/175 b/persistentStorage/data-keycloak-db/base/13780/175 deleted file mode 100644 index 0f504d0b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/175 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2187 b/persistentStorage/data-keycloak-db/base/13780/2187 deleted file mode 100644 index 6ea4d227..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2187 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2224 b/persistentStorage/data-keycloak-db/base/13780/2224 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/2228 b/persistentStorage/data-keycloak-db/base/13780/2228 deleted file mode 100644 index da192ed0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2228 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2328 b/persistentStorage/data-keycloak-db/base/13780/2328 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/2336 b/persistentStorage/data-keycloak-db/base/13780/2336 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/2337 b/persistentStorage/data-keycloak-db/base/13780/2337 deleted file mode 100644 index d6111abe..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2337 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2579 b/persistentStorage/data-keycloak-db/base/13780/2579 deleted file mode 100644 index 1659ed5e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2579 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2600 b/persistentStorage/data-keycloak-db/base/13780/2600 deleted file mode 100644 index 827b5c23..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2600 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2600_fsm b/persistentStorage/data-keycloak-db/base/13780/2600_fsm deleted file mode 100644 index 3f8f4089..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2600_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2600_vm b/persistentStorage/data-keycloak-db/base/13780/2600_vm deleted file mode 100644 index b01cf52e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2600_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2601 b/persistentStorage/data-keycloak-db/base/13780/2601 deleted file mode 100644 index d8001c8c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2601 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2601_fsm b/persistentStorage/data-keycloak-db/base/13780/2601_fsm deleted file mode 100644 index d388044f..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2601_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2601_vm b/persistentStorage/data-keycloak-db/base/13780/2601_vm deleted file mode 100644 index 0c4e3626..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2601_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2602 b/persistentStorage/data-keycloak-db/base/13780/2602 deleted file mode 100644 index 4a27b0a3..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2602 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2602_fsm b/persistentStorage/data-keycloak-db/base/13780/2602_fsm deleted file mode 100644 index 23170d85..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2602_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2602_vm b/persistentStorage/data-keycloak-db/base/13780/2602_vm deleted file mode 100644 index 3f263ec7..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2602_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2603 b/persistentStorage/data-keycloak-db/base/13780/2603 deleted file mode 100644 index d511af56..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2603 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2603_fsm b/persistentStorage/data-keycloak-db/base/13780/2603_fsm deleted file mode 100644 index 949bd18f..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2603_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2603_vm b/persistentStorage/data-keycloak-db/base/13780/2603_vm deleted file mode 100644 index 24766c7b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2603_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2604 b/persistentStorage/data-keycloak-db/base/13780/2604 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/2605 b/persistentStorage/data-keycloak-db/base/13780/2605 deleted file mode 100644 index 287bf968..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2605 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2605_fsm b/persistentStorage/data-keycloak-db/base/13780/2605_fsm deleted file mode 100644 index c7723da0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2605_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2605_vm b/persistentStorage/data-keycloak-db/base/13780/2605_vm deleted file mode 100644 index 577f6fb5..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2605_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2606 b/persistentStorage/data-keycloak-db/base/13780/2606 deleted file mode 100644 index 93ca2f3d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2606 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2606_fsm b/persistentStorage/data-keycloak-db/base/13780/2606_fsm deleted file mode 100644 index 37bfa7e7..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2606_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2606_vm b/persistentStorage/data-keycloak-db/base/13780/2606_vm deleted file mode 100644 index 8ad5bbc4..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2606_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2607 b/persistentStorage/data-keycloak-db/base/13780/2607 deleted file mode 100644 index bfad49ae..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2607 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2607_fsm b/persistentStorage/data-keycloak-db/base/13780/2607_fsm deleted file mode 100644 index 80ac8b14..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2607_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2607_vm b/persistentStorage/data-keycloak-db/base/13780/2607_vm deleted file mode 100644 index 4af50662..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2607_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2608 b/persistentStorage/data-keycloak-db/base/13780/2608 deleted file mode 100644 index 43fb1416..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2608 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2608_fsm b/persistentStorage/data-keycloak-db/base/13780/2608_fsm deleted file mode 100644 index 8e746db5..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2608_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2608_vm b/persistentStorage/data-keycloak-db/base/13780/2608_vm deleted file mode 100644 index ae30bb8a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2608_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2609 b/persistentStorage/data-keycloak-db/base/13780/2609 deleted file mode 100644 index 8bddfc4c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2609 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2609_fsm b/persistentStorage/data-keycloak-db/base/13780/2609_fsm deleted file mode 100644 index adbf4b7d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2609_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2609_vm b/persistentStorage/data-keycloak-db/base/13780/2609_vm deleted file mode 100644 index 66957e84..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2609_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2610 b/persistentStorage/data-keycloak-db/base/13780/2610 deleted file mode 100644 index b659a82f..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2610 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2610_fsm b/persistentStorage/data-keycloak-db/base/13780/2610_fsm deleted file mode 100644 index 39a3e893..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2610_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2610_vm b/persistentStorage/data-keycloak-db/base/13780/2610_vm deleted file mode 100644 index 404ddf51..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2610_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2611 b/persistentStorage/data-keycloak-db/base/13780/2611 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/2612 b/persistentStorage/data-keycloak-db/base/13780/2612 deleted file mode 100644 index 09d3db9a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2612 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2612_fsm b/persistentStorage/data-keycloak-db/base/13780/2612_fsm deleted file mode 100644 index 877976ac..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2612_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2612_vm b/persistentStorage/data-keycloak-db/base/13780/2612_vm deleted file mode 100644 index fb040308..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2612_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2613 b/persistentStorage/data-keycloak-db/base/13780/2613 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/2615 b/persistentStorage/data-keycloak-db/base/13780/2615 deleted file mode 100644 index 8db70da0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2615 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2615_fsm b/persistentStorage/data-keycloak-db/base/13780/2615_fsm deleted file mode 100644 index d041693e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2615_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2615_vm b/persistentStorage/data-keycloak-db/base/13780/2615_vm deleted file mode 100644 index 2be5d8fe..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2615_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2616 b/persistentStorage/data-keycloak-db/base/13780/2616 deleted file mode 100644 index 0d60d797..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2616 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2616_fsm b/persistentStorage/data-keycloak-db/base/13780/2616_fsm deleted file mode 100644 index cb924c95..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2616_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2616_vm b/persistentStorage/data-keycloak-db/base/13780/2616_vm deleted file mode 100644 index 32b43b65..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2616_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2617 b/persistentStorage/data-keycloak-db/base/13780/2617 deleted file mode 100644 index 86965511..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2617 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2617_fsm b/persistentStorage/data-keycloak-db/base/13780/2617_fsm deleted file mode 100644 index 84060f4b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2617_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2617_vm b/persistentStorage/data-keycloak-db/base/13780/2617_vm deleted file mode 100644 index a6a45cc3..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2617_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2618 b/persistentStorage/data-keycloak-db/base/13780/2618 deleted file mode 100644 index 2893aa34..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2618 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2618_fsm b/persistentStorage/data-keycloak-db/base/13780/2618_fsm deleted file mode 100644 index b92d2da4..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2618_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2618_vm b/persistentStorage/data-keycloak-db/base/13780/2618_vm deleted file mode 100644 index 0fd8ac1c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2618_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2619 b/persistentStorage/data-keycloak-db/base/13780/2619 deleted file mode 100644 index 7acc667a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2619 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2619_fsm b/persistentStorage/data-keycloak-db/base/13780/2619_fsm deleted file mode 100644 index ee863db4..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2619_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2619_vm b/persistentStorage/data-keycloak-db/base/13780/2619_vm deleted file mode 100644 index 6d85b37c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2619_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2620 b/persistentStorage/data-keycloak-db/base/13780/2620 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/2650 b/persistentStorage/data-keycloak-db/base/13780/2650 deleted file mode 100644 index 7627c51a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2650 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2651 b/persistentStorage/data-keycloak-db/base/13780/2651 deleted file mode 100644 index f9c68ee5..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2651 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2652 b/persistentStorage/data-keycloak-db/base/13780/2652 deleted file mode 100644 index 7b6c2f24..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2652 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2653 b/persistentStorage/data-keycloak-db/base/13780/2653 deleted file mode 100644 index 541d5f4a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2653 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2654 b/persistentStorage/data-keycloak-db/base/13780/2654 deleted file mode 100644 index 29ad199a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2654 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2655 b/persistentStorage/data-keycloak-db/base/13780/2655 deleted file mode 100644 index b4acab68..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2655 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2656 b/persistentStorage/data-keycloak-db/base/13780/2656 deleted file mode 100644 index 9e5e1b0c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2656 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2657 b/persistentStorage/data-keycloak-db/base/13780/2657 deleted file mode 100644 index 0d2b3a8d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2657 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2658 b/persistentStorage/data-keycloak-db/base/13780/2658 deleted file mode 100644 index 6dbe3957..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2658 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2659 b/persistentStorage/data-keycloak-db/base/13780/2659 deleted file mode 100644 index cf685c39..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2659 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2660 b/persistentStorage/data-keycloak-db/base/13780/2660 deleted file mode 100644 index 59c279a1..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2660 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2661 b/persistentStorage/data-keycloak-db/base/13780/2661 deleted file mode 100644 index 040e9976..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2661 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2662 b/persistentStorage/data-keycloak-db/base/13780/2662 deleted file mode 100644 index 1d56660e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2662 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2663 b/persistentStorage/data-keycloak-db/base/13780/2663 deleted file mode 100644 index 259eebed..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2663 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2664 b/persistentStorage/data-keycloak-db/base/13780/2664 deleted file mode 100644 index b7c14dee..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2664 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2665 b/persistentStorage/data-keycloak-db/base/13780/2665 deleted file mode 100644 index 1af33b9e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2665 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2666 b/persistentStorage/data-keycloak-db/base/13780/2666 deleted file mode 100644 index 5c05ac8b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2666 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2667 b/persistentStorage/data-keycloak-db/base/13780/2667 deleted file mode 100644 index ad8282f5..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2667 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2668 b/persistentStorage/data-keycloak-db/base/13780/2668 deleted file mode 100644 index 1ceedaaf..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2668 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2669 b/persistentStorage/data-keycloak-db/base/13780/2669 deleted file mode 100644 index 865bb062..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2669 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2670 b/persistentStorage/data-keycloak-db/base/13780/2670 deleted file mode 100644 index 01be7b00..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2670 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2673 b/persistentStorage/data-keycloak-db/base/13780/2673 deleted file mode 100644 index 106411b0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2673 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2673_fsm b/persistentStorage/data-keycloak-db/base/13780/2673_fsm deleted file mode 100644 index 2c8d238d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2673_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2674 b/persistentStorage/data-keycloak-db/base/13780/2674 deleted file mode 100644 index e5cc937a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2674 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2674_fsm b/persistentStorage/data-keycloak-db/base/13780/2674_fsm deleted file mode 100644 index ed74869b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2674_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2675 b/persistentStorage/data-keycloak-db/base/13780/2675 deleted file mode 100644 index 4c2d5263..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2675 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2678 b/persistentStorage/data-keycloak-db/base/13780/2678 deleted file mode 100644 index 1b959664..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2678 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2679 b/persistentStorage/data-keycloak-db/base/13780/2679 deleted file mode 100644 index afd22d69..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2679 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2680 b/persistentStorage/data-keycloak-db/base/13780/2680 deleted file mode 100644 index abc5412a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2680 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2681 b/persistentStorage/data-keycloak-db/base/13780/2681 deleted file mode 100644 index 11f4836a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2681 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2682 b/persistentStorage/data-keycloak-db/base/13780/2682 deleted file mode 100644 index a17584c1..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2682 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2683 b/persistentStorage/data-keycloak-db/base/13780/2683 deleted file mode 100644 index ef3053d1..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2683 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2684 b/persistentStorage/data-keycloak-db/base/13780/2684 deleted file mode 100644 index 0e7d9c11..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2684 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2685 b/persistentStorage/data-keycloak-db/base/13780/2685 deleted file mode 100644 index e131ea4c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2685 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2686 b/persistentStorage/data-keycloak-db/base/13780/2686 deleted file mode 100644 index 832bcb9a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2686 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2687 b/persistentStorage/data-keycloak-db/base/13780/2687 deleted file mode 100644 index 189fd41e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2687 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2688 b/persistentStorage/data-keycloak-db/base/13780/2688 deleted file mode 100644 index 6ebe3e7e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2688 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2689 b/persistentStorage/data-keycloak-db/base/13780/2689 deleted file mode 100644 index daa83a39..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2689 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2690 b/persistentStorage/data-keycloak-db/base/13780/2690 deleted file mode 100644 index 0806b469..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2690 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2691 b/persistentStorage/data-keycloak-db/base/13780/2691 deleted file mode 100644 index 9cd87042..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2691 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2692 b/persistentStorage/data-keycloak-db/base/13780/2692 deleted file mode 100644 index 7296dcf7..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2692 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2693 b/persistentStorage/data-keycloak-db/base/13780/2693 deleted file mode 100644 index 8084e6e0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2693 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2696 b/persistentStorage/data-keycloak-db/base/13780/2696 deleted file mode 100644 index f7393f47..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2696 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2699 b/persistentStorage/data-keycloak-db/base/13780/2699 deleted file mode 100644 index cb458c10..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2699 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2701 b/persistentStorage/data-keycloak-db/base/13780/2701 deleted file mode 100644 index c18ab55d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2701 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2702 b/persistentStorage/data-keycloak-db/base/13780/2702 deleted file mode 100644 index 91ddfc9a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2702 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2703 b/persistentStorage/data-keycloak-db/base/13780/2703 deleted file mode 100644 index 11d15164..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2703 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2704 b/persistentStorage/data-keycloak-db/base/13780/2704 deleted file mode 100644 index 886285ff..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2704 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2753 b/persistentStorage/data-keycloak-db/base/13780/2753 deleted file mode 100644 index 3c16dff6..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2753 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2753_fsm b/persistentStorage/data-keycloak-db/base/13780/2753_fsm deleted file mode 100644 index 642bce3b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2753_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2753_vm b/persistentStorage/data-keycloak-db/base/13780/2753_vm deleted file mode 100644 index 928f7e31..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2753_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2754 b/persistentStorage/data-keycloak-db/base/13780/2754 deleted file mode 100644 index 1cbd156e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2754 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2755 b/persistentStorage/data-keycloak-db/base/13780/2755 deleted file mode 100644 index 0fc8e919..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2755 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2756 b/persistentStorage/data-keycloak-db/base/13780/2756 deleted file mode 100644 index 5d355e2a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2756 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2757 b/persistentStorage/data-keycloak-db/base/13780/2757 deleted file mode 100644 index 6f40a7fb..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2757 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2830 b/persistentStorage/data-keycloak-db/base/13780/2830 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/2831 b/persistentStorage/data-keycloak-db/base/13780/2831 deleted file mode 100644 index e4ad5c17..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2831 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2832 b/persistentStorage/data-keycloak-db/base/13780/2832 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/2833 b/persistentStorage/data-keycloak-db/base/13780/2833 deleted file mode 100644 index b97afa32..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2833 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2834 b/persistentStorage/data-keycloak-db/base/13780/2834 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/2835 b/persistentStorage/data-keycloak-db/base/13780/2835 deleted file mode 100644 index 6aa119f3..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2835 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2836 b/persistentStorage/data-keycloak-db/base/13780/2836 deleted file mode 100644 index c688f81c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2836 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2836_fsm b/persistentStorage/data-keycloak-db/base/13780/2836_fsm deleted file mode 100644 index 4066e1ec..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2836_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2836_vm b/persistentStorage/data-keycloak-db/base/13780/2836_vm deleted file mode 100644 index d2ba922d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2836_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2837 b/persistentStorage/data-keycloak-db/base/13780/2837 deleted file mode 100644 index ed7a191d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2837 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2838 b/persistentStorage/data-keycloak-db/base/13780/2838 deleted file mode 100644 index 4cb35492..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2838 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2838_fsm b/persistentStorage/data-keycloak-db/base/13780/2838_fsm deleted file mode 100644 index 4cc16309..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2838_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2838_vm b/persistentStorage/data-keycloak-db/base/13780/2838_vm deleted file mode 100644 index c02f1ce0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2838_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2839 b/persistentStorage/data-keycloak-db/base/13780/2839 deleted file mode 100644 index 518516dd..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2839 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2840 b/persistentStorage/data-keycloak-db/base/13780/2840 deleted file mode 100644 index ea1cef46..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2840 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2840_fsm b/persistentStorage/data-keycloak-db/base/13780/2840_fsm deleted file mode 100644 index 49de3921..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2840_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2840_vm b/persistentStorage/data-keycloak-db/base/13780/2840_vm deleted file mode 100644 index 7033e055..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2840_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2841 b/persistentStorage/data-keycloak-db/base/13780/2841 deleted file mode 100644 index a0776384..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2841 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/2995 b/persistentStorage/data-keycloak-db/base/13780/2995 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/2996 b/persistentStorage/data-keycloak-db/base/13780/2996 deleted file mode 100644 index 35f2758f..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/2996 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3079 b/persistentStorage/data-keycloak-db/base/13780/3079 deleted file mode 100644 index 08f2b014..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3079 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3079_fsm b/persistentStorage/data-keycloak-db/base/13780/3079_fsm deleted file mode 100644 index 7732d22b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3079_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3079_vm b/persistentStorage/data-keycloak-db/base/13780/3079_vm deleted file mode 100644 index e2bfe1e5..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3079_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3080 b/persistentStorage/data-keycloak-db/base/13780/3080 deleted file mode 100644 index 77890e90..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3080 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3081 b/persistentStorage/data-keycloak-db/base/13780/3081 deleted file mode 100644 index c9e8c6e7..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3081 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3085 b/persistentStorage/data-keycloak-db/base/13780/3085 deleted file mode 100644 index d83ce3e2..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3085 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3118 b/persistentStorage/data-keycloak-db/base/13780/3118 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/3119 b/persistentStorage/data-keycloak-db/base/13780/3119 deleted file mode 100644 index c0d08b7e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3119 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3164 b/persistentStorage/data-keycloak-db/base/13780/3164 deleted file mode 100644 index b8d5a33f..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3164 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3256 b/persistentStorage/data-keycloak-db/base/13780/3256 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/3257 b/persistentStorage/data-keycloak-db/base/13780/3257 deleted file mode 100644 index 85937d28..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3257 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3258 b/persistentStorage/data-keycloak-db/base/13780/3258 deleted file mode 100644 index 5f252a3c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3258 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3350 b/persistentStorage/data-keycloak-db/base/13780/3350 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/3351 b/persistentStorage/data-keycloak-db/base/13780/3351 deleted file mode 100644 index 0aecbb30..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3351 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3379 b/persistentStorage/data-keycloak-db/base/13780/3379 deleted file mode 100644 index 3992c116..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3379 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3380 b/persistentStorage/data-keycloak-db/base/13780/3380 deleted file mode 100644 index 8f72126d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3380 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3381 b/persistentStorage/data-keycloak-db/base/13780/3381 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/3394 b/persistentStorage/data-keycloak-db/base/13780/3394 deleted file mode 100644 index 7fa1e11b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3394 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3394_fsm b/persistentStorage/data-keycloak-db/base/13780/3394_fsm deleted file mode 100644 index f8d6070c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3394_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3394_vm b/persistentStorage/data-keycloak-db/base/13780/3394_vm deleted file mode 100644 index 5db2a120..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3394_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3395 b/persistentStorage/data-keycloak-db/base/13780/3395 deleted file mode 100644 index fa7b9d72..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3395 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3429 b/persistentStorage/data-keycloak-db/base/13780/3429 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/3430 b/persistentStorage/data-keycloak-db/base/13780/3430 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/3431 b/persistentStorage/data-keycloak-db/base/13780/3431 deleted file mode 100644 index 553b503b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3431 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3433 b/persistentStorage/data-keycloak-db/base/13780/3433 deleted file mode 100644 index 9b9eb9ce..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3433 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3439 b/persistentStorage/data-keycloak-db/base/13780/3439 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/3440 b/persistentStorage/data-keycloak-db/base/13780/3440 deleted file mode 100644 index 47135494..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3440 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3455 b/persistentStorage/data-keycloak-db/base/13780/3455 deleted file mode 100644 index a7d2f24e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3455 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3456 b/persistentStorage/data-keycloak-db/base/13780/3456 deleted file mode 100644 index e3460d9d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3456 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3456_fsm b/persistentStorage/data-keycloak-db/base/13780/3456_fsm deleted file mode 100644 index fc8f8b80..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3456_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3456_vm b/persistentStorage/data-keycloak-db/base/13780/3456_vm deleted file mode 100644 index 89d107bd..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3456_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3466 b/persistentStorage/data-keycloak-db/base/13780/3466 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/3467 b/persistentStorage/data-keycloak-db/base/13780/3467 deleted file mode 100644 index 68eab7b6..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3467 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3468 b/persistentStorage/data-keycloak-db/base/13780/3468 deleted file mode 100644 index 63a8f7cd..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3468 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3501 b/persistentStorage/data-keycloak-db/base/13780/3501 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/3502 b/persistentStorage/data-keycloak-db/base/13780/3502 deleted file mode 100644 index 7676fd82..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3502 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3503 b/persistentStorage/data-keycloak-db/base/13780/3503 deleted file mode 100644 index 22146019..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3503 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3534 b/persistentStorage/data-keycloak-db/base/13780/3534 deleted file mode 100644 index 9a307a42..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3534 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3541 b/persistentStorage/data-keycloak-db/base/13780/3541 deleted file mode 100644 index 40869ad3..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3541 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3541_fsm b/persistentStorage/data-keycloak-db/base/13780/3541_fsm deleted file mode 100644 index a3a2de4d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3541_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3541_vm b/persistentStorage/data-keycloak-db/base/13780/3541_vm deleted file mode 100644 index bd8c84af..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3541_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3542 b/persistentStorage/data-keycloak-db/base/13780/3542 deleted file mode 100644 index ee21b6ae..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3542 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3574 b/persistentStorage/data-keycloak-db/base/13780/3574 deleted file mode 100644 index 418bbca1..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3574 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3575 b/persistentStorage/data-keycloak-db/base/13780/3575 deleted file mode 100644 index 6addf868..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3575 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3576 b/persistentStorage/data-keycloak-db/base/13780/3576 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/3596 b/persistentStorage/data-keycloak-db/base/13780/3596 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/3597 b/persistentStorage/data-keycloak-db/base/13780/3597 deleted file mode 100644 index 71d2820e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3597 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3598 b/persistentStorage/data-keycloak-db/base/13780/3598 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/3599 b/persistentStorage/data-keycloak-db/base/13780/3599 deleted file mode 100644 index 507ca587..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3599 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3600 b/persistentStorage/data-keycloak-db/base/13780/3600 deleted file mode 100644 index 41c62c58..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3600 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3600_fsm b/persistentStorage/data-keycloak-db/base/13780/3600_fsm deleted file mode 100644 index cebec199..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3600_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3600_vm b/persistentStorage/data-keycloak-db/base/13780/3600_vm deleted file mode 100644 index e611f185..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3600_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3601 b/persistentStorage/data-keycloak-db/base/13780/3601 deleted file mode 100644 index 04c846ec..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3601 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3601_fsm b/persistentStorage/data-keycloak-db/base/13780/3601_fsm deleted file mode 100644 index 7732d22b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3601_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3601_vm b/persistentStorage/data-keycloak-db/base/13780/3601_vm deleted file mode 100644 index e63f9b2d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3601_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3602 b/persistentStorage/data-keycloak-db/base/13780/3602 deleted file mode 100644 index e77e1ad5..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3602 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3602_fsm b/persistentStorage/data-keycloak-db/base/13780/3602_fsm deleted file mode 100644 index d7897de2..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3602_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3602_vm b/persistentStorage/data-keycloak-db/base/13780/3602_vm deleted file mode 100644 index 23986f7e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3602_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3603 b/persistentStorage/data-keycloak-db/base/13780/3603 deleted file mode 100644 index 57062b10..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3603 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3603_fsm b/persistentStorage/data-keycloak-db/base/13780/3603_fsm deleted file mode 100644 index c28dd4fa..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3603_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3603_vm b/persistentStorage/data-keycloak-db/base/13780/3603_vm deleted file mode 100644 index b5dac618..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3603_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3604 b/persistentStorage/data-keycloak-db/base/13780/3604 deleted file mode 100644 index 4a979b17..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3604 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3605 b/persistentStorage/data-keycloak-db/base/13780/3605 deleted file mode 100644 index 7e7c31ca..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3605 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3606 b/persistentStorage/data-keycloak-db/base/13780/3606 deleted file mode 100644 index de60e2ff..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3606 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3607 b/persistentStorage/data-keycloak-db/base/13780/3607 deleted file mode 100644 index ff537351..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3607 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3608 b/persistentStorage/data-keycloak-db/base/13780/3608 deleted file mode 100644 index bf99099a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3608 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3609 b/persistentStorage/data-keycloak-db/base/13780/3609 deleted file mode 100644 index aca244c6..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3609 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3712 b/persistentStorage/data-keycloak-db/base/13780/3712 deleted file mode 100644 index e4e2c033..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3712 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3764 b/persistentStorage/data-keycloak-db/base/13780/3764 deleted file mode 100644 index da4bd39c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3764 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3764_fsm b/persistentStorage/data-keycloak-db/base/13780/3764_fsm deleted file mode 100644 index f64db4df..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3764_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3764_vm b/persistentStorage/data-keycloak-db/base/13780/3764_vm deleted file mode 100644 index 3930bc12..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3764_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3766 b/persistentStorage/data-keycloak-db/base/13780/3766 deleted file mode 100644 index 44d0b7de..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3766 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3767 b/persistentStorage/data-keycloak-db/base/13780/3767 deleted file mode 100644 index b8e981f8..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3767 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/3997 b/persistentStorage/data-keycloak-db/base/13780/3997 deleted file mode 100644 index fd6175ff..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/3997 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/4143 b/persistentStorage/data-keycloak-db/base/13780/4143 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/4144 b/persistentStorage/data-keycloak-db/base/13780/4144 deleted file mode 100644 index a3569d11..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/4144 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/4145 b/persistentStorage/data-keycloak-db/base/13780/4145 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/4146 b/persistentStorage/data-keycloak-db/base/13780/4146 deleted file mode 100644 index 3397d87e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/4146 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/4147 b/persistentStorage/data-keycloak-db/base/13780/4147 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/4148 b/persistentStorage/data-keycloak-db/base/13780/4148 deleted file mode 100644 index 6e10fc5e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/4148 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/4149 b/persistentStorage/data-keycloak-db/base/13780/4149 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/4150 b/persistentStorage/data-keycloak-db/base/13780/4150 deleted file mode 100644 index a0ea1cc0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/4150 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/4151 b/persistentStorage/data-keycloak-db/base/13780/4151 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/4152 b/persistentStorage/data-keycloak-db/base/13780/4152 deleted file mode 100644 index 4179f382..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/4152 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/4153 b/persistentStorage/data-keycloak-db/base/13780/4153 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/4154 b/persistentStorage/data-keycloak-db/base/13780/4154 deleted file mode 100644 index a5e44b4f..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/4154 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/4155 b/persistentStorage/data-keycloak-db/base/13780/4155 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/4156 b/persistentStorage/data-keycloak-db/base/13780/4156 deleted file mode 100644 index e3a35c68..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/4156 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/4157 b/persistentStorage/data-keycloak-db/base/13780/4157 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/4158 b/persistentStorage/data-keycloak-db/base/13780/4158 deleted file mode 100644 index 3de62cdf..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/4158 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/4159 b/persistentStorage/data-keycloak-db/base/13780/4159 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/4160 b/persistentStorage/data-keycloak-db/base/13780/4160 deleted file mode 100644 index b17f909c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/4160 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/4163 b/persistentStorage/data-keycloak-db/base/13780/4163 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/4164 b/persistentStorage/data-keycloak-db/base/13780/4164 deleted file mode 100644 index 2e798538..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/4164 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/4165 b/persistentStorage/data-keycloak-db/base/13780/4165 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/4166 b/persistentStorage/data-keycloak-db/base/13780/4166 deleted file mode 100644 index 9e74293a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/4166 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/4167 b/persistentStorage/data-keycloak-db/base/13780/4167 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/4168 b/persistentStorage/data-keycloak-db/base/13780/4168 deleted file mode 100644 index a032ccae..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/4168 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/4169 b/persistentStorage/data-keycloak-db/base/13780/4169 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/4170 b/persistentStorage/data-keycloak-db/base/13780/4170 deleted file mode 100644 index c75cf673..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/4170 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/4171 b/persistentStorage/data-keycloak-db/base/13780/4171 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/4172 b/persistentStorage/data-keycloak-db/base/13780/4172 deleted file mode 100644 index f9cb0379..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/4172 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/4173 b/persistentStorage/data-keycloak-db/base/13780/4173 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/4174 b/persistentStorage/data-keycloak-db/base/13780/4174 deleted file mode 100644 index deb4a11b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/4174 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/5002 b/persistentStorage/data-keycloak-db/base/13780/5002 deleted file mode 100644 index 32af7a1e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/5002 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/548 b/persistentStorage/data-keycloak-db/base/13780/548 deleted file mode 100644 index 9f219478..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/548 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/549 b/persistentStorage/data-keycloak-db/base/13780/549 deleted file mode 100644 index 68efb3f3..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/549 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/6102 b/persistentStorage/data-keycloak-db/base/13780/6102 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/6104 b/persistentStorage/data-keycloak-db/base/13780/6104 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/6106 b/persistentStorage/data-keycloak-db/base/13780/6106 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/6110 b/persistentStorage/data-keycloak-db/base/13780/6110 deleted file mode 100644 index 536b80d3..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/6110 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/6111 b/persistentStorage/data-keycloak-db/base/13780/6111 deleted file mode 100644 index 3d22c94f..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/6111 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/6112 b/persistentStorage/data-keycloak-db/base/13780/6112 deleted file mode 100644 index 9e47d5c5..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/6112 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/6113 b/persistentStorage/data-keycloak-db/base/13780/6113 deleted file mode 100644 index 4e57f5be..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/6113 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/6117 b/persistentStorage/data-keycloak-db/base/13780/6117 deleted file mode 100644 index 296b14e8..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/6117 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/6175 b/persistentStorage/data-keycloak-db/base/13780/6175 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/6176 b/persistentStorage/data-keycloak-db/base/13780/6176 deleted file mode 100644 index 45c76f44..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/6176 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/826 b/persistentStorage/data-keycloak-db/base/13780/826 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/13780/827 b/persistentStorage/data-keycloak-db/base/13780/827 deleted file mode 100644 index 86db9fe6..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/827 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/828 b/persistentStorage/data-keycloak-db/base/13780/828 deleted file mode 100644 index 4a522991..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/828 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/13780/PG_VERSION b/persistentStorage/data-keycloak-db/base/13780/PG_VERSION deleted file mode 100644 index 8351c193..00000000 --- a/persistentStorage/data-keycloak-db/base/13780/PG_VERSION +++ /dev/null @@ -1 +0,0 @@ -14 diff --git a/persistentStorage/data-keycloak-db/base/13780/pg_filenode.map b/persistentStorage/data-keycloak-db/base/13780/pg_filenode.map deleted file mode 100644 index 193d78f3..00000000 Binary files a/persistentStorage/data-keycloak-db/base/13780/pg_filenode.map and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/112 b/persistentStorage/data-keycloak-db/base/16384/112 deleted file mode 100644 index 21db5147..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/112 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/113 b/persistentStorage/data-keycloak-db/base/16384/113 deleted file mode 100644 index 3f06e2f0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/113 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/1247 b/persistentStorage/data-keycloak-db/base/16384/1247 deleted file mode 100644 index f3c877e6..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/1247 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/1247_fsm b/persistentStorage/data-keycloak-db/base/16384/1247_fsm deleted file mode 100644 index 293152bc..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/1247_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/1247_vm b/persistentStorage/data-keycloak-db/base/16384/1247_vm deleted file mode 100644 index aa6f89b4..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/1247_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/1249 b/persistentStorage/data-keycloak-db/base/16384/1249 deleted file mode 100644 index 00149614..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/1249 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/1249_fsm b/persistentStorage/data-keycloak-db/base/16384/1249_fsm deleted file mode 100644 index 2318d62e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/1249_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/1249_vm b/persistentStorage/data-keycloak-db/base/16384/1249_vm deleted file mode 100644 index d76dbd65..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/1249_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/1255 b/persistentStorage/data-keycloak-db/base/16384/1255 deleted file mode 100644 index ad8eae9d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/1255 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/1255_fsm b/persistentStorage/data-keycloak-db/base/16384/1255_fsm deleted file mode 100644 index b730b34d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/1255_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/1255_vm b/persistentStorage/data-keycloak-db/base/16384/1255_vm deleted file mode 100644 index 32919fdd..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/1255_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/1259 b/persistentStorage/data-keycloak-db/base/16384/1259 deleted file mode 100644 index bba85a1e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/1259 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/1259_fsm b/persistentStorage/data-keycloak-db/base/16384/1259_fsm deleted file mode 100644 index 08c0ea0a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/1259_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/1259_vm b/persistentStorage/data-keycloak-db/base/16384/1259_vm deleted file mode 100644 index 81675f0c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/1259_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/13598 b/persistentStorage/data-keycloak-db/base/16384/13598 deleted file mode 100644 index f536b0d2..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/13598 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/13598_fsm b/persistentStorage/data-keycloak-db/base/16384/13598_fsm deleted file mode 100644 index dc87bf49..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/13598_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/13598_vm b/persistentStorage/data-keycloak-db/base/16384/13598_vm deleted file mode 100644 index 17ee883c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/13598_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/13601 b/persistentStorage/data-keycloak-db/base/16384/13601 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/13602 b/persistentStorage/data-keycloak-db/base/16384/13602 deleted file mode 100644 index 752d0764..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/13602 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/13603 b/persistentStorage/data-keycloak-db/base/16384/13603 deleted file mode 100644 index 239fb781..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/13603 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/13603_fsm b/persistentStorage/data-keycloak-db/base/16384/13603_fsm deleted file mode 100644 index ce7c26eb..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/13603_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/13603_vm b/persistentStorage/data-keycloak-db/base/16384/13603_vm deleted file mode 100644 index f1a19f83..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/13603_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/13606 b/persistentStorage/data-keycloak-db/base/16384/13606 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/13607 b/persistentStorage/data-keycloak-db/base/16384/13607 deleted file mode 100644 index a34d8cfe..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/13607 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/13608 b/persistentStorage/data-keycloak-db/base/16384/13608 deleted file mode 100644 index 257e1065..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/13608 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/13608_fsm b/persistentStorage/data-keycloak-db/base/16384/13608_fsm deleted file mode 100644 index d388044f..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/13608_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/13608_vm b/persistentStorage/data-keycloak-db/base/16384/13608_vm deleted file mode 100644 index 5f1cf8d0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/13608_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/13611 b/persistentStorage/data-keycloak-db/base/16384/13611 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/13612 b/persistentStorage/data-keycloak-db/base/16384/13612 deleted file mode 100644 index 28970355..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/13612 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/13613 b/persistentStorage/data-keycloak-db/base/16384/13613 deleted file mode 100644 index 2b4c488c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/13613 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/13613_fsm b/persistentStorage/data-keycloak-db/base/16384/13613_fsm deleted file mode 100644 index a836ddf7..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/13613_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/13613_vm b/persistentStorage/data-keycloak-db/base/16384/13613_vm deleted file mode 100644 index be95e308..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/13613_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/13616 b/persistentStorage/data-keycloak-db/base/16384/13616 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/13617 b/persistentStorage/data-keycloak-db/base/16384/13617 deleted file mode 100644 index 572afc12..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/13617 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/1417 b/persistentStorage/data-keycloak-db/base/16384/1417 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/1418 b/persistentStorage/data-keycloak-db/base/16384/1418 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16385 b/persistentStorage/data-keycloak-db/base/16384/16385 deleted file mode 100644 index 47276c98..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16385 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16388 b/persistentStorage/data-keycloak-db/base/16384/16388 deleted file mode 100644 index cc0dc5cb..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16388 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16390 b/persistentStorage/data-keycloak-db/base/16384/16390 deleted file mode 100644 index eceffaf9..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16390 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16390_fsm b/persistentStorage/data-keycloak-db/base/16384/16390_fsm deleted file mode 100644 index 7e430b44..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16390_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16393 b/persistentStorage/data-keycloak-db/base/16384/16393 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16394 b/persistentStorage/data-keycloak-db/base/16384/16394 deleted file mode 100644 index 951b3b1c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16394 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16398 b/persistentStorage/data-keycloak-db/base/16384/16398 deleted file mode 100644 index ab52d7fe..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16398 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16407 b/persistentStorage/data-keycloak-db/base/16384/16407 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16408 b/persistentStorage/data-keycloak-db/base/16384/16408 deleted file mode 100644 index 52327f2c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16408 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16409 b/persistentStorage/data-keycloak-db/base/16384/16409 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16412 b/persistentStorage/data-keycloak-db/base/16384/16412 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16413 b/persistentStorage/data-keycloak-db/base/16384/16413 deleted file mode 100644 index b7f8e6ba..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16413 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16414 b/persistentStorage/data-keycloak-db/base/16384/16414 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16417 b/persistentStorage/data-keycloak-db/base/16384/16417 deleted file mode 100644 index 61387a68..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16417 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16417_fsm b/persistentStorage/data-keycloak-db/base/16384/16417_fsm deleted file mode 100644 index 74952c70..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16417_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16420 b/persistentStorage/data-keycloak-db/base/16384/16420 deleted file mode 100644 index c5cbc745..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16420 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16423 b/persistentStorage/data-keycloak-db/base/16384/16423 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16424 b/persistentStorage/data-keycloak-db/base/16384/16424 deleted file mode 100644 index 38ec2d18..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16424 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16425 b/persistentStorage/data-keycloak-db/base/16384/16425 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16428 b/persistentStorage/data-keycloak-db/base/16384/16428 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16429 b/persistentStorage/data-keycloak-db/base/16384/16429 deleted file mode 100644 index 9ba438ee..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16429 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16433 b/persistentStorage/data-keycloak-db/base/16384/16433 deleted file mode 100644 index e68cd788..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16433 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16433_fsm b/persistentStorage/data-keycloak-db/base/16384/16433_fsm deleted file mode 100644 index 9f5bd87f..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16433_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16437 b/persistentStorage/data-keycloak-db/base/16384/16437 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16438 b/persistentStorage/data-keycloak-db/base/16384/16438 deleted file mode 100644 index 71a27fe7..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16438 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16439 b/persistentStorage/data-keycloak-db/base/16384/16439 deleted file mode 100644 index 02e2a97c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16439 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16451 b/persistentStorage/data-keycloak-db/base/16384/16451 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16452 b/persistentStorage/data-keycloak-db/base/16384/16452 deleted file mode 100644 index d13f50ee..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16452 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16456 b/persistentStorage/data-keycloak-db/base/16384/16456 deleted file mode 100644 index 9428af0e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16456 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16456_fsm b/persistentStorage/data-keycloak-db/base/16384/16456_fsm deleted file mode 100644 index 39488e54..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16456_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16459 b/persistentStorage/data-keycloak-db/base/16384/16459 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16460 b/persistentStorage/data-keycloak-db/base/16384/16460 deleted file mode 100644 index 12c2bdce..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16460 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16464 b/persistentStorage/data-keycloak-db/base/16384/16464 deleted file mode 100644 index 9542d1f6..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16464 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16467 b/persistentStorage/data-keycloak-db/base/16384/16467 deleted file mode 100644 index 4c7c7a7a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16467 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16472 b/persistentStorage/data-keycloak-db/base/16384/16472 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16473 b/persistentStorage/data-keycloak-db/base/16384/16473 deleted file mode 100644 index b4606689..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16473 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16474 b/persistentStorage/data-keycloak-db/base/16384/16474 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16477 b/persistentStorage/data-keycloak-db/base/16384/16477 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16478 b/persistentStorage/data-keycloak-db/base/16384/16478 deleted file mode 100644 index baf304fb..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16478 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16484 b/persistentStorage/data-keycloak-db/base/16384/16484 deleted file mode 100644 index 61fdc4ae..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16484 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16487 b/persistentStorage/data-keycloak-db/base/16384/16487 deleted file mode 100644 index dd56f685..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16487 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16490 b/persistentStorage/data-keycloak-db/base/16384/16490 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16493 b/persistentStorage/data-keycloak-db/base/16384/16493 deleted file mode 100644 index d8199ca5..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16493 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16496 b/persistentStorage/data-keycloak-db/base/16384/16496 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16497 b/persistentStorage/data-keycloak-db/base/16384/16497 deleted file mode 100644 index 174a3d59..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16497 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16498 b/persistentStorage/data-keycloak-db/base/16384/16498 deleted file mode 100644 index 78d7cf19..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16498 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16504 b/persistentStorage/data-keycloak-db/base/16384/16504 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16505 b/persistentStorage/data-keycloak-db/base/16384/16505 deleted file mode 100644 index 99dc6675..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16505 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16506 b/persistentStorage/data-keycloak-db/base/16384/16506 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16509 b/persistentStorage/data-keycloak-db/base/16384/16509 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16510 b/persistentStorage/data-keycloak-db/base/16384/16510 deleted file mode 100644 index d80c2ca9..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16510 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16511 b/persistentStorage/data-keycloak-db/base/16384/16511 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16514 b/persistentStorage/data-keycloak-db/base/16384/16514 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16515 b/persistentStorage/data-keycloak-db/base/16384/16515 deleted file mode 100644 index 877e61e2..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16515 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16516 b/persistentStorage/data-keycloak-db/base/16384/16516 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16519 b/persistentStorage/data-keycloak-db/base/16384/16519 deleted file mode 100644 index 627d5446..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16519 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16522 b/persistentStorage/data-keycloak-db/base/16384/16522 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16526 b/persistentStorage/data-keycloak-db/base/16384/16526 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16527 b/persistentStorage/data-keycloak-db/base/16384/16527 deleted file mode 100644 index 4e18b908..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16527 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16533 b/persistentStorage/data-keycloak-db/base/16384/16533 deleted file mode 100644 index 5a6fa206..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16533 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16544 b/persistentStorage/data-keycloak-db/base/16384/16544 deleted file mode 100644 index 80983d2c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16544 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16546 b/persistentStorage/data-keycloak-db/base/16384/16546 deleted file mode 100644 index 32a5710a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16546 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16548 b/persistentStorage/data-keycloak-db/base/16384/16548 deleted file mode 100644 index 076bf195..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16548 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16550 b/persistentStorage/data-keycloak-db/base/16384/16550 deleted file mode 100644 index 51a3f462..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16550 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16552 b/persistentStorage/data-keycloak-db/base/16384/16552 deleted file mode 100644 index 16fb91c8..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16552 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16556 b/persistentStorage/data-keycloak-db/base/16384/16556 deleted file mode 100644 index a7ce7377..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16556 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16558 b/persistentStorage/data-keycloak-db/base/16384/16558 deleted file mode 100644 index c0ce798d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16558 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16560 b/persistentStorage/data-keycloak-db/base/16384/16560 deleted file mode 100644 index 991bf634..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16560 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16562 b/persistentStorage/data-keycloak-db/base/16384/16562 deleted file mode 100644 index 5804c7c8..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16562 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16564 b/persistentStorage/data-keycloak-db/base/16384/16564 deleted file mode 100644 index 11da3bb6..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16564 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16566 b/persistentStorage/data-keycloak-db/base/16384/16566 deleted file mode 100644 index 04d6ee2b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16566 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16568 b/persistentStorage/data-keycloak-db/base/16384/16568 deleted file mode 100644 index 96cef329..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16568 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16570 b/persistentStorage/data-keycloak-db/base/16384/16570 deleted file mode 100644 index 5a7facfb..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16570 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16572 b/persistentStorage/data-keycloak-db/base/16384/16572 deleted file mode 100644 index 40f78528..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16572 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16574 b/persistentStorage/data-keycloak-db/base/16384/16574 deleted file mode 100644 index a2b80ae5..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16574 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16576 b/persistentStorage/data-keycloak-db/base/16384/16576 deleted file mode 100644 index b1898d71..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16576 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16580 b/persistentStorage/data-keycloak-db/base/16384/16580 deleted file mode 100644 index f1ef3640..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16580 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16584 b/persistentStorage/data-keycloak-db/base/16384/16584 deleted file mode 100644 index cd48f536..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16584 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16592 b/persistentStorage/data-keycloak-db/base/16384/16592 deleted file mode 100644 index dc4df4fb..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16592 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16756 b/persistentStorage/data-keycloak-db/base/16384/16756 deleted file mode 100644 index 2c45186e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16756 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16759 b/persistentStorage/data-keycloak-db/base/16384/16759 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16760 b/persistentStorage/data-keycloak-db/base/16384/16760 deleted file mode 100644 index 8152d915..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16760 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16761 b/persistentStorage/data-keycloak-db/base/16384/16761 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16764 b/persistentStorage/data-keycloak-db/base/16384/16764 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16765 b/persistentStorage/data-keycloak-db/base/16384/16765 deleted file mode 100644 index 31939953..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16765 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16766 b/persistentStorage/data-keycloak-db/base/16384/16766 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16770 b/persistentStorage/data-keycloak-db/base/16384/16770 deleted file mode 100644 index 50a4b246..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16770 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16772 b/persistentStorage/data-keycloak-db/base/16384/16772 deleted file mode 100644 index e000d552..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16772 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16774 b/persistentStorage/data-keycloak-db/base/16384/16774 deleted file mode 100644 index 0107e7cd..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16774 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16791 b/persistentStorage/data-keycloak-db/base/16384/16791 deleted file mode 100644 index 57fca047..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16791 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16791_fsm b/persistentStorage/data-keycloak-db/base/16384/16791_fsm deleted file mode 100644 index 9e166650..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16791_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16795 b/persistentStorage/data-keycloak-db/base/16384/16795 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16796 b/persistentStorage/data-keycloak-db/base/16384/16796 deleted file mode 100644 index ae5407fd..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16796 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16797 b/persistentStorage/data-keycloak-db/base/16384/16797 deleted file mode 100644 index a83f17e8..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16797 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16797_fsm b/persistentStorage/data-keycloak-db/base/16384/16797_fsm deleted file mode 100644 index 1c78a328..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16797_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16800 b/persistentStorage/data-keycloak-db/base/16384/16800 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16801 b/persistentStorage/data-keycloak-db/base/16384/16801 deleted file mode 100644 index ab8e88c8..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16801 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16802 b/persistentStorage/data-keycloak-db/base/16384/16802 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16805 b/persistentStorage/data-keycloak-db/base/16384/16805 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16806 b/persistentStorage/data-keycloak-db/base/16384/16806 deleted file mode 100644 index 9c2dd9ae..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16806 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16807 b/persistentStorage/data-keycloak-db/base/16384/16807 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16814 b/persistentStorage/data-keycloak-db/base/16384/16814 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16815 b/persistentStorage/data-keycloak-db/base/16384/16815 deleted file mode 100644 index e7e0924d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16815 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16816 b/persistentStorage/data-keycloak-db/base/16384/16816 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16819 b/persistentStorage/data-keycloak-db/base/16384/16819 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16820 b/persistentStorage/data-keycloak-db/base/16384/16820 deleted file mode 100644 index 0a4b847f..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16820 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16825 b/persistentStorage/data-keycloak-db/base/16384/16825 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16828 b/persistentStorage/data-keycloak-db/base/16384/16828 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16831 b/persistentStorage/data-keycloak-db/base/16384/16831 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16832 b/persistentStorage/data-keycloak-db/base/16384/16832 deleted file mode 100644 index 602e585e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16832 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16834 b/persistentStorage/data-keycloak-db/base/16384/16834 deleted file mode 100644 index 41a2a16e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16834 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16836 b/persistentStorage/data-keycloak-db/base/16384/16836 deleted file mode 100644 index 750907da..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16836 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16838 b/persistentStorage/data-keycloak-db/base/16384/16838 deleted file mode 100644 index a9f66328..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16838 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16840 b/persistentStorage/data-keycloak-db/base/16384/16840 deleted file mode 100644 index 00deab98..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16840 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16844 b/persistentStorage/data-keycloak-db/base/16384/16844 deleted file mode 100644 index 64009282..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16844 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16891 b/persistentStorage/data-keycloak-db/base/16384/16891 deleted file mode 100644 index 122aef0f..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16891 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16909 b/persistentStorage/data-keycloak-db/base/16384/16909 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16917 b/persistentStorage/data-keycloak-db/base/16384/16917 deleted file mode 100644 index 640c2953..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16917 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16920 b/persistentStorage/data-keycloak-db/base/16384/16920 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16923 b/persistentStorage/data-keycloak-db/base/16384/16923 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16924 b/persistentStorage/data-keycloak-db/base/16384/16924 deleted file mode 100644 index 411e82ed..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16924 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16925 b/persistentStorage/data-keycloak-db/base/16384/16925 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16928 b/persistentStorage/data-keycloak-db/base/16384/16928 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16929 b/persistentStorage/data-keycloak-db/base/16384/16929 deleted file mode 100644 index ffd9a720..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16929 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16930 b/persistentStorage/data-keycloak-db/base/16384/16930 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16939 b/persistentStorage/data-keycloak-db/base/16384/16939 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/16942 b/persistentStorage/data-keycloak-db/base/16384/16942 deleted file mode 100644 index 25a6a2bb..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16942 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16944 b/persistentStorage/data-keycloak-db/base/16384/16944 deleted file mode 100644 index 14a5f313..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16944 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16948 b/persistentStorage/data-keycloak-db/base/16384/16948 deleted file mode 100644 index ffbf386e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16948 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/16954 b/persistentStorage/data-keycloak-db/base/16384/16954 deleted file mode 100644 index 9a96554e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/16954 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17017 b/persistentStorage/data-keycloak-db/base/16384/17017 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17020 b/persistentStorage/data-keycloak-db/base/16384/17020 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17021 b/persistentStorage/data-keycloak-db/base/16384/17021 deleted file mode 100644 index f3d88ab8..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17021 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17022 b/persistentStorage/data-keycloak-db/base/16384/17022 deleted file mode 100644 index c38e79d2..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17022 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17025 b/persistentStorage/data-keycloak-db/base/16384/17025 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17026 b/persistentStorage/data-keycloak-db/base/16384/17026 deleted file mode 100644 index 0e0b7847..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17026 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17027 b/persistentStorage/data-keycloak-db/base/16384/17027 deleted file mode 100644 index d441397e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17027 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17030 b/persistentStorage/data-keycloak-db/base/16384/17030 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17031 b/persistentStorage/data-keycloak-db/base/16384/17031 deleted file mode 100644 index 8e260f22..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17031 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17032 b/persistentStorage/data-keycloak-db/base/16384/17032 deleted file mode 100644 index d50de017..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17032 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17032_fsm b/persistentStorage/data-keycloak-db/base/16384/17032_fsm deleted file mode 100644 index 247f99be..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17032_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17037 b/persistentStorage/data-keycloak-db/base/16384/17037 deleted file mode 100644 index 8f21be17..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17037 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17040 b/persistentStorage/data-keycloak-db/base/16384/17040 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17041 b/persistentStorage/data-keycloak-db/base/16384/17041 deleted file mode 100644 index 25372aba..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17041 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17042 b/persistentStorage/data-keycloak-db/base/16384/17042 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17045 b/persistentStorage/data-keycloak-db/base/16384/17045 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17046 b/persistentStorage/data-keycloak-db/base/16384/17046 deleted file mode 100644 index 04ab2646..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17046 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17047 b/persistentStorage/data-keycloak-db/base/16384/17047 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17050 b/persistentStorage/data-keycloak-db/base/16384/17050 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17051 b/persistentStorage/data-keycloak-db/base/16384/17051 deleted file mode 100644 index eb7e0431..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17051 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17055 b/persistentStorage/data-keycloak-db/base/16384/17055 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17061 b/persistentStorage/data-keycloak-db/base/16384/17061 deleted file mode 100644 index a2bf43de..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17061 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17063 b/persistentStorage/data-keycloak-db/base/16384/17063 deleted file mode 100644 index bbc5f5d4..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17063 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17065 b/persistentStorage/data-keycloak-db/base/16384/17065 deleted file mode 100644 index 52334b0c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17065 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17067 b/persistentStorage/data-keycloak-db/base/16384/17067 deleted file mode 100644 index 19d9df9b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17067 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17069 b/persistentStorage/data-keycloak-db/base/16384/17069 deleted file mode 100644 index a09ce889..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17069 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17071 b/persistentStorage/data-keycloak-db/base/16384/17071 deleted file mode 100644 index 867680c7..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17071 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17073 b/persistentStorage/data-keycloak-db/base/16384/17073 deleted file mode 100644 index a782de1d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17073 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17075 b/persistentStorage/data-keycloak-db/base/16384/17075 deleted file mode 100644 index d4ab168d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17075 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17117 b/persistentStorage/data-keycloak-db/base/16384/17117 deleted file mode 100644 index e2b7d8f2..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17117 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17124 b/persistentStorage/data-keycloak-db/base/16384/17124 deleted file mode 100644 index 70c5e465..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17124 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17136 b/persistentStorage/data-keycloak-db/base/16384/17136 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17139 b/persistentStorage/data-keycloak-db/base/16384/17139 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17140 b/persistentStorage/data-keycloak-db/base/16384/17140 deleted file mode 100644 index b9e46805..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17140 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17141 b/persistentStorage/data-keycloak-db/base/16384/17141 deleted file mode 100644 index 6ba0a61c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17141 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17146 b/persistentStorage/data-keycloak-db/base/16384/17146 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17147 b/persistentStorage/data-keycloak-db/base/16384/17147 deleted file mode 100644 index 0ca5bb88..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17147 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17148 b/persistentStorage/data-keycloak-db/base/16384/17148 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17151 b/persistentStorage/data-keycloak-db/base/16384/17151 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17152 b/persistentStorage/data-keycloak-db/base/16384/17152 deleted file mode 100644 index 0f9a56d9..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17152 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17153 b/persistentStorage/data-keycloak-db/base/16384/17153 deleted file mode 100644 index fb4aee25..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17153 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17155 b/persistentStorage/data-keycloak-db/base/16384/17155 deleted file mode 100644 index de8d3dcc..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17155 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17157 b/persistentStorage/data-keycloak-db/base/16384/17157 deleted file mode 100644 index 67506f65..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17157 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17159 b/persistentStorage/data-keycloak-db/base/16384/17159 deleted file mode 100644 index 1a37244a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17159 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17184 b/persistentStorage/data-keycloak-db/base/16384/17184 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17187 b/persistentStorage/data-keycloak-db/base/16384/17187 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17188 b/persistentStorage/data-keycloak-db/base/16384/17188 deleted file mode 100644 index 7ef80d22..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17188 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17189 b/persistentStorage/data-keycloak-db/base/16384/17189 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17192 b/persistentStorage/data-keycloak-db/base/16384/17192 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17193 b/persistentStorage/data-keycloak-db/base/16384/17193 deleted file mode 100644 index 60b1d8d8..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17193 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17194 b/persistentStorage/data-keycloak-db/base/16384/17194 deleted file mode 100644 index 2651cace..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17194 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17198 b/persistentStorage/data-keycloak-db/base/16384/17198 deleted file mode 100644 index 743e3c69..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17198 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17201 b/persistentStorage/data-keycloak-db/base/16384/17201 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17204 b/persistentStorage/data-keycloak-db/base/16384/17204 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17208 b/persistentStorage/data-keycloak-db/base/16384/17208 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17209 b/persistentStorage/data-keycloak-db/base/16384/17209 deleted file mode 100644 index 8498e09e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17209 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17210 b/persistentStorage/data-keycloak-db/base/16384/17210 deleted file mode 100644 index 35f24671..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17210 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17213 b/persistentStorage/data-keycloak-db/base/16384/17213 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17217 b/persistentStorage/data-keycloak-db/base/16384/17217 deleted file mode 100644 index 9e25c991..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17217 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17224 b/persistentStorage/data-keycloak-db/base/16384/17224 deleted file mode 100644 index 9db5ffba..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17224 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17231 b/persistentStorage/data-keycloak-db/base/16384/17231 deleted file mode 100644 index 99fe12cf..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17231 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17238 b/persistentStorage/data-keycloak-db/base/16384/17238 deleted file mode 100644 index a36dcd1c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17238 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17250 b/persistentStorage/data-keycloak-db/base/16384/17250 deleted file mode 100644 index 882aa33f..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17250 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17265 b/persistentStorage/data-keycloak-db/base/16384/17265 deleted file mode 100644 index 4c121cd4..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17265 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17277 b/persistentStorage/data-keycloak-db/base/16384/17277 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17278 b/persistentStorage/data-keycloak-db/base/16384/17278 deleted file mode 100644 index 06f1c176..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17278 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17279 b/persistentStorage/data-keycloak-db/base/16384/17279 deleted file mode 100644 index fdbd1dd4..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17279 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17282 b/persistentStorage/data-keycloak-db/base/16384/17282 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17283 b/persistentStorage/data-keycloak-db/base/16384/17283 deleted file mode 100644 index 812cbcc2..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17283 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17284 b/persistentStorage/data-keycloak-db/base/16384/17284 deleted file mode 100644 index df349bdd..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17284 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17293 b/persistentStorage/data-keycloak-db/base/16384/17293 deleted file mode 100644 index 689a6ed9..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17293 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17322 b/persistentStorage/data-keycloak-db/base/16384/17322 deleted file mode 100644 index fe4b82ab..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17322 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17334 b/persistentStorage/data-keycloak-db/base/16384/17334 deleted file mode 100644 index b323ca08..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17334 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17341 b/persistentStorage/data-keycloak-db/base/16384/17341 deleted file mode 100644 index 7f7fb556..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17341 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17342 b/persistentStorage/data-keycloak-db/base/16384/17342 deleted file mode 100644 index 82f4252f..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17342 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17343 b/persistentStorage/data-keycloak-db/base/16384/17343 deleted file mode 100644 index 5dfadec5..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17343 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17344 b/persistentStorage/data-keycloak-db/base/16384/17344 deleted file mode 100644 index 80528e0a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17344 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17345 b/persistentStorage/data-keycloak-db/base/16384/17345 deleted file mode 100644 index d56251db..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17345 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17348 b/persistentStorage/data-keycloak-db/base/16384/17348 deleted file mode 100644 index 9f492a13..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17348 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17349 b/persistentStorage/data-keycloak-db/base/16384/17349 deleted file mode 100644 index fd49406d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17349 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17350 b/persistentStorage/data-keycloak-db/base/16384/17350 deleted file mode 100644 index dc7c279a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17350 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17351 b/persistentStorage/data-keycloak-db/base/16384/17351 deleted file mode 100644 index 45fc01d6..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17351 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17352 b/persistentStorage/data-keycloak-db/base/16384/17352 deleted file mode 100644 index c766bc3e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17352 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17361 b/persistentStorage/data-keycloak-db/base/16384/17361 deleted file mode 100644 index dfa2ab70..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17361 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17364 b/persistentStorage/data-keycloak-db/base/16384/17364 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17365 b/persistentStorage/data-keycloak-db/base/16384/17365 deleted file mode 100644 index 7e19c80d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17365 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17366 b/persistentStorage/data-keycloak-db/base/16384/17366 deleted file mode 100644 index 2c3168fb..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17366 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17375 b/persistentStorage/data-keycloak-db/base/16384/17375 deleted file mode 100644 index 804307f2..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17375 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17378 b/persistentStorage/data-keycloak-db/base/16384/17378 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17379 b/persistentStorage/data-keycloak-db/base/16384/17379 deleted file mode 100644 index eb220ae0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17379 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17380 b/persistentStorage/data-keycloak-db/base/16384/17380 deleted file mode 100644 index 78e2a27b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17380 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/174 b/persistentStorage/data-keycloak-db/base/16384/174 deleted file mode 100644 index 6312b18f..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/174 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17403 b/persistentStorage/data-keycloak-db/base/16384/17403 deleted file mode 100644 index b2c3647d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17403 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17406 b/persistentStorage/data-keycloak-db/base/16384/17406 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17407 b/persistentStorage/data-keycloak-db/base/16384/17407 deleted file mode 100644 index 041756c0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17407 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17408 b/persistentStorage/data-keycloak-db/base/16384/17408 deleted file mode 100644 index a382d229..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17408 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17415 b/persistentStorage/data-keycloak-db/base/16384/17415 deleted file mode 100644 index b2d7379b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17415 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17418 b/persistentStorage/data-keycloak-db/base/16384/17418 deleted file mode 100644 index 08ebd031..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17418 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17430 b/persistentStorage/data-keycloak-db/base/16384/17430 deleted file mode 100644 index d7623281..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17430 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17433 b/persistentStorage/data-keycloak-db/base/16384/17433 deleted file mode 100644 index f90b93a0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17433 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17445 b/persistentStorage/data-keycloak-db/base/16384/17445 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17448 b/persistentStorage/data-keycloak-db/base/16384/17448 deleted file mode 100644 index ccbfbe30..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17448 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17460 b/persistentStorage/data-keycloak-db/base/16384/17460 deleted file mode 100644 index 4c87afc9..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17460 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17463 b/persistentStorage/data-keycloak-db/base/16384/17463 deleted file mode 100644 index 718f0c49..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17463 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17475 b/persistentStorage/data-keycloak-db/base/16384/17475 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17478 b/persistentStorage/data-keycloak-db/base/16384/17478 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17479 b/persistentStorage/data-keycloak-db/base/16384/17479 deleted file mode 100644 index 5e671c81..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17479 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17480 b/persistentStorage/data-keycloak-db/base/16384/17480 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17483 b/persistentStorage/data-keycloak-db/base/16384/17483 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17484 b/persistentStorage/data-keycloak-db/base/16384/17484 deleted file mode 100644 index a9d9efa3..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17484 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17485 b/persistentStorage/data-keycloak-db/base/16384/17485 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17494 b/persistentStorage/data-keycloak-db/base/16384/17494 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/175 b/persistentStorage/data-keycloak-db/base/16384/175 deleted file mode 100644 index 0f504d0b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/175 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17501 b/persistentStorage/data-keycloak-db/base/16384/17501 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17502 b/persistentStorage/data-keycloak-db/base/16384/17502 deleted file mode 100644 index b3cb21f1..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17502 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17503 b/persistentStorage/data-keycloak-db/base/16384/17503 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17506 b/persistentStorage/data-keycloak-db/base/16384/17506 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17510 b/persistentStorage/data-keycloak-db/base/16384/17510 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17511 b/persistentStorage/data-keycloak-db/base/16384/17511 deleted file mode 100644 index 512118a5..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17511 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17512 b/persistentStorage/data-keycloak-db/base/16384/17512 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17515 b/persistentStorage/data-keycloak-db/base/16384/17515 deleted file mode 100644 index 30d96eaa..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17515 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17515_fsm b/persistentStorage/data-keycloak-db/base/16384/17515_fsm deleted file mode 100644 index bc8d523b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17515_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17518 b/persistentStorage/data-keycloak-db/base/16384/17518 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17519 b/persistentStorage/data-keycloak-db/base/16384/17519 deleted file mode 100644 index 8dd4b294..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17519 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17520 b/persistentStorage/data-keycloak-db/base/16384/17520 deleted file mode 100644 index 11a81fd8..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17520 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17523 b/persistentStorage/data-keycloak-db/base/16384/17523 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17524 b/persistentStorage/data-keycloak-db/base/16384/17524 deleted file mode 100644 index 0e90a346..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17524 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17525 b/persistentStorage/data-keycloak-db/base/16384/17525 deleted file mode 100644 index d01b1f4a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17525 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17527 b/persistentStorage/data-keycloak-db/base/16384/17527 deleted file mode 100644 index bc7eb9bc..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17527 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17529 b/persistentStorage/data-keycloak-db/base/16384/17529 deleted file mode 100644 index 2327093f..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17529 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17535 b/persistentStorage/data-keycloak-db/base/16384/17535 deleted file mode 100644 index 714e5f04..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17535 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17537 b/persistentStorage/data-keycloak-db/base/16384/17537 deleted file mode 100644 index 57d32b35..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17537 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17539 b/persistentStorage/data-keycloak-db/base/16384/17539 deleted file mode 100644 index ac697844..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17539 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17541 b/persistentStorage/data-keycloak-db/base/16384/17541 deleted file mode 100644 index 2a894b11..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17541 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17543 b/persistentStorage/data-keycloak-db/base/16384/17543 deleted file mode 100644 index e71bd7e9..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17543 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17545 b/persistentStorage/data-keycloak-db/base/16384/17545 deleted file mode 100644 index 9a4a6c7c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17545 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17577 b/persistentStorage/data-keycloak-db/base/16384/17577 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17580 b/persistentStorage/data-keycloak-db/base/16384/17580 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17581 b/persistentStorage/data-keycloak-db/base/16384/17581 deleted file mode 100644 index 1f232699..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17581 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17582 b/persistentStorage/data-keycloak-db/base/16384/17582 deleted file mode 100644 index 8f69e7f1..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17582 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17584 b/persistentStorage/data-keycloak-db/base/16384/17584 deleted file mode 100644 index e8b8a31a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17584 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17586 b/persistentStorage/data-keycloak-db/base/16384/17586 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17587 b/persistentStorage/data-keycloak-db/base/16384/17587 deleted file mode 100644 index e760fdf1..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17587 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17588 b/persistentStorage/data-keycloak-db/base/16384/17588 deleted file mode 100644 index c77619ff..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17588 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17590 b/persistentStorage/data-keycloak-db/base/16384/17590 deleted file mode 100644 index 00b8a027..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17590 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17594 b/persistentStorage/data-keycloak-db/base/16384/17594 deleted file mode 100644 index 02313cc6..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17594 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17599 b/persistentStorage/data-keycloak-db/base/16384/17599 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17602 b/persistentStorage/data-keycloak-db/base/16384/17602 deleted file mode 100644 index 26adc5ad..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17602 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17609 b/persistentStorage/data-keycloak-db/base/16384/17609 deleted file mode 100644 index 8df62717..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17609 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17610 b/persistentStorage/data-keycloak-db/base/16384/17610 deleted file mode 100644 index f63e2cb6..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17610 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17611 b/persistentStorage/data-keycloak-db/base/16384/17611 deleted file mode 100644 index 41ed81f8..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17611 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17612 b/persistentStorage/data-keycloak-db/base/16384/17612 deleted file mode 100644 index 0ad7a7c6..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17612 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17613 b/persistentStorage/data-keycloak-db/base/16384/17613 deleted file mode 100644 index 8b18eb8b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17613 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17617 b/persistentStorage/data-keycloak-db/base/16384/17617 deleted file mode 100644 index 13c41b40..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17617 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17618 b/persistentStorage/data-keycloak-db/base/16384/17618 deleted file mode 100644 index 08755666..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17618 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17619 b/persistentStorage/data-keycloak-db/base/16384/17619 deleted file mode 100644 index 50219324..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17619 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17620 b/persistentStorage/data-keycloak-db/base/16384/17620 deleted file mode 100644 index d10b7c73..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17620 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17621 b/persistentStorage/data-keycloak-db/base/16384/17621 deleted file mode 100644 index ac0375aa..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17621 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17624 b/persistentStorage/data-keycloak-db/base/16384/17624 deleted file mode 100644 index 5d46c517..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17624 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17625 b/persistentStorage/data-keycloak-db/base/16384/17625 deleted file mode 100644 index 66a24908..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17625 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17626 b/persistentStorage/data-keycloak-db/base/16384/17626 deleted file mode 100644 index 1333a0f5..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17626 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17627 b/persistentStorage/data-keycloak-db/base/16384/17627 deleted file mode 100644 index 26f22c8f..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17627 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17628 b/persistentStorage/data-keycloak-db/base/16384/17628 deleted file mode 100644 index e644a8c0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17628 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17629 b/persistentStorage/data-keycloak-db/base/16384/17629 deleted file mode 100644 index 4def6681..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17629 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17630 b/persistentStorage/data-keycloak-db/base/16384/17630 deleted file mode 100644 index d0a3fc96..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17630 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17632 b/persistentStorage/data-keycloak-db/base/16384/17632 deleted file mode 100644 index 47adca05..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17632 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17633 b/persistentStorage/data-keycloak-db/base/16384/17633 deleted file mode 100644 index 335c1e0a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17633 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17634 b/persistentStorage/data-keycloak-db/base/16384/17634 deleted file mode 100644 index f9043f18..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17634 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17636 b/persistentStorage/data-keycloak-db/base/16384/17636 deleted file mode 100644 index 2dba7426..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17636 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17637 b/persistentStorage/data-keycloak-db/base/16384/17637 deleted file mode 100644 index 4eba0873..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17637 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17638 b/persistentStorage/data-keycloak-db/base/16384/17638 deleted file mode 100644 index 19a6a659..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17638 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17639 b/persistentStorage/data-keycloak-db/base/16384/17639 deleted file mode 100644 index 56edc8d9..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17639 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17640 b/persistentStorage/data-keycloak-db/base/16384/17640 deleted file mode 100644 index 261f1dae..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17640 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17641 b/persistentStorage/data-keycloak-db/base/16384/17641 deleted file mode 100644 index dc310c01..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17641 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17642 b/persistentStorage/data-keycloak-db/base/16384/17642 deleted file mode 100644 index 0fa02910..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17642 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17646 b/persistentStorage/data-keycloak-db/base/16384/17646 deleted file mode 100644 index 09ea9456..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17646 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17647 b/persistentStorage/data-keycloak-db/base/16384/17647 deleted file mode 100644 index 79c232fd..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17647 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17649 b/persistentStorage/data-keycloak-db/base/16384/17649 deleted file mode 100644 index 0cdce895..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17649 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17650 b/persistentStorage/data-keycloak-db/base/16384/17650 deleted file mode 100644 index 02da7def..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17650 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17651 b/persistentStorage/data-keycloak-db/base/16384/17651 deleted file mode 100644 index 0382255d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17651 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17652 b/persistentStorage/data-keycloak-db/base/16384/17652 deleted file mode 100644 index edd8a777..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17652 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17653 b/persistentStorage/data-keycloak-db/base/16384/17653 deleted file mode 100644 index 5a04f94b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17653 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17657 b/persistentStorage/data-keycloak-db/base/16384/17657 deleted file mode 100644 index cef34b75..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17657 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17659 b/persistentStorage/data-keycloak-db/base/16384/17659 deleted file mode 100644 index 52a5d69a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17659 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17662 b/persistentStorage/data-keycloak-db/base/16384/17662 deleted file mode 100644 index 0d4d792b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17662 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17663 b/persistentStorage/data-keycloak-db/base/16384/17663 deleted file mode 100644 index 48d887d2..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17663 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17684 b/persistentStorage/data-keycloak-db/base/16384/17684 deleted file mode 100644 index 85ee80d8..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17684 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17686 b/persistentStorage/data-keycloak-db/base/16384/17686 deleted file mode 100644 index fcd32d7d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17686 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17690 b/persistentStorage/data-keycloak-db/base/16384/17690 deleted file mode 100644 index a84f12e3..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17690 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17703 b/persistentStorage/data-keycloak-db/base/16384/17703 deleted file mode 100644 index a7c36d84..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17703 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17705 b/persistentStorage/data-keycloak-db/base/16384/17705 deleted file mode 100644 index 44329977..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17705 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17707 b/persistentStorage/data-keycloak-db/base/16384/17707 deleted file mode 100644 index cb21c527..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17707 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17709 b/persistentStorage/data-keycloak-db/base/16384/17709 deleted file mode 100644 index ca047dcb..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17709 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17711 b/persistentStorage/data-keycloak-db/base/16384/17711 deleted file mode 100644 index 67655c2c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17711 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17713 b/persistentStorage/data-keycloak-db/base/16384/17713 deleted file mode 100644 index 3b74d5d9..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17713 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17714 b/persistentStorage/data-keycloak-db/base/16384/17714 deleted file mode 100644 index 7a1f4fb5..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17714 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17715 b/persistentStorage/data-keycloak-db/base/16384/17715 deleted file mode 100644 index e29ff09c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17715 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17716 b/persistentStorage/data-keycloak-db/base/16384/17716 deleted file mode 100644 index 84553371..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17716 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17717 b/persistentStorage/data-keycloak-db/base/16384/17717 deleted file mode 100644 index d4a249a6..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17717 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17718 b/persistentStorage/data-keycloak-db/base/16384/17718 deleted file mode 100644 index 92249721..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17718 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17719 b/persistentStorage/data-keycloak-db/base/16384/17719 deleted file mode 100644 index ac24cc99..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17719 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17720 b/persistentStorage/data-keycloak-db/base/16384/17720 deleted file mode 100644 index 766db445..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17720 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17721 b/persistentStorage/data-keycloak-db/base/16384/17721 deleted file mode 100644 index 7459cbea..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17721 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17722 b/persistentStorage/data-keycloak-db/base/16384/17722 deleted file mode 100644 index a4735dcb..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17722 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17723 b/persistentStorage/data-keycloak-db/base/16384/17723 deleted file mode 100644 index b80b7bf2..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17723 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17724 b/persistentStorage/data-keycloak-db/base/16384/17724 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17727 b/persistentStorage/data-keycloak-db/base/16384/17727 deleted file mode 100644 index 36a6c2e2..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17727 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17729 b/persistentStorage/data-keycloak-db/base/16384/17729 deleted file mode 100644 index fac0f904..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17729 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17731 b/persistentStorage/data-keycloak-db/base/16384/17731 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17732 b/persistentStorage/data-keycloak-db/base/16384/17732 deleted file mode 100644 index 987b0de1..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17732 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17733 b/persistentStorage/data-keycloak-db/base/16384/17733 deleted file mode 100644 index 014c3845..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17733 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17736 b/persistentStorage/data-keycloak-db/base/16384/17736 deleted file mode 100644 index a94d033d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17736 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17738 b/persistentStorage/data-keycloak-db/base/16384/17738 deleted file mode 100644 index 96203551..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17738 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17765 b/persistentStorage/data-keycloak-db/base/16384/17765 deleted file mode 100644 index 7162456e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17765 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17765_fsm b/persistentStorage/data-keycloak-db/base/16384/17765_fsm deleted file mode 100644 index dc1ae01e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17765_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17765_vm b/persistentStorage/data-keycloak-db/base/16384/17765_vm deleted file mode 100644 index 87ddd320..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17765_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17769 b/persistentStorage/data-keycloak-db/base/16384/17769 deleted file mode 100644 index 5ffc5702..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17769 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17781 b/persistentStorage/data-keycloak-db/base/16384/17781 deleted file mode 100644 index 71bf2199..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17781 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17785 b/persistentStorage/data-keycloak-db/base/16384/17785 deleted file mode 100644 index 26e6f49a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17785 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17797 b/persistentStorage/data-keycloak-db/base/16384/17797 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17800 b/persistentStorage/data-keycloak-db/base/16384/17800 deleted file mode 100644 index ecd87c86..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17800 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17807 b/persistentStorage/data-keycloak-db/base/16384/17807 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17810 b/persistentStorage/data-keycloak-db/base/16384/17810 deleted file mode 100644 index aeac56fe..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17810 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17812 b/persistentStorage/data-keycloak-db/base/16384/17812 deleted file mode 100644 index c6565df0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17812 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17813 b/persistentStorage/data-keycloak-db/base/16384/17813 deleted file mode 100644 index 22603e98..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17813 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17814 b/persistentStorage/data-keycloak-db/base/16384/17814 deleted file mode 100644 index 8d5c56e8..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17814 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17815 b/persistentStorage/data-keycloak-db/base/16384/17815 deleted file mode 100644 index 3a6a5f4c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17815 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17816 b/persistentStorage/data-keycloak-db/base/16384/17816 deleted file mode 100644 index 5b1e259f..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17816 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17817 b/persistentStorage/data-keycloak-db/base/16384/17817 deleted file mode 100644 index 36701ef3..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17817 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17818 b/persistentStorage/data-keycloak-db/base/16384/17818 deleted file mode 100644 index 9cc69e49..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17818 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17819 b/persistentStorage/data-keycloak-db/base/16384/17819 deleted file mode 100644 index d4d67e37..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17819 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17820 b/persistentStorage/data-keycloak-db/base/16384/17820 deleted file mode 100644 index 2ea9d872..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17820 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17821 b/persistentStorage/data-keycloak-db/base/16384/17821 deleted file mode 100644 index cd0017e8..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17821 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17822 b/persistentStorage/data-keycloak-db/base/16384/17822 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17825 b/persistentStorage/data-keycloak-db/base/16384/17825 deleted file mode 100644 index 59b0b9ae..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17825 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17842 b/persistentStorage/data-keycloak-db/base/16384/17842 deleted file mode 100644 index 4f25d700..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17842 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17846 b/persistentStorage/data-keycloak-db/base/16384/17846 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17850 b/persistentStorage/data-keycloak-db/base/16384/17850 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17851 b/persistentStorage/data-keycloak-db/base/16384/17851 deleted file mode 100644 index 3c5d33d2..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17851 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17852 b/persistentStorage/data-keycloak-db/base/16384/17852 deleted file mode 100644 index 9cee80f5..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17852 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17864 b/persistentStorage/data-keycloak-db/base/16384/17864 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17872 b/persistentStorage/data-keycloak-db/base/16384/17872 deleted file mode 100644 index 366d1a04..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17872 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17874 b/persistentStorage/data-keycloak-db/base/16384/17874 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17877 b/persistentStorage/data-keycloak-db/base/16384/17877 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17878 b/persistentStorage/data-keycloak-db/base/16384/17878 deleted file mode 100644 index e942f5fa..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17878 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17879 b/persistentStorage/data-keycloak-db/base/16384/17879 deleted file mode 100644 index b46b0147..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17879 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17886 b/persistentStorage/data-keycloak-db/base/16384/17886 deleted file mode 100644 index 4bcf705a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17886 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17887 b/persistentStorage/data-keycloak-db/base/16384/17887 deleted file mode 100644 index d9c51747..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17887 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17891 b/persistentStorage/data-keycloak-db/base/16384/17891 deleted file mode 100644 index aa6f1a2d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17891 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17894 b/persistentStorage/data-keycloak-db/base/16384/17894 deleted file mode 100644 index fedf9ee4..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17894 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17901 b/persistentStorage/data-keycloak-db/base/16384/17901 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17902 b/persistentStorage/data-keycloak-db/base/16384/17902 deleted file mode 100644 index 3565cd8e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17902 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17909 b/persistentStorage/data-keycloak-db/base/16384/17909 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17910 b/persistentStorage/data-keycloak-db/base/16384/17910 deleted file mode 100644 index bfa0865b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17910 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17913 b/persistentStorage/data-keycloak-db/base/16384/17913 deleted file mode 100644 index 60f468a3..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17913 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17914 b/persistentStorage/data-keycloak-db/base/16384/17914 deleted file mode 100644 index 5541ef69..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17914 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17915 b/persistentStorage/data-keycloak-db/base/16384/17915 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17918 b/persistentStorage/data-keycloak-db/base/16384/17918 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17919 b/persistentStorage/data-keycloak-db/base/16384/17919 deleted file mode 100644 index cd83843c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17919 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17920 b/persistentStorage/data-keycloak-db/base/16384/17920 deleted file mode 100644 index 17b99dad..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17920 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17922 b/persistentStorage/data-keycloak-db/base/16384/17922 deleted file mode 100644 index 59173c70..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17922 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17929 b/persistentStorage/data-keycloak-db/base/16384/17929 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17930 b/persistentStorage/data-keycloak-db/base/16384/17930 deleted file mode 100644 index 78863b3a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17930 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17931 b/persistentStorage/data-keycloak-db/base/16384/17931 deleted file mode 100644 index 93ce5dbb..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17931 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17932 b/persistentStorage/data-keycloak-db/base/16384/17932 deleted file mode 100644 index 3b672557..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17932 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17933 b/persistentStorage/data-keycloak-db/base/16384/17933 deleted file mode 100644 index 97e37077..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17933 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17935 b/persistentStorage/data-keycloak-db/base/16384/17935 deleted file mode 100644 index 473c06c3..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17935 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17936 b/persistentStorage/data-keycloak-db/base/16384/17936 deleted file mode 100644 index f4f6534c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17936 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17937 b/persistentStorage/data-keycloak-db/base/16384/17937 deleted file mode 100644 index 790101ed..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17937 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17938 b/persistentStorage/data-keycloak-db/base/16384/17938 deleted file mode 100644 index bac2aa85..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17938 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17947 b/persistentStorage/data-keycloak-db/base/16384/17947 deleted file mode 100644 index 73b76fd6..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17947 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17950 b/persistentStorage/data-keycloak-db/base/16384/17950 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/17951 b/persistentStorage/data-keycloak-db/base/16384/17951 deleted file mode 100644 index 19de69d3..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17951 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17952 b/persistentStorage/data-keycloak-db/base/16384/17952 deleted file mode 100644 index 34851046..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17952 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17953 b/persistentStorage/data-keycloak-db/base/16384/17953 deleted file mode 100644 index 3ff76db4..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17953 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17954 b/persistentStorage/data-keycloak-db/base/16384/17954 deleted file mode 100644 index 55236732..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17954 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17955 b/persistentStorage/data-keycloak-db/base/16384/17955 deleted file mode 100644 index 168e1d23..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17955 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/17958 b/persistentStorage/data-keycloak-db/base/16384/17958 deleted file mode 100644 index 7210f553..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/17958 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2187 b/persistentStorage/data-keycloak-db/base/16384/2187 deleted file mode 100644 index 6ea4d227..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2187 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2224 b/persistentStorage/data-keycloak-db/base/16384/2224 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/2228 b/persistentStorage/data-keycloak-db/base/16384/2228 deleted file mode 100644 index da192ed0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2228 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2328 b/persistentStorage/data-keycloak-db/base/16384/2328 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/2336 b/persistentStorage/data-keycloak-db/base/16384/2336 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/2337 b/persistentStorage/data-keycloak-db/base/16384/2337 deleted file mode 100644 index d6111abe..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2337 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2579 b/persistentStorage/data-keycloak-db/base/16384/2579 deleted file mode 100644 index 1bac581d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2579 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2600 b/persistentStorage/data-keycloak-db/base/16384/2600 deleted file mode 100644 index 827b5c23..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2600 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2600_fsm b/persistentStorage/data-keycloak-db/base/16384/2600_fsm deleted file mode 100644 index 3f8f4089..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2600_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2600_vm b/persistentStorage/data-keycloak-db/base/16384/2600_vm deleted file mode 100644 index b01cf52e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2600_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2601 b/persistentStorage/data-keycloak-db/base/16384/2601 deleted file mode 100644 index d8001c8c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2601 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2601_fsm b/persistentStorage/data-keycloak-db/base/16384/2601_fsm deleted file mode 100644 index d388044f..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2601_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2601_vm b/persistentStorage/data-keycloak-db/base/16384/2601_vm deleted file mode 100644 index 0c4e3626..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2601_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2602 b/persistentStorage/data-keycloak-db/base/16384/2602 deleted file mode 100644 index 4a27b0a3..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2602 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2602_fsm b/persistentStorage/data-keycloak-db/base/16384/2602_fsm deleted file mode 100644 index 23170d85..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2602_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2602_vm b/persistentStorage/data-keycloak-db/base/16384/2602_vm deleted file mode 100644 index 3f263ec7..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2602_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2603 b/persistentStorage/data-keycloak-db/base/16384/2603 deleted file mode 100644 index d511af56..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2603 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2603_fsm b/persistentStorage/data-keycloak-db/base/16384/2603_fsm deleted file mode 100644 index 949bd18f..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2603_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2603_vm b/persistentStorage/data-keycloak-db/base/16384/2603_vm deleted file mode 100644 index 24766c7b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2603_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2604 b/persistentStorage/data-keycloak-db/base/16384/2604 deleted file mode 100644 index 3f9aeff7..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2604 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2604_fsm b/persistentStorage/data-keycloak-db/base/16384/2604_fsm deleted file mode 100644 index d6f1b24c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2604_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2605 b/persistentStorage/data-keycloak-db/base/16384/2605 deleted file mode 100644 index 287bf968..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2605 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2605_fsm b/persistentStorage/data-keycloak-db/base/16384/2605_fsm deleted file mode 100644 index c7723da0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2605_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2605_vm b/persistentStorage/data-keycloak-db/base/16384/2605_vm deleted file mode 100644 index 577f6fb5..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2605_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2606 b/persistentStorage/data-keycloak-db/base/16384/2606 deleted file mode 100644 index b0f69980..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2606 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2606_fsm b/persistentStorage/data-keycloak-db/base/16384/2606_fsm deleted file mode 100644 index 599fc1bf..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2606_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2606_vm b/persistentStorage/data-keycloak-db/base/16384/2606_vm deleted file mode 100644 index 4f92514d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2606_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2607 b/persistentStorage/data-keycloak-db/base/16384/2607 deleted file mode 100644 index bfad49ae..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2607 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2607_fsm b/persistentStorage/data-keycloak-db/base/16384/2607_fsm deleted file mode 100644 index 80ac8b14..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2607_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2607_vm b/persistentStorage/data-keycloak-db/base/16384/2607_vm deleted file mode 100644 index 4af50662..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2607_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2608 b/persistentStorage/data-keycloak-db/base/16384/2608 deleted file mode 100644 index f391f8c2..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2608 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2608_fsm b/persistentStorage/data-keycloak-db/base/16384/2608_fsm deleted file mode 100644 index e1e4491d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2608_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2608_vm b/persistentStorage/data-keycloak-db/base/16384/2608_vm deleted file mode 100644 index 910b3207..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2608_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2609 b/persistentStorage/data-keycloak-db/base/16384/2609 deleted file mode 100644 index 8bddfc4c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2609 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2609_fsm b/persistentStorage/data-keycloak-db/base/16384/2609_fsm deleted file mode 100644 index adbf4b7d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2609_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2609_vm b/persistentStorage/data-keycloak-db/base/16384/2609_vm deleted file mode 100644 index 66957e84..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2609_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2610 b/persistentStorage/data-keycloak-db/base/16384/2610 deleted file mode 100644 index f42e8a13..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2610 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2610_fsm b/persistentStorage/data-keycloak-db/base/16384/2610_fsm deleted file mode 100644 index b3c56edd..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2610_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2610_vm b/persistentStorage/data-keycloak-db/base/16384/2610_vm deleted file mode 100644 index 0c72aa4f..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2610_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2611 b/persistentStorage/data-keycloak-db/base/16384/2611 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/2612 b/persistentStorage/data-keycloak-db/base/16384/2612 deleted file mode 100644 index 09d3db9a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2612 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2612_fsm b/persistentStorage/data-keycloak-db/base/16384/2612_fsm deleted file mode 100644 index 877976ac..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2612_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2612_vm b/persistentStorage/data-keycloak-db/base/16384/2612_vm deleted file mode 100644 index fb040308..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2612_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2613 b/persistentStorage/data-keycloak-db/base/16384/2613 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/2615 b/persistentStorage/data-keycloak-db/base/16384/2615 deleted file mode 100644 index 8db70da0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2615 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2615_fsm b/persistentStorage/data-keycloak-db/base/16384/2615_fsm deleted file mode 100644 index d041693e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2615_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2615_vm b/persistentStorage/data-keycloak-db/base/16384/2615_vm deleted file mode 100644 index 2be5d8fe..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2615_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2616 b/persistentStorage/data-keycloak-db/base/16384/2616 deleted file mode 100644 index 0d60d797..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2616 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2616_fsm b/persistentStorage/data-keycloak-db/base/16384/2616_fsm deleted file mode 100644 index cb924c95..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2616_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2616_vm b/persistentStorage/data-keycloak-db/base/16384/2616_vm deleted file mode 100644 index 32b43b65..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2616_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2617 b/persistentStorage/data-keycloak-db/base/16384/2617 deleted file mode 100644 index 86965511..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2617 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2617_fsm b/persistentStorage/data-keycloak-db/base/16384/2617_fsm deleted file mode 100644 index 84060f4b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2617_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2617_vm b/persistentStorage/data-keycloak-db/base/16384/2617_vm deleted file mode 100644 index a6a45cc3..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2617_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2618 b/persistentStorage/data-keycloak-db/base/16384/2618 deleted file mode 100644 index 2893aa34..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2618 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2618_fsm b/persistentStorage/data-keycloak-db/base/16384/2618_fsm deleted file mode 100644 index b92d2da4..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2618_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2618_vm b/persistentStorage/data-keycloak-db/base/16384/2618_vm deleted file mode 100644 index 0fd8ac1c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2618_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2619 b/persistentStorage/data-keycloak-db/base/16384/2619 deleted file mode 100644 index 333ccf8e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2619 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2619_fsm b/persistentStorage/data-keycloak-db/base/16384/2619_fsm deleted file mode 100644 index d46d2256..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2619_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2619_vm b/persistentStorage/data-keycloak-db/base/16384/2619_vm deleted file mode 100644 index dda4504c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2619_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2620 b/persistentStorage/data-keycloak-db/base/16384/2620 deleted file mode 100644 index 5e79c655..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2620 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2620_fsm b/persistentStorage/data-keycloak-db/base/16384/2620_fsm deleted file mode 100644 index 0bd424f5..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2620_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2620_vm b/persistentStorage/data-keycloak-db/base/16384/2620_vm deleted file mode 100644 index 8306fe37..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2620_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2650 b/persistentStorage/data-keycloak-db/base/16384/2650 deleted file mode 100644 index 7627c51a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2650 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2651 b/persistentStorage/data-keycloak-db/base/16384/2651 deleted file mode 100644 index f9c68ee5..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2651 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2652 b/persistentStorage/data-keycloak-db/base/16384/2652 deleted file mode 100644 index 7b6c2f24..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2652 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2653 b/persistentStorage/data-keycloak-db/base/16384/2653 deleted file mode 100644 index 541d5f4a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2653 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2654 b/persistentStorage/data-keycloak-db/base/16384/2654 deleted file mode 100644 index 29ad199a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2654 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2655 b/persistentStorage/data-keycloak-db/base/16384/2655 deleted file mode 100644 index b4acab68..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2655 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2656 b/persistentStorage/data-keycloak-db/base/16384/2656 deleted file mode 100644 index 6473a975..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2656 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2657 b/persistentStorage/data-keycloak-db/base/16384/2657 deleted file mode 100644 index dbc0d04a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2657 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2658 b/persistentStorage/data-keycloak-db/base/16384/2658 deleted file mode 100644 index 4287f782..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2658 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2659 b/persistentStorage/data-keycloak-db/base/16384/2659 deleted file mode 100644 index 0d5862b3..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2659 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2660 b/persistentStorage/data-keycloak-db/base/16384/2660 deleted file mode 100644 index 59c279a1..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2660 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2661 b/persistentStorage/data-keycloak-db/base/16384/2661 deleted file mode 100644 index 040e9976..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2661 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2662 b/persistentStorage/data-keycloak-db/base/16384/2662 deleted file mode 100644 index f0c15b06..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2662 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2663 b/persistentStorage/data-keycloak-db/base/16384/2663 deleted file mode 100644 index 4435ae97..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2663 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2664 b/persistentStorage/data-keycloak-db/base/16384/2664 deleted file mode 100644 index 6064b799..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2664 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2665 b/persistentStorage/data-keycloak-db/base/16384/2665 deleted file mode 100644 index 8aa41abf..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2665 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2666 b/persistentStorage/data-keycloak-db/base/16384/2666 deleted file mode 100644 index 32b75e72..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2666 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2667 b/persistentStorage/data-keycloak-db/base/16384/2667 deleted file mode 100644 index 9d30db73..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2667 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2668 b/persistentStorage/data-keycloak-db/base/16384/2668 deleted file mode 100644 index 1ceedaaf..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2668 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2669 b/persistentStorage/data-keycloak-db/base/16384/2669 deleted file mode 100644 index 865bb062..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2669 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2670 b/persistentStorage/data-keycloak-db/base/16384/2670 deleted file mode 100644 index 01be7b00..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2670 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2673 b/persistentStorage/data-keycloak-db/base/16384/2673 deleted file mode 100644 index 41c1eab3..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2673 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2673_fsm b/persistentStorage/data-keycloak-db/base/16384/2673_fsm deleted file mode 100644 index f737ef10..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2673_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2674 b/persistentStorage/data-keycloak-db/base/16384/2674 deleted file mode 100644 index 483ffd6f..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2674 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2674_fsm b/persistentStorage/data-keycloak-db/base/16384/2674_fsm deleted file mode 100644 index 8b83f3e4..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2674_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2675 b/persistentStorage/data-keycloak-db/base/16384/2675 deleted file mode 100644 index 4c2d5263..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2675 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2678 b/persistentStorage/data-keycloak-db/base/16384/2678 deleted file mode 100644 index 976b4be4..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2678 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2679 b/persistentStorage/data-keycloak-db/base/16384/2679 deleted file mode 100644 index 21b2e1f9..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2679 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2680 b/persistentStorage/data-keycloak-db/base/16384/2680 deleted file mode 100644 index abc5412a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2680 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2681 b/persistentStorage/data-keycloak-db/base/16384/2681 deleted file mode 100644 index 11f4836a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2681 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2682 b/persistentStorage/data-keycloak-db/base/16384/2682 deleted file mode 100644 index a17584c1..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2682 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2683 b/persistentStorage/data-keycloak-db/base/16384/2683 deleted file mode 100644 index ef3053d1..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2683 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2684 b/persistentStorage/data-keycloak-db/base/16384/2684 deleted file mode 100644 index 0e7d9c11..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2684 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2685 b/persistentStorage/data-keycloak-db/base/16384/2685 deleted file mode 100644 index e131ea4c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2685 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2686 b/persistentStorage/data-keycloak-db/base/16384/2686 deleted file mode 100644 index 832bcb9a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2686 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2687 b/persistentStorage/data-keycloak-db/base/16384/2687 deleted file mode 100644 index 189fd41e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2687 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2688 b/persistentStorage/data-keycloak-db/base/16384/2688 deleted file mode 100644 index 6ebe3e7e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2688 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2689 b/persistentStorage/data-keycloak-db/base/16384/2689 deleted file mode 100644 index daa83a39..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2689 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2690 b/persistentStorage/data-keycloak-db/base/16384/2690 deleted file mode 100644 index 0806b469..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2690 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2691 b/persistentStorage/data-keycloak-db/base/16384/2691 deleted file mode 100644 index 9cd87042..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2691 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2692 b/persistentStorage/data-keycloak-db/base/16384/2692 deleted file mode 100644 index 7296dcf7..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2692 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2693 b/persistentStorage/data-keycloak-db/base/16384/2693 deleted file mode 100644 index 8084e6e0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2693 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2696 b/persistentStorage/data-keycloak-db/base/16384/2696 deleted file mode 100644 index f60ebe6b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2696 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2699 b/persistentStorage/data-keycloak-db/base/16384/2699 deleted file mode 100644 index c30f48b5..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2699 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2701 b/persistentStorage/data-keycloak-db/base/16384/2701 deleted file mode 100644 index 783bf0df..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2701 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2702 b/persistentStorage/data-keycloak-db/base/16384/2702 deleted file mode 100644 index 3a3773ed..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2702 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2703 b/persistentStorage/data-keycloak-db/base/16384/2703 deleted file mode 100644 index d312dbc1..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2703 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2704 b/persistentStorage/data-keycloak-db/base/16384/2704 deleted file mode 100644 index 8bd245dc..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2704 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2753 b/persistentStorage/data-keycloak-db/base/16384/2753 deleted file mode 100644 index 3c16dff6..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2753 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2753_fsm b/persistentStorage/data-keycloak-db/base/16384/2753_fsm deleted file mode 100644 index 642bce3b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2753_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2753_vm b/persistentStorage/data-keycloak-db/base/16384/2753_vm deleted file mode 100644 index 928f7e31..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2753_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2754 b/persistentStorage/data-keycloak-db/base/16384/2754 deleted file mode 100644 index 1cbd156e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2754 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2755 b/persistentStorage/data-keycloak-db/base/16384/2755 deleted file mode 100644 index 0fc8e919..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2755 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2756 b/persistentStorage/data-keycloak-db/base/16384/2756 deleted file mode 100644 index 5d355e2a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2756 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2757 b/persistentStorage/data-keycloak-db/base/16384/2757 deleted file mode 100644 index 6f40a7fb..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2757 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2830 b/persistentStorage/data-keycloak-db/base/16384/2830 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/2831 b/persistentStorage/data-keycloak-db/base/16384/2831 deleted file mode 100644 index e4ad5c17..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2831 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2832 b/persistentStorage/data-keycloak-db/base/16384/2832 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/2833 b/persistentStorage/data-keycloak-db/base/16384/2833 deleted file mode 100644 index b97afa32..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2833 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2834 b/persistentStorage/data-keycloak-db/base/16384/2834 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/2835 b/persistentStorage/data-keycloak-db/base/16384/2835 deleted file mode 100644 index 6aa119f3..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2835 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2836 b/persistentStorage/data-keycloak-db/base/16384/2836 deleted file mode 100644 index c688f81c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2836 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2836_fsm b/persistentStorage/data-keycloak-db/base/16384/2836_fsm deleted file mode 100644 index 4066e1ec..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2836_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2836_vm b/persistentStorage/data-keycloak-db/base/16384/2836_vm deleted file mode 100644 index d2ba922d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2836_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2837 b/persistentStorage/data-keycloak-db/base/16384/2837 deleted file mode 100644 index ed7a191d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2837 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2838 b/persistentStorage/data-keycloak-db/base/16384/2838 deleted file mode 100644 index 4cb35492..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2838 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2838_fsm b/persistentStorage/data-keycloak-db/base/16384/2838_fsm deleted file mode 100644 index 4cc16309..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2838_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2838_vm b/persistentStorage/data-keycloak-db/base/16384/2838_vm deleted file mode 100644 index c02f1ce0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2838_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2839 b/persistentStorage/data-keycloak-db/base/16384/2839 deleted file mode 100644 index 518516dd..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2839 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2840 b/persistentStorage/data-keycloak-db/base/16384/2840 deleted file mode 100644 index 67e3cc2d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2840 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2840_fsm b/persistentStorage/data-keycloak-db/base/16384/2840_fsm deleted file mode 100644 index b3171577..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2840_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2840_vm b/persistentStorage/data-keycloak-db/base/16384/2840_vm deleted file mode 100644 index 2f2978e5..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2840_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2841 b/persistentStorage/data-keycloak-db/base/16384/2841 deleted file mode 100644 index 2579264d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2841 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/2995 b/persistentStorage/data-keycloak-db/base/16384/2995 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/2996 b/persistentStorage/data-keycloak-db/base/16384/2996 deleted file mode 100644 index 35f2758f..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/2996 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3079 b/persistentStorage/data-keycloak-db/base/16384/3079 deleted file mode 100644 index 08f2b014..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3079 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3079_fsm b/persistentStorage/data-keycloak-db/base/16384/3079_fsm deleted file mode 100644 index 7732d22b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3079_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3079_vm b/persistentStorage/data-keycloak-db/base/16384/3079_vm deleted file mode 100644 index e2bfe1e5..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3079_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3080 b/persistentStorage/data-keycloak-db/base/16384/3080 deleted file mode 100644 index 77890e90..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3080 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3081 b/persistentStorage/data-keycloak-db/base/16384/3081 deleted file mode 100644 index c9e8c6e7..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3081 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3085 b/persistentStorage/data-keycloak-db/base/16384/3085 deleted file mode 100644 index d83ce3e2..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3085 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3118 b/persistentStorage/data-keycloak-db/base/16384/3118 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/3119 b/persistentStorage/data-keycloak-db/base/16384/3119 deleted file mode 100644 index c0d08b7e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3119 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3164 b/persistentStorage/data-keycloak-db/base/16384/3164 deleted file mode 100644 index b8d5a33f..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3164 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3256 b/persistentStorage/data-keycloak-db/base/16384/3256 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/3257 b/persistentStorage/data-keycloak-db/base/16384/3257 deleted file mode 100644 index 85937d28..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3257 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3258 b/persistentStorage/data-keycloak-db/base/16384/3258 deleted file mode 100644 index 5f252a3c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3258 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3350 b/persistentStorage/data-keycloak-db/base/16384/3350 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/3351 b/persistentStorage/data-keycloak-db/base/16384/3351 deleted file mode 100644 index 0aecbb30..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3351 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3379 b/persistentStorage/data-keycloak-db/base/16384/3379 deleted file mode 100644 index 3992c116..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3379 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3380 b/persistentStorage/data-keycloak-db/base/16384/3380 deleted file mode 100644 index 8f72126d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3380 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3381 b/persistentStorage/data-keycloak-db/base/16384/3381 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/3394 b/persistentStorage/data-keycloak-db/base/16384/3394 deleted file mode 100644 index 7fa1e11b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3394 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3394_fsm b/persistentStorage/data-keycloak-db/base/16384/3394_fsm deleted file mode 100644 index f8d6070c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3394_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3394_vm b/persistentStorage/data-keycloak-db/base/16384/3394_vm deleted file mode 100644 index 5db2a120..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3394_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3395 b/persistentStorage/data-keycloak-db/base/16384/3395 deleted file mode 100644 index fa7b9d72..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3395 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3429 b/persistentStorage/data-keycloak-db/base/16384/3429 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/3430 b/persistentStorage/data-keycloak-db/base/16384/3430 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/3431 b/persistentStorage/data-keycloak-db/base/16384/3431 deleted file mode 100644 index 553b503b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3431 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3433 b/persistentStorage/data-keycloak-db/base/16384/3433 deleted file mode 100644 index 9b9eb9ce..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3433 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3439 b/persistentStorage/data-keycloak-db/base/16384/3439 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/3440 b/persistentStorage/data-keycloak-db/base/16384/3440 deleted file mode 100644 index 47135494..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3440 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3455 b/persistentStorage/data-keycloak-db/base/16384/3455 deleted file mode 100644 index f96662ce..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3455 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3456 b/persistentStorage/data-keycloak-db/base/16384/3456 deleted file mode 100644 index e3460d9d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3456 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3456_fsm b/persistentStorage/data-keycloak-db/base/16384/3456_fsm deleted file mode 100644 index fc8f8b80..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3456_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3456_vm b/persistentStorage/data-keycloak-db/base/16384/3456_vm deleted file mode 100644 index 89d107bd..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3456_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3466 b/persistentStorage/data-keycloak-db/base/16384/3466 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/3467 b/persistentStorage/data-keycloak-db/base/16384/3467 deleted file mode 100644 index 68eab7b6..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3467 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3468 b/persistentStorage/data-keycloak-db/base/16384/3468 deleted file mode 100644 index 63a8f7cd..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3468 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3501 b/persistentStorage/data-keycloak-db/base/16384/3501 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/3502 b/persistentStorage/data-keycloak-db/base/16384/3502 deleted file mode 100644 index 7676fd82..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3502 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3503 b/persistentStorage/data-keycloak-db/base/16384/3503 deleted file mode 100644 index 22146019..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3503 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3534 b/persistentStorage/data-keycloak-db/base/16384/3534 deleted file mode 100644 index 9a307a42..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3534 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3541 b/persistentStorage/data-keycloak-db/base/16384/3541 deleted file mode 100644 index 40869ad3..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3541 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3541_fsm b/persistentStorage/data-keycloak-db/base/16384/3541_fsm deleted file mode 100644 index a3a2de4d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3541_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3541_vm b/persistentStorage/data-keycloak-db/base/16384/3541_vm deleted file mode 100644 index bd8c84af..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3541_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3542 b/persistentStorage/data-keycloak-db/base/16384/3542 deleted file mode 100644 index ee21b6ae..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3542 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3574 b/persistentStorage/data-keycloak-db/base/16384/3574 deleted file mode 100644 index 418bbca1..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3574 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3575 b/persistentStorage/data-keycloak-db/base/16384/3575 deleted file mode 100644 index 6addf868..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3575 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3576 b/persistentStorage/data-keycloak-db/base/16384/3576 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/3596 b/persistentStorage/data-keycloak-db/base/16384/3596 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/3597 b/persistentStorage/data-keycloak-db/base/16384/3597 deleted file mode 100644 index 71d2820e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3597 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3598 b/persistentStorage/data-keycloak-db/base/16384/3598 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/3599 b/persistentStorage/data-keycloak-db/base/16384/3599 deleted file mode 100644 index 507ca587..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3599 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3600 b/persistentStorage/data-keycloak-db/base/16384/3600 deleted file mode 100644 index 41c62c58..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3600 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3600_fsm b/persistentStorage/data-keycloak-db/base/16384/3600_fsm deleted file mode 100644 index cebec199..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3600_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3600_vm b/persistentStorage/data-keycloak-db/base/16384/3600_vm deleted file mode 100644 index e611f185..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3600_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3601 b/persistentStorage/data-keycloak-db/base/16384/3601 deleted file mode 100644 index 04c846ec..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3601 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3601_fsm b/persistentStorage/data-keycloak-db/base/16384/3601_fsm deleted file mode 100644 index 7732d22b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3601_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3601_vm b/persistentStorage/data-keycloak-db/base/16384/3601_vm deleted file mode 100644 index e63f9b2d..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3601_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3602 b/persistentStorage/data-keycloak-db/base/16384/3602 deleted file mode 100644 index e77e1ad5..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3602 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3602_fsm b/persistentStorage/data-keycloak-db/base/16384/3602_fsm deleted file mode 100644 index d7897de2..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3602_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3602_vm b/persistentStorage/data-keycloak-db/base/16384/3602_vm deleted file mode 100644 index 23986f7e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3602_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3603 b/persistentStorage/data-keycloak-db/base/16384/3603 deleted file mode 100644 index 57062b10..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3603 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3603_fsm b/persistentStorage/data-keycloak-db/base/16384/3603_fsm deleted file mode 100644 index c28dd4fa..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3603_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3603_vm b/persistentStorage/data-keycloak-db/base/16384/3603_vm deleted file mode 100644 index b5dac618..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3603_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3604 b/persistentStorage/data-keycloak-db/base/16384/3604 deleted file mode 100644 index 4a979b17..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3604 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3605 b/persistentStorage/data-keycloak-db/base/16384/3605 deleted file mode 100644 index 7e7c31ca..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3605 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3606 b/persistentStorage/data-keycloak-db/base/16384/3606 deleted file mode 100644 index de60e2ff..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3606 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3607 b/persistentStorage/data-keycloak-db/base/16384/3607 deleted file mode 100644 index ff537351..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3607 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3608 b/persistentStorage/data-keycloak-db/base/16384/3608 deleted file mode 100644 index bf99099a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3608 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3609 b/persistentStorage/data-keycloak-db/base/16384/3609 deleted file mode 100644 index aca244c6..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3609 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3712 b/persistentStorage/data-keycloak-db/base/16384/3712 deleted file mode 100644 index e4e2c033..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3712 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3764 b/persistentStorage/data-keycloak-db/base/16384/3764 deleted file mode 100644 index da4bd39c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3764 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3764_fsm b/persistentStorage/data-keycloak-db/base/16384/3764_fsm deleted file mode 100644 index f64db4df..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3764_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3764_vm b/persistentStorage/data-keycloak-db/base/16384/3764_vm deleted file mode 100644 index 3930bc12..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3764_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3766 b/persistentStorage/data-keycloak-db/base/16384/3766 deleted file mode 100644 index 44d0b7de..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3766 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3767 b/persistentStorage/data-keycloak-db/base/16384/3767 deleted file mode 100644 index b8e981f8..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3767 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/3997 b/persistentStorage/data-keycloak-db/base/16384/3997 deleted file mode 100644 index fd6175ff..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/3997 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/4143 b/persistentStorage/data-keycloak-db/base/16384/4143 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/4144 b/persistentStorage/data-keycloak-db/base/16384/4144 deleted file mode 100644 index a3569d11..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/4144 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/4145 b/persistentStorage/data-keycloak-db/base/16384/4145 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/4146 b/persistentStorage/data-keycloak-db/base/16384/4146 deleted file mode 100644 index 3397d87e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/4146 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/4147 b/persistentStorage/data-keycloak-db/base/16384/4147 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/4148 b/persistentStorage/data-keycloak-db/base/16384/4148 deleted file mode 100644 index 6e10fc5e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/4148 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/4149 b/persistentStorage/data-keycloak-db/base/16384/4149 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/4150 b/persistentStorage/data-keycloak-db/base/16384/4150 deleted file mode 100644 index a0ea1cc0..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/4150 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/4151 b/persistentStorage/data-keycloak-db/base/16384/4151 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/4152 b/persistentStorage/data-keycloak-db/base/16384/4152 deleted file mode 100644 index 4179f382..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/4152 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/4153 b/persistentStorage/data-keycloak-db/base/16384/4153 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/4154 b/persistentStorage/data-keycloak-db/base/16384/4154 deleted file mode 100644 index a5e44b4f..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/4154 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/4155 b/persistentStorage/data-keycloak-db/base/16384/4155 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/4156 b/persistentStorage/data-keycloak-db/base/16384/4156 deleted file mode 100644 index e3a35c68..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/4156 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/4157 b/persistentStorage/data-keycloak-db/base/16384/4157 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/4158 b/persistentStorage/data-keycloak-db/base/16384/4158 deleted file mode 100644 index 3de62cdf..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/4158 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/4159 b/persistentStorage/data-keycloak-db/base/16384/4159 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/4160 b/persistentStorage/data-keycloak-db/base/16384/4160 deleted file mode 100644 index b17f909c..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/4160 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/4163 b/persistentStorage/data-keycloak-db/base/16384/4163 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/4164 b/persistentStorage/data-keycloak-db/base/16384/4164 deleted file mode 100644 index 2e798538..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/4164 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/4165 b/persistentStorage/data-keycloak-db/base/16384/4165 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/4166 b/persistentStorage/data-keycloak-db/base/16384/4166 deleted file mode 100644 index 9e74293a..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/4166 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/4167 b/persistentStorage/data-keycloak-db/base/16384/4167 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/4168 b/persistentStorage/data-keycloak-db/base/16384/4168 deleted file mode 100644 index a032ccae..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/4168 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/4169 b/persistentStorage/data-keycloak-db/base/16384/4169 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/4170 b/persistentStorage/data-keycloak-db/base/16384/4170 deleted file mode 100644 index c75cf673..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/4170 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/4171 b/persistentStorage/data-keycloak-db/base/16384/4171 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/4172 b/persistentStorage/data-keycloak-db/base/16384/4172 deleted file mode 100644 index f9cb0379..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/4172 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/4173 b/persistentStorage/data-keycloak-db/base/16384/4173 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/4174 b/persistentStorage/data-keycloak-db/base/16384/4174 deleted file mode 100644 index deb4a11b..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/4174 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/5002 b/persistentStorage/data-keycloak-db/base/16384/5002 deleted file mode 100644 index 32af7a1e..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/5002 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/548 b/persistentStorage/data-keycloak-db/base/16384/548 deleted file mode 100644 index 9f219478..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/548 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/549 b/persistentStorage/data-keycloak-db/base/16384/549 deleted file mode 100644 index 68efb3f3..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/549 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/6102 b/persistentStorage/data-keycloak-db/base/16384/6102 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/6104 b/persistentStorage/data-keycloak-db/base/16384/6104 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/6106 b/persistentStorage/data-keycloak-db/base/16384/6106 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/6110 b/persistentStorage/data-keycloak-db/base/16384/6110 deleted file mode 100644 index 536b80d3..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/6110 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/6111 b/persistentStorage/data-keycloak-db/base/16384/6111 deleted file mode 100644 index 3d22c94f..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/6111 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/6112 b/persistentStorage/data-keycloak-db/base/16384/6112 deleted file mode 100644 index 9e47d5c5..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/6112 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/6113 b/persistentStorage/data-keycloak-db/base/16384/6113 deleted file mode 100644 index 4e57f5be..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/6113 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/6117 b/persistentStorage/data-keycloak-db/base/16384/6117 deleted file mode 100644 index 296b14e8..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/6117 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/6175 b/persistentStorage/data-keycloak-db/base/16384/6175 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/6176 b/persistentStorage/data-keycloak-db/base/16384/6176 deleted file mode 100644 index 45c76f44..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/6176 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/826 b/persistentStorage/data-keycloak-db/base/16384/826 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/base/16384/827 b/persistentStorage/data-keycloak-db/base/16384/827 deleted file mode 100644 index 86db9fe6..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/827 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/828 b/persistentStorage/data-keycloak-db/base/16384/828 deleted file mode 100644 index 4a522991..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/828 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/PG_VERSION b/persistentStorage/data-keycloak-db/base/16384/PG_VERSION deleted file mode 100644 index 8351c193..00000000 --- a/persistentStorage/data-keycloak-db/base/16384/PG_VERSION +++ /dev/null @@ -1 +0,0 @@ -14 diff --git a/persistentStorage/data-keycloak-db/base/16384/pg_filenode.map b/persistentStorage/data-keycloak-db/base/16384/pg_filenode.map deleted file mode 100644 index 193d78f3..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/pg_filenode.map and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/base/16384/pg_internal.init b/persistentStorage/data-keycloak-db/base/16384/pg_internal.init deleted file mode 100644 index 4ae7dd53..00000000 Binary files a/persistentStorage/data-keycloak-db/base/16384/pg_internal.init and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/1213 b/persistentStorage/data-keycloak-db/global/1213 deleted file mode 100644 index eec8dc3a..00000000 Binary files a/persistentStorage/data-keycloak-db/global/1213 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/1213_fsm b/persistentStorage/data-keycloak-db/global/1213_fsm deleted file mode 100644 index 86074bee..00000000 Binary files a/persistentStorage/data-keycloak-db/global/1213_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/1213_vm b/persistentStorage/data-keycloak-db/global/1213_vm deleted file mode 100644 index 0332e6d6..00000000 Binary files a/persistentStorage/data-keycloak-db/global/1213_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/1214 b/persistentStorage/data-keycloak-db/global/1214 deleted file mode 100644 index 51139725..00000000 Binary files a/persistentStorage/data-keycloak-db/global/1214 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/1214_fsm b/persistentStorage/data-keycloak-db/global/1214_fsm deleted file mode 100644 index 81fa96e3..00000000 Binary files a/persistentStorage/data-keycloak-db/global/1214_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/1214_vm b/persistentStorage/data-keycloak-db/global/1214_vm deleted file mode 100644 index 5be996b9..00000000 Binary files a/persistentStorage/data-keycloak-db/global/1214_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/1232 b/persistentStorage/data-keycloak-db/global/1232 deleted file mode 100644 index 1ac7af68..00000000 Binary files a/persistentStorage/data-keycloak-db/global/1232 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/1233 b/persistentStorage/data-keycloak-db/global/1233 deleted file mode 100644 index d0258dd7..00000000 Binary files a/persistentStorage/data-keycloak-db/global/1233 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/1260 b/persistentStorage/data-keycloak-db/global/1260 deleted file mode 100644 index a6cf3e9c..00000000 Binary files a/persistentStorage/data-keycloak-db/global/1260 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/1260_fsm b/persistentStorage/data-keycloak-db/global/1260_fsm deleted file mode 100644 index 016717f7..00000000 Binary files a/persistentStorage/data-keycloak-db/global/1260_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/1260_vm b/persistentStorage/data-keycloak-db/global/1260_vm deleted file mode 100644 index 2ad4eba5..00000000 Binary files a/persistentStorage/data-keycloak-db/global/1260_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/1261 b/persistentStorage/data-keycloak-db/global/1261 deleted file mode 100644 index d94e34ac..00000000 Binary files a/persistentStorage/data-keycloak-db/global/1261 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/1261_fsm b/persistentStorage/data-keycloak-db/global/1261_fsm deleted file mode 100644 index 7732d22b..00000000 Binary files a/persistentStorage/data-keycloak-db/global/1261_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/1261_vm b/persistentStorage/data-keycloak-db/global/1261_vm deleted file mode 100644 index 70e2320e..00000000 Binary files a/persistentStorage/data-keycloak-db/global/1261_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/1262 b/persistentStorage/data-keycloak-db/global/1262 deleted file mode 100644 index 5e5ee54e..00000000 Binary files a/persistentStorage/data-keycloak-db/global/1262 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/1262_fsm b/persistentStorage/data-keycloak-db/global/1262_fsm deleted file mode 100644 index b49966ff..00000000 Binary files a/persistentStorage/data-keycloak-db/global/1262_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/1262_vm b/persistentStorage/data-keycloak-db/global/1262_vm deleted file mode 100644 index fa71c5b4..00000000 Binary files a/persistentStorage/data-keycloak-db/global/1262_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/2396 b/persistentStorage/data-keycloak-db/global/2396 deleted file mode 100644 index 53fe1e56..00000000 Binary files a/persistentStorage/data-keycloak-db/global/2396 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/2396_fsm b/persistentStorage/data-keycloak-db/global/2396_fsm deleted file mode 100644 index 7a4f24f3..00000000 Binary files a/persistentStorage/data-keycloak-db/global/2396_fsm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/2396_vm b/persistentStorage/data-keycloak-db/global/2396_vm deleted file mode 100644 index e0065229..00000000 Binary files a/persistentStorage/data-keycloak-db/global/2396_vm and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/2397 b/persistentStorage/data-keycloak-db/global/2397 deleted file mode 100644 index c4cf8a85..00000000 Binary files a/persistentStorage/data-keycloak-db/global/2397 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/2671 b/persistentStorage/data-keycloak-db/global/2671 deleted file mode 100644 index a3991db4..00000000 Binary files a/persistentStorage/data-keycloak-db/global/2671 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/2672 b/persistentStorage/data-keycloak-db/global/2672 deleted file mode 100644 index 9987ee27..00000000 Binary files a/persistentStorage/data-keycloak-db/global/2672 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/2676 b/persistentStorage/data-keycloak-db/global/2676 deleted file mode 100644 index 4507f6bd..00000000 Binary files a/persistentStorage/data-keycloak-db/global/2676 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/2677 b/persistentStorage/data-keycloak-db/global/2677 deleted file mode 100644 index d4449ca1..00000000 Binary files a/persistentStorage/data-keycloak-db/global/2677 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/2694 b/persistentStorage/data-keycloak-db/global/2694 deleted file mode 100644 index db2a5696..00000000 Binary files a/persistentStorage/data-keycloak-db/global/2694 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/2695 b/persistentStorage/data-keycloak-db/global/2695 deleted file mode 100644 index 45540e8c..00000000 Binary files a/persistentStorage/data-keycloak-db/global/2695 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/2697 b/persistentStorage/data-keycloak-db/global/2697 deleted file mode 100644 index cfd237d2..00000000 Binary files a/persistentStorage/data-keycloak-db/global/2697 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/2698 b/persistentStorage/data-keycloak-db/global/2698 deleted file mode 100644 index 29bbcb2e..00000000 Binary files a/persistentStorage/data-keycloak-db/global/2698 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/2846 b/persistentStorage/data-keycloak-db/global/2846 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/global/2847 b/persistentStorage/data-keycloak-db/global/2847 deleted file mode 100644 index d90f5314..00000000 Binary files a/persistentStorage/data-keycloak-db/global/2847 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/2964 b/persistentStorage/data-keycloak-db/global/2964 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/global/2965 b/persistentStorage/data-keycloak-db/global/2965 deleted file mode 100644 index cfdcc087..00000000 Binary files a/persistentStorage/data-keycloak-db/global/2965 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/2966 b/persistentStorage/data-keycloak-db/global/2966 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/global/2967 b/persistentStorage/data-keycloak-db/global/2967 deleted file mode 100644 index 2499aa6f..00000000 Binary files a/persistentStorage/data-keycloak-db/global/2967 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/3592 b/persistentStorage/data-keycloak-db/global/3592 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/global/3593 b/persistentStorage/data-keycloak-db/global/3593 deleted file mode 100644 index 29c042c8..00000000 Binary files a/persistentStorage/data-keycloak-db/global/3593 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/4060 b/persistentStorage/data-keycloak-db/global/4060 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/global/4061 b/persistentStorage/data-keycloak-db/global/4061 deleted file mode 100644 index 05b33b3e..00000000 Binary files a/persistentStorage/data-keycloak-db/global/4061 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/4175 b/persistentStorage/data-keycloak-db/global/4175 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/global/4176 b/persistentStorage/data-keycloak-db/global/4176 deleted file mode 100644 index 523d8c4e..00000000 Binary files a/persistentStorage/data-keycloak-db/global/4176 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/4177 b/persistentStorage/data-keycloak-db/global/4177 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/global/4178 b/persistentStorage/data-keycloak-db/global/4178 deleted file mode 100644 index 3eff18f4..00000000 Binary files a/persistentStorage/data-keycloak-db/global/4178 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/4181 b/persistentStorage/data-keycloak-db/global/4181 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/global/4182 b/persistentStorage/data-keycloak-db/global/4182 deleted file mode 100644 index 5c00ab99..00000000 Binary files a/persistentStorage/data-keycloak-db/global/4182 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/4183 b/persistentStorage/data-keycloak-db/global/4183 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/global/4184 b/persistentStorage/data-keycloak-db/global/4184 deleted file mode 100644 index 31fdf0a6..00000000 Binary files a/persistentStorage/data-keycloak-db/global/4184 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/4185 b/persistentStorage/data-keycloak-db/global/4185 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/global/4186 b/persistentStorage/data-keycloak-db/global/4186 deleted file mode 100644 index 8b24f6ea..00000000 Binary files a/persistentStorage/data-keycloak-db/global/4186 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/6000 b/persistentStorage/data-keycloak-db/global/6000 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/global/6001 b/persistentStorage/data-keycloak-db/global/6001 deleted file mode 100644 index ed048fa9..00000000 Binary files a/persistentStorage/data-keycloak-db/global/6001 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/6002 b/persistentStorage/data-keycloak-db/global/6002 deleted file mode 100644 index 8f0fa32b..00000000 Binary files a/persistentStorage/data-keycloak-db/global/6002 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/6100 b/persistentStorage/data-keycloak-db/global/6100 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-keycloak-db/global/6114 b/persistentStorage/data-keycloak-db/global/6114 deleted file mode 100644 index 8fb4dcd4..00000000 Binary files a/persistentStorage/data-keycloak-db/global/6114 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/6115 b/persistentStorage/data-keycloak-db/global/6115 deleted file mode 100644 index 8bc0135f..00000000 Binary files a/persistentStorage/data-keycloak-db/global/6115 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/pg_control b/persistentStorage/data-keycloak-db/global/pg_control deleted file mode 100644 index cd6132b4..00000000 Binary files a/persistentStorage/data-keycloak-db/global/pg_control and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/pg_filenode.map b/persistentStorage/data-keycloak-db/global/pg_filenode.map deleted file mode 100644 index ec4cdeda..00000000 Binary files a/persistentStorage/data-keycloak-db/global/pg_filenode.map and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/global/pg_internal.init b/persistentStorage/data-keycloak-db/global/pg_internal.init deleted file mode 100644 index 61b1ca08..00000000 Binary files a/persistentStorage/data-keycloak-db/global/pg_internal.init and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/pg_hba.conf b/persistentStorage/data-keycloak-db/pg_hba.conf deleted file mode 100644 index 4e202d3c..00000000 --- a/persistentStorage/data-keycloak-db/pg_hba.conf +++ /dev/null @@ -1,100 +0,0 @@ -# PostgreSQL Client Authentication Configuration File -# =================================================== -# -# Refer to the "Client Authentication" section in the PostgreSQL -# documentation for a complete description of this file. A short -# synopsis follows. -# -# This file controls: which hosts are allowed to connect, how clients -# are authenticated, which PostgreSQL user names they can use, which -# databases they can access. Records take one of these forms: -# -# local DATABASE USER METHOD [OPTIONS] -# host DATABASE USER ADDRESS METHOD [OPTIONS] -# hostssl DATABASE USER ADDRESS METHOD [OPTIONS] -# hostnossl DATABASE USER ADDRESS METHOD [OPTIONS] -# hostgssenc DATABASE USER ADDRESS METHOD [OPTIONS] -# hostnogssenc DATABASE USER ADDRESS METHOD [OPTIONS] -# -# (The uppercase items must be replaced by actual values.) -# -# The first field is the connection type: -# - "local" is a Unix-domain socket -# - "host" is a TCP/IP socket (encrypted or not) -# - "hostssl" is a TCP/IP socket that is SSL-encrypted -# - "hostnossl" is a TCP/IP socket that is not SSL-encrypted -# - "hostgssenc" is a TCP/IP socket that is GSSAPI-encrypted -# - "hostnogssenc" is a TCP/IP socket that is not GSSAPI-encrypted -# -# DATABASE can be "all", "sameuser", "samerole", "replication", a -# database name, or a comma-separated list thereof. The "all" -# keyword does not match "replication". Access to replication -# must be enabled in a separate record (see example below). -# -# USER can be "all", a user name, a group name prefixed with "+", or a -# comma-separated list thereof. In both the DATABASE and USER fields -# you can also write a file name prefixed with "@" to include names -# from a separate file. -# -# ADDRESS specifies the set of hosts the record matches. It can be a -# host name, or it is made up of an IP address and a CIDR mask that is -# an integer (between 0 and 32 (IPv4) or 128 (IPv6) inclusive) that -# specifies the number of significant bits in the mask. A host name -# that starts with a dot (.) matches a suffix of the actual host name. -# Alternatively, you can write an IP address and netmask in separate -# columns to specify the set of hosts. Instead of a CIDR-address, you -# can write "samehost" to match any of the server's own IP addresses, -# or "samenet" to match any address in any subnet that the server is -# directly connected to. -# -# METHOD can be "trust", "reject", "md5", "password", "scram-sha-256", -# "gss", "sspi", "ident", "peer", "pam", "ldap", "radius" or "cert". -# Note that "password" sends passwords in clear text; "md5" or -# "scram-sha-256" are preferred since they send encrypted passwords. -# -# OPTIONS are a set of options for the authentication in the format -# NAME=VALUE. The available options depend on the different -# authentication methods -- refer to the "Client Authentication" -# section in the documentation for a list of which options are -# available for which authentication methods. -# -# Database and user names containing spaces, commas, quotes and other -# special characters must be quoted. Quoting one of the keywords -# "all", "sameuser", "samerole" or "replication" makes the name lose -# its special character, and just match a database or username with -# that name. -# -# This file is read on server startup and when the server receives a -# SIGHUP signal. If you edit the file on a running system, you have to -# SIGHUP the server for the changes to take effect, run "pg_ctl reload", -# or execute "SELECT pg_reload_conf()". -# -# Put your actual configuration here -# ---------------------------------- -# -# If you want to allow non-local connections, you need to add more -# "host" records. In that case you will also need to make PostgreSQL -# listen on a non-local interface via the listen_addresses -# configuration parameter, or via the -i or -h command line switches. - -# CAUTION: Configuring the system for local "trust" authentication -# allows any local user to connect as any PostgreSQL user, including -# the database superuser. If you do not trust all your local users, -# use another authentication method. - - -# TYPE DATABASE USER ADDRESS METHOD - -# "local" is for Unix domain socket connections only -local all all trust -# IPv4 local connections: -host all all 127.0.0.1/32 trust -# IPv6 local connections: -host all all ::1/128 trust -# Allow replication connections from localhost, by a user with the -# replication privilege. -local replication all trust -host replication all 127.0.0.1/32 trust -host replication all ::1/128 trust - -host all all all scram-sha-256 diff --git a/persistentStorage/data-keycloak-db/pg_ident.conf b/persistentStorage/data-keycloak-db/pg_ident.conf deleted file mode 100644 index a5870e64..00000000 --- a/persistentStorage/data-keycloak-db/pg_ident.conf +++ /dev/null @@ -1,42 +0,0 @@ -# PostgreSQL User Name Maps -# ========================= -# -# Refer to the PostgreSQL documentation, chapter "Client -# Authentication" for a complete description. A short synopsis -# follows. -# -# This file controls PostgreSQL user name mapping. It maps external -# user names to their corresponding PostgreSQL user names. Records -# are of the form: -# -# MAPNAME SYSTEM-USERNAME PG-USERNAME -# -# (The uppercase quantities must be replaced by actual values.) -# -# MAPNAME is the (otherwise freely chosen) map name that was used in -# pg_hba.conf. SYSTEM-USERNAME is the detected user name of the -# client. PG-USERNAME is the requested PostgreSQL user name. The -# existence of a record specifies that SYSTEM-USERNAME may connect as -# PG-USERNAME. -# -# If SYSTEM-USERNAME starts with a slash (/), it will be treated as a -# regular expression. Optionally this can contain a capture (a -# parenthesized subexpression). The substring matching the capture -# will be substituted for \1 (backslash-one) if present in -# PG-USERNAME. -# -# Multiple maps may be specified in this file and used by pg_hba.conf. -# -# No map names are defined in the default configuration. If all -# system user names and PostgreSQL user names are the same, you don't -# need anything in this file. -# -# This file is read on server startup and when the postmaster receives -# a SIGHUP signal. If you edit the file on a running system, you have -# to SIGHUP the postmaster for the changes to take effect. You can -# use "pg_ctl reload" to do that. - -# Put your actual configuration here -# ---------------------------------- - -# MAPNAME SYSTEM-USERNAME PG-USERNAME diff --git a/persistentStorage/data-keycloak-db/pg_multixact/members/0000 b/persistentStorage/data-keycloak-db/pg_multixact/members/0000 deleted file mode 100644 index 6d17cf9d..00000000 Binary files a/persistentStorage/data-keycloak-db/pg_multixact/members/0000 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/pg_multixact/offsets/0000 b/persistentStorage/data-keycloak-db/pg_multixact/offsets/0000 deleted file mode 100644 index 6d17cf9d..00000000 Binary files a/persistentStorage/data-keycloak-db/pg_multixact/offsets/0000 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/pg_stat_tmp/db_0.stat b/persistentStorage/data-keycloak-db/pg_stat_tmp/db_0.stat deleted file mode 100644 index 4d88a26b..00000000 Binary files a/persistentStorage/data-keycloak-db/pg_stat_tmp/db_0.stat and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/pg_stat_tmp/db_13780.stat b/persistentStorage/data-keycloak-db/pg_stat_tmp/db_13780.stat deleted file mode 100644 index 38de468d..00000000 Binary files a/persistentStorage/data-keycloak-db/pg_stat_tmp/db_13780.stat and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/pg_stat_tmp/db_16384.stat b/persistentStorage/data-keycloak-db/pg_stat_tmp/db_16384.stat deleted file mode 100644 index c14b10ab..00000000 Binary files a/persistentStorage/data-keycloak-db/pg_stat_tmp/db_16384.stat and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/pg_stat_tmp/global.stat b/persistentStorage/data-keycloak-db/pg_stat_tmp/global.stat deleted file mode 100644 index 4657a3aa..00000000 Binary files a/persistentStorage/data-keycloak-db/pg_stat_tmp/global.stat and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/pg_subtrans/0000 b/persistentStorage/data-keycloak-db/pg_subtrans/0000 deleted file mode 100644 index 6d17cf9d..00000000 Binary files a/persistentStorage/data-keycloak-db/pg_subtrans/0000 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/pg_wal/000000010000000000000001 b/persistentStorage/data-keycloak-db/pg_wal/000000010000000000000001 deleted file mode 100644 index 760603e3..00000000 Binary files a/persistentStorage/data-keycloak-db/pg_wal/000000010000000000000001 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/pg_xact/0000 b/persistentStorage/data-keycloak-db/pg_xact/0000 deleted file mode 100644 index b3175747..00000000 Binary files a/persistentStorage/data-keycloak-db/pg_xact/0000 and /dev/null differ diff --git a/persistentStorage/data-keycloak-db/postgresql.auto.conf b/persistentStorage/data-keycloak-db/postgresql.auto.conf deleted file mode 100644 index af7125e1..00000000 --- a/persistentStorage/data-keycloak-db/postgresql.auto.conf +++ /dev/null @@ -1,2 +0,0 @@ -# Do not edit this file manually! -# It will be overwritten by the ALTER SYSTEM command. diff --git a/persistentStorage/data-keycloak-db/postgresql.conf b/persistentStorage/data-keycloak-db/postgresql.conf deleted file mode 100644 index 3713f7ce..00000000 --- a/persistentStorage/data-keycloak-db/postgresql.conf +++ /dev/null @@ -1,798 +0,0 @@ -# ----------------------------- -# PostgreSQL configuration file -# ----------------------------- -# -# This file consists of lines of the form: -# -# name = value -# -# (The "=" is optional.) Whitespace may be used. Comments are introduced with -# "#" anywhere on a line. The complete list of parameter names and allowed -# values can be found in the PostgreSQL documentation. -# -# The commented-out settings shown in this file represent the default values. -# Re-commenting a setting is NOT sufficient to revert it to the default value; -# you need to reload the server. -# -# This file is read on server startup and when the server receives a SIGHUP -# signal. If you edit the file on a running system, you have to SIGHUP the -# server for the changes to take effect, run "pg_ctl reload", or execute -# "SELECT pg_reload_conf()". Some parameters, which are marked below, -# require a server shutdown and restart to take effect. -# -# Any parameter can also be given as a command-line option to the server, e.g., -# "postgres -c log_connections=on". Some parameters can be changed at run time -# with the "SET" SQL command. -# -# Memory units: B = bytes Time units: us = microseconds -# kB = kilobytes ms = milliseconds -# MB = megabytes s = seconds -# GB = gigabytes min = minutes -# TB = terabytes h = hours -# d = days - - -#------------------------------------------------------------------------------ -# FILE LOCATIONS -#------------------------------------------------------------------------------ - -# The default values of these variables are driven from the -D command-line -# option or PGDATA environment variable, represented here as ConfigDir. - -#data_directory = 'ConfigDir' # use data in another directory - # (change requires restart) -#hba_file = 'ConfigDir/pg_hba.conf' # host-based authentication file - # (change requires restart) -#ident_file = 'ConfigDir/pg_ident.conf' # ident configuration file - # (change requires restart) - -# If external_pid_file is not explicitly set, no extra PID file is written. -#external_pid_file = '' # write an extra PID file - # (change requires restart) - - -#------------------------------------------------------------------------------ -# CONNECTIONS AND AUTHENTICATION -#------------------------------------------------------------------------------ - -# - Connection Settings - - -listen_addresses = '*' - # comma-separated list of addresses; - # defaults to 'localhost'; use '*' for all - # (change requires restart) -#port = 5432 # (change requires restart) -max_connections = 100 # (change requires restart) -#superuser_reserved_connections = 3 # (change requires restart) -#unix_socket_directories = '/var/run/postgresql' # comma-separated list of directories - # (change requires restart) -#unix_socket_group = '' # (change requires restart) -#unix_socket_permissions = 0777 # begin with 0 to use octal notation - # (change requires restart) -#bonjour = off # advertise server via Bonjour - # (change requires restart) -#bonjour_name = '' # defaults to the computer name - # (change requires restart) - -# - TCP settings - -# see "man tcp" for details - -#tcp_keepalives_idle = 0 # TCP_KEEPIDLE, in seconds; - # 0 selects the system default -#tcp_keepalives_interval = 0 # TCP_KEEPINTVL, in seconds; - # 0 selects the system default -#tcp_keepalives_count = 0 # TCP_KEEPCNT; - # 0 selects the system default -#tcp_user_timeout = 0 # TCP_USER_TIMEOUT, in milliseconds; - # 0 selects the system default - -#client_connection_check_interval = 0 # time between checks for client - # disconnection while running queries; - # 0 for never - -# - Authentication - - -#authentication_timeout = 1min # 1s-600s -#password_encryption = scram-sha-256 # scram-sha-256 or md5 -#db_user_namespace = off - -# GSSAPI using Kerberos -#krb_server_keyfile = 'FILE:${sysconfdir}/krb5.keytab' -#krb_caseins_users = off - -# - SSL - - -#ssl = off -#ssl_ca_file = '' -#ssl_cert_file = 'server.crt' -#ssl_crl_file = '' -#ssl_crl_dir = '' -#ssl_key_file = 'server.key' -#ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL' # allowed SSL ciphers -#ssl_prefer_server_ciphers = on -#ssl_ecdh_curve = 'prime256v1' -#ssl_min_protocol_version = 'TLSv1.2' -#ssl_max_protocol_version = '' -#ssl_dh_params_file = '' -#ssl_passphrase_command = '' -#ssl_passphrase_command_supports_reload = off - - -#------------------------------------------------------------------------------ -# RESOURCE USAGE (except WAL) -#------------------------------------------------------------------------------ - -# - Memory - - -shared_buffers = 128MB # min 128kB - # (change requires restart) -#huge_pages = try # on, off, or try - # (change requires restart) -#huge_page_size = 0 # zero for system default - # (change requires restart) -#temp_buffers = 8MB # min 800kB -#max_prepared_transactions = 0 # zero disables the feature - # (change requires restart) -# Caution: it is not advisable to set max_prepared_transactions nonzero unless -# you actively intend to use prepared transactions. -#work_mem = 4MB # min 64kB -#hash_mem_multiplier = 1.0 # 1-1000.0 multiplier on hash table work_mem -#maintenance_work_mem = 64MB # min 1MB -#autovacuum_work_mem = -1 # min 1MB, or -1 to use maintenance_work_mem -#logical_decoding_work_mem = 64MB # min 64kB -#max_stack_depth = 2MB # min 100kB -#shared_memory_type = mmap # the default is the first option - # supported by the operating system: - # mmap - # sysv - # windows - # (change requires restart) -dynamic_shared_memory_type = posix # the default is the first option - # supported by the operating system: - # posix - # sysv - # windows - # mmap - # (change requires restart) -#min_dynamic_shared_memory = 0MB # (change requires restart) - -# - Disk - - -#temp_file_limit = -1 # limits per-process temp file space - # in kilobytes, or -1 for no limit - -# - Kernel Resources - - -#max_files_per_process = 1000 # min 64 - # (change requires restart) - -# - Cost-Based Vacuum Delay - - -#vacuum_cost_delay = 0 # 0-100 milliseconds (0 disables) -#vacuum_cost_page_hit = 1 # 0-10000 credits -#vacuum_cost_page_miss = 2 # 0-10000 credits -#vacuum_cost_page_dirty = 20 # 0-10000 credits -#vacuum_cost_limit = 200 # 1-10000 credits - -# - Background Writer - - -#bgwriter_delay = 200ms # 10-10000ms between rounds -#bgwriter_lru_maxpages = 100 # max buffers written/round, 0 disables -#bgwriter_lru_multiplier = 2.0 # 0-10.0 multiplier on buffers scanned/round -#bgwriter_flush_after = 512kB # measured in pages, 0 disables - -# - Asynchronous Behavior - - -#backend_flush_after = 0 # measured in pages, 0 disables -#effective_io_concurrency = 1 # 1-1000; 0 disables prefetching -#maintenance_io_concurrency = 10 # 1-1000; 0 disables prefetching -#max_worker_processes = 8 # (change requires restart) -#max_parallel_workers_per_gather = 2 # limited by max_parallel_workers -#max_parallel_maintenance_workers = 2 # limited by max_parallel_workers -#max_parallel_workers = 8 # number of max_worker_processes that - # can be used in parallel operations -#parallel_leader_participation = on -#old_snapshot_threshold = -1 # 1min-60d; -1 disables; 0 is immediate - # (change requires restart) - - -#------------------------------------------------------------------------------ -# WRITE-AHEAD LOG -#------------------------------------------------------------------------------ - -# - Settings - - -#wal_level = replica # minimal, replica, or logical - # (change requires restart) -#fsync = on # flush data to disk for crash safety - # (turning this off can cause - # unrecoverable data corruption) -#synchronous_commit = on # synchronization level; - # off, local, remote_write, remote_apply, or on -#wal_sync_method = fsync # the default is the first option - # supported by the operating system: - # open_datasync - # fdatasync (default on Linux and FreeBSD) - # fsync - # fsync_writethrough - # open_sync -#full_page_writes = on # recover from partial page writes -#wal_log_hints = off # also do full page writes of non-critical updates - # (change requires restart) -#wal_compression = off # enable compression of full-page writes -#wal_init_zero = on # zero-fill new WAL files -#wal_recycle = on # recycle WAL files -#wal_buffers = -1 # min 32kB, -1 sets based on shared_buffers - # (change requires restart) -#wal_writer_delay = 200ms # 1-10000 milliseconds -#wal_writer_flush_after = 1MB # measured in pages, 0 disables -#wal_skip_threshold = 2MB - -#commit_delay = 0 # range 0-100000, in microseconds -#commit_siblings = 5 # range 1-1000 - -# - Checkpoints - - -#checkpoint_timeout = 5min # range 30s-1d -#checkpoint_completion_target = 0.9 # checkpoint target duration, 0.0 - 1.0 -#checkpoint_flush_after = 256kB # measured in pages, 0 disables -#checkpoint_warning = 30s # 0 disables -max_wal_size = 1GB -min_wal_size = 80MB - -# - Archiving - - -#archive_mode = off # enables archiving; off, on, or always - # (change requires restart) -#archive_command = '' # command to use to archive a logfile segment - # placeholders: %p = path of file to archive - # %f = file name only - # e.g. 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f' -#archive_timeout = 0 # force a logfile segment switch after this - # number of seconds; 0 disables - -# - Archive Recovery - - -# These are only used in recovery mode. - -#restore_command = '' # command to use to restore an archived logfile segment - # placeholders: %p = path of file to restore - # %f = file name only - # e.g. 'cp /mnt/server/archivedir/%f %p' -#archive_cleanup_command = '' # command to execute at every restartpoint -#recovery_end_command = '' # command to execute at completion of recovery - -# - Recovery Target - - -# Set these only when performing a targeted recovery. - -#recovery_target = '' # 'immediate' to end recovery as soon as a - # consistent state is reached - # (change requires restart) -#recovery_target_name = '' # the named restore point to which recovery will proceed - # (change requires restart) -#recovery_target_time = '' # the time stamp up to which recovery will proceed - # (change requires restart) -#recovery_target_xid = '' # the transaction ID up to which recovery will proceed - # (change requires restart) -#recovery_target_lsn = '' # the WAL LSN up to which recovery will proceed - # (change requires restart) -#recovery_target_inclusive = on # Specifies whether to stop: - # just after the specified recovery target (on) - # just before the recovery target (off) - # (change requires restart) -#recovery_target_timeline = 'latest' # 'current', 'latest', or timeline ID - # (change requires restart) -#recovery_target_action = 'pause' # 'pause', 'promote', 'shutdown' - # (change requires restart) - - -#------------------------------------------------------------------------------ -# REPLICATION -#------------------------------------------------------------------------------ - -# - Sending Servers - - -# Set these on the primary and on any standby that will send replication data. - -#max_wal_senders = 10 # max number of walsender processes - # (change requires restart) -#max_replication_slots = 10 # max number of replication slots - # (change requires restart) -#wal_keep_size = 0 # in megabytes; 0 disables -#max_slot_wal_keep_size = -1 # in megabytes; -1 disables -#wal_sender_timeout = 60s # in milliseconds; 0 disables -#track_commit_timestamp = off # collect timestamp of transaction commit - # (change requires restart) - -# - Primary Server - - -# These settings are ignored on a standby server. - -#synchronous_standby_names = '' # standby servers that provide sync rep - # method to choose sync standbys, number of sync standbys, - # and comma-separated list of application_name - # from standby(s); '*' = all -#vacuum_defer_cleanup_age = 0 # number of xacts by which cleanup is delayed - -# - Standby Servers - - -# These settings are ignored on a primary server. - -#primary_conninfo = '' # connection string to sending server -#primary_slot_name = '' # replication slot on sending server -#promote_trigger_file = '' # file name whose presence ends recovery -#hot_standby = on # "off" disallows queries during recovery - # (change requires restart) -#max_standby_archive_delay = 30s # max delay before canceling queries - # when reading WAL from archive; - # -1 allows indefinite delay -#max_standby_streaming_delay = 30s # max delay before canceling queries - # when reading streaming WAL; - # -1 allows indefinite delay -#wal_receiver_create_temp_slot = off # create temp slot if primary_slot_name - # is not set -#wal_receiver_status_interval = 10s # send replies at least this often - # 0 disables -#hot_standby_feedback = off # send info from standby to prevent - # query conflicts -#wal_receiver_timeout = 60s # time that receiver waits for - # communication from primary - # in milliseconds; 0 disables -#wal_retrieve_retry_interval = 5s # time to wait before retrying to - # retrieve WAL after a failed attempt -#recovery_min_apply_delay = 0 # minimum delay for applying changes during recovery - -# - Subscribers - - -# These settings are ignored on a publisher. - -#max_logical_replication_workers = 4 # taken from max_worker_processes - # (change requires restart) -#max_sync_workers_per_subscription = 2 # taken from max_logical_replication_workers - - -#------------------------------------------------------------------------------ -# QUERY TUNING -#------------------------------------------------------------------------------ - -# - Planner Method Configuration - - -#enable_async_append = on -#enable_bitmapscan = on -#enable_gathermerge = on -#enable_hashagg = on -#enable_hashjoin = on -#enable_incremental_sort = on -#enable_indexscan = on -#enable_indexonlyscan = on -#enable_material = on -#enable_memoize = on -#enable_mergejoin = on -#enable_nestloop = on -#enable_parallel_append = on -#enable_parallel_hash = on -#enable_partition_pruning = on -#enable_partitionwise_join = off -#enable_partitionwise_aggregate = off -#enable_seqscan = on -#enable_sort = on -#enable_tidscan = on - -# - Planner Cost Constants - - -#seq_page_cost = 1.0 # measured on an arbitrary scale -#random_page_cost = 4.0 # same scale as above -#cpu_tuple_cost = 0.01 # same scale as above -#cpu_index_tuple_cost = 0.005 # same scale as above -#cpu_operator_cost = 0.0025 # same scale as above -#parallel_setup_cost = 1000.0 # same scale as above -#parallel_tuple_cost = 0.1 # same scale as above -#min_parallel_table_scan_size = 8MB -#min_parallel_index_scan_size = 512kB -#effective_cache_size = 4GB - -#jit_above_cost = 100000 # perform JIT compilation if available - # and query more expensive than this; - # -1 disables -#jit_inline_above_cost = 500000 # inline small functions if query is - # more expensive than this; -1 disables -#jit_optimize_above_cost = 500000 # use expensive JIT optimizations if - # query is more expensive than this; - # -1 disables - -# - Genetic Query Optimizer - - -#geqo = on -#geqo_threshold = 12 -#geqo_effort = 5 # range 1-10 -#geqo_pool_size = 0 # selects default based on effort -#geqo_generations = 0 # selects default based on effort -#geqo_selection_bias = 2.0 # range 1.5-2.0 -#geqo_seed = 0.0 # range 0.0-1.0 - -# - Other Planner Options - - -#default_statistics_target = 100 # range 1-10000 -#constraint_exclusion = partition # on, off, or partition -#cursor_tuple_fraction = 0.1 # range 0.0-1.0 -#from_collapse_limit = 8 -#jit = on # allow JIT compilation -#join_collapse_limit = 8 # 1 disables collapsing of explicit - # JOIN clauses -#plan_cache_mode = auto # auto, force_generic_plan or - # force_custom_plan - - -#------------------------------------------------------------------------------ -# REPORTING AND LOGGING -#------------------------------------------------------------------------------ - -# - Where to Log - - -#log_destination = 'stderr' # Valid values are combinations of - # stderr, csvlog, syslog, and eventlog, - # depending on platform. csvlog - # requires logging_collector to be on. - -# This is used when logging to stderr: -#logging_collector = off # Enable capturing of stderr and csvlog - # into log files. Required to be on for - # csvlogs. - # (change requires restart) - -# These are only used if logging_collector is on: -#log_directory = 'log' # directory where log files are written, - # can be absolute or relative to PGDATA -#log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log' # log file name pattern, - # can include strftime() escapes -#log_file_mode = 0600 # creation mode for log files, - # begin with 0 to use octal notation -#log_rotation_age = 1d # Automatic rotation of logfiles will - # happen after that time. 0 disables. -#log_rotation_size = 10MB # Automatic rotation of logfiles will - # happen after that much log output. - # 0 disables. -#log_truncate_on_rotation = off # If on, an existing log file with the - # same name as the new log file will be - # truncated rather than appended to. - # But such truncation only occurs on - # time-driven rotation, not on restarts - # or size-driven rotation. Default is - # off, meaning append to existing files - # in all cases. - -# These are relevant when logging to syslog: -#syslog_facility = 'LOCAL0' -#syslog_ident = 'postgres' -#syslog_sequence_numbers = on -#syslog_split_messages = on - -# This is only relevant when logging to eventlog (Windows): -# (change requires restart) -#event_source = 'PostgreSQL' - -# - When to Log - - -#log_min_messages = warning # values in order of decreasing detail: - # debug5 - # debug4 - # debug3 - # debug2 - # debug1 - # info - # notice - # warning - # error - # log - # fatal - # panic - -#log_min_error_statement = error # values in order of decreasing detail: - # debug5 - # debug4 - # debug3 - # debug2 - # debug1 - # info - # notice - # warning - # error - # log - # fatal - # panic (effectively off) - -#log_min_duration_statement = -1 # -1 is disabled, 0 logs all statements - # and their durations, > 0 logs only - # statements running at least this number - # of milliseconds - -#log_min_duration_sample = -1 # -1 is disabled, 0 logs a sample of statements - # and their durations, > 0 logs only a sample of - # statements running at least this number - # of milliseconds; - # sample fraction is determined by log_statement_sample_rate - -#log_statement_sample_rate = 1.0 # fraction of logged statements exceeding - # log_min_duration_sample to be logged; - # 1.0 logs all such statements, 0.0 never logs - - -#log_transaction_sample_rate = 0.0 # fraction of transactions whose statements - # are logged regardless of their duration; 1.0 logs all - # statements from all transactions, 0.0 never logs - -# - What to Log - - -#debug_print_parse = off -#debug_print_rewritten = off -#debug_print_plan = off -#debug_pretty_print = on -#log_autovacuum_min_duration = -1 # log autovacuum activity; - # -1 disables, 0 logs all actions and - # their durations, > 0 logs only - # actions running at least this number - # of milliseconds. -#log_checkpoints = off -#log_connections = off -#log_disconnections = off -#log_duration = off -#log_error_verbosity = default # terse, default, or verbose messages -#log_hostname = off -#log_line_prefix = '%m [%p] ' # special values: - # %a = application name - # %u = user name - # %d = database name - # %r = remote host and port - # %h = remote host - # %b = backend type - # %p = process ID - # %P = process ID of parallel group leader - # %t = timestamp without milliseconds - # %m = timestamp with milliseconds - # %n = timestamp with milliseconds (as a Unix epoch) - # %Q = query ID (0 if none or not computed) - # %i = command tag - # %e = SQL state - # %c = session ID - # %l = session line number - # %s = session start timestamp - # %v = virtual transaction ID - # %x = transaction ID (0 if none) - # %q = stop here in non-session - # processes - # %% = '%' - # e.g. '<%u%%%d> ' -#log_lock_waits = off # log lock waits >= deadlock_timeout -#log_recovery_conflict_waits = off # log standby recovery conflict waits - # >= deadlock_timeout -#log_parameter_max_length = -1 # when logging statements, limit logged - # bind-parameter values to N bytes; - # -1 means print in full, 0 disables -#log_parameter_max_length_on_error = 0 # when logging an error, limit logged - # bind-parameter values to N bytes; - # -1 means print in full, 0 disables -#log_statement = 'none' # none, ddl, mod, all -#log_replication_commands = off -#log_temp_files = -1 # log temporary files equal or larger - # than the specified size in kilobytes; - # -1 disables, 0 logs all temp files -log_timezone = 'Etc/UTC' - - -#------------------------------------------------------------------------------ -# PROCESS TITLE -#------------------------------------------------------------------------------ - -#cluster_name = '' # added to process titles if nonempty - # (change requires restart) -#update_process_title = on - - -#------------------------------------------------------------------------------ -# STATISTICS -#------------------------------------------------------------------------------ - -# - Query and Index Statistics Collector - - -#track_activities = on -#track_activity_query_size = 1024 # (change requires restart) -#track_counts = on -#track_io_timing = off -#track_wal_io_timing = off -#track_functions = none # none, pl, all -#stats_temp_directory = 'pg_stat_tmp' - - -# - Monitoring - - -#compute_query_id = auto -#log_statement_stats = off -#log_parser_stats = off -#log_planner_stats = off -#log_executor_stats = off - - -#------------------------------------------------------------------------------ -# AUTOVACUUM -#------------------------------------------------------------------------------ - -#autovacuum = on # Enable autovacuum subprocess? 'on' - # requires track_counts to also be on. -#autovacuum_max_workers = 3 # max number of autovacuum subprocesses - # (change requires restart) -#autovacuum_naptime = 1min # time between autovacuum runs -#autovacuum_vacuum_threshold = 50 # min number of row updates before - # vacuum -#autovacuum_vacuum_insert_threshold = 1000 # min number of row inserts - # before vacuum; -1 disables insert - # vacuums -#autovacuum_analyze_threshold = 50 # min number of row updates before - # analyze -#autovacuum_vacuum_scale_factor = 0.2 # fraction of table size before vacuum -#autovacuum_vacuum_insert_scale_factor = 0.2 # fraction of inserts over table - # size before insert vacuum -#autovacuum_analyze_scale_factor = 0.1 # fraction of table size before analyze -#autovacuum_freeze_max_age = 200000000 # maximum XID age before forced vacuum - # (change requires restart) -#autovacuum_multixact_freeze_max_age = 400000000 # maximum multixact age - # before forced vacuum - # (change requires restart) -#autovacuum_vacuum_cost_delay = 2ms # default vacuum cost delay for - # autovacuum, in milliseconds; - # -1 means use vacuum_cost_delay -#autovacuum_vacuum_cost_limit = -1 # default vacuum cost limit for - # autovacuum, -1 means use - # vacuum_cost_limit - - -#------------------------------------------------------------------------------ -# CLIENT CONNECTION DEFAULTS -#------------------------------------------------------------------------------ - -# - Statement Behavior - - -#client_min_messages = notice # values in order of decreasing detail: - # debug5 - # debug4 - # debug3 - # debug2 - # debug1 - # log - # notice - # warning - # error -#search_path = '"$user", public' # schema names -#row_security = on -#default_table_access_method = 'heap' -#default_tablespace = '' # a tablespace name, '' uses the default -#default_toast_compression = 'pglz' # 'pglz' or 'lz4' -#temp_tablespaces = '' # a list of tablespace names, '' uses - # only default tablespace -#check_function_bodies = on -#default_transaction_isolation = 'read committed' -#default_transaction_read_only = off -#default_transaction_deferrable = off -#session_replication_role = 'origin' -#statement_timeout = 0 # in milliseconds, 0 is disabled -#lock_timeout = 0 # in milliseconds, 0 is disabled -#idle_in_transaction_session_timeout = 0 # in milliseconds, 0 is disabled -#idle_session_timeout = 0 # in milliseconds, 0 is disabled -#vacuum_freeze_table_age = 150000000 -#vacuum_freeze_min_age = 50000000 -#vacuum_failsafe_age = 1600000000 -#vacuum_multixact_freeze_table_age = 150000000 -#vacuum_multixact_freeze_min_age = 5000000 -#vacuum_multixact_failsafe_age = 1600000000 -#bytea_output = 'hex' # hex, escape -#xmlbinary = 'base64' -#xmloption = 'content' -#gin_pending_list_limit = 4MB - -# - Locale and Formatting - - -datestyle = 'iso, mdy' -#intervalstyle = 'postgres' -timezone = 'Etc/UTC' -#timezone_abbreviations = 'Default' # Select the set of available time zone - # abbreviations. Currently, there are - # Default - # Australia (historical usage) - # India - # You can create your own file in - # share/timezonesets/. -#extra_float_digits = 1 # min -15, max 3; any value >0 actually - # selects precise output mode -#client_encoding = sql_ascii # actually, defaults to database - # encoding - -# These settings are initialized by initdb, but they can be changed. -lc_messages = 'en_US.utf8' # locale for system error message - # strings -lc_monetary = 'en_US.utf8' # locale for monetary formatting -lc_numeric = 'en_US.utf8' # locale for number formatting -lc_time = 'en_US.utf8' # locale for time formatting - -# default configuration for text search -default_text_search_config = 'pg_catalog.english' - -# - Shared Library Preloading - - -#local_preload_libraries = '' -#session_preload_libraries = '' -#shared_preload_libraries = '' # (change requires restart) -#jit_provider = 'llvmjit' # JIT library to use - -# - Other Defaults - - -#dynamic_library_path = '$libdir' -#extension_destdir = '' # prepend path when loading extensions - # and shared objects (added by Debian) -#gin_fuzzy_search_limit = 0 - - -#------------------------------------------------------------------------------ -# LOCK MANAGEMENT -#------------------------------------------------------------------------------ - -#deadlock_timeout = 1s -#max_locks_per_transaction = 64 # min 10 - # (change requires restart) -#max_pred_locks_per_transaction = 64 # min 10 - # (change requires restart) -#max_pred_locks_per_relation = -2 # negative values mean - # (max_pred_locks_per_transaction - # / -max_pred_locks_per_relation) - 1 -#max_pred_locks_per_page = 2 # min 0 - - -#------------------------------------------------------------------------------ -# VERSION AND PLATFORM COMPATIBILITY -#------------------------------------------------------------------------------ - -# - Previous PostgreSQL Versions - - -#array_nulls = on -#backslash_quote = safe_encoding # on, off, or safe_encoding -#escape_string_warning = on -#lo_compat_privileges = off -#quote_all_identifiers = off -#standard_conforming_strings = on -#synchronize_seqscans = on - -# - Other Platforms and Clients - - -#transform_null_equals = off - - -#------------------------------------------------------------------------------ -# ERROR HANDLING -#------------------------------------------------------------------------------ - -#exit_on_error = off # terminate session on any error? -#restart_after_crash = on # reinitialize after backend crash? -#data_sync_retry = off # retry or panic on failure to fsync - # data? - # (change requires restart) -#recovery_init_sync_method = fsync # fsync, syncfs (Linux 5.8+) - - -#------------------------------------------------------------------------------ -# CONFIG FILE INCLUDES -#------------------------------------------------------------------------------ - -# These options allow settings to be loaded from files other than the -# default postgresql.conf. Note that these are directives, not variable -# assignments, so they can usefully be given more than once. - -#include_dir = '...' # include files ending in '.conf' from - # a directory, e.g., 'conf.d' -#include_if_exists = '...' # include file only if it exists -#include = '...' # include file - - -#------------------------------------------------------------------------------ -# CUSTOMIZED OPTIONS -#------------------------------------------------------------------------------ - -# Add settings for extensions here diff --git a/persistentStorage/data-keycloak-db/postmaster.opts b/persistentStorage/data-keycloak-db/postmaster.opts deleted file mode 100644 index 5a715e5c..00000000 --- a/persistentStorage/data-keycloak-db/postmaster.opts +++ /dev/null @@ -1 +0,0 @@ -/usr/lib/postgresql/14/bin/postgres diff --git a/persistentStorage/data-keycloak-db/postmaster.pid b/persistentStorage/data-keycloak-db/postmaster.pid deleted file mode 100644 index cb3ad76b..00000000 --- a/persistentStorage/data-keycloak-db/postmaster.pid +++ /dev/null @@ -1,8 +0,0 @@ -1 -/var/lib/postgresql/data -1720109580 -5432 -/var/run/postgresql -* - 37 0 -ready diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/02732061-9daf-5a64-99f5-c550320c7916/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/02732061-9daf-5a64-99f5-c550320c7916/fs.json deleted file mode 100644 index 0eb42965..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/02732061-9daf-5a64-99f5-c550320c7916/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"1ed3b901f40e0f16916288861c470e85-1"},"parts":[{"number":1,"name":"","etag":"cc20167c878bd3302e91be057701686b","size":116014}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/05dc857c-1a01-5a47-9bbb-ceddad8da90a/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/05dc857c-1a01-5a47-9bbb-ceddad8da90a/fs.json deleted file mode 100644 index 98e1ff4d..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/05dc857c-1a01-5a47-9bbb-ceddad8da90a/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"5635841753610e87069168d1d6be8a15-1"},"parts":[{"number":1,"name":"","etag":"c0e92c3059a3dd763c72a1e633c08b4a","size":159}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/0dc8a919-fdd0-5c59-b2ea-c654f93279b9/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/0dc8a919-fdd0-5c59-b2ea-c654f93279b9/fs.json deleted file mode 100644 index ef7fa0fd..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/0dc8a919-fdd0-5c59-b2ea-c654f93279b9/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"3d9ab18ad20bf2c978f622814581b4d6-1"},"parts":[{"number":1,"name":"","etag":"4b3a3c832b21ef7f7278b071f2245169","size":27136}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/0f05867b-6b66-5e1f-b79e-2c489130d926/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/0f05867b-6b66-5e1f-b79e-2c489130d926/fs.json deleted file mode 100644 index a5d8003d..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/0f05867b-6b66-5e1f-b79e-2c489130d926/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"9e7b14d0a92624f30bc04ccbd6179778-1"},"parts":[{"number":1,"name":"","etag":"236a6fe3f791d3a505e786d730780658","size":149}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/11fe277d-454b-51be-a6c8-9a890e2e332c/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/11fe277d-454b-51be-a6c8-9a890e2e332c/fs.json deleted file mode 100644 index 5c3154b2..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/11fe277d-454b-51be-a6c8-9a890e2e332c/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"0533f304c43005f36e3b2d24283b3b98-1"},"parts":[{"number":1,"name":"","etag":"0fffe3a8969892bebfb92554748d1d60","size":151}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/190e1812-563f-5158-9b35-0925edea4a1d/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/190e1812-563f-5158-9b35-0925edea4a1d/fs.json deleted file mode 100644 index 1debfc63..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/190e1812-563f-5158-9b35-0925edea4a1d/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"e9777015469387eabc33fde07a854fde-1"},"parts":[{"number":1,"name":"","etag":"99a812795e2c6cb4df2fcfe9c26981fe","size":125283}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/1bf7f1df-02ea-5937-833c-dfc72be8f55f/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/1bf7f1df-02ea-5937-833c-dfc72be8f55f/fs.json deleted file mode 100644 index 73223322..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/1bf7f1df-02ea-5937-833c-dfc72be8f55f/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"dea0719601b04af1720beb08f18e049e-1"},"parts":[{"number":1,"name":"","etag":"fea2626c58a5f79a9e1e51f6662dba8f","size":27160}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/1d1fe30b-191b-58ff-abb7-c9ea6ec83906/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/1d1fe30b-191b-58ff-abb7-c9ea6ec83906/fs.json deleted file mode 100644 index 4967e548..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/1d1fe30b-191b-58ff-abb7-c9ea6ec83906/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"8820920c41b550bb8c0ca2fd1ec1108a-1"},"parts":[{"number":1,"name":"","etag":"8566392f47fcc703008a950393967efa","size":52}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/2216c52c-9890-5613-a831-3752d0a89f0d/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/2216c52c-9890-5613-a831-3752d0a89f0d/fs.json deleted file mode 100644 index d47eabd6..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/2216c52c-9890-5613-a831-3752d0a89f0d/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"fdf0976b395174730eb08f2a8d68a90f-1"},"parts":[{"number":1,"name":"","etag":"a529e8896fcde6e3c1b9c50a72206571","size":142}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/22a0f109-77ac-5c09-b3e4-26a783e898c1/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/22a0f109-77ac-5c09-b3e4-26a783e898c1/fs.json deleted file mode 100644 index 12ba6966..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/22a0f109-77ac-5c09-b3e4-26a783e898c1/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"145ab1f182e7a586a8dff123fc1693c4-1"},"parts":[{"number":1,"name":"","etag":"c1b6423c50b84e87453d5eb49c31c524","size":125266}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/2c7b355a-c47b-5cd6-8268-f3ace739eef6/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/2c7b355a-c47b-5cd6-8268-f3ace739eef6/fs.json deleted file mode 100644 index 2aa2ff35..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/2c7b355a-c47b-5cd6-8268-f3ace739eef6/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"10ba1250b619c3eb8afd2e42ff09fa9b-1"},"parts":[{"number":1,"name":"","etag":"88ac07b88db7f194099614cf958906d5","size":17245}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/2cb8cdd1-3686-52ec-9b67-1c99d664a2e0/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/2cb8cdd1-3686-52ec-9b67-1c99d664a2e0/fs.json deleted file mode 100644 index ffabc3eb..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/2cb8cdd1-3686-52ec-9b67-1c99d664a2e0/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"43a627540b75a29e5a4868f52e6eb53e-1"},"parts":[{"number":1,"name":"","etag":"d5ad09fbcf9405daffbbf0d9ff38e2e6","size":144}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/2e53bb40-91a1-5d2b-ae3a-9a4d488c15ae/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/2e53bb40-91a1-5d2b-ae3a-9a4d488c15ae/fs.json deleted file mode 100644 index 4b903e5c..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/2e53bb40-91a1-5d2b-ae3a-9a4d488c15ae/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"a5237e3c9cd11dcd5cac50cd84eacd0c-1"},"parts":[{"number":1,"name":"","etag":"ea7783f8c94e2623b163631f7542073c","size":52}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/329d1b22-a387-51ac-bc12-53625ea9ff80/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/329d1b22-a387-51ac-bc12-53625ea9ff80/fs.json deleted file mode 100644 index 8a61f6fb..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/329d1b22-a387-51ac-bc12-53625ea9ff80/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"a7fb71da2ab9ec82d76cea3796899d7c-1"},"parts":[{"number":1,"name":"","etag":"5dbddafb5b591aee33fe53ef7db3d097","size":27232}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/38a0187c-203a-5669-83b8-d074e7362783/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/38a0187c-203a-5669-83b8-d074e7362783/fs.json deleted file mode 100644 index 02363009..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/38a0187c-203a-5669-83b8-d074e7362783/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"0db01549ffabdb03ee744b50821755a3-1"},"parts":[{"number":1,"name":"","etag":"a5e32b78bd52dc2cfe1cffcdaadcb335","size":17346}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/3f037c6f-3b0e-58eb-8ebc-788ba82e466a/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/3f037c6f-3b0e-58eb-8ebc-788ba82e466a/fs.json deleted file mode 100644 index a98b2947..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/3f037c6f-3b0e-58eb-8ebc-788ba82e466a/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"2e80cabfc98331d1c39e85170922f967-1"},"parts":[{"number":1,"name":"","etag":"bf31495ee155fe79f785120c9b41130d","size":142}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/41bde62d-e63e-5b4a-a8ea-58aa63b1e6e9/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/41bde62d-e63e-5b4a-a8ea-58aa63b1e6e9/fs.json deleted file mode 100644 index 9da6f625..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/41bde62d-e63e-5b4a-a8ea-58aa63b1e6e9/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"c223e009f69e252ff649edae606fb32b-1"},"parts":[{"number":1,"name":"","etag":"9ffbd86a4a5562e8bb686030f7314f5d","size":17380}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/434c3dc4-5833-50eb-9cc1-1c6685fda47d/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/434c3dc4-5833-50eb-9cc1-1c6685fda47d/fs.json deleted file mode 100644 index 4cdba012..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/434c3dc4-5833-50eb-9cc1-1c6685fda47d/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"aa3ab94030341e1a2484cfd61adf7c08-1"},"parts":[{"number":1,"name":"","etag":"e7e432156b2418c599abe54b520d7f57","size":27160}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/44a53c0b-4622-5602-a958-338891712724/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/44a53c0b-4622-5602-a958-338891712724/fs.json deleted file mode 100644 index 95f52bb8..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/44a53c0b-4622-5602-a958-338891712724/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"caa77eac5d2bcea840d6171f6d950e51-1"},"parts":[{"number":1,"name":"","etag":"3879f75773626af1ddf231684517cdff","size":17248}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/4ec2c13a-e03d-516c-b393-ece343963eb9/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/4ec2c13a-e03d-516c-b393-ece343963eb9/fs.json deleted file mode 100644 index 047d0b96..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/4ec2c13a-e03d-516c-b393-ece343963eb9/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"c3d752c53821f5a85d3d142c59800b2e-1"},"parts":[{"number":1,"name":"","etag":"5d9afaaf221b44f17c0f12eb2b440f2a","size":17250}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/4fd0be6f-ce25-521a-9a54-1dbc2318ce05/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/4fd0be6f-ce25-521a-9a54-1dbc2318ce05/fs.json deleted file mode 100644 index 0a1bc2da..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/4fd0be6f-ce25-521a-9a54-1dbc2318ce05/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"3fd73f5214fe7bd000996f0ed4a0aa72-1"},"parts":[{"number":1,"name":"","etag":"c445d6cd5e1aa1d7dec13096feae788c","size":17328}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/59291c9f-0b02-575a-85b7-501e54951e63/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/59291c9f-0b02-575a-85b7-501e54951e63/fs.json deleted file mode 100644 index 3bb7e1eb..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/59291c9f-0b02-575a-85b7-501e54951e63/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"f82ea4b8cfb67454ed198dea8665a93b-1"},"parts":[{"number":1,"name":"","etag":"d4968ece01282590f24f6b90a97c5af3","size":17330}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/5b431188-0ba3-53a2-88db-5b5a710d4a74/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/5b431188-0ba3-53a2-88db-5b5a710d4a74/fs.json deleted file mode 100644 index 47840084..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/5b431188-0ba3-53a2-88db-5b5a710d4a74/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"6749cbb816c10892cfbd77ce6a92a1a0-1"},"parts":[{"number":1,"name":"","etag":"7a3d673c9f09e63b51a52ec5ce85f679","size":17247}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/603d285a-9070-51da-bb9d-d32b3429c9db/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/603d285a-9070-51da-bb9d-d32b3429c9db/fs.json deleted file mode 100644 index b8c98554..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/603d285a-9070-51da-bb9d-d32b3429c9db/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"02e3a4555d8fae8ad065544f3673d0f4-1"},"parts":[{"number":1,"name":"","etag":"6bd6da76fb11fd1d0c0be468776d4caa","size":125437}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/6b1decda-5b48-5e42-b499-28bad8aa5611/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/6b1decda-5b48-5e42-b499-28bad8aa5611/fs.json deleted file mode 100644 index e4e5ed7f..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/6b1decda-5b48-5e42-b499-28bad8aa5611/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"cd91d7c8ab9f8596d198ecf5882159c8-1"},"parts":[{"number":1,"name":"","etag":"1a3370926a70960735c93f3ccc4e3fa8","size":142}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/6ba7e370-9833-56b4-aba5-6d9562daa83d/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/6ba7e370-9833-56b4-aba5-6d9562daa83d/fs.json deleted file mode 100644 index fb41b1b0..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/6ba7e370-9833-56b4-aba5-6d9562daa83d/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"0578ae1ba481b34aa5fbaa3245d594cf-1"},"parts":[{"number":1,"name":"","etag":"c719518af10bce03d220bc56c11e970d","size":143}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/726a01c6-a491-5213-9b4a-22a8d431337a/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/726a01c6-a491-5213-9b4a-22a8d431337a/fs.json deleted file mode 100644 index 69a63a7c..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/726a01c6-a491-5213-9b4a-22a8d431337a/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"946218bc1fd9e06890ec868b3bfdea05-1"},"parts":[{"number":1,"name":"","etag":"a259d993349d3a1e285f47414146cda9","size":115987}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/782f544a-be42-5425-9649-44a7523800bc/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/782f544a-be42-5425-9649-44a7523800bc/fs.json deleted file mode 100644 index e93454eb..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/782f544a-be42-5425-9649-44a7523800bc/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"81d80ccefcdbdf34791815c5981a5ffd-1"},"parts":[{"number":1,"name":"","etag":"f3459ce35d70fcf8dc7afe4da93e15af","size":158}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/798480ca-3919-5d8b-aa25-37f97115cfb5/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/798480ca-3919-5d8b-aa25-37f97115cfb5/fs.json deleted file mode 100644 index 5a90e135..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/798480ca-3919-5d8b-aa25-37f97115cfb5/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"c6c570ae8aa15f2af7456b4749ee54c9-1"},"parts":[{"number":1,"name":"","etag":"f8329c8c667203d98fae606df0400232","size":150}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/79f178e4-c033-59c5-82df-c460ec7b19d6/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/79f178e4-c033-59c5-82df-c460ec7b19d6/fs.json deleted file mode 100644 index e87fe40a..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/79f178e4-c033-59c5-82df-c460ec7b19d6/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"5c6446db69e3be8fbba01af486796cb6-1"},"parts":[{"number":1,"name":"","etag":"ae67942b1efbfcac4491401cf98d50b6","size":125502}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/86105e1b-0b7f-553f-8de5-6a7f28e4d183/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/86105e1b-0b7f-553f-8de5-6a7f28e4d183/fs.json deleted file mode 100644 index 02d387e5..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/86105e1b-0b7f-553f-8de5-6a7f28e4d183/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"e11c592134dfc380e79f42cc93b536eb-1"},"parts":[{"number":1,"name":"","etag":"f6386e770442a795016540f9ff6524b3","size":141}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/8b593ddb-9c57-550d-ae66-8f5122e73de9/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/8b593ddb-9c57-550d-ae66-8f5122e73de9/fs.json deleted file mode 100644 index ef207c81..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/8b593ddb-9c57-550d-ae66-8f5122e73de9/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"0e3168e88661dd6f5b7c018ed1186171-1"},"parts":[{"number":1,"name":"","etag":"222c2bc2b6a00051183cc4630b3fb6f2","size":146}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/8fcf286a-4f81-5c05-9cbd-d4096501779a/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/8fcf286a-4f81-5c05-9cbd-d4096501779a/fs.json deleted file mode 100644 index b5af4a17..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/8fcf286a-4f81-5c05-9cbd-d4096501779a/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"1ef8b764c53a7b02298a485fcab2dd77-1"},"parts":[{"number":1,"name":"","etag":"3066b32d06be4ac1c5238346e8ad4270","size":53}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/900dd0e0-5f18-51c8-8dc6-a3b91b6acd9c/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/900dd0e0-5f18-51c8-8dc6-a3b91b6acd9c/fs.json deleted file mode 100644 index e2ac997c..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/900dd0e0-5f18-51c8-8dc6-a3b91b6acd9c/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"cfd7a2fdc3bd71a7b575c6be126e33f0-1"},"parts":[{"number":1,"name":"","etag":"8211e43de0e47830a67b016265f21977","size":146}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/970c4b15-2ba3-5779-b0cb-f3c88ba3932b/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/970c4b15-2ba3-5779-b0cb-f3c88ba3932b/fs.json deleted file mode 100644 index 64615967..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/970c4b15-2ba3-5779-b0cb-f3c88ba3932b/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"932d1979e360c696037b4866ffb1578c-1"},"parts":[{"number":1,"name":"","etag":"51567d8aaa36ec2093f3f7c5293084e0","size":142}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/998f068b-0856-539e-86c3-a392e4ea171d/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/998f068b-0856-539e-86c3-a392e4ea171d/fs.json deleted file mode 100644 index 8ef39153..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/998f068b-0856-539e-86c3-a392e4ea171d/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"4f2a004d2761fec3f0e57347737012f6-1"},"parts":[{"number":1,"name":"","etag":"50b5b6b50584e8afeb85e64f86dda864","size":125412}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/9ec6bdd4-1265-5e98-ae1d-57f76abeb483/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/9ec6bdd4-1265-5e98-ae1d-57f76abeb483/fs.json deleted file mode 100644 index 6e147d84..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/9ec6bdd4-1265-5e98-ae1d-57f76abeb483/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"cc043f8cac1c53688ed002bc53b6681b-1"},"parts":[{"number":1,"name":"","etag":"602f723b376324584d6b3b391f65a54c","size":115995}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/a22f4c66-0f46-564b-b2ee-ea46cd18ad98/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/a22f4c66-0f46-564b-b2ee-ea46cd18ad98/fs.json deleted file mode 100644 index 82f5fbcf..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/a22f4c66-0f46-564b-b2ee-ea46cd18ad98/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"cbcdc7b85edf8ac77ca17c9fce3313c0-1"},"parts":[{"number":1,"name":"","etag":"20de00567d1ae550f4b6ad894b817c12","size":150}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/a2c664fb-6e1a-554f-9c40-351998586f24/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/a2c664fb-6e1a-554f-9c40-351998586f24/fs.json deleted file mode 100644 index eb4fd177..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/a2c664fb-6e1a-554f-9c40-351998586f24/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"53c5058dadc198d77329506647258824-1"},"parts":[{"number":1,"name":"","etag":"e8791a99c428c09f1ea9b6e2a1b6df0e","size":53}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/a36547ca-da4a-5591-a0fc-4e11e03a829c/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/a36547ca-da4a-5591-a0fc-4e11e03a829c/fs.json deleted file mode 100644 index 5b7a1a66..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/a36547ca-da4a-5591-a0fc-4e11e03a829c/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"825083efb822e9f15720319746aa32c9-1"},"parts":[{"number":1,"name":"","etag":"dd2b54ec315db4ef29ffeec3777fc8a0","size":27160}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/a9e44028-6858-5e85-96eb-c57873da6658/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/a9e44028-6858-5e85-96eb-c57873da6658/fs.json deleted file mode 100644 index 9adda72f..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/a9e44028-6858-5e85-96eb-c57873da6658/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"61c69d660da1995461c606fa4bfdc9a7-1"},"parts":[{"number":1,"name":"","etag":"c852b26260bb6e80918e5b35f4a7c101","size":115973}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/ae23ca2d-d8f8-5e05-bdac-c9e0ec1bd275/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/ae23ca2d-d8f8-5e05-bdac-c9e0ec1bd275/fs.json deleted file mode 100644 index c58f78f8..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/ae23ca2d-d8f8-5e05-bdac-c9e0ec1bd275/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"05653a0a2902bd73703e024457a4da5d-1"},"parts":[{"number":1,"name":"","etag":"7ecf7ab47df62450fedc0d365b33b76a","size":115958}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/b00c7461-46bb-57e3-918f-4592cb32df23/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/b00c7461-46bb-57e3-918f-4592cb32df23/fs.json deleted file mode 100644 index 7ec94fb8..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/b00c7461-46bb-57e3-918f-4592cb32df23/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"6767664975665f1ddac9391c146ee9ad-1"},"parts":[{"number":1,"name":"","etag":"98bcf6ebd70311cb260e8555ce80466c","size":27280}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/b08d8ad0-1dfc-5559-9233-b78091fff52f/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/b08d8ad0-1dfc-5559-9233-b78091fff52f/fs.json deleted file mode 100644 index d97bbd3b..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/b08d8ad0-1dfc-5559-9233-b78091fff52f/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"a5cfe5ed7ae6861c9b487e7d671799e1-1"},"parts":[{"number":1,"name":"","etag":"c5aa0b57090c2179430491ca652e5ef8","size":17246}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/b2d7d5be-d3bd-5cdd-b4d0-924cf4236212/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/b2d7d5be-d3bd-5cdd-b4d0-924cf4236212/fs.json deleted file mode 100644 index f2f67e03..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/b2d7d5be-d3bd-5cdd-b4d0-924cf4236212/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"50f834186ad9c234208ba04289ae9d04-1"},"parts":[{"number":1,"name":"","etag":"e4d3b0751f2824bac22f42147dd41fd8","size":144}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/b2dec936-af54-5b2c-9ab9-7502b94191d0/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/b2dec936-af54-5b2c-9ab9-7502b94191d0/fs.json deleted file mode 100644 index 66f9af45..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/b2dec936-af54-5b2c-9ab9-7502b94191d0/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"67407bad5ab44e4b74e7f121cd8d4c75-1"},"parts":[{"number":1,"name":"","etag":"b1f642c5cdf743b068379a03939a2512","size":17248}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/b4b672be-f917-504b-b4e3-c4d6d580af06/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/b4b672be-f917-504b-b4e3-c4d6d580af06/fs.json deleted file mode 100644 index 7fe5cd93..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/b4b672be-f917-504b-b4e3-c4d6d580af06/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"fd3eeacf6e714c094959e7a080838374-1"},"parts":[{"number":1,"name":"","etag":"e6c73525fff2192be7df534ca6d8a8bb","size":17248}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/b8cdb477-995e-55cc-88ce-3e1f9b0de1d9/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/b8cdb477-995e-55cc-88ce-3e1f9b0de1d9/fs.json deleted file mode 100644 index ccb8b505..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/b8cdb477-995e-55cc-88ce-3e1f9b0de1d9/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"e60762f84ea089d186aafe6e0705d2a8-1"},"parts":[{"number":1,"name":"","etag":"4d42c0db3a1b64682bb2a992a7d90fce","size":17318}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/bba25936-6d51-5b24-be2c-6af6d462c434/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/bba25936-6d51-5b24-be2c-6af6d462c434/fs.json deleted file mode 100644 index 04849fc9..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/bba25936-6d51-5b24-be2c-6af6d462c434/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"4b22229bb725ce7343dd9a992a75333b-1"},"parts":[{"number":1,"name":"","etag":"ebec6c266ba376c11a97cca3a3180d49","size":17292}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/bf14635d-e43e-5dfd-b977-f2735e98f7e3/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/bf14635d-e43e-5dfd-b977-f2735e98f7e3/fs.json deleted file mode 100644 index 021bb852..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/bf14635d-e43e-5dfd-b977-f2735e98f7e3/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"7d85b3f3e4c56f69aee9a62cf09f6698-1"},"parts":[{"number":1,"name":"","etag":"51b47fe36f87185ab15fe84cfb4fcb81","size":17322}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/c0ecacdb-92c1-5e37-b949-24e9acfb50e2/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/c0ecacdb-92c1-5e37-b949-24e9acfb50e2/fs.json deleted file mode 100644 index a7f87083..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/c0ecacdb-92c1-5e37-b949-24e9acfb50e2/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"3ebd2a3a038b6e767009204684b9ea1e-1"},"parts":[{"number":1,"name":"","etag":"df0fd6e0bd5e9a79f54e120bdbc82c5c","size":17314}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/d52ad945-1f3b-54d9-b3c9-45a17c5db655/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/d52ad945-1f3b-54d9-b3c9-45a17c5db655/fs.json deleted file mode 100644 index 97a6ddd2..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/d52ad945-1f3b-54d9-b3c9-45a17c5db655/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"555341a95b7636510d42caae8d04b072-1"},"parts":[{"number":1,"name":"","etag":"75f26b946ad64977b1148f08f33a26b3","size":148}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/deaeaa56-c56d-54ee-ad75-f5b90bb7eda6/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/deaeaa56-c56d-54ee-ad75-f5b90bb7eda6/fs.json deleted file mode 100644 index 2d597e31..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/deaeaa56-c56d-54ee-ad75-f5b90bb7eda6/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"834fddd97c8c791b17139469bffb8ac8-1"},"parts":[{"number":1,"name":"","etag":"ae025b596b2fb562d33073338eb23a7d","size":148}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/e3ef7c5a-244e-5323-acd0-94d66c2f0125/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/e3ef7c5a-244e-5323-acd0-94d66c2f0125/fs.json deleted file mode 100644 index 8e0c1ad6..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/e3ef7c5a-244e-5323-acd0-94d66c2f0125/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"395995cfbab1f7330182faf9eea82cd6-1"},"parts":[{"number":1,"name":"","etag":"3a1b62929d0b9762fa72e5c7d99456b7","size":17360}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/e45bed7a-552d-5076-9507-405c51b2f196/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/e45bed7a-552d-5076-9507-405c51b2f196/fs.json deleted file mode 100644 index 33678596..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/e45bed7a-552d-5076-9507-405c51b2f196/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"93cd9a05c44bc3305d8b52cae2a9e974-1"},"parts":[{"number":1,"name":"","etag":"a420e75cf90ea41f20f79873357a44e0","size":125371}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/e9e7922a-a102-5381-be8f-b020e6045877/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/e9e7922a-a102-5381-be8f-b020e6045877/fs.json deleted file mode 100644 index 748bee83..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/e9e7922a-a102-5381-be8f-b020e6045877/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"52dfaa399028a6178b79615e823541f2-1"},"parts":[{"number":1,"name":"","etag":"b32991cae3845c0b38ff42dc6179a5c1","size":17405}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/f701f36d-c795-5dd4-9e4c-e9c33a9dd284/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/f701f36d-c795-5dd4-9e4c-e9c33a9dd284/fs.json deleted file mode 100644 index c6ca83ad..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/f701f36d-c795-5dd4-9e4c-e9c33a9dd284/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"0cdb550c1caaddc707026e346d4adf07-1"},"parts":[{"number":1,"name":"","etag":"114d6d5a7568666bb5fe3b365197f137","size":52}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/f99fe6f8-10b6-5989-ba33-92c7a3527476/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/f99fe6f8-10b6-5989-ba33-92c7a3527476/fs.json deleted file mode 100644 index e1078970..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/f99fe6f8-10b6-5989-ba33-92c7a3527476/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"28eb2baa3a4a66f2e7957f0d8df62473-1"},"parts":[{"number":1,"name":"","etag":"261b232a0c997eb4972f9b5f7b29f840","size":27256}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/fa6ed231-77fe-5b2b-8df4-f32f8d526208/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/fa6ed231-77fe-5b2b-8df4-f32f8d526208/fs.json deleted file mode 100644 index 39d0f0e7..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/fa6ed231-77fe-5b2b-8df4-f32f8d526208/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"81ce0a459de92497fcebecc401b5050f-1"},"parts":[{"number":1,"name":"","etag":"d713f83a36ff6d95a49268905b8a0206","size":17380}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/object/data/ff7b8ca2-2b43-5503-b407-35dc8b0591b0/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/object/data/ff7b8ca2-2b43-5503-b407-35dc8b0591b0/fs.json deleted file mode 100644 index f5ca39b4..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/object/data/ff7b8ca2-2b43-5503-b407-35dc8b0591b0/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"c0d1202931f880b13d0be950eed74d7f-1"},"parts":[{"number":1,"name":"","etag":"7df44e073f73923d05893764889039d2","size":125255}]} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/02732061-9daf-5a64-99f5-c550320c7916.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/02732061-9daf-5a64-99f5-c550320c7916.meta/fs.json deleted file mode 100644 index 7f8c65eb..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/02732061-9daf-5a64-99f5-c550320c7916.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"a765ffe79b3c081ab375f6ed1148716c"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/05dc857c-1a01-5a47-9bbb-ceddad8da90a.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/05dc857c-1a01-5a47-9bbb-ceddad8da90a.meta/fs.json deleted file mode 100644 index 9e338d97..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/05dc857c-1a01-5a47-9bbb-ceddad8da90a.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"9d5867086f9cd5738be4a9f64d088f4c"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/0dc8a919-fdd0-5c59-b2ea-c654f93279b9.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/0dc8a919-fdd0-5c59-b2ea-c654f93279b9.meta/fs.json deleted file mode 100644 index c317064c..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/0dc8a919-fdd0-5c59-b2ea-c654f93279b9.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"275eeeec7750619764d056c8b806bed2"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/0f05867b-6b66-5e1f-b79e-2c489130d926.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/0f05867b-6b66-5e1f-b79e-2c489130d926.meta/fs.json deleted file mode 100644 index 4c2f48a6..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/0f05867b-6b66-5e1f-b79e-2c489130d926.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"83451cef4171c762094222038ca61469"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/11fe277d-454b-51be-a6c8-9a890e2e332c.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/11fe277d-454b-51be-a6c8-9a890e2e332c.meta/fs.json deleted file mode 100644 index bc87fc69..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/11fe277d-454b-51be-a6c8-9a890e2e332c.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"79ab32af15029d53df2188ce296865d5"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/190e1812-563f-5158-9b35-0925edea4a1d.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/190e1812-563f-5158-9b35-0925edea4a1d.meta/fs.json deleted file mode 100644 index 01e50a11..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/190e1812-563f-5158-9b35-0925edea4a1d.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"e57bf443744f3eb957a6cc56d03405a8"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/1bf7f1df-02ea-5937-833c-dfc72be8f55f.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/1bf7f1df-02ea-5937-833c-dfc72be8f55f.meta/fs.json deleted file mode 100644 index 115ae68f..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/1bf7f1df-02ea-5937-833c-dfc72be8f55f.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"abaccf335a6514f268bb4672eaf1c3df"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/1d1fe30b-191b-58ff-abb7-c9ea6ec83906.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/1d1fe30b-191b-58ff-abb7-c9ea6ec83906.meta/fs.json deleted file mode 100644 index d6d2c589..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/1d1fe30b-191b-58ff-abb7-c9ea6ec83906.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"bd65962853da87fbe0a21f7b5a3c57c9"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/2216c52c-9890-5613-a831-3752d0a89f0d.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/2216c52c-9890-5613-a831-3752d0a89f0d.meta/fs.json deleted file mode 100644 index e0d1eabb..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/2216c52c-9890-5613-a831-3752d0a89f0d.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"cc513a04726eb4d9faed53286bd9da41"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/22a0f109-77ac-5c09-b3e4-26a783e898c1.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/22a0f109-77ac-5c09-b3e4-26a783e898c1.meta/fs.json deleted file mode 100644 index 15d9f1f6..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/22a0f109-77ac-5c09-b3e4-26a783e898c1.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"0d4aa52bff7c377413d6f3d8854467bd"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/2c7b355a-c47b-5cd6-8268-f3ace739eef6.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/2c7b355a-c47b-5cd6-8268-f3ace739eef6.meta/fs.json deleted file mode 100644 index 7bbd43fe..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/2c7b355a-c47b-5cd6-8268-f3ace739eef6.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"03044626f6fa20c531b11892e62cf179"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/2cb8cdd1-3686-52ec-9b67-1c99d664a2e0.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/2cb8cdd1-3686-52ec-9b67-1c99d664a2e0.meta/fs.json deleted file mode 100644 index 27621229..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/2cb8cdd1-3686-52ec-9b67-1c99d664a2e0.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"7872c50ca5cbc012c180eec36412841f"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/2e53bb40-91a1-5d2b-ae3a-9a4d488c15ae.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/2e53bb40-91a1-5d2b-ae3a-9a4d488c15ae.meta/fs.json deleted file mode 100644 index 7af63e3d..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/2e53bb40-91a1-5d2b-ae3a-9a4d488c15ae.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"86700cd84cf343314b1d949881a221ac"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/329d1b22-a387-51ac-bc12-53625ea9ff80.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/329d1b22-a387-51ac-bc12-53625ea9ff80.meta/fs.json deleted file mode 100644 index 624d3e69..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/329d1b22-a387-51ac-bc12-53625ea9ff80.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"d94baa0bb005b0bd49a47459ce2cf622"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/38a0187c-203a-5669-83b8-d074e7362783.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/38a0187c-203a-5669-83b8-d074e7362783.meta/fs.json deleted file mode 100644 index a8f35a14..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/38a0187c-203a-5669-83b8-d074e7362783.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"8c8449990a25a3accf3b53fbdd571d62"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/3f037c6f-3b0e-58eb-8ebc-788ba82e466a.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/3f037c6f-3b0e-58eb-8ebc-788ba82e466a.meta/fs.json deleted file mode 100644 index a029d84e..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/3f037c6f-3b0e-58eb-8ebc-788ba82e466a.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"0624c86893842055f2bd73725c3697fa"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/41bde62d-e63e-5b4a-a8ea-58aa63b1e6e9.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/41bde62d-e63e-5b4a-a8ea-58aa63b1e6e9.meta/fs.json deleted file mode 100644 index 036f8989..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/41bde62d-e63e-5b4a-a8ea-58aa63b1e6e9.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"b413364edf3bd89ac197107614ec83c4"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/434c3dc4-5833-50eb-9cc1-1c6685fda47d.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/434c3dc4-5833-50eb-9cc1-1c6685fda47d.meta/fs.json deleted file mode 100644 index 12c7677d..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/434c3dc4-5833-50eb-9cc1-1c6685fda47d.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"ca5034d96ef2abd92d208e76f2d234af"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/44a53c0b-4622-5602-a958-338891712724.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/44a53c0b-4622-5602-a958-338891712724.meta/fs.json deleted file mode 100644 index 586d968f..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/44a53c0b-4622-5602-a958-338891712724.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"4cc66ea02ec9f8af60ec2d9512f800cd"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/4ec2c13a-e03d-516c-b393-ece343963eb9.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/4ec2c13a-e03d-516c-b393-ece343963eb9.meta/fs.json deleted file mode 100644 index 06b4921c..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/4ec2c13a-e03d-516c-b393-ece343963eb9.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"a271a3de94bfc35beab9f12005c9868f"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/4fd0be6f-ce25-521a-9a54-1dbc2318ce05.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/4fd0be6f-ce25-521a-9a54-1dbc2318ce05.meta/fs.json deleted file mode 100644 index d6aa7d41..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/4fd0be6f-ce25-521a-9a54-1dbc2318ce05.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"d836178cb2bb23c651d54798043f3152"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/59291c9f-0b02-575a-85b7-501e54951e63.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/59291c9f-0b02-575a-85b7-501e54951e63.meta/fs.json deleted file mode 100644 index c5c0b5c2..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/59291c9f-0b02-575a-85b7-501e54951e63.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"6806ce9acb110597957b5998a8dc7ebe"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/5b431188-0ba3-53a2-88db-5b5a710d4a74.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/5b431188-0ba3-53a2-88db-5b5a710d4a74.meta/fs.json deleted file mode 100644 index 4f3827f8..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/5b431188-0ba3-53a2-88db-5b5a710d4a74.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"57f78a4b0d117d29c44dddba3961031d"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/603d285a-9070-51da-bb9d-d32b3429c9db.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/603d285a-9070-51da-bb9d-d32b3429c9db.meta/fs.json deleted file mode 100644 index 74033291..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/603d285a-9070-51da-bb9d-d32b3429c9db.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"412629e9c5f63ac84581f1267f966824"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/6b1decda-5b48-5e42-b499-28bad8aa5611.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/6b1decda-5b48-5e42-b499-28bad8aa5611.meta/fs.json deleted file mode 100644 index f8ef3a0c..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/6b1decda-5b48-5e42-b499-28bad8aa5611.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"d51a78159967287ee9dab6da78770e6c"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/6ba7e370-9833-56b4-aba5-6d9562daa83d.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/6ba7e370-9833-56b4-aba5-6d9562daa83d.meta/fs.json deleted file mode 100644 index 858f3e4e..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/6ba7e370-9833-56b4-aba5-6d9562daa83d.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"afaef1e320874e3b54baf64bf9dfcd11"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/726a01c6-a491-5213-9b4a-22a8d431337a.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/726a01c6-a491-5213-9b4a-22a8d431337a.meta/fs.json deleted file mode 100644 index bfdce79c..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/726a01c6-a491-5213-9b4a-22a8d431337a.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"e5008f7e1c5e96c112de441c89bfeb55"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/782f544a-be42-5425-9649-44a7523800bc.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/782f544a-be42-5425-9649-44a7523800bc.meta/fs.json deleted file mode 100644 index 7ee5724a..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/782f544a-be42-5425-9649-44a7523800bc.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"c7f49c6f9d2b1d2cb3a0c74b2fe3d2d3"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/798480ca-3919-5d8b-aa25-37f97115cfb5.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/798480ca-3919-5d8b-aa25-37f97115cfb5.meta/fs.json deleted file mode 100644 index d6356c60..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/798480ca-3919-5d8b-aa25-37f97115cfb5.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"de3bf982b228a6ac7ed48277eb75bb3a"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/79f178e4-c033-59c5-82df-c460ec7b19d6.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/79f178e4-c033-59c5-82df-c460ec7b19d6.meta/fs.json deleted file mode 100644 index 091755f1..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/79f178e4-c033-59c5-82df-c460ec7b19d6.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"717e532cbcb9bf776710691391777972"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/86105e1b-0b7f-553f-8de5-6a7f28e4d183.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/86105e1b-0b7f-553f-8de5-6a7f28e4d183.meta/fs.json deleted file mode 100644 index 4d4fffe8..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/86105e1b-0b7f-553f-8de5-6a7f28e4d183.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"3c47dd97ee413b1143231348685a2d00"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/8b593ddb-9c57-550d-ae66-8f5122e73de9.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/8b593ddb-9c57-550d-ae66-8f5122e73de9.meta/fs.json deleted file mode 100644 index 62744d37..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/8b593ddb-9c57-550d-ae66-8f5122e73de9.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"4fcd918b3d07cc2630889a57ca72ba36"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/8fcf286a-4f81-5c05-9cbd-d4096501779a.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/8fcf286a-4f81-5c05-9cbd-d4096501779a.meta/fs.json deleted file mode 100644 index 5ccdb78e..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/8fcf286a-4f81-5c05-9cbd-d4096501779a.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"ea4cd5f664fd2c41e49442eb0a3c6548"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/900dd0e0-5f18-51c8-8dc6-a3b91b6acd9c.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/900dd0e0-5f18-51c8-8dc6-a3b91b6acd9c.meta/fs.json deleted file mode 100644 index 08924161..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/900dd0e0-5f18-51c8-8dc6-a3b91b6acd9c.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"6449459a7411c1a0de886edb693b5164"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/970c4b15-2ba3-5779-b0cb-f3c88ba3932b.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/970c4b15-2ba3-5779-b0cb-f3c88ba3932b.meta/fs.json deleted file mode 100644 index f7ee2f36..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/970c4b15-2ba3-5779-b0cb-f3c88ba3932b.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"6ec21e7fe11befb68e28f65a98135e47"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/998f068b-0856-539e-86c3-a392e4ea171d.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/998f068b-0856-539e-86c3-a392e4ea171d.meta/fs.json deleted file mode 100644 index 9ffc891a..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/998f068b-0856-539e-86c3-a392e4ea171d.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"946fd18162d422c95f78e88b7b588912"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/9ec6bdd4-1265-5e98-ae1d-57f76abeb483.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/9ec6bdd4-1265-5e98-ae1d-57f76abeb483.meta/fs.json deleted file mode 100644 index 59cf3417..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/9ec6bdd4-1265-5e98-ae1d-57f76abeb483.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"c6f5c65da0dc2539cea0110d071a27b8"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/a22f4c66-0f46-564b-b2ee-ea46cd18ad98.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/a22f4c66-0f46-564b-b2ee-ea46cd18ad98.meta/fs.json deleted file mode 100644 index ef9babbb..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/a22f4c66-0f46-564b-b2ee-ea46cd18ad98.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"ec58ffaef8f439028b358960c7a30292"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/a2c664fb-6e1a-554f-9c40-351998586f24.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/a2c664fb-6e1a-554f-9c40-351998586f24.meta/fs.json deleted file mode 100644 index 2dc7078f..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/a2c664fb-6e1a-554f-9c40-351998586f24.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"d7df93c1dba8f67328949f29f8248687"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/a36547ca-da4a-5591-a0fc-4e11e03a829c.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/a36547ca-da4a-5591-a0fc-4e11e03a829c.meta/fs.json deleted file mode 100644 index 6f88d6f9..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/a36547ca-da4a-5591-a0fc-4e11e03a829c.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"51fb5fd5ed97898ca375caf464098fd1"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/a9e44028-6858-5e85-96eb-c57873da6658.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/a9e44028-6858-5e85-96eb-c57873da6658.meta/fs.json deleted file mode 100644 index b265b3f1..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/a9e44028-6858-5e85-96eb-c57873da6658.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"a362b677984ddbf86d90bab414186a41"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/ae23ca2d-d8f8-5e05-bdac-c9e0ec1bd275.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/ae23ca2d-d8f8-5e05-bdac-c9e0ec1bd275.meta/fs.json deleted file mode 100644 index 536166e4..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/ae23ca2d-d8f8-5e05-bdac-c9e0ec1bd275.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"c7de5f3d55dc7ff1d571a4effa75cdeb"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/b00c7461-46bb-57e3-918f-4592cb32df23.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/b00c7461-46bb-57e3-918f-4592cb32df23.meta/fs.json deleted file mode 100644 index b6a4b650..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/b00c7461-46bb-57e3-918f-4592cb32df23.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"e11aa84d3a564bc07200910d409a9837"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/b08d8ad0-1dfc-5559-9233-b78091fff52f.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/b08d8ad0-1dfc-5559-9233-b78091fff52f.meta/fs.json deleted file mode 100644 index e2639e6b..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/b08d8ad0-1dfc-5559-9233-b78091fff52f.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"488518175064cae177c1b43e7fb68ba7"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/b2d7d5be-d3bd-5cdd-b4d0-924cf4236212.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/b2d7d5be-d3bd-5cdd-b4d0-924cf4236212.meta/fs.json deleted file mode 100644 index 66ff33b8..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/b2d7d5be-d3bd-5cdd-b4d0-924cf4236212.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"cbb11de6ef21ae61932113ee9ad518dd"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/b2dec936-af54-5b2c-9ab9-7502b94191d0.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/b2dec936-af54-5b2c-9ab9-7502b94191d0.meta/fs.json deleted file mode 100644 index 3fb02a65..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/b2dec936-af54-5b2c-9ab9-7502b94191d0.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"ff88e75d298986bb1ae07b9eb4bef2cc"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/b4b672be-f917-504b-b4e3-c4d6d580af06.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/b4b672be-f917-504b-b4e3-c4d6d580af06.meta/fs.json deleted file mode 100644 index bcdbbe1f..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/b4b672be-f917-504b-b4e3-c4d6d580af06.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"04ed1d38e690b1dad44dabf99efc1851"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/b8cdb477-995e-55cc-88ce-3e1f9b0de1d9.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/b8cdb477-995e-55cc-88ce-3e1f9b0de1d9.meta/fs.json deleted file mode 100644 index 3773baa6..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/b8cdb477-995e-55cc-88ce-3e1f9b0de1d9.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"1b12f23938735d69146f3c536e5f2a26"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/bba25936-6d51-5b24-be2c-6af6d462c434.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/bba25936-6d51-5b24-be2c-6af6d462c434.meta/fs.json deleted file mode 100644 index e5bc4a37..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/bba25936-6d51-5b24-be2c-6af6d462c434.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"dbe16be077fa4debb4f5de75c6e98598"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/bf14635d-e43e-5dfd-b977-f2735e98f7e3.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/bf14635d-e43e-5dfd-b977-f2735e98f7e3.meta/fs.json deleted file mode 100644 index 0a7ce606..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/bf14635d-e43e-5dfd-b977-f2735e98f7e3.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"645baa410d006de477163a8dface0f6d"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/c0ecacdb-92c1-5e37-b949-24e9acfb50e2.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/c0ecacdb-92c1-5e37-b949-24e9acfb50e2.meta/fs.json deleted file mode 100644 index f8ef5f9d..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/c0ecacdb-92c1-5e37-b949-24e9acfb50e2.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"56c631bc90f86b33255703711adfda03"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/d52ad945-1f3b-54d9-b3c9-45a17c5db655.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/d52ad945-1f3b-54d9-b3c9-45a17c5db655.meta/fs.json deleted file mode 100644 index db3757cd..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/d52ad945-1f3b-54d9-b3c9-45a17c5db655.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"cefc6a1c07a3d28b7caf69652184fb3c"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/deaeaa56-c56d-54ee-ad75-f5b90bb7eda6.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/deaeaa56-c56d-54ee-ad75-f5b90bb7eda6.meta/fs.json deleted file mode 100644 index 66440279..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/deaeaa56-c56d-54ee-ad75-f5b90bb7eda6.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"4a89c90619425ad0f176d4e1c9787d04"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/e3ef7c5a-244e-5323-acd0-94d66c2f0125.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/e3ef7c5a-244e-5323-acd0-94d66c2f0125.meta/fs.json deleted file mode 100644 index 3f72b779..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/e3ef7c5a-244e-5323-acd0-94d66c2f0125.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"7d656395cd986f489a60feaf33965607"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/e45bed7a-552d-5076-9507-405c51b2f196.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/e45bed7a-552d-5076-9507-405c51b2f196.meta/fs.json deleted file mode 100644 index 6f5d81a0..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/e45bed7a-552d-5076-9507-405c51b2f196.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"432bbd0fc57bec27b7281cfe7c184bb3"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/e9e7922a-a102-5381-be8f-b020e6045877.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/e9e7922a-a102-5381-be8f-b020e6045877.meta/fs.json deleted file mode 100644 index befe5d40..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/e9e7922a-a102-5381-be8f-b020e6045877.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"595618a95e7b226db4eed15cf2c4819e"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/f701f36d-c795-5dd4-9e4c-e9c33a9dd284.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/f701f36d-c795-5dd4-9e4c-e9c33a9dd284.meta/fs.json deleted file mode 100644 index 5e29fb6f..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/f701f36d-c795-5dd4-9e4c-e9c33a9dd284.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"719a936b6e4df72c70b85a9ff8ef3cb4"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/f99fe6f8-10b6-5989-ba33-92c7a3527476.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/f99fe6f8-10b6-5989-ba33-92c7a3527476.meta/fs.json deleted file mode 100644 index 7dc5b2b9..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/f99fe6f8-10b6-5989-ba33-92c7a3527476.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"d367182736c4d6f27d8c0ee7608cafbc"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/fa6ed231-77fe-5b2b-8df4-f32f8d526208.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/fa6ed231-77fe-5b2b-8df4-f32f8d526208.meta/fs.json deleted file mode 100644 index bbc0e752..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/fa6ed231-77fe-5b2b-8df4-f32f8d526208.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"fe8379c16d06bf45550fd4ce50e78a64"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/.minio.sys/buckets/state/data/ff7b8ca2-2b43-5503-b407-35dc8b0591b0.meta/fs.json b/persistentStorage/data-minio/.minio.sys/buckets/state/data/ff7b8ca2-2b43-5503-b407-35dc8b0591b0.meta/fs.json deleted file mode 100644 index 06855d10..00000000 --- a/persistentStorage/data-minio/.minio.sys/buckets/state/data/ff7b8ca2-2b43-5503-b407-35dc8b0591b0.meta/fs.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.0.2","checksum":{"algorithm":"","blocksize":0,"hashes":null},"meta":{"content-type":"application/octet-stream","etag":"693e2c3262c60cf34e2c1fee7e5ff633"}} \ No newline at end of file diff --git a/persistentStorage/data-minio/object/data/02732061-9daf-5a64-99f5-c550320c7916 b/persistentStorage/data-minio/object/data/02732061-9daf-5a64-99f5-c550320c7916 deleted file mode 100644 index 80eba3ac..00000000 Binary files a/persistentStorage/data-minio/object/data/02732061-9daf-5a64-99f5-c550320c7916 and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/05dc857c-1a01-5a47-9bbb-ceddad8da90a b/persistentStorage/data-minio/object/data/05dc857c-1a01-5a47-9bbb-ceddad8da90a deleted file mode 100644 index 51cb808d..00000000 Binary files a/persistentStorage/data-minio/object/data/05dc857c-1a01-5a47-9bbb-ceddad8da90a and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/0dc8a919-fdd0-5c59-b2ea-c654f93279b9 b/persistentStorage/data-minio/object/data/0dc8a919-fdd0-5c59-b2ea-c654f93279b9 deleted file mode 100644 index ca9bd410..00000000 Binary files a/persistentStorage/data-minio/object/data/0dc8a919-fdd0-5c59-b2ea-c654f93279b9 and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/0f05867b-6b66-5e1f-b79e-2c489130d926 b/persistentStorage/data-minio/object/data/0f05867b-6b66-5e1f-b79e-2c489130d926 deleted file mode 100644 index a8c7355d..00000000 Binary files a/persistentStorage/data-minio/object/data/0f05867b-6b66-5e1f-b79e-2c489130d926 and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/11fe277d-454b-51be-a6c8-9a890e2e332c b/persistentStorage/data-minio/object/data/11fe277d-454b-51be-a6c8-9a890e2e332c deleted file mode 100644 index 4a10f2e2..00000000 Binary files a/persistentStorage/data-minio/object/data/11fe277d-454b-51be-a6c8-9a890e2e332c and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/190e1812-563f-5158-9b35-0925edea4a1d b/persistentStorage/data-minio/object/data/190e1812-563f-5158-9b35-0925edea4a1d deleted file mode 100644 index 920b46b9..00000000 Binary files a/persistentStorage/data-minio/object/data/190e1812-563f-5158-9b35-0925edea4a1d and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/1bf7f1df-02ea-5937-833c-dfc72be8f55f b/persistentStorage/data-minio/object/data/1bf7f1df-02ea-5937-833c-dfc72be8f55f deleted file mode 100644 index aca4e0a6..00000000 Binary files a/persistentStorage/data-minio/object/data/1bf7f1df-02ea-5937-833c-dfc72be8f55f and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/1d1fe30b-191b-58ff-abb7-c9ea6ec83906 b/persistentStorage/data-minio/object/data/1d1fe30b-191b-58ff-abb7-c9ea6ec83906 deleted file mode 100644 index 9e41e2dc..00000000 Binary files a/persistentStorage/data-minio/object/data/1d1fe30b-191b-58ff-abb7-c9ea6ec83906 and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/2216c52c-9890-5613-a831-3752d0a89f0d b/persistentStorage/data-minio/object/data/2216c52c-9890-5613-a831-3752d0a89f0d deleted file mode 100644 index b63e0674..00000000 Binary files a/persistentStorage/data-minio/object/data/2216c52c-9890-5613-a831-3752d0a89f0d and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/22a0f109-77ac-5c09-b3e4-26a783e898c1 b/persistentStorage/data-minio/object/data/22a0f109-77ac-5c09-b3e4-26a783e898c1 deleted file mode 100644 index 68ef9c0f..00000000 Binary files a/persistentStorage/data-minio/object/data/22a0f109-77ac-5c09-b3e4-26a783e898c1 and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/2c7b355a-c47b-5cd6-8268-f3ace739eef6 b/persistentStorage/data-minio/object/data/2c7b355a-c47b-5cd6-8268-f3ace739eef6 deleted file mode 100644 index 422779d8..00000000 Binary files a/persistentStorage/data-minio/object/data/2c7b355a-c47b-5cd6-8268-f3ace739eef6 and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/2cb8cdd1-3686-52ec-9b67-1c99d664a2e0 b/persistentStorage/data-minio/object/data/2cb8cdd1-3686-52ec-9b67-1c99d664a2e0 deleted file mode 100644 index 953ef81f..00000000 Binary files a/persistentStorage/data-minio/object/data/2cb8cdd1-3686-52ec-9b67-1c99d664a2e0 and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/2e53bb40-91a1-5d2b-ae3a-9a4d488c15ae b/persistentStorage/data-minio/object/data/2e53bb40-91a1-5d2b-ae3a-9a4d488c15ae deleted file mode 100644 index e9ea24eb..00000000 Binary files a/persistentStorage/data-minio/object/data/2e53bb40-91a1-5d2b-ae3a-9a4d488c15ae and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/329d1b22-a387-51ac-bc12-53625ea9ff80 b/persistentStorage/data-minio/object/data/329d1b22-a387-51ac-bc12-53625ea9ff80 deleted file mode 100644 index d4673aca..00000000 Binary files a/persistentStorage/data-minio/object/data/329d1b22-a387-51ac-bc12-53625ea9ff80 and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/38a0187c-203a-5669-83b8-d074e7362783 b/persistentStorage/data-minio/object/data/38a0187c-203a-5669-83b8-d074e7362783 deleted file mode 100644 index b9c6228b..00000000 Binary files a/persistentStorage/data-minio/object/data/38a0187c-203a-5669-83b8-d074e7362783 and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/3f037c6f-3b0e-58eb-8ebc-788ba82e466a b/persistentStorage/data-minio/object/data/3f037c6f-3b0e-58eb-8ebc-788ba82e466a deleted file mode 100644 index c1b4f49c..00000000 Binary files a/persistentStorage/data-minio/object/data/3f037c6f-3b0e-58eb-8ebc-788ba82e466a and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/41bde62d-e63e-5b4a-a8ea-58aa63b1e6e9 b/persistentStorage/data-minio/object/data/41bde62d-e63e-5b4a-a8ea-58aa63b1e6e9 deleted file mode 100644 index 2d3f3292..00000000 Binary files a/persistentStorage/data-minio/object/data/41bde62d-e63e-5b4a-a8ea-58aa63b1e6e9 and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/434c3dc4-5833-50eb-9cc1-1c6685fda47d b/persistentStorage/data-minio/object/data/434c3dc4-5833-50eb-9cc1-1c6685fda47d deleted file mode 100644 index 1284543f..00000000 Binary files a/persistentStorage/data-minio/object/data/434c3dc4-5833-50eb-9cc1-1c6685fda47d and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/44a53c0b-4622-5602-a958-338891712724 b/persistentStorage/data-minio/object/data/44a53c0b-4622-5602-a958-338891712724 deleted file mode 100644 index 8c99ae5b..00000000 Binary files a/persistentStorage/data-minio/object/data/44a53c0b-4622-5602-a958-338891712724 and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/4ec2c13a-e03d-516c-b393-ece343963eb9 b/persistentStorage/data-minio/object/data/4ec2c13a-e03d-516c-b393-ece343963eb9 deleted file mode 100644 index ac6428da..00000000 Binary files a/persistentStorage/data-minio/object/data/4ec2c13a-e03d-516c-b393-ece343963eb9 and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/4fd0be6f-ce25-521a-9a54-1dbc2318ce05 b/persistentStorage/data-minio/object/data/4fd0be6f-ce25-521a-9a54-1dbc2318ce05 deleted file mode 100644 index 426ed8b0..00000000 Binary files a/persistentStorage/data-minio/object/data/4fd0be6f-ce25-521a-9a54-1dbc2318ce05 and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/59291c9f-0b02-575a-85b7-501e54951e63 b/persistentStorage/data-minio/object/data/59291c9f-0b02-575a-85b7-501e54951e63 deleted file mode 100644 index c266f810..00000000 Binary files a/persistentStorage/data-minio/object/data/59291c9f-0b02-575a-85b7-501e54951e63 and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/5b431188-0ba3-53a2-88db-5b5a710d4a74 b/persistentStorage/data-minio/object/data/5b431188-0ba3-53a2-88db-5b5a710d4a74 deleted file mode 100644 index 48f71143..00000000 Binary files a/persistentStorage/data-minio/object/data/5b431188-0ba3-53a2-88db-5b5a710d4a74 and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/603d285a-9070-51da-bb9d-d32b3429c9db b/persistentStorage/data-minio/object/data/603d285a-9070-51da-bb9d-d32b3429c9db deleted file mode 100644 index 27a35633..00000000 Binary files a/persistentStorage/data-minio/object/data/603d285a-9070-51da-bb9d-d32b3429c9db and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/6b1decda-5b48-5e42-b499-28bad8aa5611 b/persistentStorage/data-minio/object/data/6b1decda-5b48-5e42-b499-28bad8aa5611 deleted file mode 100644 index ba5d9e1a..00000000 Binary files a/persistentStorage/data-minio/object/data/6b1decda-5b48-5e42-b499-28bad8aa5611 and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/6ba7e370-9833-56b4-aba5-6d9562daa83d b/persistentStorage/data-minio/object/data/6ba7e370-9833-56b4-aba5-6d9562daa83d deleted file mode 100644 index c4a46245..00000000 Binary files a/persistentStorage/data-minio/object/data/6ba7e370-9833-56b4-aba5-6d9562daa83d and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/726a01c6-a491-5213-9b4a-22a8d431337a b/persistentStorage/data-minio/object/data/726a01c6-a491-5213-9b4a-22a8d431337a deleted file mode 100644 index 10d20749..00000000 Binary files a/persistentStorage/data-minio/object/data/726a01c6-a491-5213-9b4a-22a8d431337a and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/782f544a-be42-5425-9649-44a7523800bc b/persistentStorage/data-minio/object/data/782f544a-be42-5425-9649-44a7523800bc deleted file mode 100644 index bcdbef15..00000000 Binary files a/persistentStorage/data-minio/object/data/782f544a-be42-5425-9649-44a7523800bc and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/798480ca-3919-5d8b-aa25-37f97115cfb5 b/persistentStorage/data-minio/object/data/798480ca-3919-5d8b-aa25-37f97115cfb5 deleted file mode 100644 index 6db5eb38..00000000 Binary files a/persistentStorage/data-minio/object/data/798480ca-3919-5d8b-aa25-37f97115cfb5 and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/79f178e4-c033-59c5-82df-c460ec7b19d6 b/persistentStorage/data-minio/object/data/79f178e4-c033-59c5-82df-c460ec7b19d6 deleted file mode 100644 index 62af55ab..00000000 Binary files a/persistentStorage/data-minio/object/data/79f178e4-c033-59c5-82df-c460ec7b19d6 and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/86105e1b-0b7f-553f-8de5-6a7f28e4d183 b/persistentStorage/data-minio/object/data/86105e1b-0b7f-553f-8de5-6a7f28e4d183 deleted file mode 100644 index da0c790c..00000000 Binary files a/persistentStorage/data-minio/object/data/86105e1b-0b7f-553f-8de5-6a7f28e4d183 and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/8b593ddb-9c57-550d-ae66-8f5122e73de9 b/persistentStorage/data-minio/object/data/8b593ddb-9c57-550d-ae66-8f5122e73de9 deleted file mode 100644 index a7a3772c..00000000 Binary files a/persistentStorage/data-minio/object/data/8b593ddb-9c57-550d-ae66-8f5122e73de9 and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/8fcf286a-4f81-5c05-9cbd-d4096501779a b/persistentStorage/data-minio/object/data/8fcf286a-4f81-5c05-9cbd-d4096501779a deleted file mode 100644 index b10438a1..00000000 Binary files a/persistentStorage/data-minio/object/data/8fcf286a-4f81-5c05-9cbd-d4096501779a and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/900dd0e0-5f18-51c8-8dc6-a3b91b6acd9c b/persistentStorage/data-minio/object/data/900dd0e0-5f18-51c8-8dc6-a3b91b6acd9c deleted file mode 100644 index 172daa59..00000000 Binary files a/persistentStorage/data-minio/object/data/900dd0e0-5f18-51c8-8dc6-a3b91b6acd9c and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/970c4b15-2ba3-5779-b0cb-f3c88ba3932b b/persistentStorage/data-minio/object/data/970c4b15-2ba3-5779-b0cb-f3c88ba3932b deleted file mode 100644 index 652fc8b5..00000000 Binary files a/persistentStorage/data-minio/object/data/970c4b15-2ba3-5779-b0cb-f3c88ba3932b and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/998f068b-0856-539e-86c3-a392e4ea171d b/persistentStorage/data-minio/object/data/998f068b-0856-539e-86c3-a392e4ea171d deleted file mode 100644 index 9d0ecb19..00000000 Binary files a/persistentStorage/data-minio/object/data/998f068b-0856-539e-86c3-a392e4ea171d and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/9ec6bdd4-1265-5e98-ae1d-57f76abeb483 b/persistentStorage/data-minio/object/data/9ec6bdd4-1265-5e98-ae1d-57f76abeb483 deleted file mode 100644 index 5a340f89..00000000 Binary files a/persistentStorage/data-minio/object/data/9ec6bdd4-1265-5e98-ae1d-57f76abeb483 and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/a22f4c66-0f46-564b-b2ee-ea46cd18ad98 b/persistentStorage/data-minio/object/data/a22f4c66-0f46-564b-b2ee-ea46cd18ad98 deleted file mode 100644 index f83dccac..00000000 Binary files a/persistentStorage/data-minio/object/data/a22f4c66-0f46-564b-b2ee-ea46cd18ad98 and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/a2c664fb-6e1a-554f-9c40-351998586f24 b/persistentStorage/data-minio/object/data/a2c664fb-6e1a-554f-9c40-351998586f24 deleted file mode 100644 index 9a4e33dc..00000000 Binary files a/persistentStorage/data-minio/object/data/a2c664fb-6e1a-554f-9c40-351998586f24 and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/a36547ca-da4a-5591-a0fc-4e11e03a829c b/persistentStorage/data-minio/object/data/a36547ca-da4a-5591-a0fc-4e11e03a829c deleted file mode 100644 index 6a063553..00000000 Binary files a/persistentStorage/data-minio/object/data/a36547ca-da4a-5591-a0fc-4e11e03a829c and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/a9e44028-6858-5e85-96eb-c57873da6658 b/persistentStorage/data-minio/object/data/a9e44028-6858-5e85-96eb-c57873da6658 deleted file mode 100644 index 0c4deca7..00000000 Binary files a/persistentStorage/data-minio/object/data/a9e44028-6858-5e85-96eb-c57873da6658 and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/ae23ca2d-d8f8-5e05-bdac-c9e0ec1bd275 b/persistentStorage/data-minio/object/data/ae23ca2d-d8f8-5e05-bdac-c9e0ec1bd275 deleted file mode 100644 index ecdd6195..00000000 Binary files a/persistentStorage/data-minio/object/data/ae23ca2d-d8f8-5e05-bdac-c9e0ec1bd275 and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/b00c7461-46bb-57e3-918f-4592cb32df23 b/persistentStorage/data-minio/object/data/b00c7461-46bb-57e3-918f-4592cb32df23 deleted file mode 100644 index 8466baf1..00000000 Binary files a/persistentStorage/data-minio/object/data/b00c7461-46bb-57e3-918f-4592cb32df23 and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/b08d8ad0-1dfc-5559-9233-b78091fff52f b/persistentStorage/data-minio/object/data/b08d8ad0-1dfc-5559-9233-b78091fff52f deleted file mode 100644 index 6f961a46..00000000 Binary files a/persistentStorage/data-minio/object/data/b08d8ad0-1dfc-5559-9233-b78091fff52f and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/b2d7d5be-d3bd-5cdd-b4d0-924cf4236212 b/persistentStorage/data-minio/object/data/b2d7d5be-d3bd-5cdd-b4d0-924cf4236212 deleted file mode 100644 index 75dae1ec..00000000 Binary files a/persistentStorage/data-minio/object/data/b2d7d5be-d3bd-5cdd-b4d0-924cf4236212 and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/b2dec936-af54-5b2c-9ab9-7502b94191d0 b/persistentStorage/data-minio/object/data/b2dec936-af54-5b2c-9ab9-7502b94191d0 deleted file mode 100644 index d5253698..00000000 Binary files a/persistentStorage/data-minio/object/data/b2dec936-af54-5b2c-9ab9-7502b94191d0 and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/b4b672be-f917-504b-b4e3-c4d6d580af06 b/persistentStorage/data-minio/object/data/b4b672be-f917-504b-b4e3-c4d6d580af06 deleted file mode 100644 index 814f4bcb..00000000 Binary files a/persistentStorage/data-minio/object/data/b4b672be-f917-504b-b4e3-c4d6d580af06 and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/b8cdb477-995e-55cc-88ce-3e1f9b0de1d9 b/persistentStorage/data-minio/object/data/b8cdb477-995e-55cc-88ce-3e1f9b0de1d9 deleted file mode 100644 index f1fba49e..00000000 Binary files a/persistentStorage/data-minio/object/data/b8cdb477-995e-55cc-88ce-3e1f9b0de1d9 and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/bba25936-6d51-5b24-be2c-6af6d462c434 b/persistentStorage/data-minio/object/data/bba25936-6d51-5b24-be2c-6af6d462c434 deleted file mode 100644 index bbefb2cc..00000000 Binary files a/persistentStorage/data-minio/object/data/bba25936-6d51-5b24-be2c-6af6d462c434 and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/bf14635d-e43e-5dfd-b977-f2735e98f7e3 b/persistentStorage/data-minio/object/data/bf14635d-e43e-5dfd-b977-f2735e98f7e3 deleted file mode 100644 index e5daab28..00000000 Binary files a/persistentStorage/data-minio/object/data/bf14635d-e43e-5dfd-b977-f2735e98f7e3 and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/c0ecacdb-92c1-5e37-b949-24e9acfb50e2 b/persistentStorage/data-minio/object/data/c0ecacdb-92c1-5e37-b949-24e9acfb50e2 deleted file mode 100644 index 1187ea41..00000000 Binary files a/persistentStorage/data-minio/object/data/c0ecacdb-92c1-5e37-b949-24e9acfb50e2 and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/d52ad945-1f3b-54d9-b3c9-45a17c5db655 b/persistentStorage/data-minio/object/data/d52ad945-1f3b-54d9-b3c9-45a17c5db655 deleted file mode 100644 index 9cc57f99..00000000 Binary files a/persistentStorage/data-minio/object/data/d52ad945-1f3b-54d9-b3c9-45a17c5db655 and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/deaeaa56-c56d-54ee-ad75-f5b90bb7eda6 b/persistentStorage/data-minio/object/data/deaeaa56-c56d-54ee-ad75-f5b90bb7eda6 deleted file mode 100644 index 57b43738..00000000 Binary files a/persistentStorage/data-minio/object/data/deaeaa56-c56d-54ee-ad75-f5b90bb7eda6 and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/e3ef7c5a-244e-5323-acd0-94d66c2f0125 b/persistentStorage/data-minio/object/data/e3ef7c5a-244e-5323-acd0-94d66c2f0125 deleted file mode 100644 index f90c0cc2..00000000 Binary files a/persistentStorage/data-minio/object/data/e3ef7c5a-244e-5323-acd0-94d66c2f0125 and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/e45bed7a-552d-5076-9507-405c51b2f196 b/persistentStorage/data-minio/object/data/e45bed7a-552d-5076-9507-405c51b2f196 deleted file mode 100644 index d2f4cf7c..00000000 Binary files a/persistentStorage/data-minio/object/data/e45bed7a-552d-5076-9507-405c51b2f196 and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/e9e7922a-a102-5381-be8f-b020e6045877 b/persistentStorage/data-minio/object/data/e9e7922a-a102-5381-be8f-b020e6045877 deleted file mode 100644 index 9510b086..00000000 Binary files a/persistentStorage/data-minio/object/data/e9e7922a-a102-5381-be8f-b020e6045877 and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/f701f36d-c795-5dd4-9e4c-e9c33a9dd284 b/persistentStorage/data-minio/object/data/f701f36d-c795-5dd4-9e4c-e9c33a9dd284 deleted file mode 100644 index 5cafd83a..00000000 Binary files a/persistentStorage/data-minio/object/data/f701f36d-c795-5dd4-9e4c-e9c33a9dd284 and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/f99fe6f8-10b6-5989-ba33-92c7a3527476 b/persistentStorage/data-minio/object/data/f99fe6f8-10b6-5989-ba33-92c7a3527476 deleted file mode 100644 index 035d2d7d..00000000 Binary files a/persistentStorage/data-minio/object/data/f99fe6f8-10b6-5989-ba33-92c7a3527476 and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/fa6ed231-77fe-5b2b-8df4-f32f8d526208 b/persistentStorage/data-minio/object/data/fa6ed231-77fe-5b2b-8df4-f32f8d526208 deleted file mode 100644 index 1cba31d6..00000000 Binary files a/persistentStorage/data-minio/object/data/fa6ed231-77fe-5b2b-8df4-f32f8d526208 and /dev/null differ diff --git a/persistentStorage/data-minio/object/data/ff7b8ca2-2b43-5503-b407-35dc8b0591b0 b/persistentStorage/data-minio/object/data/ff7b8ca2-2b43-5503-b407-35dc8b0591b0 deleted file mode 100644 index c7c0543b..00000000 Binary files a/persistentStorage/data-minio/object/data/ff7b8ca2-2b43-5503-b407-35dc8b0591b0 and /dev/null differ diff --git a/persistentStorage/data-minio/state/data/02732061-9daf-5a64-99f5-c550320c7916.meta b/persistentStorage/data-minio/state/data/02732061-9daf-5a64-99f5-c550320c7916.meta deleted file mode 100644 index 55c2e5ce..00000000 --- a/persistentStorage/data-minio/state/data/02732061-9daf-5a64-99f5-c550320c7916.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/02732061-9daf-5a64-99f5-c550320c7916","objectId":"02732061-9daf-5a64-99f5-c550320c7916","uploadId":"cd0b78cc-b81a-4d37-9b05-f8db97034ca9","parts":[{"partNumber":1,"partSize":116014,"offset":0,"url":"http://host.docker.internal:9000/object/data/02732061-9daf-5a64-99f5-c550320c7916?uploadId=cd0b78cc-b81a-4d37-9b05-f8db97034ca9&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T163347Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518399&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=f12fe0a9e568c34887fe9a2a49553416c133fb8c15e4d3de8e037eea2bc5383d","md5":null,"sourceMd5":"cc20167c878bd3302e91be057701686b"}],"objectSize":116014,"objectMd5":"cc20167c878bd3302e91be057701686b"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/05dc857c-1a01-5a47-9bbb-ceddad8da90a.meta b/persistentStorage/data-minio/state/data/05dc857c-1a01-5a47-9bbb-ceddad8da90a.meta deleted file mode 100644 index b7d53cae..00000000 --- a/persistentStorage/data-minio/state/data/05dc857c-1a01-5a47-9bbb-ceddad8da90a.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/05dc857c-1a01-5a47-9bbb-ceddad8da90a","objectId":"05dc857c-1a01-5a47-9bbb-ceddad8da90a","uploadId":"dc42c3b2-6e3e-46b9-9e50-136de724bb02","parts":[{"partNumber":1,"partSize":159,"offset":0,"url":"http://host.docker.internal:9000/object/data/05dc857c-1a01-5a47-9bbb-ceddad8da90a?uploadId=dc42c3b2-6e3e-46b9-9e50-136de724bb02&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T163112Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518400&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=bec19e95e3a00f33f59236c28affedc13c59168eba8147348272067119758f18","md5":null,"sourceMd5":"c0e92c3059a3dd763c72a1e633c08b4a"}],"objectSize":159,"objectMd5":"c0e92c3059a3dd763c72a1e633c08b4a"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/0dc8a919-fdd0-5c59-b2ea-c654f93279b9.meta b/persistentStorage/data-minio/state/data/0dc8a919-fdd0-5c59-b2ea-c654f93279b9.meta deleted file mode 100644 index a8c44b61..00000000 --- a/persistentStorage/data-minio/state/data/0dc8a919-fdd0-5c59-b2ea-c654f93279b9.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/0dc8a919-fdd0-5c59-b2ea-c654f93279b9","objectId":"0dc8a919-fdd0-5c59-b2ea-c654f93279b9","uploadId":"12d65897-f155-4b6b-8a93-2105184bcad5","parts":[{"partNumber":1,"partSize":27136,"offset":0,"url":"http://host.docker.internal:9000/object/data/0dc8a919-fdd0-5c59-b2ea-c654f93279b9?uploadId=12d65897-f155-4b6b-8a93-2105184bcad5&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T163203Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518399&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=bf29c3c07549f1d4a2154edee2294aeca5c9b9399e62964d76ef9b27eed9c5cd","md5":null,"sourceMd5":"4b3a3c832b21ef7f7278b071f2245169"}],"objectSize":27136,"objectMd5":"4b3a3c832b21ef7f7278b071f2245169"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/0f05867b-6b66-5e1f-b79e-2c489130d926.meta b/persistentStorage/data-minio/state/data/0f05867b-6b66-5e1f-b79e-2c489130d926.meta deleted file mode 100644 index b8e73be7..00000000 --- a/persistentStorage/data-minio/state/data/0f05867b-6b66-5e1f-b79e-2c489130d926.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/0f05867b-6b66-5e1f-b79e-2c489130d926","objectId":"0f05867b-6b66-5e1f-b79e-2c489130d926","uploadId":"03c923ca-31b6-4c23-b3ce-4268fbe57dc2","parts":[{"partNumber":1,"partSize":149,"offset":0,"url":"http://host.docker.internal:9000/object/data/0f05867b-6b66-5e1f-b79e-2c489130d926?uploadId=03c923ca-31b6-4c23-b3ce-4268fbe57dc2&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T163545Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518399&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=5ddb2fb96efc2b28f218176c695f4cce6400c79eb896fb828d77939e7fdb033f","md5":null,"sourceMd5":"236a6fe3f791d3a505e786d730780658"}],"objectSize":149,"objectMd5":"236a6fe3f791d3a505e786d730780658"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/11fe277d-454b-51be-a6c8-9a890e2e332c.meta b/persistentStorage/data-minio/state/data/11fe277d-454b-51be-a6c8-9a890e2e332c.meta deleted file mode 100644 index e316c752..00000000 --- a/persistentStorage/data-minio/state/data/11fe277d-454b-51be-a6c8-9a890e2e332c.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/11fe277d-454b-51be-a6c8-9a890e2e332c","objectId":"11fe277d-454b-51be-a6c8-9a890e2e332c","uploadId":"5b61c3e6-8a3b-498e-b248-86e0c3d59337","parts":[{"partNumber":1,"partSize":151,"offset":0,"url":"http://host.docker.internal:9000/object/data/11fe277d-454b-51be-a6c8-9a890e2e332c?uploadId=5b61c3e6-8a3b-498e-b248-86e0c3d59337&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T162637Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518400&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=6f5b2a0f5ff936fac0611182246575d9ea9c9bc41f3b4253e63d3d16f51c3591","md5":null,"sourceMd5":"0fffe3a8969892bebfb92554748d1d60"}],"objectSize":151,"objectMd5":"0fffe3a8969892bebfb92554748d1d60"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/190e1812-563f-5158-9b35-0925edea4a1d.meta b/persistentStorage/data-minio/state/data/190e1812-563f-5158-9b35-0925edea4a1d.meta deleted file mode 100644 index 97582915..00000000 --- a/persistentStorage/data-minio/state/data/190e1812-563f-5158-9b35-0925edea4a1d.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/190e1812-563f-5158-9b35-0925edea4a1d","objectId":"190e1812-563f-5158-9b35-0925edea4a1d","uploadId":"c3e7ece7-6924-4813-aa43-0a5c81ad1cd8","parts":[{"partNumber":1,"partSize":125283,"offset":0,"url":"http://host.docker.internal:9000/object/data/190e1812-563f-5158-9b35-0925edea4a1d?uploadId=c3e7ece7-6924-4813-aa43-0a5c81ad1cd8&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T163159Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518400&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=ffe91ecddca301816e8124383c1dc1cdb103782edab5e87ed5076ad450da3d7d","md5":null,"sourceMd5":"99a812795e2c6cb4df2fcfe9c26981fe"}],"objectSize":125283,"objectMd5":"99a812795e2c6cb4df2fcfe9c26981fe"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/1bf7f1df-02ea-5937-833c-dfc72be8f55f.meta b/persistentStorage/data-minio/state/data/1bf7f1df-02ea-5937-833c-dfc72be8f55f.meta deleted file mode 100644 index d751dc1d..00000000 --- a/persistentStorage/data-minio/state/data/1bf7f1df-02ea-5937-833c-dfc72be8f55f.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/1bf7f1df-02ea-5937-833c-dfc72be8f55f","objectId":"1bf7f1df-02ea-5937-833c-dfc72be8f55f","uploadId":"3b876554-7fd1-49d2-9078-ebc48fcfb9a6","parts":[{"partNumber":1,"partSize":27160,"offset":0,"url":"http://host.docker.internal:9000/object/data/1bf7f1df-02ea-5937-833c-dfc72be8f55f?uploadId=3b876554-7fd1-49d2-9078-ebc48fcfb9a6&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T163047Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518400&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=a69bb080aa9a84a783c213efea530e31c0bdb96ccd23702d8bf163c70d4083fc","md5":null,"sourceMd5":"fea2626c58a5f79a9e1e51f6662dba8f"}],"objectSize":27160,"objectMd5":"fea2626c58a5f79a9e1e51f6662dba8f"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/1d1fe30b-191b-58ff-abb7-c9ea6ec83906.meta b/persistentStorage/data-minio/state/data/1d1fe30b-191b-58ff-abb7-c9ea6ec83906.meta deleted file mode 100644 index 8a415aaf..00000000 --- a/persistentStorage/data-minio/state/data/1d1fe30b-191b-58ff-abb7-c9ea6ec83906.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/1d1fe30b-191b-58ff-abb7-c9ea6ec83906","objectId":"1d1fe30b-191b-58ff-abb7-c9ea6ec83906","uploadId":"ce5db162-b6d0-4421-9cad-ddcd61f92bf7","parts":[{"partNumber":1,"partSize":52,"offset":0,"url":"http://host.docker.internal:9000/object/data/1d1fe30b-191b-58ff-abb7-c9ea6ec83906?uploadId=ce5db162-b6d0-4421-9cad-ddcd61f92bf7&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T162859Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518399&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=9f45f34d8eecbe61fc9a93e8a891a5d4265d72c1436878e516bed21bbfdc3329","md5":null,"sourceMd5":"8566392f47fcc703008a950393967efa"}],"objectSize":52,"objectMd5":"8566392f47fcc703008a950393967efa"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/2216c52c-9890-5613-a831-3752d0a89f0d.meta b/persistentStorage/data-minio/state/data/2216c52c-9890-5613-a831-3752d0a89f0d.meta deleted file mode 100644 index 257d2b73..00000000 --- a/persistentStorage/data-minio/state/data/2216c52c-9890-5613-a831-3752d0a89f0d.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/2216c52c-9890-5613-a831-3752d0a89f0d","objectId":"2216c52c-9890-5613-a831-3752d0a89f0d","uploadId":"37ac8eb3-92d6-4307-98e1-d5aeb2d2fe82","parts":[{"partNumber":1,"partSize":142,"offset":0,"url":"http://host.docker.internal:9000/object/data/2216c52c-9890-5613-a831-3752d0a89f0d?uploadId=37ac8eb3-92d6-4307-98e1-d5aeb2d2fe82&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T162949Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518400&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=7973916d696340b6a37824e3b41252b0250f39f25f0353257dea44ebd80e11d9","md5":null,"sourceMd5":"a529e8896fcde6e3c1b9c50a72206571"}],"objectSize":142,"objectMd5":"a529e8896fcde6e3c1b9c50a72206571"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/22a0f109-77ac-5c09-b3e4-26a783e898c1.meta b/persistentStorage/data-minio/state/data/22a0f109-77ac-5c09-b3e4-26a783e898c1.meta deleted file mode 100644 index 1e2c7bd8..00000000 --- a/persistentStorage/data-minio/state/data/22a0f109-77ac-5c09-b3e4-26a783e898c1.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/22a0f109-77ac-5c09-b3e4-26a783e898c1","objectId":"22a0f109-77ac-5c09-b3e4-26a783e898c1","uploadId":"470f160b-f807-46b0-a0c7-97667d4d3464","parts":[{"partNumber":1,"partSize":125266,"offset":0,"url":"http://host.docker.internal:9000/object/data/22a0f109-77ac-5c09-b3e4-26a783e898c1?uploadId=470f160b-f807-46b0-a0c7-97667d4d3464&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T163608Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518399&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=fc3e1fa338671ca43b612a35b277f9997e7f0497bb65a2c674f8a7772ef2fe88","md5":null,"sourceMd5":"c1b6423c50b84e87453d5eb49c31c524"}],"objectSize":125266,"objectMd5":"c1b6423c50b84e87453d5eb49c31c524"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/2c7b355a-c47b-5cd6-8268-f3ace739eef6.meta b/persistentStorage/data-minio/state/data/2c7b355a-c47b-5cd6-8268-f3ace739eef6.meta deleted file mode 100644 index c01c6b8c..00000000 --- a/persistentStorage/data-minio/state/data/2c7b355a-c47b-5cd6-8268-f3ace739eef6.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/2c7b355a-c47b-5cd6-8268-f3ace739eef6","objectId":"2c7b355a-c47b-5cd6-8268-f3ace739eef6","uploadId":"3c67abe9-0b1f-4745-b215-03faf734c03e","parts":[{"partNumber":1,"partSize":17245,"offset":0,"url":"http://host.docker.internal:9000/object/data/2c7b355a-c47b-5cd6-8268-f3ace739eef6?uploadId=3c67abe9-0b1f-4745-b215-03faf734c03e&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T163700Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518399&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=03157ae00fdf81d16f198025243c5ff8c81196f01278964b2710bad57a0a2dbe","md5":null,"sourceMd5":"88ac07b88db7f194099614cf958906d5"}],"objectSize":17245,"objectMd5":"88ac07b88db7f194099614cf958906d5"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/2cb8cdd1-3686-52ec-9b67-1c99d664a2e0.meta b/persistentStorage/data-minio/state/data/2cb8cdd1-3686-52ec-9b67-1c99d664a2e0.meta deleted file mode 100644 index bedfdcba..00000000 --- a/persistentStorage/data-minio/state/data/2cb8cdd1-3686-52ec-9b67-1c99d664a2e0.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/2cb8cdd1-3686-52ec-9b67-1c99d664a2e0","objectId":"2cb8cdd1-3686-52ec-9b67-1c99d664a2e0","uploadId":"ba5bbcb1-5c1b-462d-88b8-d8fdf283626b","parts":[{"partNumber":1,"partSize":144,"offset":0,"url":"http://host.docker.internal:9000/object/data/2cb8cdd1-3686-52ec-9b67-1c99d664a2e0?uploadId=ba5bbcb1-5c1b-462d-88b8-d8fdf283626b&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T163800Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518400&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=1be46898224ef35d4dbd470b0bc94a45436c659bad2ff4768c4b7f3e89d4f3c3","md5":null,"sourceMd5":"d5ad09fbcf9405daffbbf0d9ff38e2e6"}],"objectSize":144,"objectMd5":"d5ad09fbcf9405daffbbf0d9ff38e2e6"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/2e53bb40-91a1-5d2b-ae3a-9a4d488c15ae.meta b/persistentStorage/data-minio/state/data/2e53bb40-91a1-5d2b-ae3a-9a4d488c15ae.meta deleted file mode 100644 index 30f8c719..00000000 --- a/persistentStorage/data-minio/state/data/2e53bb40-91a1-5d2b-ae3a-9a4d488c15ae.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/2e53bb40-91a1-5d2b-ae3a-9a4d488c15ae","objectId":"2e53bb40-91a1-5d2b-ae3a-9a4d488c15ae","uploadId":"aabb325d-11a3-431c-a341-4c4d749058bb","parts":[{"partNumber":1,"partSize":52,"offset":0,"url":"http://host.docker.internal:9000/object/data/2e53bb40-91a1-5d2b-ae3a-9a4d488c15ae?uploadId=aabb325d-11a3-431c-a341-4c4d749058bb&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T162924Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518399&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=1cdf8740de05158b615c9bc16bbd5051ab8c0eb3147308f8763c2d27f69147ea","md5":null,"sourceMd5":"ea7783f8c94e2623b163631f7542073c"}],"objectSize":52,"objectMd5":"ea7783f8c94e2623b163631f7542073c"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/329d1b22-a387-51ac-bc12-53625ea9ff80.meta b/persistentStorage/data-minio/state/data/329d1b22-a387-51ac-bc12-53625ea9ff80.meta deleted file mode 100644 index 25b8959d..00000000 --- a/persistentStorage/data-minio/state/data/329d1b22-a387-51ac-bc12-53625ea9ff80.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/329d1b22-a387-51ac-bc12-53625ea9ff80","objectId":"329d1b22-a387-51ac-bc12-53625ea9ff80","uploadId":"3de3f375-842b-4a09-b472-31e198a79447","parts":[{"partNumber":1,"partSize":27232,"offset":0,"url":"http://host.docker.internal:9000/object/data/329d1b22-a387-51ac-bc12-53625ea9ff80?uploadId=3de3f375-842b-4a09-b472-31e198a79447&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T162704Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518400&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=ba2cd9c23990dbbb5b7d8ff7403ab1b6dfe94ca422c6d0367ddc3ed20fa29bb8","md5":null,"sourceMd5":"5dbddafb5b591aee33fe53ef7db3d097"}],"objectSize":27232,"objectMd5":"5dbddafb5b591aee33fe53ef7db3d097"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/38a0187c-203a-5669-83b8-d074e7362783.meta b/persistentStorage/data-minio/state/data/38a0187c-203a-5669-83b8-d074e7362783.meta deleted file mode 100644 index 71900037..00000000 --- a/persistentStorage/data-minio/state/data/38a0187c-203a-5669-83b8-d074e7362783.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/38a0187c-203a-5669-83b8-d074e7362783","objectId":"38a0187c-203a-5669-83b8-d074e7362783","uploadId":"2400ba78-032f-4f43-a47b-74da9191118a","parts":[{"partNumber":1,"partSize":17346,"offset":0,"url":"http://host.docker.internal:9000/object/data/38a0187c-203a-5669-83b8-d074e7362783?uploadId=2400ba78-032f-4f43-a47b-74da9191118a&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T162457Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518399&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=cbbce373976d664dc8de22511e457c05806fb1df09c9c4e6ab1594e1596df527","md5":null,"sourceMd5":"a5e32b78bd52dc2cfe1cffcdaadcb335"}],"objectSize":17346,"objectMd5":"a5e32b78bd52dc2cfe1cffcdaadcb335"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/3f037c6f-3b0e-58eb-8ebc-788ba82e466a.meta b/persistentStorage/data-minio/state/data/3f037c6f-3b0e-58eb-8ebc-788ba82e466a.meta deleted file mode 100644 index a14dc8a2..00000000 --- a/persistentStorage/data-minio/state/data/3f037c6f-3b0e-58eb-8ebc-788ba82e466a.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/3f037c6f-3b0e-58eb-8ebc-788ba82e466a","objectId":"3f037c6f-3b0e-58eb-8ebc-788ba82e466a","uploadId":"7cb8cf92-1089-432c-930a-60ce0ea5955b","parts":[{"partNumber":1,"partSize":142,"offset":0,"url":"http://host.docker.internal:9000/object/data/3f037c6f-3b0e-58eb-8ebc-788ba82e466a?uploadId=7cb8cf92-1089-432c-930a-60ce0ea5955b&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T163137Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518400&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=496470d1dcfd9a7da3cc3db537aabf9d2c9f8ba78a43d273688bb2b434162a0c","md5":null,"sourceMd5":"bf31495ee155fe79f785120c9b41130d"}],"objectSize":142,"objectMd5":"bf31495ee155fe79f785120c9b41130d"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/41bde62d-e63e-5b4a-a8ea-58aa63b1e6e9.meta b/persistentStorage/data-minio/state/data/41bde62d-e63e-5b4a-a8ea-58aa63b1e6e9.meta deleted file mode 100644 index eb0e4876..00000000 --- a/persistentStorage/data-minio/state/data/41bde62d-e63e-5b4a-a8ea-58aa63b1e6e9.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/41bde62d-e63e-5b4a-a8ea-58aa63b1e6e9","objectId":"41bde62d-e63e-5b4a-a8ea-58aa63b1e6e9","uploadId":"f27949ef-60ff-4361-8c3a-0b557bbc1cc3","parts":[{"partNumber":1,"partSize":17380,"offset":0,"url":"http://host.docker.internal:9000/object/data/41bde62d-e63e-5b4a-a8ea-58aa63b1e6e9?uploadId=f27949ef-60ff-4361-8c3a-0b557bbc1cc3&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T163321Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518399&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=280b353e0ef6b04d0425e03bb5e00dca2e1b42756d25f59c224e40d1abd24a77","md5":null,"sourceMd5":"9ffbd86a4a5562e8bb686030f7314f5d"}],"objectSize":17380,"objectMd5":"9ffbd86a4a5562e8bb686030f7314f5d"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/434c3dc4-5833-50eb-9cc1-1c6685fda47d.meta b/persistentStorage/data-minio/state/data/434c3dc4-5833-50eb-9cc1-1c6685fda47d.meta deleted file mode 100644 index 8d450e55..00000000 --- a/persistentStorage/data-minio/state/data/434c3dc4-5833-50eb-9cc1-1c6685fda47d.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/434c3dc4-5833-50eb-9cc1-1c6685fda47d","objectId":"434c3dc4-5833-50eb-9cc1-1c6685fda47d","uploadId":"2ccdcbfa-2959-4029-8413-321046dee100","parts":[{"partNumber":1,"partSize":27160,"offset":0,"url":"http://host.docker.internal:9000/object/data/434c3dc4-5833-50eb-9cc1-1c6685fda47d?uploadId=2ccdcbfa-2959-4029-8413-321046dee100&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T163734Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518400&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=544e680a716b526e69bdbdf2933ac2b524388423ec2f5d63ead00dd8fe83b35e","md5":null,"sourceMd5":"e7e432156b2418c599abe54b520d7f57"}],"objectSize":27160,"objectMd5":"e7e432156b2418c599abe54b520d7f57"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/44a53c0b-4622-5602-a958-338891712724.meta b/persistentStorage/data-minio/state/data/44a53c0b-4622-5602-a958-338891712724.meta deleted file mode 100644 index f20afe37..00000000 --- a/persistentStorage/data-minio/state/data/44a53c0b-4622-5602-a958-338891712724.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/44a53c0b-4622-5602-a958-338891712724","objectId":"44a53c0b-4622-5602-a958-338891712724","uploadId":"c2a816ef-ebc7-4669-8cfc-d79977bc6f20","parts":[{"partNumber":1,"partSize":17248,"offset":0,"url":"http://host.docker.internal:9000/object/data/44a53c0b-4622-5602-a958-338891712724?uploadId=c2a816ef-ebc7-4669-8cfc-d79977bc6f20&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T162828Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518399&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=7fee80ad8c8a138f356046860127621885a340d90f9657297a2ac5e3936fbcb9","md5":null,"sourceMd5":"3879f75773626af1ddf231684517cdff"}],"objectSize":17248,"objectMd5":"3879f75773626af1ddf231684517cdff"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/4ec2c13a-e03d-516c-b393-ece343963eb9.meta b/persistentStorage/data-minio/state/data/4ec2c13a-e03d-516c-b393-ece343963eb9.meta deleted file mode 100644 index 16933e9c..00000000 --- a/persistentStorage/data-minio/state/data/4ec2c13a-e03d-516c-b393-ece343963eb9.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/4ec2c13a-e03d-516c-b393-ece343963eb9","objectId":"4ec2c13a-e03d-516c-b393-ece343963eb9","uploadId":"33c67df6-2d92-426f-9458-892b944a9aed","parts":[{"partNumber":1,"partSize":17250,"offset":0,"url":"http://host.docker.internal:9000/object/data/4ec2c13a-e03d-516c-b393-ece343963eb9?uploadId=33c67df6-2d92-426f-9458-892b944a9aed&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T163515Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518399&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=19524cf411da1ab9259ffb7216b390c3cd53a1edab82a8e5d2ec0fab91e7f67d","md5":null,"sourceMd5":"5d9afaaf221b44f17c0f12eb2b440f2a"}],"objectSize":17250,"objectMd5":"5d9afaaf221b44f17c0f12eb2b440f2a"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/4fd0be6f-ce25-521a-9a54-1dbc2318ce05.meta b/persistentStorage/data-minio/state/data/4fd0be6f-ce25-521a-9a54-1dbc2318ce05.meta deleted file mode 100644 index 106eeb86..00000000 --- a/persistentStorage/data-minio/state/data/4fd0be6f-ce25-521a-9a54-1dbc2318ce05.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/4fd0be6f-ce25-521a-9a54-1dbc2318ce05","objectId":"4fd0be6f-ce25-521a-9a54-1dbc2318ce05","uploadId":"dd86a0eb-9990-4468-abfb-332d519f42ba","parts":[{"partNumber":1,"partSize":17328,"offset":0,"url":"http://host.docker.internal:9000/object/data/4fd0be6f-ce25-521a-9a54-1dbc2318ce05?uploadId=dd86a0eb-9990-4468-abfb-332d519f42ba&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T162529Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518399&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=c828f58d2a4ecea371579fd7e2d0d918a7a87a710e1953fc541ddc4122681c0f","md5":null,"sourceMd5":"c445d6cd5e1aa1d7dec13096feae788c"}],"objectSize":17328,"objectMd5":"c445d6cd5e1aa1d7dec13096feae788c"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/59291c9f-0b02-575a-85b7-501e54951e63.meta b/persistentStorage/data-minio/state/data/59291c9f-0b02-575a-85b7-501e54951e63.meta deleted file mode 100644 index 5eca343d..00000000 --- a/persistentStorage/data-minio/state/data/59291c9f-0b02-575a-85b7-501e54951e63.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/59291c9f-0b02-575a-85b7-501e54951e63","objectId":"59291c9f-0b02-575a-85b7-501e54951e63","uploadId":"cf040293-9242-4e95-b48e-a149b8cce950","parts":[{"partNumber":1,"partSize":17330,"offset":0,"url":"http://host.docker.internal:9000/object/data/59291c9f-0b02-575a-85b7-501e54951e63?uploadId=cf040293-9242-4e95-b48e-a149b8cce950&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T163011Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518400&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=97513f1b44792ae67e6ee6b6181fe076bfc1d18e6b6d74290198f0097567455a","md5":null,"sourceMd5":"d4968ece01282590f24f6b90a97c5af3"}],"objectSize":17330,"objectMd5":"d4968ece01282590f24f6b90a97c5af3"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/5b431188-0ba3-53a2-88db-5b5a710d4a74.meta b/persistentStorage/data-minio/state/data/5b431188-0ba3-53a2-88db-5b5a710d4a74.meta deleted file mode 100644 index 2605b9bd..00000000 --- a/persistentStorage/data-minio/state/data/5b431188-0ba3-53a2-88db-5b5a710d4a74.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/5b431188-0ba3-53a2-88db-5b5a710d4a74","objectId":"5b431188-0ba3-53a2-88db-5b5a710d4a74","uploadId":"baaea62a-1a43-40ca-9635-2a1b3b12a69b","parts":[{"partNumber":1,"partSize":17247,"offset":0,"url":"http://host.docker.internal:9000/object/data/5b431188-0ba3-53a2-88db-5b5a710d4a74?uploadId=baaea62a-1a43-40ca-9635-2a1b3b12a69b&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T163541Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518400&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=fbc02936edfc38bf3eb79d2169de99aff3806bc300da1f2ed14bb6ebe5751690","md5":null,"sourceMd5":"7a3d673c9f09e63b51a52ec5ce85f679"}],"objectSize":17247,"objectMd5":"7a3d673c9f09e63b51a52ec5ce85f679"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/603d285a-9070-51da-bb9d-d32b3429c9db.meta b/persistentStorage/data-minio/state/data/603d285a-9070-51da-bb9d-d32b3429c9db.meta deleted file mode 100644 index 5ee209e3..00000000 --- a/persistentStorage/data-minio/state/data/603d285a-9070-51da-bb9d-d32b3429c9db.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/603d285a-9070-51da-bb9d-d32b3429c9db","objectId":"603d285a-9070-51da-bb9d-d32b3429c9db","uploadId":"1c1c9e16-8cf4-45b4-9d13-92de9794896d","parts":[{"partNumber":1,"partSize":125437,"offset":0,"url":"http://host.docker.internal:9000/object/data/603d285a-9070-51da-bb9d-d32b3429c9db?uploadId=1c1c9e16-8cf4-45b4-9d13-92de9794896d&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T163731Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518399&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=34aec5e59c03413f512dc5d7dd14b0214e9f3fa4ba6e86bf813ee33ac81cc7a8","md5":null,"sourceMd5":"6bd6da76fb11fd1d0c0be468776d4caa"}],"objectSize":125437,"objectMd5":"6bd6da76fb11fd1d0c0be468776d4caa"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/6b1decda-5b48-5e42-b499-28bad8aa5611.meta b/persistentStorage/data-minio/state/data/6b1decda-5b48-5e42-b499-28bad8aa5611.meta deleted file mode 100644 index 02e82aad..00000000 --- a/persistentStorage/data-minio/state/data/6b1decda-5b48-5e42-b499-28bad8aa5611.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/6b1decda-5b48-5e42-b499-28bad8aa5611","objectId":"6b1decda-5b48-5e42-b499-28bad8aa5611","uploadId":"72e31b01-23f8-4fbf-b834-5c8b5e8cb26e","parts":[{"partNumber":1,"partSize":142,"offset":0,"url":"http://host.docker.internal:9000/object/data/6b1decda-5b48-5e42-b499-28bad8aa5611?uploadId=72e31b01-23f8-4fbf-b834-5c8b5e8cb26e&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T163300Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518400&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=bd55006272dba897e103a04f2eefd5e0a255d7e6ab1aa5c78daaff7d47a0fde2","md5":null,"sourceMd5":"1a3370926a70960735c93f3ccc4e3fa8"}],"objectSize":142,"objectMd5":"1a3370926a70960735c93f3ccc4e3fa8"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/6ba7e370-9833-56b4-aba5-6d9562daa83d.meta b/persistentStorage/data-minio/state/data/6ba7e370-9833-56b4-aba5-6d9562daa83d.meta deleted file mode 100644 index b4d50b1d..00000000 --- a/persistentStorage/data-minio/state/data/6ba7e370-9833-56b4-aba5-6d9562daa83d.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/6ba7e370-9833-56b4-aba5-6d9562daa83d","objectId":"6ba7e370-9833-56b4-aba5-6d9562daa83d","uploadId":"b164d8e8-897a-4068-8925-baee39428e8c","parts":[{"partNumber":1,"partSize":143,"offset":0,"url":"http://host.docker.internal:9000/object/data/6ba7e370-9833-56b4-aba5-6d9562daa83d?uploadId=b164d8e8-897a-4068-8925-baee39428e8c&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T163015Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518400&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=3054639a92ea03d5bbbe821a7ef478e7661841c40e616e6ecfdf0f199a2c9135","md5":null,"sourceMd5":"c719518af10bce03d220bc56c11e970d"}],"objectSize":143,"objectMd5":"c719518af10bce03d220bc56c11e970d"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/726a01c6-a491-5213-9b4a-22a8d431337a.meta b/persistentStorage/data-minio/state/data/726a01c6-a491-5213-9b4a-22a8d431337a.meta deleted file mode 100644 index d473d77f..00000000 --- a/persistentStorage/data-minio/state/data/726a01c6-a491-5213-9b4a-22a8d431337a.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/726a01c6-a491-5213-9b4a-22a8d431337a","objectId":"726a01c6-a491-5213-9b4a-22a8d431337a","uploadId":"86bf9173-8f3d-4d0d-af00-c4cfc59d812e","parts":[{"partNumber":1,"partSize":115987,"offset":0,"url":"http://host.docker.internal:9000/object/data/726a01c6-a491-5213-9b4a-22a8d431337a?uploadId=86bf9173-8f3d-4d0d-af00-c4cfc59d812e&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T162920Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518399&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=a813b8cf00cbfda29bb5e968bcd927e0dc4bd540bc1b33a8241398b44ea61457","md5":null,"sourceMd5":"a259d993349d3a1e285f47414146cda9"}],"objectSize":115987,"objectMd5":"a259d993349d3a1e285f47414146cda9"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/782f544a-be42-5425-9649-44a7523800bc.meta b/persistentStorage/data-minio/state/data/782f544a-be42-5425-9649-44a7523800bc.meta deleted file mode 100644 index 949aa20c..00000000 --- a/persistentStorage/data-minio/state/data/782f544a-be42-5425-9649-44a7523800bc.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/782f544a-be42-5425-9649-44a7523800bc","objectId":"782f544a-be42-5425-9649-44a7523800bc","uploadId":"019ac734-d8b7-4136-bec8-622845c74e84","parts":[{"partNumber":1,"partSize":158,"offset":0,"url":"http://host.docker.internal:9000/object/data/782f544a-be42-5425-9649-44a7523800bc?uploadId=019ac734-d8b7-4136-bec8-622845c74e84&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T163519Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518399&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=10c15cd78ba0b29dee2d8c1556515627b4f26296f4597d7ffab9f41ddb0cc631","md5":null,"sourceMd5":"f3459ce35d70fcf8dc7afe4da93e15af"}],"objectSize":158,"objectMd5":"f3459ce35d70fcf8dc7afe4da93e15af"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/798480ca-3919-5d8b-aa25-37f97115cfb5.meta b/persistentStorage/data-minio/state/data/798480ca-3919-5d8b-aa25-37f97115cfb5.meta deleted file mode 100644 index e9fbf505..00000000 --- a/persistentStorage/data-minio/state/data/798480ca-3919-5d8b-aa25-37f97115cfb5.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/798480ca-3919-5d8b-aa25-37f97115cfb5","objectId":"798480ca-3919-5d8b-aa25-37f97115cfb5","uploadId":"975e8e40-13a2-420f-b177-5f03f8e40c61","parts":[{"partNumber":1,"partSize":150,"offset":0,"url":"http://host.docker.internal:9000/object/data/798480ca-3919-5d8b-aa25-37f97115cfb5?uploadId=975e8e40-13a2-420f-b177-5f03f8e40c61&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T162559Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518400&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=34e6e56e89c752eb7a47b374f58b47e6493eb4a053da480f4d8b9db1c9430d2c","md5":null,"sourceMd5":"f8329c8c667203d98fae606df0400232"}],"objectSize":150,"objectMd5":"f8329c8c667203d98fae606df0400232"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/79f178e4-c033-59c5-82df-c460ec7b19d6.meta b/persistentStorage/data-minio/state/data/79f178e4-c033-59c5-82df-c460ec7b19d6.meta deleted file mode 100644 index 4ab98d1f..00000000 --- a/persistentStorage/data-minio/state/data/79f178e4-c033-59c5-82df-c460ec7b19d6.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/79f178e4-c033-59c5-82df-c460ec7b19d6","objectId":"79f178e4-c033-59c5-82df-c460ec7b19d6","uploadId":"9db9c13d-d5f4-4f59-a35d-d7b6b469e194","parts":[{"partNumber":1,"partSize":125502,"offset":0,"url":"http://host.docker.internal:9000/object/data/79f178e4-c033-59c5-82df-c460ec7b19d6?uploadId=9db9c13d-d5f4-4f59-a35d-d7b6b469e194&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T162700Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518399&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=8d2df4a9c2380b87176057da3bd57e70ea6cdf1adec127575783378fbc943f01","md5":null,"sourceMd5":"ae67942b1efbfcac4491401cf98d50b6"}],"objectSize":125502,"objectMd5":"ae67942b1efbfcac4491401cf98d50b6"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/86105e1b-0b7f-553f-8de5-6a7f28e4d183.meta b/persistentStorage/data-minio/state/data/86105e1b-0b7f-553f-8de5-6a7f28e4d183.meta deleted file mode 100644 index 12f2b3da..00000000 --- a/persistentStorage/data-minio/state/data/86105e1b-0b7f-553f-8de5-6a7f28e4d183.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/86105e1b-0b7f-553f-8de5-6a7f28e4d183","objectId":"86105e1b-0b7f-553f-8de5-6a7f28e4d183","uploadId":"b2d407e3-2a94-4066-b63d-f1ae4787fb15","parts":[{"partNumber":1,"partSize":141,"offset":0,"url":"http://host.docker.internal:9000/object/data/86105e1b-0b7f-553f-8de5-6a7f28e4d183?uploadId=b2d407e3-2a94-4066-b63d-f1ae4787fb15&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T162759Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518400&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=406b7d3ef9a36c8598a611fd16e884479fe5d7d2982f8557e07a30727d24cd8d","md5":null,"sourceMd5":"f6386e770442a795016540f9ff6524b3"}],"objectSize":141,"objectMd5":"f6386e770442a795016540f9ff6524b3"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/8b593ddb-9c57-550d-ae66-8f5122e73de9.meta b/persistentStorage/data-minio/state/data/8b593ddb-9c57-550d-ae66-8f5122e73de9.meta deleted file mode 100644 index 81a4ffcc..00000000 --- a/persistentStorage/data-minio/state/data/8b593ddb-9c57-550d-ae66-8f5122e73de9.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/8b593ddb-9c57-550d-ae66-8f5122e73de9","objectId":"8b593ddb-9c57-550d-ae66-8f5122e73de9","uploadId":"080615da-b998-4a69-b54c-699b7282c039","parts":[{"partNumber":1,"partSize":146,"offset":0,"url":"http://host.docker.internal:9000/object/data/8b593ddb-9c57-550d-ae66-8f5122e73de9?uploadId=080615da-b998-4a69-b54c-699b7282c039&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T163704Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518400&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=eaa4821bd1413394aa34da5fd482c1b8d6187d8416d80284fe9c00dc6a557bce","md5":null,"sourceMd5":"222c2bc2b6a00051183cc4630b3fb6f2"}],"objectSize":146,"objectMd5":"222c2bc2b6a00051183cc4630b3fb6f2"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/8fcf286a-4f81-5c05-9cbd-d4096501779a.meta b/persistentStorage/data-minio/state/data/8fcf286a-4f81-5c05-9cbd-d4096501779a.meta deleted file mode 100644 index 8624b589..00000000 --- a/persistentStorage/data-minio/state/data/8fcf286a-4f81-5c05-9cbd-d4096501779a.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/8fcf286a-4f81-5c05-9cbd-d4096501779a","objectId":"8fcf286a-4f81-5c05-9cbd-d4096501779a","uploadId":"d7f445a5-bc75-491f-81f4-34aaa322802c","parts":[{"partNumber":1,"partSize":53,"offset":0,"url":"http://host.docker.internal:9000/object/data/8fcf286a-4f81-5c05-9cbd-d4096501779a?uploadId=d7f445a5-bc75-491f-81f4-34aaa322802c&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T163418Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518400&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=fe4e571009f42650cb34b304296ba599be0f59cdc2fabc3500ec329687c5bb20","md5":null,"sourceMd5":"3066b32d06be4ac1c5238346e8ad4270"}],"objectSize":53,"objectMd5":"3066b32d06be4ac1c5238346e8ad4270"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/900dd0e0-5f18-51c8-8dc6-a3b91b6acd9c.meta b/persistentStorage/data-minio/state/data/900dd0e0-5f18-51c8-8dc6-a3b91b6acd9c.meta deleted file mode 100644 index ee3d4ff7..00000000 --- a/persistentStorage/data-minio/state/data/900dd0e0-5f18-51c8-8dc6-a3b91b6acd9c.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/900dd0e0-5f18-51c8-8dc6-a3b91b6acd9c","objectId":"900dd0e0-5f18-51c8-8dc6-a3b91b6acd9c","uploadId":"f5dce5d5-7f01-4094-ab66-f7792379e48f","parts":[{"partNumber":1,"partSize":146,"offset":0,"url":"http://host.docker.internal:9000/object/data/900dd0e0-5f18-51c8-8dc6-a3b91b6acd9c?uploadId=f5dce5d5-7f01-4094-ab66-f7792379e48f&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T162834Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518399&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=b69fabe9b91ee7632022e899f54db48b6ab661f1932cfe52887f436e0712afdb","md5":null,"sourceMd5":"8211e43de0e47830a67b016265f21977"}],"objectSize":146,"objectMd5":"8211e43de0e47830a67b016265f21977"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/970c4b15-2ba3-5779-b0cb-f3c88ba3932b.meta b/persistentStorage/data-minio/state/data/970c4b15-2ba3-5779-b0cb-f3c88ba3932b.meta deleted file mode 100644 index baf81231..00000000 --- a/persistentStorage/data-minio/state/data/970c4b15-2ba3-5779-b0cb-f3c88ba3932b.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/970c4b15-2ba3-5779-b0cb-f3c88ba3932b","objectId":"970c4b15-2ba3-5779-b0cb-f3c88ba3932b","uploadId":"652f9439-8938-4bee-9596-2e8148506fcd","parts":[{"partNumber":1,"partSize":142,"offset":0,"url":"http://host.docker.internal:9000/object/data/970c4b15-2ba3-5779-b0cb-f3c88ba3932b?uploadId=652f9439-8938-4bee-9596-2e8148506fcd&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T163826Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518399&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=4489901e79b1dfa5d02aa6025129e4991bedf5138d885146a3afc64ee2e0631b","md5":null,"sourceMd5":"51567d8aaa36ec2093f3f7c5293084e0"}],"objectSize":142,"objectMd5":"51567d8aaa36ec2093f3f7c5293084e0"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/998f068b-0856-539e-86c3-a392e4ea171d.meta b/persistentStorage/data-minio/state/data/998f068b-0856-539e-86c3-a392e4ea171d.meta deleted file mode 100644 index f4a5b964..00000000 --- a/persistentStorage/data-minio/state/data/998f068b-0856-539e-86c3-a392e4ea171d.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/998f068b-0856-539e-86c3-a392e4ea171d","objectId":"998f068b-0856-539e-86c3-a392e4ea171d","uploadId":"c017a784-c8a3-4159-ab85-3655a4617a31","parts":[{"partNumber":1,"partSize":125412,"offset":0,"url":"http://host.docker.internal:9000/object/data/998f068b-0856-539e-86c3-a392e4ea171d?uploadId=c017a784-c8a3-4159-ab85-3655a4617a31&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T163042Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518399&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=f6d5dcaece97612174abbe9150732c6eb8717c282a589eee29e5af634996a366","md5":null,"sourceMd5":"50b5b6b50584e8afeb85e64f86dda864"}],"objectSize":125412,"objectMd5":"50b5b6b50584e8afeb85e64f86dda864"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/9ec6bdd4-1265-5e98-ae1d-57f76abeb483.meta b/persistentStorage/data-minio/state/data/9ec6bdd4-1265-5e98-ae1d-57f76abeb483.meta deleted file mode 100644 index 3d588bd0..00000000 --- a/persistentStorage/data-minio/state/data/9ec6bdd4-1265-5e98-ae1d-57f76abeb483.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/9ec6bdd4-1265-5e98-ae1d-57f76abeb483","objectId":"9ec6bdd4-1265-5e98-ae1d-57f76abeb483","uploadId":"2afb91e1-2556-4c4d-a3ea-3fba7ac219bb","parts":[{"partNumber":1,"partSize":115995,"offset":0,"url":"http://host.docker.internal:9000/object/data/9ec6bdd4-1265-5e98-ae1d-57f76abeb483?uploadId=2afb91e1-2556-4c4d-a3ea-3fba7ac219bb&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T163224Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518400&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=ac3d7fdb5c0adc61d280f9996482f73121658c3064afaabd3d641d5c170db5dd","md5":null,"sourceMd5":"602f723b376324584d6b3b391f65a54c"}],"objectSize":115995,"objectMd5":"602f723b376324584d6b3b391f65a54c"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/a22f4c66-0f46-564b-b2ee-ea46cd18ad98.meta b/persistentStorage/data-minio/state/data/a22f4c66-0f46-564b-b2ee-ea46cd18ad98.meta deleted file mode 100644 index e225203d..00000000 --- a/persistentStorage/data-minio/state/data/a22f4c66-0f46-564b-b2ee-ea46cd18ad98.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/a22f4c66-0f46-564b-b2ee-ea46cd18ad98","objectId":"a22f4c66-0f46-564b-b2ee-ea46cd18ad98","uploadId":"431a11b1-fed2-4e82-b388-273d932047f1","parts":[{"partNumber":1,"partSize":150,"offset":0,"url":"http://host.docker.internal:9000/object/data/a22f4c66-0f46-564b-b2ee-ea46cd18ad98?uploadId=431a11b1-fed2-4e82-b388-273d932047f1&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T163325Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518399&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=a334a07fca6a0c8a83bf6b9af60b87c71fdd54f4c410daa47ccc70030709e9e1","md5":null,"sourceMd5":"20de00567d1ae550f4b6ad894b817c12"}],"objectSize":150,"objectMd5":"20de00567d1ae550f4b6ad894b817c12"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/a2c664fb-6e1a-554f-9c40-351998586f24.meta b/persistentStorage/data-minio/state/data/a2c664fb-6e1a-554f-9c40-351998586f24.meta deleted file mode 100644 index ccdf0c72..00000000 --- a/persistentStorage/data-minio/state/data/a2c664fb-6e1a-554f-9c40-351998586f24.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/a2c664fb-6e1a-554f-9c40-351998586f24","objectId":"a2c664fb-6e1a-554f-9c40-351998586f24","uploadId":"0934238e-6b6a-4783-a657-9e91e9c699b2","parts":[{"partNumber":1,"partSize":53,"offset":0,"url":"http://host.docker.internal:9000/object/data/a2c664fb-6e1a-554f-9c40-351998586f24?uploadId=0934238e-6b6a-4783-a657-9e91e9c699b2&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T163228Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518400&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=bfe1c8da104a4a9f7195ea466d255d5f74d15687d2e2c749b5693fd34b0a09a9","md5":null,"sourceMd5":"e8791a99c428c09f1ea9b6e2a1b6df0e"}],"objectSize":53,"objectMd5":"e8791a99c428c09f1ea9b6e2a1b6df0e"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/a36547ca-da4a-5591-a0fc-4e11e03a829c.meta b/persistentStorage/data-minio/state/data/a36547ca-da4a-5591-a0fc-4e11e03a829c.meta deleted file mode 100644 index f71758aa..00000000 --- a/persistentStorage/data-minio/state/data/a36547ca-da4a-5591-a0fc-4e11e03a829c.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/a36547ca-da4a-5591-a0fc-4e11e03a829c","objectId":"a36547ca-da4a-5591-a0fc-4e11e03a829c","uploadId":"f256f545-dfff-482c-82d6-ee8354d4d4f5","parts":[{"partNumber":1,"partSize":27160,"offset":0,"url":"http://host.docker.internal:9000/object/data/a36547ca-da4a-5591-a0fc-4e11e03a829c?uploadId=f256f545-dfff-482c-82d6-ee8354d4d4f5&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T162732Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518399&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=1382fb28b666acd9591be709baa690853b3fbddd3605de32ef77e20c3e837756","md5":null,"sourceMd5":"dd2b54ec315db4ef29ffeec3777fc8a0"}],"objectSize":27160,"objectMd5":"dd2b54ec315db4ef29ffeec3777fc8a0"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/a9e44028-6858-5e85-96eb-c57873da6658.meta b/persistentStorage/data-minio/state/data/a9e44028-6858-5e85-96eb-c57873da6658.meta deleted file mode 100644 index 467dd936..00000000 --- a/persistentStorage/data-minio/state/data/a9e44028-6858-5e85-96eb-c57873da6658.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/a9e44028-6858-5e85-96eb-c57873da6658","objectId":"a9e44028-6858-5e85-96eb-c57873da6658","uploadId":"2e98d877-defd-46d4-8936-9671afe5a34b","parts":[{"partNumber":1,"partSize":115973,"offset":0,"url":"http://host.docker.internal:9000/object/data/a9e44028-6858-5e85-96eb-c57873da6658?uploadId=2e98d877-defd-46d4-8936-9671afe5a34b&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T162855Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518399&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=6140e42c7db2f17b8e6579f70aa785fdc4fc5fd74bff5da0ed83cc3d0b7e073f","md5":null,"sourceMd5":"c852b26260bb6e80918e5b35f4a7c101"}],"objectSize":115973,"objectMd5":"c852b26260bb6e80918e5b35f4a7c101"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/ae23ca2d-d8f8-5e05-bdac-c9e0ec1bd275.meta b/persistentStorage/data-minio/state/data/ae23ca2d-d8f8-5e05-bdac-c9e0ec1bd275.meta deleted file mode 100644 index a417b170..00000000 --- a/persistentStorage/data-minio/state/data/ae23ca2d-d8f8-5e05-bdac-c9e0ec1bd275.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/ae23ca2d-d8f8-5e05-bdac-c9e0ec1bd275","objectId":"ae23ca2d-d8f8-5e05-bdac-c9e0ec1bd275","uploadId":"154ec173-413a-4175-b200-70bedd1c6b6e","parts":[{"partNumber":1,"partSize":115958,"offset":0,"url":"http://host.docker.internal:9000/object/data/ae23ca2d-d8f8-5e05-bdac-c9e0ec1bd275?uploadId=154ec173-413a-4175-b200-70bedd1c6b6e&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T163415Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518399&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=3a6cc3227fdbd2d521bbb3a4fd2d43cc1148432b7891ae5203c19e54975255f5","md5":null,"sourceMd5":"7ecf7ab47df62450fedc0d365b33b76a"}],"objectSize":115958,"objectMd5":"7ecf7ab47df62450fedc0d365b33b76a"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/b00c7461-46bb-57e3-918f-4592cb32df23.meta b/persistentStorage/data-minio/state/data/b00c7461-46bb-57e3-918f-4592cb32df23.meta deleted file mode 100644 index 1e106d2a..00000000 --- a/persistentStorage/data-minio/state/data/b00c7461-46bb-57e3-918f-4592cb32df23.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/b00c7461-46bb-57e3-918f-4592cb32df23","objectId":"b00c7461-46bb-57e3-918f-4592cb32df23","uploadId":"2b41df4f-2acf-4da4-8c1c-8f16d458d464","parts":[{"partNumber":1,"partSize":27280,"offset":0,"url":"http://host.docker.internal:9000/object/data/b00c7461-46bb-57e3-918f-4592cb32df23?uploadId=2b41df4f-2acf-4da4-8c1c-8f16d458d464&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T163612Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518399&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=d289a5e22b113996bf06d5cd1905e0b18be6428cbd3d26c8138060557ea83310","md5":null,"sourceMd5":"98bcf6ebd70311cb260e8555ce80466c"}],"objectSize":27280,"objectMd5":"98bcf6ebd70311cb260e8555ce80466c"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/b08d8ad0-1dfc-5559-9233-b78091fff52f.meta b/persistentStorage/data-minio/state/data/b08d8ad0-1dfc-5559-9233-b78091fff52f.meta deleted file mode 100644 index db96287d..00000000 --- a/persistentStorage/data-minio/state/data/b08d8ad0-1dfc-5559-9233-b78091fff52f.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/b08d8ad0-1dfc-5559-9233-b78091fff52f","objectId":"b08d8ad0-1dfc-5559-9233-b78091fff52f","uploadId":"a6a6bd5a-2312-4fb9-8da4-d3be8a6882ce","parts":[{"partNumber":1,"partSize":17246,"offset":0,"url":"http://host.docker.internal:9000/object/data/b08d8ad0-1dfc-5559-9233-b78091fff52f?uploadId=a6a6bd5a-2312-4fb9-8da4-d3be8a6882ce&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T162945Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518400&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=513d29129c2830a4e972e45fad753a3d0b7c4f907ae28c570c9152016aa4d62d","md5":null,"sourceMd5":"c5aa0b57090c2179430491ca652e5ef8"}],"objectSize":17246,"objectMd5":"c5aa0b57090c2179430491ca652e5ef8"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/b2d7d5be-d3bd-5cdd-b4d0-924cf4236212.meta b/persistentStorage/data-minio/state/data/b2d7d5be-d3bd-5cdd-b4d0-924cf4236212.meta deleted file mode 100644 index 4fa6082a..00000000 --- a/persistentStorage/data-minio/state/data/b2d7d5be-d3bd-5cdd-b4d0-924cf4236212.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/b2d7d5be-d3bd-5cdd-b4d0-924cf4236212","objectId":"b2d7d5be-d3bd-5cdd-b4d0-924cf4236212","uploadId":"751f42dc-0b94-4cf4-a041-d8384385e1a6","parts":[{"partNumber":1,"partSize":144,"offset":0,"url":"http://host.docker.internal:9000/object/data/b2d7d5be-d3bd-5cdd-b4d0-924cf4236212?uploadId=751f42dc-0b94-4cf4-a041-d8384385e1a6&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T162503Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518399&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=aac7ca5de1f673e7471a3bcb5f0b9a4c7177e548bf845ea39b267b8a754f225a","md5":null,"sourceMd5":"e4d3b0751f2824bac22f42147dd41fd8"}],"objectSize":144,"objectMd5":"e4d3b0751f2824bac22f42147dd41fd8"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/b2dec936-af54-5b2c-9ab9-7502b94191d0.meta b/persistentStorage/data-minio/state/data/b2dec936-af54-5b2c-9ab9-7502b94191d0.meta deleted file mode 100644 index ee5bf70c..00000000 --- a/persistentStorage/data-minio/state/data/b2dec936-af54-5b2c-9ab9-7502b94191d0.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/b2dec936-af54-5b2c-9ab9-7502b94191d0","objectId":"b2dec936-af54-5b2c-9ab9-7502b94191d0","uploadId":"6b7eda13-fa41-49e3-a30a-c4d6773daece","parts":[{"partNumber":1,"partSize":17248,"offset":0,"url":"http://host.docker.internal:9000/object/data/b2dec936-af54-5b2c-9ab9-7502b94191d0?uploadId=6b7eda13-fa41-49e3-a30a-c4d6773daece&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T163634Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518400&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=bbfb3455d8fded77f96dd10d7cb191faf32a1397554eac0582845fd0983f4ec7","md5":null,"sourceMd5":"b1f642c5cdf743b068379a03939a2512"}],"objectSize":17248,"objectMd5":"b1f642c5cdf743b068379a03939a2512"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/b4b672be-f917-504b-b4e3-c4d6d580af06.meta b/persistentStorage/data-minio/state/data/b4b672be-f917-504b-b4e3-c4d6d580af06.meta deleted file mode 100644 index e3b5fe32..00000000 --- a/persistentStorage/data-minio/state/data/b4b672be-f917-504b-b4e3-c4d6d580af06.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/b4b672be-f917-504b-b4e3-c4d6d580af06","objectId":"b4b672be-f917-504b-b4e3-c4d6d580af06","uploadId":"f6e2b69a-c770-4475-894d-bfeecfcc2f26","parts":[{"partNumber":1,"partSize":17248,"offset":0,"url":"http://host.docker.internal:9000/object/data/b4b672be-f917-504b-b4e3-c4d6d580af06?uploadId=f6e2b69a-c770-4475-894d-bfeecfcc2f26&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T162755Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518399&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=01527e3c504c9541175632e9b5b237fdddfefe394a89e8e9e97c2c401c4155c7","md5":null,"sourceMd5":"e6c73525fff2192be7df534ca6d8a8bb"}],"objectSize":17248,"objectMd5":"e6c73525fff2192be7df534ca6d8a8bb"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/b8cdb477-995e-55cc-88ce-3e1f9b0de1d9.meta b/persistentStorage/data-minio/state/data/b8cdb477-995e-55cc-88ce-3e1f9b0de1d9.meta deleted file mode 100644 index 06c00996..00000000 --- a/persistentStorage/data-minio/state/data/b8cdb477-995e-55cc-88ce-3e1f9b0de1d9.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/b8cdb477-995e-55cc-88ce-3e1f9b0de1d9","objectId":"b8cdb477-995e-55cc-88ce-3e1f9b0de1d9","uploadId":"84eb07e3-7fc3-4b9b-833c-e9bda06a53a1","parts":[{"partNumber":1,"partSize":17318,"offset":0,"url":"http://host.docker.internal:9000/object/data/b8cdb477-995e-55cc-88ce-3e1f9b0de1d9?uploadId=84eb07e3-7fc3-4b9b-833c-e9bda06a53a1&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T163256Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518399&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=3e392ef9297cc0403107cb72b887ab38cc1e4356e3033d346a3d2d1fe198713b","md5":null,"sourceMd5":"4d42c0db3a1b64682bb2a992a7d90fce"}],"objectSize":17318,"objectMd5":"4d42c0db3a1b64682bb2a992a7d90fce"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/bba25936-6d51-5b24-be2c-6af6d462c434.meta b/persistentStorage/data-minio/state/data/bba25936-6d51-5b24-be2c-6af6d462c434.meta deleted file mode 100644 index 54c2b8d2..00000000 --- a/persistentStorage/data-minio/state/data/bba25936-6d51-5b24-be2c-6af6d462c434.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/bba25936-6d51-5b24-be2c-6af6d462c434","objectId":"bba25936-6d51-5b24-be2c-6af6d462c434","uploadId":"68e69c7a-14d3-4627-9606-e78e89918e83","parts":[{"partNumber":1,"partSize":17292,"offset":0,"url":"http://host.docker.internal:9000/object/data/bba25936-6d51-5b24-be2c-6af6d462c434?uploadId=68e69c7a-14d3-4627-9606-e78e89918e83&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T163821Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518399&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=6062baa4183c65a21e60303e5f5a0dd79c7b97df3d9bd0016777e0d1c34a5517","md5":null,"sourceMd5":"ebec6c266ba376c11a97cca3a3180d49"}],"objectSize":17292,"objectMd5":"ebec6c266ba376c11a97cca3a3180d49"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/bf14635d-e43e-5dfd-b977-f2735e98f7e3.meta b/persistentStorage/data-minio/state/data/bf14635d-e43e-5dfd-b977-f2735e98f7e3.meta deleted file mode 100644 index 61611eac..00000000 --- a/persistentStorage/data-minio/state/data/bf14635d-e43e-5dfd-b977-f2735e98f7e3.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/bf14635d-e43e-5dfd-b977-f2735e98f7e3","objectId":"bf14635d-e43e-5dfd-b977-f2735e98f7e3","uploadId":"c72e583e-f557-431a-a945-e93007a1c85c","parts":[{"partNumber":1,"partSize":17322,"offset":0,"url":"http://host.docker.internal:9000/object/data/bf14635d-e43e-5dfd-b977-f2735e98f7e3?uploadId=c72e583e-f557-431a-a945-e93007a1c85c&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T163756Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518400&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=b06fc25c1729b02d5f11db0048bf2dd522ae7f29fb70dc6fcc6f3aadcb55fbf8","md5":null,"sourceMd5":"51b47fe36f87185ab15fe84cfb4fcb81"}],"objectSize":17322,"objectMd5":"51b47fe36f87185ab15fe84cfb4fcb81"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/c0ecacdb-92c1-5e37-b949-24e9acfb50e2.meta b/persistentStorage/data-minio/state/data/c0ecacdb-92c1-5e37-b949-24e9acfb50e2.meta deleted file mode 100644 index 8c8b6384..00000000 --- a/persistentStorage/data-minio/state/data/c0ecacdb-92c1-5e37-b949-24e9acfb50e2.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/c0ecacdb-92c1-5e37-b949-24e9acfb50e2","objectId":"c0ecacdb-92c1-5e37-b949-24e9acfb50e2","uploadId":"38a4dbc5-fe96-4eea-9484-526848a3e3e7","parts":[{"partNumber":1,"partSize":17314,"offset":0,"url":"http://host.docker.internal:9000/object/data/c0ecacdb-92c1-5e37-b949-24e9acfb50e2?uploadId=38a4dbc5-fe96-4eea-9484-526848a3e3e7&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T162555Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518400&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=499bc4bf2c3d94fd737e14759634244783cf94bccbd8dbd9aef1c4e75ff54033","md5":null,"sourceMd5":"df0fd6e0bd5e9a79f54e120bdbc82c5c"}],"objectSize":17314,"objectMd5":"df0fd6e0bd5e9a79f54e120bdbc82c5c"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/d52ad945-1f3b-54d9-b3c9-45a17c5db655.meta b/persistentStorage/data-minio/state/data/d52ad945-1f3b-54d9-b3c9-45a17c5db655.meta deleted file mode 100644 index ab13162f..00000000 --- a/persistentStorage/data-minio/state/data/d52ad945-1f3b-54d9-b3c9-45a17c5db655.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/d52ad945-1f3b-54d9-b3c9-45a17c5db655","objectId":"d52ad945-1f3b-54d9-b3c9-45a17c5db655","uploadId":"7f10c2b3-d8be-4edb-967b-2896882ab3e8","parts":[{"partNumber":1,"partSize":148,"offset":0,"url":"http://host.docker.internal:9000/object/data/d52ad945-1f3b-54d9-b3c9-45a17c5db655?uploadId=7f10c2b3-d8be-4edb-967b-2896882ab3e8&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T163638Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518400&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=ba4c61fe089fa2a0af719b52170a29259dcb8ce1ee33495270c3c9d7f404a97d","md5":null,"sourceMd5":"75f26b946ad64977b1148f08f33a26b3"}],"objectSize":148,"objectMd5":"75f26b946ad64977b1148f08f33a26b3"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/deaeaa56-c56d-54ee-ad75-f5b90bb7eda6.meta b/persistentStorage/data-minio/state/data/deaeaa56-c56d-54ee-ad75-f5b90bb7eda6.meta deleted file mode 100644 index 608dc88e..00000000 --- a/persistentStorage/data-minio/state/data/deaeaa56-c56d-54ee-ad75-f5b90bb7eda6.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/deaeaa56-c56d-54ee-ad75-f5b90bb7eda6","objectId":"deaeaa56-c56d-54ee-ad75-f5b90bb7eda6","uploadId":"d0f96e3c-06ce-4e90-b65c-4e2a30753cb3","parts":[{"partNumber":1,"partSize":148,"offset":0,"url":"http://host.docker.internal:9000/object/data/deaeaa56-c56d-54ee-ad75-f5b90bb7eda6?uploadId=d0f96e3c-06ce-4e90-b65c-4e2a30753cb3&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T162533Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518400&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=0550068594489dc106f1ba38c46c60d640d6f32856715d875faf1379339800c4","md5":null,"sourceMd5":"ae025b596b2fb562d33073338eb23a7d"}],"objectSize":148,"objectMd5":"ae025b596b2fb562d33073338eb23a7d"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/e3ef7c5a-244e-5323-acd0-94d66c2f0125.meta b/persistentStorage/data-minio/state/data/e3ef7c5a-244e-5323-acd0-94d66c2f0125.meta deleted file mode 100644 index 886ec162..00000000 --- a/persistentStorage/data-minio/state/data/e3ef7c5a-244e-5323-acd0-94d66c2f0125.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/e3ef7c5a-244e-5323-acd0-94d66c2f0125","objectId":"e3ef7c5a-244e-5323-acd0-94d66c2f0125","uploadId":"a6c4f93c-1363-47ec-a88a-7532489906a0","parts":[{"partNumber":1,"partSize":17360,"offset":0,"url":"http://host.docker.internal:9000/object/data/e3ef7c5a-244e-5323-acd0-94d66c2f0125?uploadId=a6c4f93c-1363-47ec-a88a-7532489906a0&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T163133Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518400&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=41f2c7ea003bfe48258474e50ab23905508c891b6ed88921c823e0542a949fcf","md5":null,"sourceMd5":"3a1b62929d0b9762fa72e5c7d99456b7"}],"objectSize":17360,"objectMd5":"3a1b62929d0b9762fa72e5c7d99456b7"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/e45bed7a-552d-5076-9507-405c51b2f196.meta b/persistentStorage/data-minio/state/data/e45bed7a-552d-5076-9507-405c51b2f196.meta deleted file mode 100644 index 8105c38b..00000000 --- a/persistentStorage/data-minio/state/data/e45bed7a-552d-5076-9507-405c51b2f196.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/e45bed7a-552d-5076-9507-405c51b2f196","objectId":"e45bed7a-552d-5076-9507-405c51b2f196","uploadId":"30d41de6-9186-4c20-b399-1f80e9f225ca","parts":[{"partNumber":1,"partSize":125371,"offset":0,"url":"http://host.docker.internal:9000/object/data/e45bed7a-552d-5076-9507-405c51b2f196?uploadId=30d41de6-9186-4c20-b399-1f80e9f225ca&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T163440Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518400&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=2365a27939d2f22c7397dc7ebddccc46026dc13b62791d3e6f81c5d772124920","md5":null,"sourceMd5":"a420e75cf90ea41f20f79873357a44e0"}],"objectSize":125371,"objectMd5":"a420e75cf90ea41f20f79873357a44e0"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/e9e7922a-a102-5381-be8f-b020e6045877.meta b/persistentStorage/data-minio/state/data/e9e7922a-a102-5381-be8f-b020e6045877.meta deleted file mode 100644 index d4143038..00000000 --- a/persistentStorage/data-minio/state/data/e9e7922a-a102-5381-be8f-b020e6045877.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/e9e7922a-a102-5381-be8f-b020e6045877","objectId":"e9e7922a-a102-5381-be8f-b020e6045877","uploadId":"5561688a-9eb2-433c-a165-39c376c6faee","parts":[{"partNumber":1,"partSize":17405,"offset":0,"url":"http://host.docker.internal:9000/object/data/e9e7922a-a102-5381-be8f-b020e6045877?uploadId=5561688a-9eb2-433c-a165-39c376c6faee&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T163108Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518399&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=40159c28e2411830b7d208c6c51c2709c5668ffb48fc4f9b831b8f5cc55f13af","md5":null,"sourceMd5":"b32991cae3845c0b38ff42dc6179a5c1"}],"objectSize":17405,"objectMd5":"b32991cae3845c0b38ff42dc6179a5c1"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/f701f36d-c795-5dd4-9e4c-e9c33a9dd284.meta b/persistentStorage/data-minio/state/data/f701f36d-c795-5dd4-9e4c-e9c33a9dd284.meta deleted file mode 100644 index f676c589..00000000 --- a/persistentStorage/data-minio/state/data/f701f36d-c795-5dd4-9e4c-e9c33a9dd284.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/f701f36d-c795-5dd4-9e4c-e9c33a9dd284","objectId":"f701f36d-c795-5dd4-9e4c-e9c33a9dd284","uploadId":"ec91188b-ca2b-4a5d-ada8-ef11764ec98b","parts":[{"partNumber":1,"partSize":52,"offset":0,"url":"http://host.docker.internal:9000/object/data/f701f36d-c795-5dd4-9e4c-e9c33a9dd284?uploadId=ec91188b-ca2b-4a5d-ada8-ef11764ec98b&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T163351Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518400&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=bf1175da7d422943e023cd05db6532b5eff725a98cd5e6c15d69ccd85713adff","md5":null,"sourceMd5":"114d6d5a7568666bb5fe3b365197f137"}],"objectSize":52,"objectMd5":"114d6d5a7568666bb5fe3b365197f137"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/f99fe6f8-10b6-5989-ba33-92c7a3527476.meta b/persistentStorage/data-minio/state/data/f99fe6f8-10b6-5989-ba33-92c7a3527476.meta deleted file mode 100644 index d6133393..00000000 --- a/persistentStorage/data-minio/state/data/f99fe6f8-10b6-5989-ba33-92c7a3527476.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/f99fe6f8-10b6-5989-ba33-92c7a3527476","objectId":"f99fe6f8-10b6-5989-ba33-92c7a3527476","uploadId":"43d04a1b-022f-452d-9324-5d76a9943e65","parts":[{"partNumber":1,"partSize":27256,"offset":0,"url":"http://host.docker.internal:9000/object/data/f99fe6f8-10b6-5989-ba33-92c7a3527476?uploadId=43d04a1b-022f-452d-9324-5d76a9943e65&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T163445Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518399&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=97d9f747c1160be199a86ed3b6743a024878b0b8a74484f62bf3796e3faf56d0","md5":null,"sourceMd5":"261b232a0c997eb4972f9b5f7b29f840"}],"objectSize":27256,"objectMd5":"261b232a0c997eb4972f9b5f7b29f840"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/fa6ed231-77fe-5b2b-8df4-f32f8d526208.meta b/persistentStorage/data-minio/state/data/fa6ed231-77fe-5b2b-8df4-f32f8d526208.meta deleted file mode 100644 index f306e4fd..00000000 --- a/persistentStorage/data-minio/state/data/fa6ed231-77fe-5b2b-8df4-f32f8d526208.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/fa6ed231-77fe-5b2b-8df4-f32f8d526208","objectId":"fa6ed231-77fe-5b2b-8df4-f32f8d526208","uploadId":"8233456f-e751-4f7f-ba9e-cd7a1dafd615","parts":[{"partNumber":1,"partSize":17380,"offset":0,"url":"http://host.docker.internal:9000/object/data/fa6ed231-77fe-5b2b-8df4-f32f8d526208?uploadId=8233456f-e751-4f7f-ba9e-cd7a1dafd615&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T162633Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518400&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=f9dd5e38af801fb77c92eff6d74aa3958910a1f634d6dec5af7e76f8b195715f","md5":null,"sourceMd5":"d713f83a36ff6d95a49268905b8a0206"}],"objectSize":17380,"objectMd5":"d713f83a36ff6d95a49268905b8a0206"} \ No newline at end of file diff --git a/persistentStorage/data-minio/state/data/ff7b8ca2-2b43-5503-b407-35dc8b0591b0.meta b/persistentStorage/data-minio/state/data/ff7b8ca2-2b43-5503-b407-35dc8b0591b0.meta deleted file mode 100644 index aafb8d69..00000000 --- a/persistentStorage/data-minio/state/data/ff7b8ca2-2b43-5503-b407-35dc8b0591b0.meta +++ /dev/null @@ -1 +0,0 @@ -{"objectKey":"data/ff7b8ca2-2b43-5503-b407-35dc8b0591b0","objectId":"ff7b8ca2-2b43-5503-b407-35dc8b0591b0","uploadId":"f17c80af-fbe5-4ce4-baa9-82f5140c924a","parts":[{"partNumber":1,"partSize":125255,"offset":0,"url":"http://host.docker.internal:9000/object/data/ff7b8ca2-2b43-5503-b407-35dc8b0591b0?uploadId=f17c80af-fbe5-4ce4-baa9-82f5140c924a&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240704T162728Z&X-Amz-SignedHeaders=host&X-Amz-Expires=518399&X-Amz-Credential=admin%2F20240704%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=caa60b9f110d137479a647506d1aa3148e456a751a8d3147b5cd5afc11455e52","md5":null,"sourceMd5":"7df44e073f73923d05893764889039d2"}],"objectSize":125255,"objectMd5":"7df44e073f73923d05893764889039d2"} \ No newline at end of file diff --git a/persistentStorage/data-song-db/PG_VERSION b/persistentStorage/data-song-db/PG_VERSION deleted file mode 100644 index b4de3947..00000000 --- a/persistentStorage/data-song-db/PG_VERSION +++ /dev/null @@ -1 +0,0 @@ -11 diff --git a/persistentStorage/data-song-db/base/1/112 b/persistentStorage/data-song-db/base/1/112 deleted file mode 100644 index 4667847b..00000000 Binary files a/persistentStorage/data-song-db/base/1/112 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/113 b/persistentStorage/data-song-db/base/1/113 deleted file mode 100644 index 99d1648e..00000000 Binary files a/persistentStorage/data-song-db/base/1/113 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/1247 b/persistentStorage/data-song-db/base/1/1247 deleted file mode 100644 index c4062a4d..00000000 Binary files a/persistentStorage/data-song-db/base/1/1247 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/1247_fsm b/persistentStorage/data-song-db/base/1/1247_fsm deleted file mode 100644 index f082f631..00000000 Binary files a/persistentStorage/data-song-db/base/1/1247_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/1247_vm b/persistentStorage/data-song-db/base/1/1247_vm deleted file mode 100644 index 06b36841..00000000 Binary files a/persistentStorage/data-song-db/base/1/1247_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/1249 b/persistentStorage/data-song-db/base/1/1249 deleted file mode 100644 index 0a5d1110..00000000 Binary files a/persistentStorage/data-song-db/base/1/1249 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/1249_fsm b/persistentStorage/data-song-db/base/1/1249_fsm deleted file mode 100644 index 2be958d7..00000000 Binary files a/persistentStorage/data-song-db/base/1/1249_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/1249_vm b/persistentStorage/data-song-db/base/1/1249_vm deleted file mode 100644 index efb6e3d2..00000000 Binary files a/persistentStorage/data-song-db/base/1/1249_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/1255 b/persistentStorage/data-song-db/base/1/1255 deleted file mode 100644 index a15c41f0..00000000 Binary files a/persistentStorage/data-song-db/base/1/1255 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/1255_fsm b/persistentStorage/data-song-db/base/1/1255_fsm deleted file mode 100644 index dde16352..00000000 Binary files a/persistentStorage/data-song-db/base/1/1255_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/1255_vm b/persistentStorage/data-song-db/base/1/1255_vm deleted file mode 100644 index 66cf3a9b..00000000 Binary files a/persistentStorage/data-song-db/base/1/1255_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/1259 b/persistentStorage/data-song-db/base/1/1259 deleted file mode 100644 index 4339d8ba..00000000 Binary files a/persistentStorage/data-song-db/base/1/1259 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/1259_fsm b/persistentStorage/data-song-db/base/1/1259_fsm deleted file mode 100644 index 9cba2542..00000000 Binary files a/persistentStorage/data-song-db/base/1/1259_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/1259_vm b/persistentStorage/data-song-db/base/1/1259_vm deleted file mode 100644 index a046d262..00000000 Binary files a/persistentStorage/data-song-db/base/1/1259_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/12902 b/persistentStorage/data-song-db/base/1/12902 deleted file mode 100644 index d298c664..00000000 Binary files a/persistentStorage/data-song-db/base/1/12902 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/12902_fsm b/persistentStorage/data-song-db/base/1/12902_fsm deleted file mode 100644 index 19948ba3..00000000 Binary files a/persistentStorage/data-song-db/base/1/12902_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/12902_vm b/persistentStorage/data-song-db/base/1/12902_vm deleted file mode 100644 index e024e219..00000000 Binary files a/persistentStorage/data-song-db/base/1/12902_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/12904 b/persistentStorage/data-song-db/base/1/12904 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/12906 b/persistentStorage/data-song-db/base/1/12906 deleted file mode 100644 index eaaf7f9c..00000000 Binary files a/persistentStorage/data-song-db/base/1/12906 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/12907 b/persistentStorage/data-song-db/base/1/12907 deleted file mode 100644 index 39eb183c..00000000 Binary files a/persistentStorage/data-song-db/base/1/12907 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/12907_fsm b/persistentStorage/data-song-db/base/1/12907_fsm deleted file mode 100644 index ce7c26eb..00000000 Binary files a/persistentStorage/data-song-db/base/1/12907_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/12907_vm b/persistentStorage/data-song-db/base/1/12907_vm deleted file mode 100644 index 7f46a300..00000000 Binary files a/persistentStorage/data-song-db/base/1/12907_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/12909 b/persistentStorage/data-song-db/base/1/12909 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/12911 b/persistentStorage/data-song-db/base/1/12911 deleted file mode 100644 index 24ec5ac2..00000000 Binary files a/persistentStorage/data-song-db/base/1/12911 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/12912 b/persistentStorage/data-song-db/base/1/12912 deleted file mode 100644 index b0d3e632..00000000 Binary files a/persistentStorage/data-song-db/base/1/12912 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/12912_fsm b/persistentStorage/data-song-db/base/1/12912_fsm deleted file mode 100644 index 98dc620a..00000000 Binary files a/persistentStorage/data-song-db/base/1/12912_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/12912_vm b/persistentStorage/data-song-db/base/1/12912_vm deleted file mode 100644 index 754665b0..00000000 Binary files a/persistentStorage/data-song-db/base/1/12912_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/12914 b/persistentStorage/data-song-db/base/1/12914 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/12916 b/persistentStorage/data-song-db/base/1/12916 deleted file mode 100644 index 911c123e..00000000 Binary files a/persistentStorage/data-song-db/base/1/12916 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/12917 b/persistentStorage/data-song-db/base/1/12917 deleted file mode 100644 index 75b5dc26..00000000 Binary files a/persistentStorage/data-song-db/base/1/12917 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/12917_fsm b/persistentStorage/data-song-db/base/1/12917_fsm deleted file mode 100644 index f8a0e258..00000000 Binary files a/persistentStorage/data-song-db/base/1/12917_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/12917_vm b/persistentStorage/data-song-db/base/1/12917_vm deleted file mode 100644 index 999ef8c0..00000000 Binary files a/persistentStorage/data-song-db/base/1/12917_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/12919 b/persistentStorage/data-song-db/base/1/12919 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/12921 b/persistentStorage/data-song-db/base/1/12921 deleted file mode 100644 index 7692fb50..00000000 Binary files a/persistentStorage/data-song-db/base/1/12921 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/12922 b/persistentStorage/data-song-db/base/1/12922 deleted file mode 100644 index 70ef93a9..00000000 Binary files a/persistentStorage/data-song-db/base/1/12922 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/12922_fsm b/persistentStorage/data-song-db/base/1/12922_fsm deleted file mode 100644 index ecbfaee5..00000000 Binary files a/persistentStorage/data-song-db/base/1/12922_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/12922_vm b/persistentStorage/data-song-db/base/1/12922_vm deleted file mode 100644 index 031bad16..00000000 Binary files a/persistentStorage/data-song-db/base/1/12922_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/12924 b/persistentStorage/data-song-db/base/1/12924 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/12926 b/persistentStorage/data-song-db/base/1/12926 deleted file mode 100644 index 0bd7b2a1..00000000 Binary files a/persistentStorage/data-song-db/base/1/12926 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/12927 b/persistentStorage/data-song-db/base/1/12927 deleted file mode 100644 index 81d71b93..00000000 Binary files a/persistentStorage/data-song-db/base/1/12927 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/12927_fsm b/persistentStorage/data-song-db/base/1/12927_fsm deleted file mode 100644 index a836ddf7..00000000 Binary files a/persistentStorage/data-song-db/base/1/12927_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/12927_vm b/persistentStorage/data-song-db/base/1/12927_vm deleted file mode 100644 index dbff9bc0..00000000 Binary files a/persistentStorage/data-song-db/base/1/12927_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/12929 b/persistentStorage/data-song-db/base/1/12929 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/12931 b/persistentStorage/data-song-db/base/1/12931 deleted file mode 100644 index 39e60ec0..00000000 Binary files a/persistentStorage/data-song-db/base/1/12931 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/12932 b/persistentStorage/data-song-db/base/1/12932 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/12934 b/persistentStorage/data-song-db/base/1/12934 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/12936 b/persistentStorage/data-song-db/base/1/12936 deleted file mode 100644 index 5d072ab6..00000000 Binary files a/persistentStorage/data-song-db/base/1/12936 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/1417 b/persistentStorage/data-song-db/base/1/1417 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/1417_vm b/persistentStorage/data-song-db/base/1/1417_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/1418 b/persistentStorage/data-song-db/base/1/1418 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/1418_vm b/persistentStorage/data-song-db/base/1/1418_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/174 b/persistentStorage/data-song-db/base/1/174 deleted file mode 100644 index b0f68c81..00000000 Binary files a/persistentStorage/data-song-db/base/1/174 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/175 b/persistentStorage/data-song-db/base/1/175 deleted file mode 100644 index 09f50ec8..00000000 Binary files a/persistentStorage/data-song-db/base/1/175 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2187 b/persistentStorage/data-song-db/base/1/2187 deleted file mode 100644 index b759e4fb..00000000 Binary files a/persistentStorage/data-song-db/base/1/2187 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2224 b/persistentStorage/data-song-db/base/1/2224 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/2224_vm b/persistentStorage/data-song-db/base/1/2224_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/2328 b/persistentStorage/data-song-db/base/1/2328 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/2328_vm b/persistentStorage/data-song-db/base/1/2328_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/2336 b/persistentStorage/data-song-db/base/1/2336 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/2336_vm b/persistentStorage/data-song-db/base/1/2336_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/2337 b/persistentStorage/data-song-db/base/1/2337 deleted file mode 100644 index ee992828..00000000 Binary files a/persistentStorage/data-song-db/base/1/2337 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2579 b/persistentStorage/data-song-db/base/1/2579 deleted file mode 100644 index f256cc4b..00000000 Binary files a/persistentStorage/data-song-db/base/1/2579 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2600 b/persistentStorage/data-song-db/base/1/2600 deleted file mode 100644 index ffdfb66d..00000000 Binary files a/persistentStorage/data-song-db/base/1/2600 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2600_fsm b/persistentStorage/data-song-db/base/1/2600_fsm deleted file mode 100644 index e63ffab3..00000000 Binary files a/persistentStorage/data-song-db/base/1/2600_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2600_vm b/persistentStorage/data-song-db/base/1/2600_vm deleted file mode 100644 index 562ae092..00000000 Binary files a/persistentStorage/data-song-db/base/1/2600_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2601 b/persistentStorage/data-song-db/base/1/2601 deleted file mode 100644 index 1d44fa56..00000000 Binary files a/persistentStorage/data-song-db/base/1/2601 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2601_fsm b/persistentStorage/data-song-db/base/1/2601_fsm deleted file mode 100644 index 0908076c..00000000 Binary files a/persistentStorage/data-song-db/base/1/2601_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2601_vm b/persistentStorage/data-song-db/base/1/2601_vm deleted file mode 100644 index e136061c..00000000 Binary files a/persistentStorage/data-song-db/base/1/2601_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2602 b/persistentStorage/data-song-db/base/1/2602 deleted file mode 100644 index bb94020c..00000000 Binary files a/persistentStorage/data-song-db/base/1/2602 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2602_fsm b/persistentStorage/data-song-db/base/1/2602_fsm deleted file mode 100644 index 2f7c0547..00000000 Binary files a/persistentStorage/data-song-db/base/1/2602_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2602_vm b/persistentStorage/data-song-db/base/1/2602_vm deleted file mode 100644 index 23b4a397..00000000 Binary files a/persistentStorage/data-song-db/base/1/2602_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2603 b/persistentStorage/data-song-db/base/1/2603 deleted file mode 100644 index fc1644f2..00000000 Binary files a/persistentStorage/data-song-db/base/1/2603 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2603_fsm b/persistentStorage/data-song-db/base/1/2603_fsm deleted file mode 100644 index 9646dc6c..00000000 Binary files a/persistentStorage/data-song-db/base/1/2603_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2603_vm b/persistentStorage/data-song-db/base/1/2603_vm deleted file mode 100644 index f7296825..00000000 Binary files a/persistentStorage/data-song-db/base/1/2603_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2604 b/persistentStorage/data-song-db/base/1/2604 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/2604_vm b/persistentStorage/data-song-db/base/1/2604_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/2605 b/persistentStorage/data-song-db/base/1/2605 deleted file mode 100644 index 5c0c8aba..00000000 Binary files a/persistentStorage/data-song-db/base/1/2605 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2605_fsm b/persistentStorage/data-song-db/base/1/2605_fsm deleted file mode 100644 index 3e435bbe..00000000 Binary files a/persistentStorage/data-song-db/base/1/2605_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2605_vm b/persistentStorage/data-song-db/base/1/2605_vm deleted file mode 100644 index 67845a0b..00000000 Binary files a/persistentStorage/data-song-db/base/1/2605_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2606 b/persistentStorage/data-song-db/base/1/2606 deleted file mode 100644 index d728c62e..00000000 Binary files a/persistentStorage/data-song-db/base/1/2606 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2606_fsm b/persistentStorage/data-song-db/base/1/2606_fsm deleted file mode 100644 index f79adf92..00000000 Binary files a/persistentStorage/data-song-db/base/1/2606_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2606_vm b/persistentStorage/data-song-db/base/1/2606_vm deleted file mode 100644 index 8b61fa51..00000000 Binary files a/persistentStorage/data-song-db/base/1/2606_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2607 b/persistentStorage/data-song-db/base/1/2607 deleted file mode 100644 index f0bdac3d..00000000 Binary files a/persistentStorage/data-song-db/base/1/2607 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2607_fsm b/persistentStorage/data-song-db/base/1/2607_fsm deleted file mode 100644 index 5b066f1a..00000000 Binary files a/persistentStorage/data-song-db/base/1/2607_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2607_vm b/persistentStorage/data-song-db/base/1/2607_vm deleted file mode 100644 index 25439067..00000000 Binary files a/persistentStorage/data-song-db/base/1/2607_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2608 b/persistentStorage/data-song-db/base/1/2608 deleted file mode 100644 index c840ae43..00000000 Binary files a/persistentStorage/data-song-db/base/1/2608 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2608_fsm b/persistentStorage/data-song-db/base/1/2608_fsm deleted file mode 100644 index 9e44fb9e..00000000 Binary files a/persistentStorage/data-song-db/base/1/2608_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2608_vm b/persistentStorage/data-song-db/base/1/2608_vm deleted file mode 100644 index 17073ad1..00000000 Binary files a/persistentStorage/data-song-db/base/1/2608_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2609 b/persistentStorage/data-song-db/base/1/2609 deleted file mode 100644 index adbbbb19..00000000 Binary files a/persistentStorage/data-song-db/base/1/2609 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2609_fsm b/persistentStorage/data-song-db/base/1/2609_fsm deleted file mode 100644 index a8427c61..00000000 Binary files a/persistentStorage/data-song-db/base/1/2609_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2609_vm b/persistentStorage/data-song-db/base/1/2609_vm deleted file mode 100644 index 454e602f..00000000 Binary files a/persistentStorage/data-song-db/base/1/2609_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2610 b/persistentStorage/data-song-db/base/1/2610 deleted file mode 100644 index d0d5eb8b..00000000 Binary files a/persistentStorage/data-song-db/base/1/2610 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2610_fsm b/persistentStorage/data-song-db/base/1/2610_fsm deleted file mode 100644 index 5bb455d6..00000000 Binary files a/persistentStorage/data-song-db/base/1/2610_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2610_vm b/persistentStorage/data-song-db/base/1/2610_vm deleted file mode 100644 index c137743f..00000000 Binary files a/persistentStorage/data-song-db/base/1/2610_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2611 b/persistentStorage/data-song-db/base/1/2611 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/2611_vm b/persistentStorage/data-song-db/base/1/2611_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/2612 b/persistentStorage/data-song-db/base/1/2612 deleted file mode 100644 index 0c8b5d61..00000000 Binary files a/persistentStorage/data-song-db/base/1/2612 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2612_fsm b/persistentStorage/data-song-db/base/1/2612_fsm deleted file mode 100644 index 877976ac..00000000 Binary files a/persistentStorage/data-song-db/base/1/2612_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2612_vm b/persistentStorage/data-song-db/base/1/2612_vm deleted file mode 100644 index 1a440474..00000000 Binary files a/persistentStorage/data-song-db/base/1/2612_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2613 b/persistentStorage/data-song-db/base/1/2613 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/2613_vm b/persistentStorage/data-song-db/base/1/2613_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/2615 b/persistentStorage/data-song-db/base/1/2615 deleted file mode 100644 index 16bf9c18..00000000 Binary files a/persistentStorage/data-song-db/base/1/2615 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2615_fsm b/persistentStorage/data-song-db/base/1/2615_fsm deleted file mode 100644 index 948882ce..00000000 Binary files a/persistentStorage/data-song-db/base/1/2615_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2615_vm b/persistentStorage/data-song-db/base/1/2615_vm deleted file mode 100644 index 4536ff4a..00000000 Binary files a/persistentStorage/data-song-db/base/1/2615_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2616 b/persistentStorage/data-song-db/base/1/2616 deleted file mode 100644 index 4ed2d540..00000000 Binary files a/persistentStorage/data-song-db/base/1/2616 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2616_fsm b/persistentStorage/data-song-db/base/1/2616_fsm deleted file mode 100644 index 190c114a..00000000 Binary files a/persistentStorage/data-song-db/base/1/2616_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2616_vm b/persistentStorage/data-song-db/base/1/2616_vm deleted file mode 100644 index b8ae452e..00000000 Binary files a/persistentStorage/data-song-db/base/1/2616_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2617 b/persistentStorage/data-song-db/base/1/2617 deleted file mode 100644 index aba148f8..00000000 Binary files a/persistentStorage/data-song-db/base/1/2617 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2617_fsm b/persistentStorage/data-song-db/base/1/2617_fsm deleted file mode 100644 index a90280bd..00000000 Binary files a/persistentStorage/data-song-db/base/1/2617_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2617_vm b/persistentStorage/data-song-db/base/1/2617_vm deleted file mode 100644 index 9272e4f7..00000000 Binary files a/persistentStorage/data-song-db/base/1/2617_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2618 b/persistentStorage/data-song-db/base/1/2618 deleted file mode 100644 index df005446..00000000 Binary files a/persistentStorage/data-song-db/base/1/2618 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2618_fsm b/persistentStorage/data-song-db/base/1/2618_fsm deleted file mode 100644 index 030e6ca7..00000000 Binary files a/persistentStorage/data-song-db/base/1/2618_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2618_vm b/persistentStorage/data-song-db/base/1/2618_vm deleted file mode 100644 index 15ac97f5..00000000 Binary files a/persistentStorage/data-song-db/base/1/2618_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2619 b/persistentStorage/data-song-db/base/1/2619 deleted file mode 100644 index f8149fc7..00000000 Binary files a/persistentStorage/data-song-db/base/1/2619 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2619_fsm b/persistentStorage/data-song-db/base/1/2619_fsm deleted file mode 100644 index 6dbef269..00000000 Binary files a/persistentStorage/data-song-db/base/1/2619_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2619_vm b/persistentStorage/data-song-db/base/1/2619_vm deleted file mode 100644 index d015a350..00000000 Binary files a/persistentStorage/data-song-db/base/1/2619_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2620 b/persistentStorage/data-song-db/base/1/2620 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/2620_vm b/persistentStorage/data-song-db/base/1/2620_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/2650 b/persistentStorage/data-song-db/base/1/2650 deleted file mode 100644 index 4fe77717..00000000 Binary files a/persistentStorage/data-song-db/base/1/2650 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2651 b/persistentStorage/data-song-db/base/1/2651 deleted file mode 100644 index 9fa3ede8..00000000 Binary files a/persistentStorage/data-song-db/base/1/2651 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2652 b/persistentStorage/data-song-db/base/1/2652 deleted file mode 100644 index d7414a9a..00000000 Binary files a/persistentStorage/data-song-db/base/1/2652 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2653 b/persistentStorage/data-song-db/base/1/2653 deleted file mode 100644 index 068979bc..00000000 Binary files a/persistentStorage/data-song-db/base/1/2653 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2654 b/persistentStorage/data-song-db/base/1/2654 deleted file mode 100644 index 394e3b6f..00000000 Binary files a/persistentStorage/data-song-db/base/1/2654 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2655 b/persistentStorage/data-song-db/base/1/2655 deleted file mode 100644 index 25baea2d..00000000 Binary files a/persistentStorage/data-song-db/base/1/2655 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2656 b/persistentStorage/data-song-db/base/1/2656 deleted file mode 100644 index 4ec744f0..00000000 Binary files a/persistentStorage/data-song-db/base/1/2656 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2657 b/persistentStorage/data-song-db/base/1/2657 deleted file mode 100644 index de750e3c..00000000 Binary files a/persistentStorage/data-song-db/base/1/2657 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2658 b/persistentStorage/data-song-db/base/1/2658 deleted file mode 100644 index d4557855..00000000 Binary files a/persistentStorage/data-song-db/base/1/2658 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2659 b/persistentStorage/data-song-db/base/1/2659 deleted file mode 100644 index 6c7e3f40..00000000 Binary files a/persistentStorage/data-song-db/base/1/2659 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2660 b/persistentStorage/data-song-db/base/1/2660 deleted file mode 100644 index 35c7c4fa..00000000 Binary files a/persistentStorage/data-song-db/base/1/2660 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2661 b/persistentStorage/data-song-db/base/1/2661 deleted file mode 100644 index 3176dc9d..00000000 Binary files a/persistentStorage/data-song-db/base/1/2661 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2662 b/persistentStorage/data-song-db/base/1/2662 deleted file mode 100644 index d72dac39..00000000 Binary files a/persistentStorage/data-song-db/base/1/2662 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2663 b/persistentStorage/data-song-db/base/1/2663 deleted file mode 100644 index 53826419..00000000 Binary files a/persistentStorage/data-song-db/base/1/2663 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2664 b/persistentStorage/data-song-db/base/1/2664 deleted file mode 100644 index e08344fd..00000000 Binary files a/persistentStorage/data-song-db/base/1/2664 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2665 b/persistentStorage/data-song-db/base/1/2665 deleted file mode 100644 index 3193c401..00000000 Binary files a/persistentStorage/data-song-db/base/1/2665 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2666 b/persistentStorage/data-song-db/base/1/2666 deleted file mode 100644 index 335f0219..00000000 Binary files a/persistentStorage/data-song-db/base/1/2666 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2667 b/persistentStorage/data-song-db/base/1/2667 deleted file mode 100644 index dd026897..00000000 Binary files a/persistentStorage/data-song-db/base/1/2667 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2668 b/persistentStorage/data-song-db/base/1/2668 deleted file mode 100644 index a9164882..00000000 Binary files a/persistentStorage/data-song-db/base/1/2668 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2669 b/persistentStorage/data-song-db/base/1/2669 deleted file mode 100644 index b1799837..00000000 Binary files a/persistentStorage/data-song-db/base/1/2669 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2670 b/persistentStorage/data-song-db/base/1/2670 deleted file mode 100644 index 557d749e..00000000 Binary files a/persistentStorage/data-song-db/base/1/2670 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2673 b/persistentStorage/data-song-db/base/1/2673 deleted file mode 100644 index 84ec7c1a..00000000 Binary files a/persistentStorage/data-song-db/base/1/2673 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2674 b/persistentStorage/data-song-db/base/1/2674 deleted file mode 100644 index 0fcdb185..00000000 Binary files a/persistentStorage/data-song-db/base/1/2674 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2675 b/persistentStorage/data-song-db/base/1/2675 deleted file mode 100644 index 0d3253a7..00000000 Binary files a/persistentStorage/data-song-db/base/1/2675 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2678 b/persistentStorage/data-song-db/base/1/2678 deleted file mode 100644 index 067f7693..00000000 Binary files a/persistentStorage/data-song-db/base/1/2678 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2679 b/persistentStorage/data-song-db/base/1/2679 deleted file mode 100644 index d1b6c9e0..00000000 Binary files a/persistentStorage/data-song-db/base/1/2679 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2680 b/persistentStorage/data-song-db/base/1/2680 deleted file mode 100644 index 5ccb7772..00000000 Binary files a/persistentStorage/data-song-db/base/1/2680 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2681 b/persistentStorage/data-song-db/base/1/2681 deleted file mode 100644 index 2252a269..00000000 Binary files a/persistentStorage/data-song-db/base/1/2681 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2682 b/persistentStorage/data-song-db/base/1/2682 deleted file mode 100644 index 4c2ac670..00000000 Binary files a/persistentStorage/data-song-db/base/1/2682 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2683 b/persistentStorage/data-song-db/base/1/2683 deleted file mode 100644 index 2d90b905..00000000 Binary files a/persistentStorage/data-song-db/base/1/2683 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2684 b/persistentStorage/data-song-db/base/1/2684 deleted file mode 100644 index 5672d5af..00000000 Binary files a/persistentStorage/data-song-db/base/1/2684 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2685 b/persistentStorage/data-song-db/base/1/2685 deleted file mode 100644 index 64219310..00000000 Binary files a/persistentStorage/data-song-db/base/1/2685 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2686 b/persistentStorage/data-song-db/base/1/2686 deleted file mode 100644 index 1cce52ef..00000000 Binary files a/persistentStorage/data-song-db/base/1/2686 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2687 b/persistentStorage/data-song-db/base/1/2687 deleted file mode 100644 index f6d0b8a7..00000000 Binary files a/persistentStorage/data-song-db/base/1/2687 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2688 b/persistentStorage/data-song-db/base/1/2688 deleted file mode 100644 index e0f79deb..00000000 Binary files a/persistentStorage/data-song-db/base/1/2688 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2689 b/persistentStorage/data-song-db/base/1/2689 deleted file mode 100644 index 6e11243f..00000000 Binary files a/persistentStorage/data-song-db/base/1/2689 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2690 b/persistentStorage/data-song-db/base/1/2690 deleted file mode 100644 index 40d56d54..00000000 Binary files a/persistentStorage/data-song-db/base/1/2690 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2691 b/persistentStorage/data-song-db/base/1/2691 deleted file mode 100644 index fe34196f..00000000 Binary files a/persistentStorage/data-song-db/base/1/2691 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2692 b/persistentStorage/data-song-db/base/1/2692 deleted file mode 100644 index 50751afa..00000000 Binary files a/persistentStorage/data-song-db/base/1/2692 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2693 b/persistentStorage/data-song-db/base/1/2693 deleted file mode 100644 index 96b012bb..00000000 Binary files a/persistentStorage/data-song-db/base/1/2693 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2696 b/persistentStorage/data-song-db/base/1/2696 deleted file mode 100644 index c0b7371f..00000000 Binary files a/persistentStorage/data-song-db/base/1/2696 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2699 b/persistentStorage/data-song-db/base/1/2699 deleted file mode 100644 index d3c634ed..00000000 Binary files a/persistentStorage/data-song-db/base/1/2699 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2701 b/persistentStorage/data-song-db/base/1/2701 deleted file mode 100644 index 0e85b803..00000000 Binary files a/persistentStorage/data-song-db/base/1/2701 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2702 b/persistentStorage/data-song-db/base/1/2702 deleted file mode 100644 index ba82e6bd..00000000 Binary files a/persistentStorage/data-song-db/base/1/2702 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2703 b/persistentStorage/data-song-db/base/1/2703 deleted file mode 100644 index 0bc615e9..00000000 Binary files a/persistentStorage/data-song-db/base/1/2703 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2704 b/persistentStorage/data-song-db/base/1/2704 deleted file mode 100644 index 3cbe8f98..00000000 Binary files a/persistentStorage/data-song-db/base/1/2704 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2753 b/persistentStorage/data-song-db/base/1/2753 deleted file mode 100644 index bc0cb93f..00000000 Binary files a/persistentStorage/data-song-db/base/1/2753 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2753_fsm b/persistentStorage/data-song-db/base/1/2753_fsm deleted file mode 100644 index e962a4f5..00000000 Binary files a/persistentStorage/data-song-db/base/1/2753_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2753_vm b/persistentStorage/data-song-db/base/1/2753_vm deleted file mode 100644 index 65103a84..00000000 Binary files a/persistentStorage/data-song-db/base/1/2753_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2754 b/persistentStorage/data-song-db/base/1/2754 deleted file mode 100644 index 36d63e7e..00000000 Binary files a/persistentStorage/data-song-db/base/1/2754 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2755 b/persistentStorage/data-song-db/base/1/2755 deleted file mode 100644 index 2ff74dd5..00000000 Binary files a/persistentStorage/data-song-db/base/1/2755 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2756 b/persistentStorage/data-song-db/base/1/2756 deleted file mode 100644 index 5b31770e..00000000 Binary files a/persistentStorage/data-song-db/base/1/2756 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2757 b/persistentStorage/data-song-db/base/1/2757 deleted file mode 100644 index 78dbfcd7..00000000 Binary files a/persistentStorage/data-song-db/base/1/2757 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2830 b/persistentStorage/data-song-db/base/1/2830 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/2830_vm b/persistentStorage/data-song-db/base/1/2830_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/2831 b/persistentStorage/data-song-db/base/1/2831 deleted file mode 100644 index 0149aa9a..00000000 Binary files a/persistentStorage/data-song-db/base/1/2831 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2832 b/persistentStorage/data-song-db/base/1/2832 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/2832_vm b/persistentStorage/data-song-db/base/1/2832_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/2833 b/persistentStorage/data-song-db/base/1/2833 deleted file mode 100644 index 2afaafbb..00000000 Binary files a/persistentStorage/data-song-db/base/1/2833 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2834 b/persistentStorage/data-song-db/base/1/2834 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/2834_vm b/persistentStorage/data-song-db/base/1/2834_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/2835 b/persistentStorage/data-song-db/base/1/2835 deleted file mode 100644 index 375600a1..00000000 Binary files a/persistentStorage/data-song-db/base/1/2835 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2836 b/persistentStorage/data-song-db/base/1/2836 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/2836_vm b/persistentStorage/data-song-db/base/1/2836_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/2837 b/persistentStorage/data-song-db/base/1/2837 deleted file mode 100644 index 80e7375c..00000000 Binary files a/persistentStorage/data-song-db/base/1/2837 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2838 b/persistentStorage/data-song-db/base/1/2838 deleted file mode 100644 index ca74c148..00000000 Binary files a/persistentStorage/data-song-db/base/1/2838 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2838_fsm b/persistentStorage/data-song-db/base/1/2838_fsm deleted file mode 100644 index 4e32ef90..00000000 Binary files a/persistentStorage/data-song-db/base/1/2838_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2838_vm b/persistentStorage/data-song-db/base/1/2838_vm deleted file mode 100644 index 8f6fc319..00000000 Binary files a/persistentStorage/data-song-db/base/1/2838_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2839 b/persistentStorage/data-song-db/base/1/2839 deleted file mode 100644 index 80a9515f..00000000 Binary files a/persistentStorage/data-song-db/base/1/2839 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2840 b/persistentStorage/data-song-db/base/1/2840 deleted file mode 100644 index bf88e4fe..00000000 Binary files a/persistentStorage/data-song-db/base/1/2840 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2840_fsm b/persistentStorage/data-song-db/base/1/2840_fsm deleted file mode 100644 index cbf230f7..00000000 Binary files a/persistentStorage/data-song-db/base/1/2840_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2840_vm b/persistentStorage/data-song-db/base/1/2840_vm deleted file mode 100644 index 6b797608..00000000 Binary files a/persistentStorage/data-song-db/base/1/2840_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2841 b/persistentStorage/data-song-db/base/1/2841 deleted file mode 100644 index 0d287be6..00000000 Binary files a/persistentStorage/data-song-db/base/1/2841 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/2995 b/persistentStorage/data-song-db/base/1/2995 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/2995_vm b/persistentStorage/data-song-db/base/1/2995_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/2996 b/persistentStorage/data-song-db/base/1/2996 deleted file mode 100644 index 3a0a8a3b..00000000 Binary files a/persistentStorage/data-song-db/base/1/2996 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3079 b/persistentStorage/data-song-db/base/1/3079 deleted file mode 100644 index cbd37332..00000000 Binary files a/persistentStorage/data-song-db/base/1/3079 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3079_fsm b/persistentStorage/data-song-db/base/1/3079_fsm deleted file mode 100644 index 7732d22b..00000000 Binary files a/persistentStorage/data-song-db/base/1/3079_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3079_vm b/persistentStorage/data-song-db/base/1/3079_vm deleted file mode 100644 index 041508f2..00000000 Binary files a/persistentStorage/data-song-db/base/1/3079_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3080 b/persistentStorage/data-song-db/base/1/3080 deleted file mode 100644 index f8c0497f..00000000 Binary files a/persistentStorage/data-song-db/base/1/3080 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3081 b/persistentStorage/data-song-db/base/1/3081 deleted file mode 100644 index e82b3a57..00000000 Binary files a/persistentStorage/data-song-db/base/1/3081 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3085 b/persistentStorage/data-song-db/base/1/3085 deleted file mode 100644 index 3d091fbb..00000000 Binary files a/persistentStorage/data-song-db/base/1/3085 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3118 b/persistentStorage/data-song-db/base/1/3118 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/3118_vm b/persistentStorage/data-song-db/base/1/3118_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/3119 b/persistentStorage/data-song-db/base/1/3119 deleted file mode 100644 index 89ce6bec..00000000 Binary files a/persistentStorage/data-song-db/base/1/3119 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3164 b/persistentStorage/data-song-db/base/1/3164 deleted file mode 100644 index c5bee0eb..00000000 Binary files a/persistentStorage/data-song-db/base/1/3164 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3256 b/persistentStorage/data-song-db/base/1/3256 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/3256_vm b/persistentStorage/data-song-db/base/1/3256_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/3257 b/persistentStorage/data-song-db/base/1/3257 deleted file mode 100644 index 1072cde4..00000000 Binary files a/persistentStorage/data-song-db/base/1/3257 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3258 b/persistentStorage/data-song-db/base/1/3258 deleted file mode 100644 index b8ad6fda..00000000 Binary files a/persistentStorage/data-song-db/base/1/3258 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3350 b/persistentStorage/data-song-db/base/1/3350 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/3350_vm b/persistentStorage/data-song-db/base/1/3350_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/3351 b/persistentStorage/data-song-db/base/1/3351 deleted file mode 100644 index 37e64629..00000000 Binary files a/persistentStorage/data-song-db/base/1/3351 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3379 b/persistentStorage/data-song-db/base/1/3379 deleted file mode 100644 index a9b554c1..00000000 Binary files a/persistentStorage/data-song-db/base/1/3379 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3380 b/persistentStorage/data-song-db/base/1/3380 deleted file mode 100644 index 11d9675b..00000000 Binary files a/persistentStorage/data-song-db/base/1/3380 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3381 b/persistentStorage/data-song-db/base/1/3381 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/3381_vm b/persistentStorage/data-song-db/base/1/3381_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/3394 b/persistentStorage/data-song-db/base/1/3394 deleted file mode 100644 index 62dfdd73..00000000 Binary files a/persistentStorage/data-song-db/base/1/3394 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3394_fsm b/persistentStorage/data-song-db/base/1/3394_fsm deleted file mode 100644 index e63ffab3..00000000 Binary files a/persistentStorage/data-song-db/base/1/3394_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3394_vm b/persistentStorage/data-song-db/base/1/3394_vm deleted file mode 100644 index 43fe11be..00000000 Binary files a/persistentStorage/data-song-db/base/1/3394_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3395 b/persistentStorage/data-song-db/base/1/3395 deleted file mode 100644 index 3d655ba2..00000000 Binary files a/persistentStorage/data-song-db/base/1/3395 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3439 b/persistentStorage/data-song-db/base/1/3439 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/3439_vm b/persistentStorage/data-song-db/base/1/3439_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/3440 b/persistentStorage/data-song-db/base/1/3440 deleted file mode 100644 index 5a34d837..00000000 Binary files a/persistentStorage/data-song-db/base/1/3440 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3455 b/persistentStorage/data-song-db/base/1/3455 deleted file mode 100644 index df42af62..00000000 Binary files a/persistentStorage/data-song-db/base/1/3455 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3456 b/persistentStorage/data-song-db/base/1/3456 deleted file mode 100644 index 9a4de77e..00000000 Binary files a/persistentStorage/data-song-db/base/1/3456 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3456_fsm b/persistentStorage/data-song-db/base/1/3456_fsm deleted file mode 100644 index ea43ee9d..00000000 Binary files a/persistentStorage/data-song-db/base/1/3456_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3456_vm b/persistentStorage/data-song-db/base/1/3456_vm deleted file mode 100644 index 5c9dc2b3..00000000 Binary files a/persistentStorage/data-song-db/base/1/3456_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3466 b/persistentStorage/data-song-db/base/1/3466 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/3466_vm b/persistentStorage/data-song-db/base/1/3466_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/3467 b/persistentStorage/data-song-db/base/1/3467 deleted file mode 100644 index 3b8a7cad..00000000 Binary files a/persistentStorage/data-song-db/base/1/3467 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3468 b/persistentStorage/data-song-db/base/1/3468 deleted file mode 100644 index 351953a7..00000000 Binary files a/persistentStorage/data-song-db/base/1/3468 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3501 b/persistentStorage/data-song-db/base/1/3501 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/3501_vm b/persistentStorage/data-song-db/base/1/3501_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/3502 b/persistentStorage/data-song-db/base/1/3502 deleted file mode 100644 index 24d7db5f..00000000 Binary files a/persistentStorage/data-song-db/base/1/3502 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3503 b/persistentStorage/data-song-db/base/1/3503 deleted file mode 100644 index 0992f362..00000000 Binary files a/persistentStorage/data-song-db/base/1/3503 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3534 b/persistentStorage/data-song-db/base/1/3534 deleted file mode 100644 index 56a983d6..00000000 Binary files a/persistentStorage/data-song-db/base/1/3534 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3541 b/persistentStorage/data-song-db/base/1/3541 deleted file mode 100644 index ad69913a..00000000 Binary files a/persistentStorage/data-song-db/base/1/3541 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3541_fsm b/persistentStorage/data-song-db/base/1/3541_fsm deleted file mode 100644 index 62f01566..00000000 Binary files a/persistentStorage/data-song-db/base/1/3541_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3541_vm b/persistentStorage/data-song-db/base/1/3541_vm deleted file mode 100644 index 6f81205d..00000000 Binary files a/persistentStorage/data-song-db/base/1/3541_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3542 b/persistentStorage/data-song-db/base/1/3542 deleted file mode 100644 index e4bfd841..00000000 Binary files a/persistentStorage/data-song-db/base/1/3542 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3574 b/persistentStorage/data-song-db/base/1/3574 deleted file mode 100644 index 929626a5..00000000 Binary files a/persistentStorage/data-song-db/base/1/3574 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3575 b/persistentStorage/data-song-db/base/1/3575 deleted file mode 100644 index bd5674c3..00000000 Binary files a/persistentStorage/data-song-db/base/1/3575 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3576 b/persistentStorage/data-song-db/base/1/3576 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/3576_vm b/persistentStorage/data-song-db/base/1/3576_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/3596 b/persistentStorage/data-song-db/base/1/3596 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/3596_vm b/persistentStorage/data-song-db/base/1/3596_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/3597 b/persistentStorage/data-song-db/base/1/3597 deleted file mode 100644 index c054e788..00000000 Binary files a/persistentStorage/data-song-db/base/1/3597 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3598 b/persistentStorage/data-song-db/base/1/3598 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/3598_vm b/persistentStorage/data-song-db/base/1/3598_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/3599 b/persistentStorage/data-song-db/base/1/3599 deleted file mode 100644 index cae63029..00000000 Binary files a/persistentStorage/data-song-db/base/1/3599 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3600 b/persistentStorage/data-song-db/base/1/3600 deleted file mode 100644 index 613977cc..00000000 Binary files a/persistentStorage/data-song-db/base/1/3600 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3600_fsm b/persistentStorage/data-song-db/base/1/3600_fsm deleted file mode 100644 index ffd4b159..00000000 Binary files a/persistentStorage/data-song-db/base/1/3600_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3600_vm b/persistentStorage/data-song-db/base/1/3600_vm deleted file mode 100644 index 5f2324dc..00000000 Binary files a/persistentStorage/data-song-db/base/1/3600_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3601 b/persistentStorage/data-song-db/base/1/3601 deleted file mode 100644 index 065e4e19..00000000 Binary files a/persistentStorage/data-song-db/base/1/3601 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3601_fsm b/persistentStorage/data-song-db/base/1/3601_fsm deleted file mode 100644 index 7732d22b..00000000 Binary files a/persistentStorage/data-song-db/base/1/3601_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3601_vm b/persistentStorage/data-song-db/base/1/3601_vm deleted file mode 100644 index 5d7215c1..00000000 Binary files a/persistentStorage/data-song-db/base/1/3601_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3602 b/persistentStorage/data-song-db/base/1/3602 deleted file mode 100644 index cd08d614..00000000 Binary files a/persistentStorage/data-song-db/base/1/3602 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3602_fsm b/persistentStorage/data-song-db/base/1/3602_fsm deleted file mode 100644 index 7cbf8340..00000000 Binary files a/persistentStorage/data-song-db/base/1/3602_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3602_vm b/persistentStorage/data-song-db/base/1/3602_vm deleted file mode 100644 index 545a04e5..00000000 Binary files a/persistentStorage/data-song-db/base/1/3602_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3603 b/persistentStorage/data-song-db/base/1/3603 deleted file mode 100644 index a055b23e..00000000 Binary files a/persistentStorage/data-song-db/base/1/3603 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3603_fsm b/persistentStorage/data-song-db/base/1/3603_fsm deleted file mode 100644 index 6d00d685..00000000 Binary files a/persistentStorage/data-song-db/base/1/3603_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3603_vm b/persistentStorage/data-song-db/base/1/3603_vm deleted file mode 100644 index c1773b04..00000000 Binary files a/persistentStorage/data-song-db/base/1/3603_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3604 b/persistentStorage/data-song-db/base/1/3604 deleted file mode 100644 index 74275331..00000000 Binary files a/persistentStorage/data-song-db/base/1/3604 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3605 b/persistentStorage/data-song-db/base/1/3605 deleted file mode 100644 index 2850f784..00000000 Binary files a/persistentStorage/data-song-db/base/1/3605 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3606 b/persistentStorage/data-song-db/base/1/3606 deleted file mode 100644 index 7d6e7670..00000000 Binary files a/persistentStorage/data-song-db/base/1/3606 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3607 b/persistentStorage/data-song-db/base/1/3607 deleted file mode 100644 index 8c5ad631..00000000 Binary files a/persistentStorage/data-song-db/base/1/3607 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3608 b/persistentStorage/data-song-db/base/1/3608 deleted file mode 100644 index e50d2ba5..00000000 Binary files a/persistentStorage/data-song-db/base/1/3608 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3609 b/persistentStorage/data-song-db/base/1/3609 deleted file mode 100644 index 8b2e6b4d..00000000 Binary files a/persistentStorage/data-song-db/base/1/3609 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3712 b/persistentStorage/data-song-db/base/1/3712 deleted file mode 100644 index 8a67eef7..00000000 Binary files a/persistentStorage/data-song-db/base/1/3712 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3764 b/persistentStorage/data-song-db/base/1/3764 deleted file mode 100644 index 971a5c60..00000000 Binary files a/persistentStorage/data-song-db/base/1/3764 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3764_fsm b/persistentStorage/data-song-db/base/1/3764_fsm deleted file mode 100644 index d041693e..00000000 Binary files a/persistentStorage/data-song-db/base/1/3764_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3764_vm b/persistentStorage/data-song-db/base/1/3764_vm deleted file mode 100644 index 14c5846b..00000000 Binary files a/persistentStorage/data-song-db/base/1/3764_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3766 b/persistentStorage/data-song-db/base/1/3766 deleted file mode 100644 index fad3c19c..00000000 Binary files a/persistentStorage/data-song-db/base/1/3766 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3767 b/persistentStorage/data-song-db/base/1/3767 deleted file mode 100644 index 63185238..00000000 Binary files a/persistentStorage/data-song-db/base/1/3767 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/3997 b/persistentStorage/data-song-db/base/1/3997 deleted file mode 100644 index 4297eb48..00000000 Binary files a/persistentStorage/data-song-db/base/1/3997 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/5002 b/persistentStorage/data-song-db/base/1/5002 deleted file mode 100644 index f0a233cd..00000000 Binary files a/persistentStorage/data-song-db/base/1/5002 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/548 b/persistentStorage/data-song-db/base/1/548 deleted file mode 100644 index d0f31da0..00000000 Binary files a/persistentStorage/data-song-db/base/1/548 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/549 b/persistentStorage/data-song-db/base/1/549 deleted file mode 100644 index 55343ef2..00000000 Binary files a/persistentStorage/data-song-db/base/1/549 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/6102 b/persistentStorage/data-song-db/base/1/6102 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/6102_vm b/persistentStorage/data-song-db/base/1/6102_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/6104 b/persistentStorage/data-song-db/base/1/6104 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/6104_vm b/persistentStorage/data-song-db/base/1/6104_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/6106 b/persistentStorage/data-song-db/base/1/6106 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/6106_vm b/persistentStorage/data-song-db/base/1/6106_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/6110 b/persistentStorage/data-song-db/base/1/6110 deleted file mode 100644 index 18a4d692..00000000 Binary files a/persistentStorage/data-song-db/base/1/6110 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/6111 b/persistentStorage/data-song-db/base/1/6111 deleted file mode 100644 index f0d7cbc4..00000000 Binary files a/persistentStorage/data-song-db/base/1/6111 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/6112 b/persistentStorage/data-song-db/base/1/6112 deleted file mode 100644 index 0518dbc0..00000000 Binary files a/persistentStorage/data-song-db/base/1/6112 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/6113 b/persistentStorage/data-song-db/base/1/6113 deleted file mode 100644 index 49a0523d..00000000 Binary files a/persistentStorage/data-song-db/base/1/6113 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/6117 b/persistentStorage/data-song-db/base/1/6117 deleted file mode 100644 index f5dd001c..00000000 Binary files a/persistentStorage/data-song-db/base/1/6117 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/826 b/persistentStorage/data-song-db/base/1/826 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/826_vm b/persistentStorage/data-song-db/base/1/826_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/1/827 b/persistentStorage/data-song-db/base/1/827 deleted file mode 100644 index 136d1d28..00000000 Binary files a/persistentStorage/data-song-db/base/1/827 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/828 b/persistentStorage/data-song-db/base/1/828 deleted file mode 100644 index bf8caada..00000000 Binary files a/persistentStorage/data-song-db/base/1/828 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/1/PG_VERSION b/persistentStorage/data-song-db/base/1/PG_VERSION deleted file mode 100644 index b4de3947..00000000 --- a/persistentStorage/data-song-db/base/1/PG_VERSION +++ /dev/null @@ -1 +0,0 @@ -11 diff --git a/persistentStorage/data-song-db/base/1/pg_filenode.map b/persistentStorage/data-song-db/base/1/pg_filenode.map deleted file mode 100644 index 428c97e9..00000000 Binary files a/persistentStorage/data-song-db/base/1/pg_filenode.map and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/112 b/persistentStorage/data-song-db/base/13066/112 deleted file mode 100644 index 4667847b..00000000 Binary files a/persistentStorage/data-song-db/base/13066/112 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/113 b/persistentStorage/data-song-db/base/13066/113 deleted file mode 100644 index 99d1648e..00000000 Binary files a/persistentStorage/data-song-db/base/13066/113 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/1247 b/persistentStorage/data-song-db/base/13066/1247 deleted file mode 100644 index c4062a4d..00000000 Binary files a/persistentStorage/data-song-db/base/13066/1247 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/1247_fsm b/persistentStorage/data-song-db/base/13066/1247_fsm deleted file mode 100644 index f082f631..00000000 Binary files a/persistentStorage/data-song-db/base/13066/1247_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/1247_vm b/persistentStorage/data-song-db/base/13066/1247_vm deleted file mode 100644 index 06b36841..00000000 Binary files a/persistentStorage/data-song-db/base/13066/1247_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/1249 b/persistentStorage/data-song-db/base/13066/1249 deleted file mode 100644 index 0a5d1110..00000000 Binary files a/persistentStorage/data-song-db/base/13066/1249 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/1249_fsm b/persistentStorage/data-song-db/base/13066/1249_fsm deleted file mode 100644 index 2be958d7..00000000 Binary files a/persistentStorage/data-song-db/base/13066/1249_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/1249_vm b/persistentStorage/data-song-db/base/13066/1249_vm deleted file mode 100644 index efb6e3d2..00000000 Binary files a/persistentStorage/data-song-db/base/13066/1249_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/1255 b/persistentStorage/data-song-db/base/13066/1255 deleted file mode 100644 index a15c41f0..00000000 Binary files a/persistentStorage/data-song-db/base/13066/1255 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/1255_fsm b/persistentStorage/data-song-db/base/13066/1255_fsm deleted file mode 100644 index dde16352..00000000 Binary files a/persistentStorage/data-song-db/base/13066/1255_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/1255_vm b/persistentStorage/data-song-db/base/13066/1255_vm deleted file mode 100644 index 66cf3a9b..00000000 Binary files a/persistentStorage/data-song-db/base/13066/1255_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/1259 b/persistentStorage/data-song-db/base/13066/1259 deleted file mode 100644 index 75894579..00000000 Binary files a/persistentStorage/data-song-db/base/13066/1259 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/1259_fsm b/persistentStorage/data-song-db/base/13066/1259_fsm deleted file mode 100644 index 9cba2542..00000000 Binary files a/persistentStorage/data-song-db/base/13066/1259_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/1259_vm b/persistentStorage/data-song-db/base/13066/1259_vm deleted file mode 100644 index a046d262..00000000 Binary files a/persistentStorage/data-song-db/base/13066/1259_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/12902 b/persistentStorage/data-song-db/base/13066/12902 deleted file mode 100644 index d298c664..00000000 Binary files a/persistentStorage/data-song-db/base/13066/12902 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/12902_fsm b/persistentStorage/data-song-db/base/13066/12902_fsm deleted file mode 100644 index 19948ba3..00000000 Binary files a/persistentStorage/data-song-db/base/13066/12902_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/12902_vm b/persistentStorage/data-song-db/base/13066/12902_vm deleted file mode 100644 index e024e219..00000000 Binary files a/persistentStorage/data-song-db/base/13066/12902_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/12904 b/persistentStorage/data-song-db/base/13066/12904 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/12906 b/persistentStorage/data-song-db/base/13066/12906 deleted file mode 100644 index eaaf7f9c..00000000 Binary files a/persistentStorage/data-song-db/base/13066/12906 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/12907 b/persistentStorage/data-song-db/base/13066/12907 deleted file mode 100644 index 39eb183c..00000000 Binary files a/persistentStorage/data-song-db/base/13066/12907 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/12907_fsm b/persistentStorage/data-song-db/base/13066/12907_fsm deleted file mode 100644 index ce7c26eb..00000000 Binary files a/persistentStorage/data-song-db/base/13066/12907_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/12907_vm b/persistentStorage/data-song-db/base/13066/12907_vm deleted file mode 100644 index 7f46a300..00000000 Binary files a/persistentStorage/data-song-db/base/13066/12907_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/12909 b/persistentStorage/data-song-db/base/13066/12909 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/12911 b/persistentStorage/data-song-db/base/13066/12911 deleted file mode 100644 index 24ec5ac2..00000000 Binary files a/persistentStorage/data-song-db/base/13066/12911 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/12912 b/persistentStorage/data-song-db/base/13066/12912 deleted file mode 100644 index b0d3e632..00000000 Binary files a/persistentStorage/data-song-db/base/13066/12912 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/12912_fsm b/persistentStorage/data-song-db/base/13066/12912_fsm deleted file mode 100644 index 98dc620a..00000000 Binary files a/persistentStorage/data-song-db/base/13066/12912_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/12912_vm b/persistentStorage/data-song-db/base/13066/12912_vm deleted file mode 100644 index 754665b0..00000000 Binary files a/persistentStorage/data-song-db/base/13066/12912_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/12914 b/persistentStorage/data-song-db/base/13066/12914 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/12916 b/persistentStorage/data-song-db/base/13066/12916 deleted file mode 100644 index 911c123e..00000000 Binary files a/persistentStorage/data-song-db/base/13066/12916 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/12917 b/persistentStorage/data-song-db/base/13066/12917 deleted file mode 100644 index 75b5dc26..00000000 Binary files a/persistentStorage/data-song-db/base/13066/12917 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/12917_fsm b/persistentStorage/data-song-db/base/13066/12917_fsm deleted file mode 100644 index f8a0e258..00000000 Binary files a/persistentStorage/data-song-db/base/13066/12917_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/12917_vm b/persistentStorage/data-song-db/base/13066/12917_vm deleted file mode 100644 index 999ef8c0..00000000 Binary files a/persistentStorage/data-song-db/base/13066/12917_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/12919 b/persistentStorage/data-song-db/base/13066/12919 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/12921 b/persistentStorage/data-song-db/base/13066/12921 deleted file mode 100644 index 7692fb50..00000000 Binary files a/persistentStorage/data-song-db/base/13066/12921 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/12922 b/persistentStorage/data-song-db/base/13066/12922 deleted file mode 100644 index 70ef93a9..00000000 Binary files a/persistentStorage/data-song-db/base/13066/12922 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/12922_fsm b/persistentStorage/data-song-db/base/13066/12922_fsm deleted file mode 100644 index ecbfaee5..00000000 Binary files a/persistentStorage/data-song-db/base/13066/12922_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/12922_vm b/persistentStorage/data-song-db/base/13066/12922_vm deleted file mode 100644 index 031bad16..00000000 Binary files a/persistentStorage/data-song-db/base/13066/12922_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/12924 b/persistentStorage/data-song-db/base/13066/12924 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/12926 b/persistentStorage/data-song-db/base/13066/12926 deleted file mode 100644 index 0bd7b2a1..00000000 Binary files a/persistentStorage/data-song-db/base/13066/12926 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/12927 b/persistentStorage/data-song-db/base/13066/12927 deleted file mode 100644 index 81d71b93..00000000 Binary files a/persistentStorage/data-song-db/base/13066/12927 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/12927_fsm b/persistentStorage/data-song-db/base/13066/12927_fsm deleted file mode 100644 index a836ddf7..00000000 Binary files a/persistentStorage/data-song-db/base/13066/12927_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/12927_vm b/persistentStorage/data-song-db/base/13066/12927_vm deleted file mode 100644 index dbff9bc0..00000000 Binary files a/persistentStorage/data-song-db/base/13066/12927_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/12929 b/persistentStorage/data-song-db/base/13066/12929 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/12931 b/persistentStorage/data-song-db/base/13066/12931 deleted file mode 100644 index 39e60ec0..00000000 Binary files a/persistentStorage/data-song-db/base/13066/12931 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/12932 b/persistentStorage/data-song-db/base/13066/12932 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/12934 b/persistentStorage/data-song-db/base/13066/12934 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/12936 b/persistentStorage/data-song-db/base/13066/12936 deleted file mode 100644 index 5d072ab6..00000000 Binary files a/persistentStorage/data-song-db/base/13066/12936 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/1417 b/persistentStorage/data-song-db/base/13066/1417 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/1417_vm b/persistentStorage/data-song-db/base/13066/1417_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/1418 b/persistentStorage/data-song-db/base/13066/1418 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/1418_vm b/persistentStorage/data-song-db/base/13066/1418_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/174 b/persistentStorage/data-song-db/base/13066/174 deleted file mode 100644 index b0f68c81..00000000 Binary files a/persistentStorage/data-song-db/base/13066/174 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/175 b/persistentStorage/data-song-db/base/13066/175 deleted file mode 100644 index 09f50ec8..00000000 Binary files a/persistentStorage/data-song-db/base/13066/175 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2187 b/persistentStorage/data-song-db/base/13066/2187 deleted file mode 100644 index b759e4fb..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2187 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2224 b/persistentStorage/data-song-db/base/13066/2224 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/2224_vm b/persistentStorage/data-song-db/base/13066/2224_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/2328 b/persistentStorage/data-song-db/base/13066/2328 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/2328_vm b/persistentStorage/data-song-db/base/13066/2328_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/2336 b/persistentStorage/data-song-db/base/13066/2336 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/2336_vm b/persistentStorage/data-song-db/base/13066/2336_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/2337 b/persistentStorage/data-song-db/base/13066/2337 deleted file mode 100644 index ee992828..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2337 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2579 b/persistentStorage/data-song-db/base/13066/2579 deleted file mode 100644 index f256cc4b..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2579 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2600 b/persistentStorage/data-song-db/base/13066/2600 deleted file mode 100644 index ffdfb66d..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2600 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2600_fsm b/persistentStorage/data-song-db/base/13066/2600_fsm deleted file mode 100644 index e63ffab3..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2600_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2600_vm b/persistentStorage/data-song-db/base/13066/2600_vm deleted file mode 100644 index 562ae092..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2600_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2601 b/persistentStorage/data-song-db/base/13066/2601 deleted file mode 100644 index 1d44fa56..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2601 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2601_fsm b/persistentStorage/data-song-db/base/13066/2601_fsm deleted file mode 100644 index 0908076c..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2601_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2601_vm b/persistentStorage/data-song-db/base/13066/2601_vm deleted file mode 100644 index e136061c..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2601_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2602 b/persistentStorage/data-song-db/base/13066/2602 deleted file mode 100644 index bb94020c..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2602 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2602_fsm b/persistentStorage/data-song-db/base/13066/2602_fsm deleted file mode 100644 index 2f7c0547..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2602_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2602_vm b/persistentStorage/data-song-db/base/13066/2602_vm deleted file mode 100644 index 23b4a397..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2602_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2603 b/persistentStorage/data-song-db/base/13066/2603 deleted file mode 100644 index fc1644f2..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2603 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2603_fsm b/persistentStorage/data-song-db/base/13066/2603_fsm deleted file mode 100644 index 9646dc6c..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2603_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2603_vm b/persistentStorage/data-song-db/base/13066/2603_vm deleted file mode 100644 index f7296825..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2603_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2604 b/persistentStorage/data-song-db/base/13066/2604 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/2604_vm b/persistentStorage/data-song-db/base/13066/2604_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/2605 b/persistentStorage/data-song-db/base/13066/2605 deleted file mode 100644 index 5c0c8aba..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2605 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2605_fsm b/persistentStorage/data-song-db/base/13066/2605_fsm deleted file mode 100644 index 3e435bbe..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2605_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2605_vm b/persistentStorage/data-song-db/base/13066/2605_vm deleted file mode 100644 index 67845a0b..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2605_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2606 b/persistentStorage/data-song-db/base/13066/2606 deleted file mode 100644 index d728c62e..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2606 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2606_fsm b/persistentStorage/data-song-db/base/13066/2606_fsm deleted file mode 100644 index f79adf92..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2606_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2606_vm b/persistentStorage/data-song-db/base/13066/2606_vm deleted file mode 100644 index 8b61fa51..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2606_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2607 b/persistentStorage/data-song-db/base/13066/2607 deleted file mode 100644 index f0bdac3d..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2607 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2607_fsm b/persistentStorage/data-song-db/base/13066/2607_fsm deleted file mode 100644 index 5b066f1a..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2607_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2607_vm b/persistentStorage/data-song-db/base/13066/2607_vm deleted file mode 100644 index 25439067..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2607_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2608 b/persistentStorage/data-song-db/base/13066/2608 deleted file mode 100644 index c840ae43..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2608 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2608_fsm b/persistentStorage/data-song-db/base/13066/2608_fsm deleted file mode 100644 index 9e44fb9e..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2608_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2608_vm b/persistentStorage/data-song-db/base/13066/2608_vm deleted file mode 100644 index 17073ad1..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2608_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2609 b/persistentStorage/data-song-db/base/13066/2609 deleted file mode 100644 index adbbbb19..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2609 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2609_fsm b/persistentStorage/data-song-db/base/13066/2609_fsm deleted file mode 100644 index a8427c61..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2609_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2609_vm b/persistentStorage/data-song-db/base/13066/2609_vm deleted file mode 100644 index 454e602f..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2609_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2610 b/persistentStorage/data-song-db/base/13066/2610 deleted file mode 100644 index d0d5eb8b..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2610 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2610_fsm b/persistentStorage/data-song-db/base/13066/2610_fsm deleted file mode 100644 index 5bb455d6..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2610_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2610_vm b/persistentStorage/data-song-db/base/13066/2610_vm deleted file mode 100644 index c137743f..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2610_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2611 b/persistentStorage/data-song-db/base/13066/2611 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/2611_vm b/persistentStorage/data-song-db/base/13066/2611_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/2612 b/persistentStorage/data-song-db/base/13066/2612 deleted file mode 100644 index 0c8b5d61..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2612 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2612_fsm b/persistentStorage/data-song-db/base/13066/2612_fsm deleted file mode 100644 index 877976ac..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2612_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2612_vm b/persistentStorage/data-song-db/base/13066/2612_vm deleted file mode 100644 index 1a440474..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2612_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2613 b/persistentStorage/data-song-db/base/13066/2613 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/2613_vm b/persistentStorage/data-song-db/base/13066/2613_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/2615 b/persistentStorage/data-song-db/base/13066/2615 deleted file mode 100644 index 16bf9c18..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2615 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2615_fsm b/persistentStorage/data-song-db/base/13066/2615_fsm deleted file mode 100644 index 948882ce..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2615_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2615_vm b/persistentStorage/data-song-db/base/13066/2615_vm deleted file mode 100644 index 4536ff4a..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2615_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2616 b/persistentStorage/data-song-db/base/13066/2616 deleted file mode 100644 index 4ed2d540..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2616 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2616_fsm b/persistentStorage/data-song-db/base/13066/2616_fsm deleted file mode 100644 index 190c114a..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2616_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2616_vm b/persistentStorage/data-song-db/base/13066/2616_vm deleted file mode 100644 index b8ae452e..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2616_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2617 b/persistentStorage/data-song-db/base/13066/2617 deleted file mode 100644 index aba148f8..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2617 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2617_fsm b/persistentStorage/data-song-db/base/13066/2617_fsm deleted file mode 100644 index a90280bd..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2617_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2617_vm b/persistentStorage/data-song-db/base/13066/2617_vm deleted file mode 100644 index 9272e4f7..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2617_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2618 b/persistentStorage/data-song-db/base/13066/2618 deleted file mode 100644 index df005446..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2618 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2618_fsm b/persistentStorage/data-song-db/base/13066/2618_fsm deleted file mode 100644 index 030e6ca7..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2618_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2618_vm b/persistentStorage/data-song-db/base/13066/2618_vm deleted file mode 100644 index 15ac97f5..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2618_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2619 b/persistentStorage/data-song-db/base/13066/2619 deleted file mode 100644 index f8149fc7..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2619 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2619_fsm b/persistentStorage/data-song-db/base/13066/2619_fsm deleted file mode 100644 index 6dbef269..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2619_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2619_vm b/persistentStorage/data-song-db/base/13066/2619_vm deleted file mode 100644 index d015a350..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2619_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2620 b/persistentStorage/data-song-db/base/13066/2620 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/2620_vm b/persistentStorage/data-song-db/base/13066/2620_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/2650 b/persistentStorage/data-song-db/base/13066/2650 deleted file mode 100644 index 4fe77717..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2650 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2651 b/persistentStorage/data-song-db/base/13066/2651 deleted file mode 100644 index 9fa3ede8..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2651 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2652 b/persistentStorage/data-song-db/base/13066/2652 deleted file mode 100644 index d7414a9a..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2652 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2653 b/persistentStorage/data-song-db/base/13066/2653 deleted file mode 100644 index 068979bc..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2653 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2654 b/persistentStorage/data-song-db/base/13066/2654 deleted file mode 100644 index 394e3b6f..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2654 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2655 b/persistentStorage/data-song-db/base/13066/2655 deleted file mode 100644 index 25baea2d..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2655 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2656 b/persistentStorage/data-song-db/base/13066/2656 deleted file mode 100644 index 4ec744f0..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2656 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2657 b/persistentStorage/data-song-db/base/13066/2657 deleted file mode 100644 index de750e3c..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2657 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2658 b/persistentStorage/data-song-db/base/13066/2658 deleted file mode 100644 index d4557855..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2658 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2659 b/persistentStorage/data-song-db/base/13066/2659 deleted file mode 100644 index 6c7e3f40..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2659 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2660 b/persistentStorage/data-song-db/base/13066/2660 deleted file mode 100644 index 35c7c4fa..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2660 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2661 b/persistentStorage/data-song-db/base/13066/2661 deleted file mode 100644 index 3176dc9d..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2661 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2662 b/persistentStorage/data-song-db/base/13066/2662 deleted file mode 100644 index d72dac39..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2662 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2663 b/persistentStorage/data-song-db/base/13066/2663 deleted file mode 100644 index 53826419..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2663 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2664 b/persistentStorage/data-song-db/base/13066/2664 deleted file mode 100644 index e08344fd..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2664 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2665 b/persistentStorage/data-song-db/base/13066/2665 deleted file mode 100644 index 3193c401..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2665 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2666 b/persistentStorage/data-song-db/base/13066/2666 deleted file mode 100644 index 335f0219..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2666 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2667 b/persistentStorage/data-song-db/base/13066/2667 deleted file mode 100644 index dd026897..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2667 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2668 b/persistentStorage/data-song-db/base/13066/2668 deleted file mode 100644 index a9164882..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2668 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2669 b/persistentStorage/data-song-db/base/13066/2669 deleted file mode 100644 index b1799837..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2669 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2670 b/persistentStorage/data-song-db/base/13066/2670 deleted file mode 100644 index 557d749e..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2670 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2673 b/persistentStorage/data-song-db/base/13066/2673 deleted file mode 100644 index 84ec7c1a..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2673 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2674 b/persistentStorage/data-song-db/base/13066/2674 deleted file mode 100644 index 0fcdb185..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2674 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2675 b/persistentStorage/data-song-db/base/13066/2675 deleted file mode 100644 index 0d3253a7..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2675 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2678 b/persistentStorage/data-song-db/base/13066/2678 deleted file mode 100644 index 067f7693..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2678 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2679 b/persistentStorage/data-song-db/base/13066/2679 deleted file mode 100644 index d1b6c9e0..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2679 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2680 b/persistentStorage/data-song-db/base/13066/2680 deleted file mode 100644 index 5ccb7772..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2680 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2681 b/persistentStorage/data-song-db/base/13066/2681 deleted file mode 100644 index 2252a269..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2681 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2682 b/persistentStorage/data-song-db/base/13066/2682 deleted file mode 100644 index 4c2ac670..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2682 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2683 b/persistentStorage/data-song-db/base/13066/2683 deleted file mode 100644 index 2d90b905..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2683 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2684 b/persistentStorage/data-song-db/base/13066/2684 deleted file mode 100644 index 5672d5af..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2684 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2685 b/persistentStorage/data-song-db/base/13066/2685 deleted file mode 100644 index 64219310..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2685 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2686 b/persistentStorage/data-song-db/base/13066/2686 deleted file mode 100644 index 1cce52ef..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2686 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2687 b/persistentStorage/data-song-db/base/13066/2687 deleted file mode 100644 index f6d0b8a7..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2687 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2688 b/persistentStorage/data-song-db/base/13066/2688 deleted file mode 100644 index e0f79deb..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2688 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2689 b/persistentStorage/data-song-db/base/13066/2689 deleted file mode 100644 index 6e11243f..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2689 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2690 b/persistentStorage/data-song-db/base/13066/2690 deleted file mode 100644 index 40d56d54..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2690 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2691 b/persistentStorage/data-song-db/base/13066/2691 deleted file mode 100644 index fe34196f..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2691 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2692 b/persistentStorage/data-song-db/base/13066/2692 deleted file mode 100644 index 50751afa..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2692 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2693 b/persistentStorage/data-song-db/base/13066/2693 deleted file mode 100644 index 96b012bb..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2693 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2696 b/persistentStorage/data-song-db/base/13066/2696 deleted file mode 100644 index c0b7371f..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2696 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2699 b/persistentStorage/data-song-db/base/13066/2699 deleted file mode 100644 index d3c634ed..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2699 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2701 b/persistentStorage/data-song-db/base/13066/2701 deleted file mode 100644 index 0e85b803..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2701 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2702 b/persistentStorage/data-song-db/base/13066/2702 deleted file mode 100644 index ba82e6bd..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2702 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2703 b/persistentStorage/data-song-db/base/13066/2703 deleted file mode 100644 index 0bc615e9..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2703 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2704 b/persistentStorage/data-song-db/base/13066/2704 deleted file mode 100644 index 3cbe8f98..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2704 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2753 b/persistentStorage/data-song-db/base/13066/2753 deleted file mode 100644 index bc0cb93f..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2753 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2753_fsm b/persistentStorage/data-song-db/base/13066/2753_fsm deleted file mode 100644 index e962a4f5..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2753_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2753_vm b/persistentStorage/data-song-db/base/13066/2753_vm deleted file mode 100644 index 65103a84..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2753_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2754 b/persistentStorage/data-song-db/base/13066/2754 deleted file mode 100644 index 36d63e7e..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2754 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2755 b/persistentStorage/data-song-db/base/13066/2755 deleted file mode 100644 index 2ff74dd5..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2755 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2756 b/persistentStorage/data-song-db/base/13066/2756 deleted file mode 100644 index 5b31770e..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2756 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2757 b/persistentStorage/data-song-db/base/13066/2757 deleted file mode 100644 index 78dbfcd7..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2757 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2830 b/persistentStorage/data-song-db/base/13066/2830 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/2830_vm b/persistentStorage/data-song-db/base/13066/2830_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/2831 b/persistentStorage/data-song-db/base/13066/2831 deleted file mode 100644 index 0149aa9a..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2831 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2832 b/persistentStorage/data-song-db/base/13066/2832 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/2832_vm b/persistentStorage/data-song-db/base/13066/2832_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/2833 b/persistentStorage/data-song-db/base/13066/2833 deleted file mode 100644 index 2afaafbb..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2833 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2834 b/persistentStorage/data-song-db/base/13066/2834 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/2834_vm b/persistentStorage/data-song-db/base/13066/2834_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/2835 b/persistentStorage/data-song-db/base/13066/2835 deleted file mode 100644 index 375600a1..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2835 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2836 b/persistentStorage/data-song-db/base/13066/2836 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/2836_vm b/persistentStorage/data-song-db/base/13066/2836_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/2837 b/persistentStorage/data-song-db/base/13066/2837 deleted file mode 100644 index 80e7375c..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2837 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2838 b/persistentStorage/data-song-db/base/13066/2838 deleted file mode 100644 index ca74c148..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2838 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2838_fsm b/persistentStorage/data-song-db/base/13066/2838_fsm deleted file mode 100644 index 4e32ef90..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2838_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2838_vm b/persistentStorage/data-song-db/base/13066/2838_vm deleted file mode 100644 index 8f6fc319..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2838_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2839 b/persistentStorage/data-song-db/base/13066/2839 deleted file mode 100644 index 80a9515f..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2839 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2840 b/persistentStorage/data-song-db/base/13066/2840 deleted file mode 100644 index bf88e4fe..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2840 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2840_fsm b/persistentStorage/data-song-db/base/13066/2840_fsm deleted file mode 100644 index cbf230f7..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2840_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2840_vm b/persistentStorage/data-song-db/base/13066/2840_vm deleted file mode 100644 index 6b797608..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2840_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2841 b/persistentStorage/data-song-db/base/13066/2841 deleted file mode 100644 index 0d287be6..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2841 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/2995 b/persistentStorage/data-song-db/base/13066/2995 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/2995_vm b/persistentStorage/data-song-db/base/13066/2995_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/2996 b/persistentStorage/data-song-db/base/13066/2996 deleted file mode 100644 index 3a0a8a3b..00000000 Binary files a/persistentStorage/data-song-db/base/13066/2996 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3079 b/persistentStorage/data-song-db/base/13066/3079 deleted file mode 100644 index cbd37332..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3079 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3079_fsm b/persistentStorage/data-song-db/base/13066/3079_fsm deleted file mode 100644 index 7732d22b..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3079_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3079_vm b/persistentStorage/data-song-db/base/13066/3079_vm deleted file mode 100644 index 041508f2..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3079_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3080 b/persistentStorage/data-song-db/base/13066/3080 deleted file mode 100644 index f8c0497f..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3080 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3081 b/persistentStorage/data-song-db/base/13066/3081 deleted file mode 100644 index e82b3a57..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3081 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3085 b/persistentStorage/data-song-db/base/13066/3085 deleted file mode 100644 index 3d091fbb..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3085 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3118 b/persistentStorage/data-song-db/base/13066/3118 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/3118_vm b/persistentStorage/data-song-db/base/13066/3118_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/3119 b/persistentStorage/data-song-db/base/13066/3119 deleted file mode 100644 index 89ce6bec..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3119 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3164 b/persistentStorage/data-song-db/base/13066/3164 deleted file mode 100644 index c5bee0eb..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3164 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3256 b/persistentStorage/data-song-db/base/13066/3256 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/3256_vm b/persistentStorage/data-song-db/base/13066/3256_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/3257 b/persistentStorage/data-song-db/base/13066/3257 deleted file mode 100644 index 1072cde4..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3257 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3258 b/persistentStorage/data-song-db/base/13066/3258 deleted file mode 100644 index b8ad6fda..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3258 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3350 b/persistentStorage/data-song-db/base/13066/3350 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/3350_vm b/persistentStorage/data-song-db/base/13066/3350_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/3351 b/persistentStorage/data-song-db/base/13066/3351 deleted file mode 100644 index 37e64629..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3351 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3379 b/persistentStorage/data-song-db/base/13066/3379 deleted file mode 100644 index a9b554c1..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3379 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3380 b/persistentStorage/data-song-db/base/13066/3380 deleted file mode 100644 index 11d9675b..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3380 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3381 b/persistentStorage/data-song-db/base/13066/3381 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/3381_vm b/persistentStorage/data-song-db/base/13066/3381_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/3394 b/persistentStorage/data-song-db/base/13066/3394 deleted file mode 100644 index 62dfdd73..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3394 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3394_fsm b/persistentStorage/data-song-db/base/13066/3394_fsm deleted file mode 100644 index e63ffab3..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3394_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3394_vm b/persistentStorage/data-song-db/base/13066/3394_vm deleted file mode 100644 index 43fe11be..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3394_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3395 b/persistentStorage/data-song-db/base/13066/3395 deleted file mode 100644 index 3d655ba2..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3395 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3439 b/persistentStorage/data-song-db/base/13066/3439 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/3439_vm b/persistentStorage/data-song-db/base/13066/3439_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/3440 b/persistentStorage/data-song-db/base/13066/3440 deleted file mode 100644 index 5a34d837..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3440 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3455 b/persistentStorage/data-song-db/base/13066/3455 deleted file mode 100644 index df42af62..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3455 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3456 b/persistentStorage/data-song-db/base/13066/3456 deleted file mode 100644 index 9a4de77e..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3456 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3456_fsm b/persistentStorage/data-song-db/base/13066/3456_fsm deleted file mode 100644 index ea43ee9d..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3456_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3456_vm b/persistentStorage/data-song-db/base/13066/3456_vm deleted file mode 100644 index 5c9dc2b3..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3456_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3466 b/persistentStorage/data-song-db/base/13066/3466 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/3466_vm b/persistentStorage/data-song-db/base/13066/3466_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/3467 b/persistentStorage/data-song-db/base/13066/3467 deleted file mode 100644 index 3b8a7cad..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3467 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3468 b/persistentStorage/data-song-db/base/13066/3468 deleted file mode 100644 index 351953a7..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3468 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3501 b/persistentStorage/data-song-db/base/13066/3501 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/3501_vm b/persistentStorage/data-song-db/base/13066/3501_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/3502 b/persistentStorage/data-song-db/base/13066/3502 deleted file mode 100644 index 24d7db5f..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3502 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3503 b/persistentStorage/data-song-db/base/13066/3503 deleted file mode 100644 index 0992f362..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3503 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3534 b/persistentStorage/data-song-db/base/13066/3534 deleted file mode 100644 index 56a983d6..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3534 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3541 b/persistentStorage/data-song-db/base/13066/3541 deleted file mode 100644 index ad69913a..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3541 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3541_fsm b/persistentStorage/data-song-db/base/13066/3541_fsm deleted file mode 100644 index 62f01566..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3541_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3541_vm b/persistentStorage/data-song-db/base/13066/3541_vm deleted file mode 100644 index 6f81205d..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3541_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3542 b/persistentStorage/data-song-db/base/13066/3542 deleted file mode 100644 index e4bfd841..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3542 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3574 b/persistentStorage/data-song-db/base/13066/3574 deleted file mode 100644 index 929626a5..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3574 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3575 b/persistentStorage/data-song-db/base/13066/3575 deleted file mode 100644 index bd5674c3..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3575 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3576 b/persistentStorage/data-song-db/base/13066/3576 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/3576_vm b/persistentStorage/data-song-db/base/13066/3576_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/3596 b/persistentStorage/data-song-db/base/13066/3596 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/3596_vm b/persistentStorage/data-song-db/base/13066/3596_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/3597 b/persistentStorage/data-song-db/base/13066/3597 deleted file mode 100644 index c054e788..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3597 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3598 b/persistentStorage/data-song-db/base/13066/3598 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/3598_vm b/persistentStorage/data-song-db/base/13066/3598_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/3599 b/persistentStorage/data-song-db/base/13066/3599 deleted file mode 100644 index cae63029..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3599 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3600 b/persistentStorage/data-song-db/base/13066/3600 deleted file mode 100644 index 613977cc..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3600 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3600_fsm b/persistentStorage/data-song-db/base/13066/3600_fsm deleted file mode 100644 index ffd4b159..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3600_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3600_vm b/persistentStorage/data-song-db/base/13066/3600_vm deleted file mode 100644 index 5f2324dc..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3600_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3601 b/persistentStorage/data-song-db/base/13066/3601 deleted file mode 100644 index 065e4e19..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3601 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3601_fsm b/persistentStorage/data-song-db/base/13066/3601_fsm deleted file mode 100644 index 7732d22b..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3601_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3601_vm b/persistentStorage/data-song-db/base/13066/3601_vm deleted file mode 100644 index 5d7215c1..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3601_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3602 b/persistentStorage/data-song-db/base/13066/3602 deleted file mode 100644 index cd08d614..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3602 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3602_fsm b/persistentStorage/data-song-db/base/13066/3602_fsm deleted file mode 100644 index 7cbf8340..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3602_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3602_vm b/persistentStorage/data-song-db/base/13066/3602_vm deleted file mode 100644 index 545a04e5..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3602_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3603 b/persistentStorage/data-song-db/base/13066/3603 deleted file mode 100644 index a055b23e..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3603 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3603_fsm b/persistentStorage/data-song-db/base/13066/3603_fsm deleted file mode 100644 index 6d00d685..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3603_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3603_vm b/persistentStorage/data-song-db/base/13066/3603_vm deleted file mode 100644 index c1773b04..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3603_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3604 b/persistentStorage/data-song-db/base/13066/3604 deleted file mode 100644 index 74275331..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3604 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3605 b/persistentStorage/data-song-db/base/13066/3605 deleted file mode 100644 index 2850f784..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3605 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3606 b/persistentStorage/data-song-db/base/13066/3606 deleted file mode 100644 index 7d6e7670..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3606 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3607 b/persistentStorage/data-song-db/base/13066/3607 deleted file mode 100644 index 8c5ad631..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3607 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3608 b/persistentStorage/data-song-db/base/13066/3608 deleted file mode 100644 index e50d2ba5..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3608 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3609 b/persistentStorage/data-song-db/base/13066/3609 deleted file mode 100644 index 8b2e6b4d..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3609 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3712 b/persistentStorage/data-song-db/base/13066/3712 deleted file mode 100644 index 8a67eef7..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3712 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3764 b/persistentStorage/data-song-db/base/13066/3764 deleted file mode 100644 index 971a5c60..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3764 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3764_fsm b/persistentStorage/data-song-db/base/13066/3764_fsm deleted file mode 100644 index d041693e..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3764_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3764_vm b/persistentStorage/data-song-db/base/13066/3764_vm deleted file mode 100644 index 14c5846b..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3764_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3766 b/persistentStorage/data-song-db/base/13066/3766 deleted file mode 100644 index fad3c19c..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3766 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3767 b/persistentStorage/data-song-db/base/13066/3767 deleted file mode 100644 index 63185238..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3767 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/3997 b/persistentStorage/data-song-db/base/13066/3997 deleted file mode 100644 index 4297eb48..00000000 Binary files a/persistentStorage/data-song-db/base/13066/3997 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/5002 b/persistentStorage/data-song-db/base/13066/5002 deleted file mode 100644 index f0a233cd..00000000 Binary files a/persistentStorage/data-song-db/base/13066/5002 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/548 b/persistentStorage/data-song-db/base/13066/548 deleted file mode 100644 index d0f31da0..00000000 Binary files a/persistentStorage/data-song-db/base/13066/548 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/549 b/persistentStorage/data-song-db/base/13066/549 deleted file mode 100644 index 55343ef2..00000000 Binary files a/persistentStorage/data-song-db/base/13066/549 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/6102 b/persistentStorage/data-song-db/base/13066/6102 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/6102_vm b/persistentStorage/data-song-db/base/13066/6102_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/6104 b/persistentStorage/data-song-db/base/13066/6104 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/6104_vm b/persistentStorage/data-song-db/base/13066/6104_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/6106 b/persistentStorage/data-song-db/base/13066/6106 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/6106_vm b/persistentStorage/data-song-db/base/13066/6106_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/6110 b/persistentStorage/data-song-db/base/13066/6110 deleted file mode 100644 index 18a4d692..00000000 Binary files a/persistentStorage/data-song-db/base/13066/6110 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/6111 b/persistentStorage/data-song-db/base/13066/6111 deleted file mode 100644 index f0d7cbc4..00000000 Binary files a/persistentStorage/data-song-db/base/13066/6111 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/6112 b/persistentStorage/data-song-db/base/13066/6112 deleted file mode 100644 index 0518dbc0..00000000 Binary files a/persistentStorage/data-song-db/base/13066/6112 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/6113 b/persistentStorage/data-song-db/base/13066/6113 deleted file mode 100644 index 49a0523d..00000000 Binary files a/persistentStorage/data-song-db/base/13066/6113 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/6117 b/persistentStorage/data-song-db/base/13066/6117 deleted file mode 100644 index f5dd001c..00000000 Binary files a/persistentStorage/data-song-db/base/13066/6117 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/826 b/persistentStorage/data-song-db/base/13066/826 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/826_vm b/persistentStorage/data-song-db/base/13066/826_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13066/827 b/persistentStorage/data-song-db/base/13066/827 deleted file mode 100644 index 136d1d28..00000000 Binary files a/persistentStorage/data-song-db/base/13066/827 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/828 b/persistentStorage/data-song-db/base/13066/828 deleted file mode 100644 index bf8caada..00000000 Binary files a/persistentStorage/data-song-db/base/13066/828 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13066/PG_VERSION b/persistentStorage/data-song-db/base/13066/PG_VERSION deleted file mode 100644 index b4de3947..00000000 --- a/persistentStorage/data-song-db/base/13066/PG_VERSION +++ /dev/null @@ -1 +0,0 @@ -11 diff --git a/persistentStorage/data-song-db/base/13066/pg_filenode.map b/persistentStorage/data-song-db/base/13066/pg_filenode.map deleted file mode 100644 index 428c97e9..00000000 Binary files a/persistentStorage/data-song-db/base/13066/pg_filenode.map and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/112 b/persistentStorage/data-song-db/base/13067/112 deleted file mode 100644 index 4667847b..00000000 Binary files a/persistentStorage/data-song-db/base/13067/112 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/113 b/persistentStorage/data-song-db/base/13067/113 deleted file mode 100644 index 99d1648e..00000000 Binary files a/persistentStorage/data-song-db/base/13067/113 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/1247 b/persistentStorage/data-song-db/base/13067/1247 deleted file mode 100644 index c4062a4d..00000000 Binary files a/persistentStorage/data-song-db/base/13067/1247 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/1247_fsm b/persistentStorage/data-song-db/base/13067/1247_fsm deleted file mode 100644 index f082f631..00000000 Binary files a/persistentStorage/data-song-db/base/13067/1247_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/1247_vm b/persistentStorage/data-song-db/base/13067/1247_vm deleted file mode 100644 index 06b36841..00000000 Binary files a/persistentStorage/data-song-db/base/13067/1247_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/1249 b/persistentStorage/data-song-db/base/13067/1249 deleted file mode 100644 index 0a5d1110..00000000 Binary files a/persistentStorage/data-song-db/base/13067/1249 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/1249_fsm b/persistentStorage/data-song-db/base/13067/1249_fsm deleted file mode 100644 index 2be958d7..00000000 Binary files a/persistentStorage/data-song-db/base/13067/1249_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/1249_vm b/persistentStorage/data-song-db/base/13067/1249_vm deleted file mode 100644 index efb6e3d2..00000000 Binary files a/persistentStorage/data-song-db/base/13067/1249_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/1255 b/persistentStorage/data-song-db/base/13067/1255 deleted file mode 100644 index a15c41f0..00000000 Binary files a/persistentStorage/data-song-db/base/13067/1255 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/1255_fsm b/persistentStorage/data-song-db/base/13067/1255_fsm deleted file mode 100644 index dde16352..00000000 Binary files a/persistentStorage/data-song-db/base/13067/1255_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/1255_vm b/persistentStorage/data-song-db/base/13067/1255_vm deleted file mode 100644 index 66cf3a9b..00000000 Binary files a/persistentStorage/data-song-db/base/13067/1255_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/1259 b/persistentStorage/data-song-db/base/13067/1259 deleted file mode 100644 index 4339d8ba..00000000 Binary files a/persistentStorage/data-song-db/base/13067/1259 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/1259_fsm b/persistentStorage/data-song-db/base/13067/1259_fsm deleted file mode 100644 index 9cba2542..00000000 Binary files a/persistentStorage/data-song-db/base/13067/1259_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/1259_vm b/persistentStorage/data-song-db/base/13067/1259_vm deleted file mode 100644 index a046d262..00000000 Binary files a/persistentStorage/data-song-db/base/13067/1259_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/12902 b/persistentStorage/data-song-db/base/13067/12902 deleted file mode 100644 index d298c664..00000000 Binary files a/persistentStorage/data-song-db/base/13067/12902 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/12902_fsm b/persistentStorage/data-song-db/base/13067/12902_fsm deleted file mode 100644 index 19948ba3..00000000 Binary files a/persistentStorage/data-song-db/base/13067/12902_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/12902_vm b/persistentStorage/data-song-db/base/13067/12902_vm deleted file mode 100644 index e024e219..00000000 Binary files a/persistentStorage/data-song-db/base/13067/12902_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/12904 b/persistentStorage/data-song-db/base/13067/12904 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/12906 b/persistentStorage/data-song-db/base/13067/12906 deleted file mode 100644 index eaaf7f9c..00000000 Binary files a/persistentStorage/data-song-db/base/13067/12906 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/12907 b/persistentStorage/data-song-db/base/13067/12907 deleted file mode 100644 index 39eb183c..00000000 Binary files a/persistentStorage/data-song-db/base/13067/12907 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/12907_fsm b/persistentStorage/data-song-db/base/13067/12907_fsm deleted file mode 100644 index ce7c26eb..00000000 Binary files a/persistentStorage/data-song-db/base/13067/12907_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/12907_vm b/persistentStorage/data-song-db/base/13067/12907_vm deleted file mode 100644 index 7f46a300..00000000 Binary files a/persistentStorage/data-song-db/base/13067/12907_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/12909 b/persistentStorage/data-song-db/base/13067/12909 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/12911 b/persistentStorage/data-song-db/base/13067/12911 deleted file mode 100644 index 24ec5ac2..00000000 Binary files a/persistentStorage/data-song-db/base/13067/12911 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/12912 b/persistentStorage/data-song-db/base/13067/12912 deleted file mode 100644 index b0d3e632..00000000 Binary files a/persistentStorage/data-song-db/base/13067/12912 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/12912_fsm b/persistentStorage/data-song-db/base/13067/12912_fsm deleted file mode 100644 index 98dc620a..00000000 Binary files a/persistentStorage/data-song-db/base/13067/12912_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/12912_vm b/persistentStorage/data-song-db/base/13067/12912_vm deleted file mode 100644 index 754665b0..00000000 Binary files a/persistentStorage/data-song-db/base/13067/12912_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/12914 b/persistentStorage/data-song-db/base/13067/12914 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/12916 b/persistentStorage/data-song-db/base/13067/12916 deleted file mode 100644 index 911c123e..00000000 Binary files a/persistentStorage/data-song-db/base/13067/12916 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/12917 b/persistentStorage/data-song-db/base/13067/12917 deleted file mode 100644 index 75b5dc26..00000000 Binary files a/persistentStorage/data-song-db/base/13067/12917 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/12917_fsm b/persistentStorage/data-song-db/base/13067/12917_fsm deleted file mode 100644 index f8a0e258..00000000 Binary files a/persistentStorage/data-song-db/base/13067/12917_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/12917_vm b/persistentStorage/data-song-db/base/13067/12917_vm deleted file mode 100644 index 999ef8c0..00000000 Binary files a/persistentStorage/data-song-db/base/13067/12917_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/12919 b/persistentStorage/data-song-db/base/13067/12919 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/12921 b/persistentStorage/data-song-db/base/13067/12921 deleted file mode 100644 index 7692fb50..00000000 Binary files a/persistentStorage/data-song-db/base/13067/12921 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/12922 b/persistentStorage/data-song-db/base/13067/12922 deleted file mode 100644 index 70ef93a9..00000000 Binary files a/persistentStorage/data-song-db/base/13067/12922 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/12922_fsm b/persistentStorage/data-song-db/base/13067/12922_fsm deleted file mode 100644 index ecbfaee5..00000000 Binary files a/persistentStorage/data-song-db/base/13067/12922_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/12922_vm b/persistentStorage/data-song-db/base/13067/12922_vm deleted file mode 100644 index 031bad16..00000000 Binary files a/persistentStorage/data-song-db/base/13067/12922_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/12924 b/persistentStorage/data-song-db/base/13067/12924 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/12926 b/persistentStorage/data-song-db/base/13067/12926 deleted file mode 100644 index 0bd7b2a1..00000000 Binary files a/persistentStorage/data-song-db/base/13067/12926 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/12927 b/persistentStorage/data-song-db/base/13067/12927 deleted file mode 100644 index 81d71b93..00000000 Binary files a/persistentStorage/data-song-db/base/13067/12927 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/12927_fsm b/persistentStorage/data-song-db/base/13067/12927_fsm deleted file mode 100644 index a836ddf7..00000000 Binary files a/persistentStorage/data-song-db/base/13067/12927_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/12927_vm b/persistentStorage/data-song-db/base/13067/12927_vm deleted file mode 100644 index dbff9bc0..00000000 Binary files a/persistentStorage/data-song-db/base/13067/12927_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/12929 b/persistentStorage/data-song-db/base/13067/12929 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/12931 b/persistentStorage/data-song-db/base/13067/12931 deleted file mode 100644 index 39e60ec0..00000000 Binary files a/persistentStorage/data-song-db/base/13067/12931 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/12932 b/persistentStorage/data-song-db/base/13067/12932 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/12934 b/persistentStorage/data-song-db/base/13067/12934 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/12936 b/persistentStorage/data-song-db/base/13067/12936 deleted file mode 100644 index 5d072ab6..00000000 Binary files a/persistentStorage/data-song-db/base/13067/12936 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/1417 b/persistentStorage/data-song-db/base/13067/1417 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/1417_vm b/persistentStorage/data-song-db/base/13067/1417_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/1418 b/persistentStorage/data-song-db/base/13067/1418 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/1418_vm b/persistentStorage/data-song-db/base/13067/1418_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/174 b/persistentStorage/data-song-db/base/13067/174 deleted file mode 100644 index b0f68c81..00000000 Binary files a/persistentStorage/data-song-db/base/13067/174 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/175 b/persistentStorage/data-song-db/base/13067/175 deleted file mode 100644 index 09f50ec8..00000000 Binary files a/persistentStorage/data-song-db/base/13067/175 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2187 b/persistentStorage/data-song-db/base/13067/2187 deleted file mode 100644 index b759e4fb..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2187 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2224 b/persistentStorage/data-song-db/base/13067/2224 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/2224_vm b/persistentStorage/data-song-db/base/13067/2224_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/2328 b/persistentStorage/data-song-db/base/13067/2328 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/2328_vm b/persistentStorage/data-song-db/base/13067/2328_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/2336 b/persistentStorage/data-song-db/base/13067/2336 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/2336_vm b/persistentStorage/data-song-db/base/13067/2336_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/2337 b/persistentStorage/data-song-db/base/13067/2337 deleted file mode 100644 index ee992828..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2337 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2579 b/persistentStorage/data-song-db/base/13067/2579 deleted file mode 100644 index f256cc4b..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2579 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2600 b/persistentStorage/data-song-db/base/13067/2600 deleted file mode 100644 index ffdfb66d..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2600 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2600_fsm b/persistentStorage/data-song-db/base/13067/2600_fsm deleted file mode 100644 index e63ffab3..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2600_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2600_vm b/persistentStorage/data-song-db/base/13067/2600_vm deleted file mode 100644 index 562ae092..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2600_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2601 b/persistentStorage/data-song-db/base/13067/2601 deleted file mode 100644 index 1d44fa56..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2601 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2601_fsm b/persistentStorage/data-song-db/base/13067/2601_fsm deleted file mode 100644 index 0908076c..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2601_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2601_vm b/persistentStorage/data-song-db/base/13067/2601_vm deleted file mode 100644 index e136061c..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2601_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2602 b/persistentStorage/data-song-db/base/13067/2602 deleted file mode 100644 index bb94020c..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2602 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2602_fsm b/persistentStorage/data-song-db/base/13067/2602_fsm deleted file mode 100644 index 2f7c0547..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2602_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2602_vm b/persistentStorage/data-song-db/base/13067/2602_vm deleted file mode 100644 index 23b4a397..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2602_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2603 b/persistentStorage/data-song-db/base/13067/2603 deleted file mode 100644 index fc1644f2..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2603 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2603_fsm b/persistentStorage/data-song-db/base/13067/2603_fsm deleted file mode 100644 index 9646dc6c..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2603_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2603_vm b/persistentStorage/data-song-db/base/13067/2603_vm deleted file mode 100644 index f7296825..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2603_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2604 b/persistentStorage/data-song-db/base/13067/2604 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/2604_vm b/persistentStorage/data-song-db/base/13067/2604_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/2605 b/persistentStorage/data-song-db/base/13067/2605 deleted file mode 100644 index 5c0c8aba..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2605 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2605_fsm b/persistentStorage/data-song-db/base/13067/2605_fsm deleted file mode 100644 index 3e435bbe..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2605_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2605_vm b/persistentStorage/data-song-db/base/13067/2605_vm deleted file mode 100644 index 67845a0b..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2605_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2606 b/persistentStorage/data-song-db/base/13067/2606 deleted file mode 100644 index d728c62e..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2606 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2606_fsm b/persistentStorage/data-song-db/base/13067/2606_fsm deleted file mode 100644 index f79adf92..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2606_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2606_vm b/persistentStorage/data-song-db/base/13067/2606_vm deleted file mode 100644 index 8b61fa51..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2606_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2607 b/persistentStorage/data-song-db/base/13067/2607 deleted file mode 100644 index f0bdac3d..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2607 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2607_fsm b/persistentStorage/data-song-db/base/13067/2607_fsm deleted file mode 100644 index 5b066f1a..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2607_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2607_vm b/persistentStorage/data-song-db/base/13067/2607_vm deleted file mode 100644 index 25439067..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2607_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2608 b/persistentStorage/data-song-db/base/13067/2608 deleted file mode 100644 index c840ae43..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2608 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2608_fsm b/persistentStorage/data-song-db/base/13067/2608_fsm deleted file mode 100644 index 9e44fb9e..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2608_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2608_vm b/persistentStorage/data-song-db/base/13067/2608_vm deleted file mode 100644 index 17073ad1..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2608_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2609 b/persistentStorage/data-song-db/base/13067/2609 deleted file mode 100644 index adbbbb19..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2609 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2609_fsm b/persistentStorage/data-song-db/base/13067/2609_fsm deleted file mode 100644 index a8427c61..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2609_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2609_vm b/persistentStorage/data-song-db/base/13067/2609_vm deleted file mode 100644 index 454e602f..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2609_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2610 b/persistentStorage/data-song-db/base/13067/2610 deleted file mode 100644 index d0d5eb8b..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2610 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2610_fsm b/persistentStorage/data-song-db/base/13067/2610_fsm deleted file mode 100644 index 5bb455d6..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2610_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2610_vm b/persistentStorage/data-song-db/base/13067/2610_vm deleted file mode 100644 index c137743f..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2610_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2611 b/persistentStorage/data-song-db/base/13067/2611 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/2611_vm b/persistentStorage/data-song-db/base/13067/2611_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/2612 b/persistentStorage/data-song-db/base/13067/2612 deleted file mode 100644 index 0c8b5d61..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2612 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2612_fsm b/persistentStorage/data-song-db/base/13067/2612_fsm deleted file mode 100644 index 877976ac..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2612_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2612_vm b/persistentStorage/data-song-db/base/13067/2612_vm deleted file mode 100644 index 1a440474..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2612_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2613 b/persistentStorage/data-song-db/base/13067/2613 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/2613_vm b/persistentStorage/data-song-db/base/13067/2613_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/2615 b/persistentStorage/data-song-db/base/13067/2615 deleted file mode 100644 index 16bf9c18..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2615 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2615_fsm b/persistentStorage/data-song-db/base/13067/2615_fsm deleted file mode 100644 index 948882ce..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2615_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2615_vm b/persistentStorage/data-song-db/base/13067/2615_vm deleted file mode 100644 index 4536ff4a..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2615_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2616 b/persistentStorage/data-song-db/base/13067/2616 deleted file mode 100644 index 4ed2d540..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2616 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2616_fsm b/persistentStorage/data-song-db/base/13067/2616_fsm deleted file mode 100644 index 190c114a..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2616_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2616_vm b/persistentStorage/data-song-db/base/13067/2616_vm deleted file mode 100644 index b8ae452e..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2616_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2617 b/persistentStorage/data-song-db/base/13067/2617 deleted file mode 100644 index aba148f8..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2617 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2617_fsm b/persistentStorage/data-song-db/base/13067/2617_fsm deleted file mode 100644 index a90280bd..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2617_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2617_vm b/persistentStorage/data-song-db/base/13067/2617_vm deleted file mode 100644 index 9272e4f7..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2617_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2618 b/persistentStorage/data-song-db/base/13067/2618 deleted file mode 100644 index df005446..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2618 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2618_fsm b/persistentStorage/data-song-db/base/13067/2618_fsm deleted file mode 100644 index 030e6ca7..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2618_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2618_vm b/persistentStorage/data-song-db/base/13067/2618_vm deleted file mode 100644 index 15ac97f5..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2618_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2619 b/persistentStorage/data-song-db/base/13067/2619 deleted file mode 100644 index f8149fc7..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2619 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2619_fsm b/persistentStorage/data-song-db/base/13067/2619_fsm deleted file mode 100644 index 6dbef269..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2619_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2619_vm b/persistentStorage/data-song-db/base/13067/2619_vm deleted file mode 100644 index d015a350..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2619_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2620 b/persistentStorage/data-song-db/base/13067/2620 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/2620_vm b/persistentStorage/data-song-db/base/13067/2620_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/2650 b/persistentStorage/data-song-db/base/13067/2650 deleted file mode 100644 index 4fe77717..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2650 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2651 b/persistentStorage/data-song-db/base/13067/2651 deleted file mode 100644 index 9fa3ede8..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2651 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2652 b/persistentStorage/data-song-db/base/13067/2652 deleted file mode 100644 index d7414a9a..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2652 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2653 b/persistentStorage/data-song-db/base/13067/2653 deleted file mode 100644 index 068979bc..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2653 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2654 b/persistentStorage/data-song-db/base/13067/2654 deleted file mode 100644 index 394e3b6f..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2654 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2655 b/persistentStorage/data-song-db/base/13067/2655 deleted file mode 100644 index 25baea2d..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2655 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2656 b/persistentStorage/data-song-db/base/13067/2656 deleted file mode 100644 index 4ec744f0..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2656 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2657 b/persistentStorage/data-song-db/base/13067/2657 deleted file mode 100644 index de750e3c..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2657 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2658 b/persistentStorage/data-song-db/base/13067/2658 deleted file mode 100644 index d4557855..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2658 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2659 b/persistentStorage/data-song-db/base/13067/2659 deleted file mode 100644 index 6c7e3f40..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2659 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2660 b/persistentStorage/data-song-db/base/13067/2660 deleted file mode 100644 index 35c7c4fa..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2660 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2661 b/persistentStorage/data-song-db/base/13067/2661 deleted file mode 100644 index 3176dc9d..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2661 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2662 b/persistentStorage/data-song-db/base/13067/2662 deleted file mode 100644 index d72dac39..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2662 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2663 b/persistentStorage/data-song-db/base/13067/2663 deleted file mode 100644 index 53826419..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2663 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2664 b/persistentStorage/data-song-db/base/13067/2664 deleted file mode 100644 index e08344fd..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2664 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2665 b/persistentStorage/data-song-db/base/13067/2665 deleted file mode 100644 index 3193c401..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2665 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2666 b/persistentStorage/data-song-db/base/13067/2666 deleted file mode 100644 index 335f0219..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2666 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2667 b/persistentStorage/data-song-db/base/13067/2667 deleted file mode 100644 index dd026897..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2667 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2668 b/persistentStorage/data-song-db/base/13067/2668 deleted file mode 100644 index a9164882..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2668 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2669 b/persistentStorage/data-song-db/base/13067/2669 deleted file mode 100644 index b1799837..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2669 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2670 b/persistentStorage/data-song-db/base/13067/2670 deleted file mode 100644 index 557d749e..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2670 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2673 b/persistentStorage/data-song-db/base/13067/2673 deleted file mode 100644 index 84ec7c1a..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2673 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2674 b/persistentStorage/data-song-db/base/13067/2674 deleted file mode 100644 index 0fcdb185..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2674 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2675 b/persistentStorage/data-song-db/base/13067/2675 deleted file mode 100644 index 0d3253a7..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2675 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2678 b/persistentStorage/data-song-db/base/13067/2678 deleted file mode 100644 index 067f7693..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2678 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2679 b/persistentStorage/data-song-db/base/13067/2679 deleted file mode 100644 index d1b6c9e0..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2679 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2680 b/persistentStorage/data-song-db/base/13067/2680 deleted file mode 100644 index 5ccb7772..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2680 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2681 b/persistentStorage/data-song-db/base/13067/2681 deleted file mode 100644 index 2252a269..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2681 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2682 b/persistentStorage/data-song-db/base/13067/2682 deleted file mode 100644 index 4c2ac670..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2682 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2683 b/persistentStorage/data-song-db/base/13067/2683 deleted file mode 100644 index 2d90b905..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2683 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2684 b/persistentStorage/data-song-db/base/13067/2684 deleted file mode 100644 index 5672d5af..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2684 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2685 b/persistentStorage/data-song-db/base/13067/2685 deleted file mode 100644 index 64219310..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2685 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2686 b/persistentStorage/data-song-db/base/13067/2686 deleted file mode 100644 index 1cce52ef..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2686 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2687 b/persistentStorage/data-song-db/base/13067/2687 deleted file mode 100644 index f6d0b8a7..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2687 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2688 b/persistentStorage/data-song-db/base/13067/2688 deleted file mode 100644 index e0f79deb..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2688 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2689 b/persistentStorage/data-song-db/base/13067/2689 deleted file mode 100644 index 6e11243f..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2689 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2690 b/persistentStorage/data-song-db/base/13067/2690 deleted file mode 100644 index 40d56d54..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2690 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2691 b/persistentStorage/data-song-db/base/13067/2691 deleted file mode 100644 index fe34196f..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2691 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2692 b/persistentStorage/data-song-db/base/13067/2692 deleted file mode 100644 index 50751afa..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2692 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2693 b/persistentStorage/data-song-db/base/13067/2693 deleted file mode 100644 index 96b012bb..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2693 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2696 b/persistentStorage/data-song-db/base/13067/2696 deleted file mode 100644 index c0b7371f..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2696 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2699 b/persistentStorage/data-song-db/base/13067/2699 deleted file mode 100644 index d3c634ed..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2699 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2701 b/persistentStorage/data-song-db/base/13067/2701 deleted file mode 100644 index 0e85b803..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2701 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2702 b/persistentStorage/data-song-db/base/13067/2702 deleted file mode 100644 index ba82e6bd..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2702 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2703 b/persistentStorage/data-song-db/base/13067/2703 deleted file mode 100644 index 0bc615e9..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2703 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2704 b/persistentStorage/data-song-db/base/13067/2704 deleted file mode 100644 index 3cbe8f98..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2704 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2753 b/persistentStorage/data-song-db/base/13067/2753 deleted file mode 100644 index bc0cb93f..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2753 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2753_fsm b/persistentStorage/data-song-db/base/13067/2753_fsm deleted file mode 100644 index e962a4f5..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2753_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2753_vm b/persistentStorage/data-song-db/base/13067/2753_vm deleted file mode 100644 index 65103a84..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2753_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2754 b/persistentStorage/data-song-db/base/13067/2754 deleted file mode 100644 index 36d63e7e..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2754 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2755 b/persistentStorage/data-song-db/base/13067/2755 deleted file mode 100644 index 2ff74dd5..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2755 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2756 b/persistentStorage/data-song-db/base/13067/2756 deleted file mode 100644 index 5b31770e..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2756 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2757 b/persistentStorage/data-song-db/base/13067/2757 deleted file mode 100644 index 78dbfcd7..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2757 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2830 b/persistentStorage/data-song-db/base/13067/2830 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/2830_vm b/persistentStorage/data-song-db/base/13067/2830_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/2831 b/persistentStorage/data-song-db/base/13067/2831 deleted file mode 100644 index 0149aa9a..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2831 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2832 b/persistentStorage/data-song-db/base/13067/2832 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/2832_vm b/persistentStorage/data-song-db/base/13067/2832_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/2833 b/persistentStorage/data-song-db/base/13067/2833 deleted file mode 100644 index 2afaafbb..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2833 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2834 b/persistentStorage/data-song-db/base/13067/2834 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/2834_vm b/persistentStorage/data-song-db/base/13067/2834_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/2835 b/persistentStorage/data-song-db/base/13067/2835 deleted file mode 100644 index 375600a1..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2835 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2836 b/persistentStorage/data-song-db/base/13067/2836 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/2836_vm b/persistentStorage/data-song-db/base/13067/2836_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/2837 b/persistentStorage/data-song-db/base/13067/2837 deleted file mode 100644 index 80e7375c..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2837 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2838 b/persistentStorage/data-song-db/base/13067/2838 deleted file mode 100644 index ca74c148..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2838 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2838_fsm b/persistentStorage/data-song-db/base/13067/2838_fsm deleted file mode 100644 index 4e32ef90..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2838_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2838_vm b/persistentStorage/data-song-db/base/13067/2838_vm deleted file mode 100644 index 8f6fc319..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2838_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2839 b/persistentStorage/data-song-db/base/13067/2839 deleted file mode 100644 index 80a9515f..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2839 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2840 b/persistentStorage/data-song-db/base/13067/2840 deleted file mode 100644 index bf88e4fe..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2840 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2840_fsm b/persistentStorage/data-song-db/base/13067/2840_fsm deleted file mode 100644 index cbf230f7..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2840_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2840_vm b/persistentStorage/data-song-db/base/13067/2840_vm deleted file mode 100644 index 6b797608..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2840_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2841 b/persistentStorage/data-song-db/base/13067/2841 deleted file mode 100644 index 0d287be6..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2841 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/2995 b/persistentStorage/data-song-db/base/13067/2995 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/2995_vm b/persistentStorage/data-song-db/base/13067/2995_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/2996 b/persistentStorage/data-song-db/base/13067/2996 deleted file mode 100644 index 3a0a8a3b..00000000 Binary files a/persistentStorage/data-song-db/base/13067/2996 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3079 b/persistentStorage/data-song-db/base/13067/3079 deleted file mode 100644 index cbd37332..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3079 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3079_fsm b/persistentStorage/data-song-db/base/13067/3079_fsm deleted file mode 100644 index 7732d22b..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3079_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3079_vm b/persistentStorage/data-song-db/base/13067/3079_vm deleted file mode 100644 index 041508f2..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3079_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3080 b/persistentStorage/data-song-db/base/13067/3080 deleted file mode 100644 index f8c0497f..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3080 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3081 b/persistentStorage/data-song-db/base/13067/3081 deleted file mode 100644 index e82b3a57..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3081 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3085 b/persistentStorage/data-song-db/base/13067/3085 deleted file mode 100644 index 3d091fbb..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3085 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3118 b/persistentStorage/data-song-db/base/13067/3118 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/3118_vm b/persistentStorage/data-song-db/base/13067/3118_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/3119 b/persistentStorage/data-song-db/base/13067/3119 deleted file mode 100644 index 89ce6bec..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3119 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3164 b/persistentStorage/data-song-db/base/13067/3164 deleted file mode 100644 index c5bee0eb..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3164 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3256 b/persistentStorage/data-song-db/base/13067/3256 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/3256_vm b/persistentStorage/data-song-db/base/13067/3256_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/3257 b/persistentStorage/data-song-db/base/13067/3257 deleted file mode 100644 index 1072cde4..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3257 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3258 b/persistentStorage/data-song-db/base/13067/3258 deleted file mode 100644 index b8ad6fda..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3258 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3350 b/persistentStorage/data-song-db/base/13067/3350 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/3350_vm b/persistentStorage/data-song-db/base/13067/3350_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/3351 b/persistentStorage/data-song-db/base/13067/3351 deleted file mode 100644 index 37e64629..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3351 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3379 b/persistentStorage/data-song-db/base/13067/3379 deleted file mode 100644 index a9b554c1..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3379 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3380 b/persistentStorage/data-song-db/base/13067/3380 deleted file mode 100644 index 11d9675b..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3380 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3381 b/persistentStorage/data-song-db/base/13067/3381 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/3381_vm b/persistentStorage/data-song-db/base/13067/3381_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/3394 b/persistentStorage/data-song-db/base/13067/3394 deleted file mode 100644 index 62dfdd73..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3394 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3394_fsm b/persistentStorage/data-song-db/base/13067/3394_fsm deleted file mode 100644 index e63ffab3..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3394_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3394_vm b/persistentStorage/data-song-db/base/13067/3394_vm deleted file mode 100644 index 43fe11be..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3394_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3395 b/persistentStorage/data-song-db/base/13067/3395 deleted file mode 100644 index 3d655ba2..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3395 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3439 b/persistentStorage/data-song-db/base/13067/3439 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/3439_vm b/persistentStorage/data-song-db/base/13067/3439_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/3440 b/persistentStorage/data-song-db/base/13067/3440 deleted file mode 100644 index 5a34d837..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3440 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3455 b/persistentStorage/data-song-db/base/13067/3455 deleted file mode 100644 index df42af62..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3455 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3456 b/persistentStorage/data-song-db/base/13067/3456 deleted file mode 100644 index 9a4de77e..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3456 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3456_fsm b/persistentStorage/data-song-db/base/13067/3456_fsm deleted file mode 100644 index ea43ee9d..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3456_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3456_vm b/persistentStorage/data-song-db/base/13067/3456_vm deleted file mode 100644 index 5c9dc2b3..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3456_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3466 b/persistentStorage/data-song-db/base/13067/3466 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/3466_vm b/persistentStorage/data-song-db/base/13067/3466_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/3467 b/persistentStorage/data-song-db/base/13067/3467 deleted file mode 100644 index 3b8a7cad..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3467 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3468 b/persistentStorage/data-song-db/base/13067/3468 deleted file mode 100644 index 351953a7..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3468 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3501 b/persistentStorage/data-song-db/base/13067/3501 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/3501_vm b/persistentStorage/data-song-db/base/13067/3501_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/3502 b/persistentStorage/data-song-db/base/13067/3502 deleted file mode 100644 index 24d7db5f..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3502 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3503 b/persistentStorage/data-song-db/base/13067/3503 deleted file mode 100644 index 0992f362..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3503 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3534 b/persistentStorage/data-song-db/base/13067/3534 deleted file mode 100644 index 56a983d6..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3534 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3541 b/persistentStorage/data-song-db/base/13067/3541 deleted file mode 100644 index ad69913a..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3541 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3541_fsm b/persistentStorage/data-song-db/base/13067/3541_fsm deleted file mode 100644 index 62f01566..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3541_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3541_vm b/persistentStorage/data-song-db/base/13067/3541_vm deleted file mode 100644 index 6f81205d..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3541_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3542 b/persistentStorage/data-song-db/base/13067/3542 deleted file mode 100644 index e4bfd841..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3542 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3574 b/persistentStorage/data-song-db/base/13067/3574 deleted file mode 100644 index 929626a5..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3574 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3575 b/persistentStorage/data-song-db/base/13067/3575 deleted file mode 100644 index bd5674c3..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3575 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3576 b/persistentStorage/data-song-db/base/13067/3576 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/3576_vm b/persistentStorage/data-song-db/base/13067/3576_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/3596 b/persistentStorage/data-song-db/base/13067/3596 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/3596_vm b/persistentStorage/data-song-db/base/13067/3596_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/3597 b/persistentStorage/data-song-db/base/13067/3597 deleted file mode 100644 index c054e788..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3597 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3598 b/persistentStorage/data-song-db/base/13067/3598 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/3598_vm b/persistentStorage/data-song-db/base/13067/3598_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/3599 b/persistentStorage/data-song-db/base/13067/3599 deleted file mode 100644 index cae63029..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3599 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3600 b/persistentStorage/data-song-db/base/13067/3600 deleted file mode 100644 index 613977cc..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3600 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3600_fsm b/persistentStorage/data-song-db/base/13067/3600_fsm deleted file mode 100644 index ffd4b159..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3600_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3600_vm b/persistentStorage/data-song-db/base/13067/3600_vm deleted file mode 100644 index 5f2324dc..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3600_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3601 b/persistentStorage/data-song-db/base/13067/3601 deleted file mode 100644 index 065e4e19..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3601 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3601_fsm b/persistentStorage/data-song-db/base/13067/3601_fsm deleted file mode 100644 index 7732d22b..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3601_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3601_vm b/persistentStorage/data-song-db/base/13067/3601_vm deleted file mode 100644 index 5d7215c1..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3601_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3602 b/persistentStorage/data-song-db/base/13067/3602 deleted file mode 100644 index cd08d614..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3602 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3602_fsm b/persistentStorage/data-song-db/base/13067/3602_fsm deleted file mode 100644 index 7cbf8340..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3602_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3602_vm b/persistentStorage/data-song-db/base/13067/3602_vm deleted file mode 100644 index 545a04e5..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3602_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3603 b/persistentStorage/data-song-db/base/13067/3603 deleted file mode 100644 index a055b23e..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3603 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3603_fsm b/persistentStorage/data-song-db/base/13067/3603_fsm deleted file mode 100644 index 6d00d685..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3603_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3603_vm b/persistentStorage/data-song-db/base/13067/3603_vm deleted file mode 100644 index c1773b04..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3603_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3604 b/persistentStorage/data-song-db/base/13067/3604 deleted file mode 100644 index 74275331..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3604 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3605 b/persistentStorage/data-song-db/base/13067/3605 deleted file mode 100644 index 2850f784..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3605 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3606 b/persistentStorage/data-song-db/base/13067/3606 deleted file mode 100644 index 7d6e7670..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3606 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3607 b/persistentStorage/data-song-db/base/13067/3607 deleted file mode 100644 index 8c5ad631..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3607 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3608 b/persistentStorage/data-song-db/base/13067/3608 deleted file mode 100644 index e50d2ba5..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3608 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3609 b/persistentStorage/data-song-db/base/13067/3609 deleted file mode 100644 index 8b2e6b4d..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3609 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3712 b/persistentStorage/data-song-db/base/13067/3712 deleted file mode 100644 index 8a67eef7..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3712 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3764 b/persistentStorage/data-song-db/base/13067/3764 deleted file mode 100644 index 971a5c60..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3764 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3764_fsm b/persistentStorage/data-song-db/base/13067/3764_fsm deleted file mode 100644 index d041693e..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3764_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3764_vm b/persistentStorage/data-song-db/base/13067/3764_vm deleted file mode 100644 index 14c5846b..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3764_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3766 b/persistentStorage/data-song-db/base/13067/3766 deleted file mode 100644 index fad3c19c..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3766 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3767 b/persistentStorage/data-song-db/base/13067/3767 deleted file mode 100644 index 63185238..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3767 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/3997 b/persistentStorage/data-song-db/base/13067/3997 deleted file mode 100644 index 4297eb48..00000000 Binary files a/persistentStorage/data-song-db/base/13067/3997 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/5002 b/persistentStorage/data-song-db/base/13067/5002 deleted file mode 100644 index f0a233cd..00000000 Binary files a/persistentStorage/data-song-db/base/13067/5002 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/548 b/persistentStorage/data-song-db/base/13067/548 deleted file mode 100644 index d0f31da0..00000000 Binary files a/persistentStorage/data-song-db/base/13067/548 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/549 b/persistentStorage/data-song-db/base/13067/549 deleted file mode 100644 index 55343ef2..00000000 Binary files a/persistentStorage/data-song-db/base/13067/549 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/6102 b/persistentStorage/data-song-db/base/13067/6102 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/6102_vm b/persistentStorage/data-song-db/base/13067/6102_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/6104 b/persistentStorage/data-song-db/base/13067/6104 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/6104_vm b/persistentStorage/data-song-db/base/13067/6104_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/6106 b/persistentStorage/data-song-db/base/13067/6106 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/6106_vm b/persistentStorage/data-song-db/base/13067/6106_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/6110 b/persistentStorage/data-song-db/base/13067/6110 deleted file mode 100644 index 18a4d692..00000000 Binary files a/persistentStorage/data-song-db/base/13067/6110 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/6111 b/persistentStorage/data-song-db/base/13067/6111 deleted file mode 100644 index f0d7cbc4..00000000 Binary files a/persistentStorage/data-song-db/base/13067/6111 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/6112 b/persistentStorage/data-song-db/base/13067/6112 deleted file mode 100644 index 0518dbc0..00000000 Binary files a/persistentStorage/data-song-db/base/13067/6112 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/6113 b/persistentStorage/data-song-db/base/13067/6113 deleted file mode 100644 index 49a0523d..00000000 Binary files a/persistentStorage/data-song-db/base/13067/6113 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/6117 b/persistentStorage/data-song-db/base/13067/6117 deleted file mode 100644 index f5dd001c..00000000 Binary files a/persistentStorage/data-song-db/base/13067/6117 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/826 b/persistentStorage/data-song-db/base/13067/826 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/826_vm b/persistentStorage/data-song-db/base/13067/826_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/13067/827 b/persistentStorage/data-song-db/base/13067/827 deleted file mode 100644 index 136d1d28..00000000 Binary files a/persistentStorage/data-song-db/base/13067/827 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/828 b/persistentStorage/data-song-db/base/13067/828 deleted file mode 100644 index bf8caada..00000000 Binary files a/persistentStorage/data-song-db/base/13067/828 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/13067/PG_VERSION b/persistentStorage/data-song-db/base/13067/PG_VERSION deleted file mode 100644 index b4de3947..00000000 --- a/persistentStorage/data-song-db/base/13067/PG_VERSION +++ /dev/null @@ -1 +0,0 @@ -11 diff --git a/persistentStorage/data-song-db/base/13067/pg_filenode.map b/persistentStorage/data-song-db/base/13067/pg_filenode.map deleted file mode 100644 index 428c97e9..00000000 Binary files a/persistentStorage/data-song-db/base/13067/pg_filenode.map and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/112 b/persistentStorage/data-song-db/base/16384/112 deleted file mode 100644 index 4667847b..00000000 Binary files a/persistentStorage/data-song-db/base/16384/112 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/113 b/persistentStorage/data-song-db/base/16384/113 deleted file mode 100644 index 99d1648e..00000000 Binary files a/persistentStorage/data-song-db/base/16384/113 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/1247 b/persistentStorage/data-song-db/base/16384/1247 deleted file mode 100644 index 7fddc97d..00000000 Binary files a/persistentStorage/data-song-db/base/16384/1247 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/1247_fsm b/persistentStorage/data-song-db/base/16384/1247_fsm deleted file mode 100644 index 2b28dd54..00000000 Binary files a/persistentStorage/data-song-db/base/16384/1247_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/1247_vm b/persistentStorage/data-song-db/base/16384/1247_vm deleted file mode 100644 index e5901aa0..00000000 Binary files a/persistentStorage/data-song-db/base/16384/1247_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/1249 b/persistentStorage/data-song-db/base/16384/1249 deleted file mode 100644 index 25ac0d52..00000000 Binary files a/persistentStorage/data-song-db/base/16384/1249 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/1249_fsm b/persistentStorage/data-song-db/base/16384/1249_fsm deleted file mode 100644 index c1061fb4..00000000 Binary files a/persistentStorage/data-song-db/base/16384/1249_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/1249_vm b/persistentStorage/data-song-db/base/16384/1249_vm deleted file mode 100644 index 98ed38ce..00000000 Binary files a/persistentStorage/data-song-db/base/16384/1249_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/1255 b/persistentStorage/data-song-db/base/16384/1255 deleted file mode 100644 index 0310f8b7..00000000 Binary files a/persistentStorage/data-song-db/base/16384/1255 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/1255_fsm b/persistentStorage/data-song-db/base/16384/1255_fsm deleted file mode 100644 index 8b5f6e0d..00000000 Binary files a/persistentStorage/data-song-db/base/16384/1255_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/1255_vm b/persistentStorage/data-song-db/base/16384/1255_vm deleted file mode 100644 index c175e28a..00000000 Binary files a/persistentStorage/data-song-db/base/16384/1255_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/1259 b/persistentStorage/data-song-db/base/16384/1259 deleted file mode 100644 index ea800cea..00000000 Binary files a/persistentStorage/data-song-db/base/16384/1259 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/1259_fsm b/persistentStorage/data-song-db/base/16384/1259_fsm deleted file mode 100644 index 171b3651..00000000 Binary files a/persistentStorage/data-song-db/base/16384/1259_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/1259_vm b/persistentStorage/data-song-db/base/16384/1259_vm deleted file mode 100644 index d5635fb9..00000000 Binary files a/persistentStorage/data-song-db/base/16384/1259_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/12902 b/persistentStorage/data-song-db/base/16384/12902 deleted file mode 100644 index d298c664..00000000 Binary files a/persistentStorage/data-song-db/base/16384/12902 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/12902_fsm b/persistentStorage/data-song-db/base/16384/12902_fsm deleted file mode 100644 index 19948ba3..00000000 Binary files a/persistentStorage/data-song-db/base/16384/12902_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/12902_vm b/persistentStorage/data-song-db/base/16384/12902_vm deleted file mode 100644 index e024e219..00000000 Binary files a/persistentStorage/data-song-db/base/16384/12902_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/12904 b/persistentStorage/data-song-db/base/16384/12904 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/12906 b/persistentStorage/data-song-db/base/16384/12906 deleted file mode 100644 index eaaf7f9c..00000000 Binary files a/persistentStorage/data-song-db/base/16384/12906 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/12907 b/persistentStorage/data-song-db/base/16384/12907 deleted file mode 100644 index 39eb183c..00000000 Binary files a/persistentStorage/data-song-db/base/16384/12907 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/12907_fsm b/persistentStorage/data-song-db/base/16384/12907_fsm deleted file mode 100644 index ce7c26eb..00000000 Binary files a/persistentStorage/data-song-db/base/16384/12907_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/12907_vm b/persistentStorage/data-song-db/base/16384/12907_vm deleted file mode 100644 index 7f46a300..00000000 Binary files a/persistentStorage/data-song-db/base/16384/12907_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/12909 b/persistentStorage/data-song-db/base/16384/12909 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/12911 b/persistentStorage/data-song-db/base/16384/12911 deleted file mode 100644 index 24ec5ac2..00000000 Binary files a/persistentStorage/data-song-db/base/16384/12911 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/12912 b/persistentStorage/data-song-db/base/16384/12912 deleted file mode 100644 index b0d3e632..00000000 Binary files a/persistentStorage/data-song-db/base/16384/12912 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/12912_fsm b/persistentStorage/data-song-db/base/16384/12912_fsm deleted file mode 100644 index 98dc620a..00000000 Binary files a/persistentStorage/data-song-db/base/16384/12912_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/12912_vm b/persistentStorage/data-song-db/base/16384/12912_vm deleted file mode 100644 index 754665b0..00000000 Binary files a/persistentStorage/data-song-db/base/16384/12912_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/12914 b/persistentStorage/data-song-db/base/16384/12914 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/12916 b/persistentStorage/data-song-db/base/16384/12916 deleted file mode 100644 index 911c123e..00000000 Binary files a/persistentStorage/data-song-db/base/16384/12916 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/12917 b/persistentStorage/data-song-db/base/16384/12917 deleted file mode 100644 index 75b5dc26..00000000 Binary files a/persistentStorage/data-song-db/base/16384/12917 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/12917_fsm b/persistentStorage/data-song-db/base/16384/12917_fsm deleted file mode 100644 index f8a0e258..00000000 Binary files a/persistentStorage/data-song-db/base/16384/12917_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/12917_vm b/persistentStorage/data-song-db/base/16384/12917_vm deleted file mode 100644 index 999ef8c0..00000000 Binary files a/persistentStorage/data-song-db/base/16384/12917_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/12919 b/persistentStorage/data-song-db/base/16384/12919 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/12921 b/persistentStorage/data-song-db/base/16384/12921 deleted file mode 100644 index 7692fb50..00000000 Binary files a/persistentStorage/data-song-db/base/16384/12921 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/12922 b/persistentStorage/data-song-db/base/16384/12922 deleted file mode 100644 index 70ef93a9..00000000 Binary files a/persistentStorage/data-song-db/base/16384/12922 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/12922_fsm b/persistentStorage/data-song-db/base/16384/12922_fsm deleted file mode 100644 index ecbfaee5..00000000 Binary files a/persistentStorage/data-song-db/base/16384/12922_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/12922_vm b/persistentStorage/data-song-db/base/16384/12922_vm deleted file mode 100644 index 031bad16..00000000 Binary files a/persistentStorage/data-song-db/base/16384/12922_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/12924 b/persistentStorage/data-song-db/base/16384/12924 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/12926 b/persistentStorage/data-song-db/base/16384/12926 deleted file mode 100644 index 0bd7b2a1..00000000 Binary files a/persistentStorage/data-song-db/base/16384/12926 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/12927 b/persistentStorage/data-song-db/base/16384/12927 deleted file mode 100644 index 81d71b93..00000000 Binary files a/persistentStorage/data-song-db/base/16384/12927 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/12927_fsm b/persistentStorage/data-song-db/base/16384/12927_fsm deleted file mode 100644 index a836ddf7..00000000 Binary files a/persistentStorage/data-song-db/base/16384/12927_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/12927_vm b/persistentStorage/data-song-db/base/16384/12927_vm deleted file mode 100644 index dbff9bc0..00000000 Binary files a/persistentStorage/data-song-db/base/16384/12927_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/12929 b/persistentStorage/data-song-db/base/16384/12929 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/12931 b/persistentStorage/data-song-db/base/16384/12931 deleted file mode 100644 index 39e60ec0..00000000 Binary files a/persistentStorage/data-song-db/base/16384/12931 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/12932 b/persistentStorage/data-song-db/base/16384/12932 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/12934 b/persistentStorage/data-song-db/base/16384/12934 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/12936 b/persistentStorage/data-song-db/base/16384/12936 deleted file mode 100644 index 5d072ab6..00000000 Binary files a/persistentStorage/data-song-db/base/16384/12936 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/1417 b/persistentStorage/data-song-db/base/16384/1417 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/1417_vm b/persistentStorage/data-song-db/base/16384/1417_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/1418 b/persistentStorage/data-song-db/base/16384/1418 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/1418_vm b/persistentStorage/data-song-db/base/16384/1418_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/16385 b/persistentStorage/data-song-db/base/16384/16385 deleted file mode 100644 index 4eb24194..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16385 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16389 b/persistentStorage/data-song-db/base/16384/16389 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/16391 b/persistentStorage/data-song-db/base/16384/16391 deleted file mode 100644 index f0474ef5..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16391 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16392 b/persistentStorage/data-song-db/base/16384/16392 deleted file mode 100644 index 8b3f406a..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16392 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16394 b/persistentStorage/data-song-db/base/16384/16394 deleted file mode 100644 index 4557c5f0..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16394 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16567 b/persistentStorage/data-song-db/base/16384/16567 deleted file mode 100644 index 460f7b0b..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16567 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16570 b/persistentStorage/data-song-db/base/16384/16570 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/16572 b/persistentStorage/data-song-db/base/16384/16572 deleted file mode 100644 index 6d891208..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16572 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16573 b/persistentStorage/data-song-db/base/16384/16573 deleted file mode 100644 index 02633c97..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16573 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16575 b/persistentStorage/data-song-db/base/16384/16575 deleted file mode 100644 index 799a57b0..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16575 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16578 b/persistentStorage/data-song-db/base/16384/16578 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/16580 b/persistentStorage/data-song-db/base/16384/16580 deleted file mode 100644 index a9a2193c..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16580 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16581 b/persistentStorage/data-song-db/base/16384/16581 deleted file mode 100644 index 780792cc..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16581 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16588 b/persistentStorage/data-song-db/base/16384/16588 deleted file mode 100644 index 09ed83a3..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16588 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16591 b/persistentStorage/data-song-db/base/16384/16591 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/16593 b/persistentStorage/data-song-db/base/16384/16593 deleted file mode 100644 index a9d9fc2b..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16593 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16594 b/persistentStorage/data-song-db/base/16384/16594 deleted file mode 100644 index 5ab7ce34..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16594 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16601 b/persistentStorage/data-song-db/base/16384/16601 deleted file mode 100644 index 9b8ad3fe..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16601 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16604 b/persistentStorage/data-song-db/base/16384/16604 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/16606 b/persistentStorage/data-song-db/base/16384/16606 deleted file mode 100644 index a5548ef4..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16606 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16607 b/persistentStorage/data-song-db/base/16384/16607 deleted file mode 100644 index f5122764..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16607 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16614 b/persistentStorage/data-song-db/base/16384/16614 deleted file mode 100644 index 141d44fd..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16614 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16617 b/persistentStorage/data-song-db/base/16384/16617 deleted file mode 100644 index db563969..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16617 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16624 b/persistentStorage/data-song-db/base/16384/16624 deleted file mode 100644 index c9872b9e..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16624 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16624_fsm b/persistentStorage/data-song-db/base/16384/16624_fsm deleted file mode 100644 index 9e166650..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16624_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16627 b/persistentStorage/data-song-db/base/16384/16627 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/16629 b/persistentStorage/data-song-db/base/16384/16629 deleted file mode 100644 index 82b94c4a..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16629 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16630 b/persistentStorage/data-song-db/base/16384/16630 deleted file mode 100644 index 8f49fe64..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16630 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16642 b/persistentStorage/data-song-db/base/16384/16642 deleted file mode 100644 index f44dbea4..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16642 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16677 b/persistentStorage/data-song-db/base/16384/16677 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/16682 b/persistentStorage/data-song-db/base/16384/16682 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/16684 b/persistentStorage/data-song-db/base/16384/16684 deleted file mode 100644 index be785847..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16684 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16685 b/persistentStorage/data-song-db/base/16384/16685 deleted file mode 100644 index 4a52e4c6..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16685 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16692 b/persistentStorage/data-song-db/base/16384/16692 deleted file mode 100644 index 6b91b3d4..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16692 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16692_fsm b/persistentStorage/data-song-db/base/16384/16692_fsm deleted file mode 100644 index 74952c70..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16692_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16695 b/persistentStorage/data-song-db/base/16384/16695 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/16697 b/persistentStorage/data-song-db/base/16384/16697 deleted file mode 100644 index 5e0b440e..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16697 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16718 b/persistentStorage/data-song-db/base/16384/16718 deleted file mode 100644 index 87842a00..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16718 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16719 b/persistentStorage/data-song-db/base/16384/16719 deleted file mode 100644 index 1a48e873..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16719 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16720 b/persistentStorage/data-song-db/base/16384/16720 deleted file mode 100644 index 7360c6ee..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16720 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16721 b/persistentStorage/data-song-db/base/16384/16721 deleted file mode 100644 index 2ee26c40..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16721 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16722 b/persistentStorage/data-song-db/base/16384/16722 deleted file mode 100644 index 6ff237eb..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16722 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16723 b/persistentStorage/data-song-db/base/16384/16723 deleted file mode 100644 index f3bdd0fa..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16723 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16724 b/persistentStorage/data-song-db/base/16384/16724 deleted file mode 100644 index 1f07fad6..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16724 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16725 b/persistentStorage/data-song-db/base/16384/16725 deleted file mode 100644 index 0091eab9..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16725 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16726 b/persistentStorage/data-song-db/base/16384/16726 deleted file mode 100644 index 97e99722..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16726 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16727 b/persistentStorage/data-song-db/base/16384/16727 deleted file mode 100644 index 761a00ed..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16727 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16728 b/persistentStorage/data-song-db/base/16384/16728 deleted file mode 100644 index 5d9937a9..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16728 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16729 b/persistentStorage/data-song-db/base/16384/16729 deleted file mode 100644 index 827da663..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16729 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16730 b/persistentStorage/data-song-db/base/16384/16730 deleted file mode 100644 index d719baa6..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16730 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16731 b/persistentStorage/data-song-db/base/16384/16731 deleted file mode 100644 index 658607ef..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16731 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16732 b/persistentStorage/data-song-db/base/16384/16732 deleted file mode 100644 index a7aecc3e..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16732 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16733 b/persistentStorage/data-song-db/base/16384/16733 deleted file mode 100644 index 3e1c7baf..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16733 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16734 b/persistentStorage/data-song-db/base/16384/16734 deleted file mode 100644 index 5fbf3b2a..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16734 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16735 b/persistentStorage/data-song-db/base/16384/16735 deleted file mode 100644 index 6df6c1d4..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16735 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16736 b/persistentStorage/data-song-db/base/16384/16736 deleted file mode 100644 index 691db46b..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16736 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16737 b/persistentStorage/data-song-db/base/16384/16737 deleted file mode 100644 index 98517a08..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16737 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16738 b/persistentStorage/data-song-db/base/16384/16738 deleted file mode 100644 index d81b7ad5..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16738 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16739 b/persistentStorage/data-song-db/base/16384/16739 deleted file mode 100644 index 3265ea44..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16739 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16740 b/persistentStorage/data-song-db/base/16384/16740 deleted file mode 100644 index 44d6c298..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16740 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16741 b/persistentStorage/data-song-db/base/16384/16741 deleted file mode 100644 index a58428e6..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16741 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16742 b/persistentStorage/data-song-db/base/16384/16742 deleted file mode 100644 index 93d15b20..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16742 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16743 b/persistentStorage/data-song-db/base/16384/16743 deleted file mode 100644 index c4df35de..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16743 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16746 b/persistentStorage/data-song-db/base/16384/16746 deleted file mode 100644 index 1f821ff0..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16746 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16747 b/persistentStorage/data-song-db/base/16384/16747 deleted file mode 100644 index e8f5b054..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16747 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16748 b/persistentStorage/data-song-db/base/16384/16748 deleted file mode 100644 index 46fd999f..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16748 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16749 b/persistentStorage/data-song-db/base/16384/16749 deleted file mode 100644 index cb0d74a3..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16749 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16750 b/persistentStorage/data-song-db/base/16384/16750 deleted file mode 100644 index 351c7336..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16750 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16751 b/persistentStorage/data-song-db/base/16384/16751 deleted file mode 100644 index 9db0f1d7..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16751 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16763 b/persistentStorage/data-song-db/base/16384/16763 deleted file mode 100644 index cdca3772..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16763 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16765 b/persistentStorage/data-song-db/base/16384/16765 deleted file mode 100644 index 3ab54595..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16765 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16769 b/persistentStorage/data-song-db/base/16384/16769 deleted file mode 100644 index a5aeacf7..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16769 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16769_fsm b/persistentStorage/data-song-db/base/16384/16769_fsm deleted file mode 100644 index ddc5352b..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16769_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16771 b/persistentStorage/data-song-db/base/16384/16771 deleted file mode 100644 index cff5b46b..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16771 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16772 b/persistentStorage/data-song-db/base/16384/16772 deleted file mode 100644 index 24ce371e..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16772 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16774 b/persistentStorage/data-song-db/base/16384/16774 deleted file mode 100644 index d95e55c7..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16774 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16775 b/persistentStorage/data-song-db/base/16384/16775 deleted file mode 100644 index 422260c6..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16775 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16776 b/persistentStorage/data-song-db/base/16384/16776 deleted file mode 100644 index 4a200285..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16776 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16782 b/persistentStorage/data-song-db/base/16384/16782 deleted file mode 100644 index 0086a560..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16782 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16784 b/persistentStorage/data-song-db/base/16384/16784 deleted file mode 100644 index 7b4082d8..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16784 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16784_fsm b/persistentStorage/data-song-db/base/16384/16784_fsm deleted file mode 100644 index 2d26cf91..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16784_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16788 b/persistentStorage/data-song-db/base/16384/16788 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/16790 b/persistentStorage/data-song-db/base/16384/16790 deleted file mode 100644 index 1aa95d9c..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16790 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16791 b/persistentStorage/data-song-db/base/16384/16791 deleted file mode 100644 index abf302bb..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16791 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16947 b/persistentStorage/data-song-db/base/16384/16947 deleted file mode 100644 index dc275614..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16947 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16949 b/persistentStorage/data-song-db/base/16384/16949 deleted file mode 100644 index 59cf205e..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16949 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16954 b/persistentStorage/data-song-db/base/16384/16954 deleted file mode 100644 index 296898ac..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16954 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/16961 b/persistentStorage/data-song-db/base/16384/16961 deleted file mode 100644 index 1b8765c4..00000000 Binary files a/persistentStorage/data-song-db/base/16384/16961 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/174 b/persistentStorage/data-song-db/base/16384/174 deleted file mode 100644 index b0f68c81..00000000 Binary files a/persistentStorage/data-song-db/base/16384/174 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/175 b/persistentStorage/data-song-db/base/16384/175 deleted file mode 100644 index 09f50ec8..00000000 Binary files a/persistentStorage/data-song-db/base/16384/175 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2187 b/persistentStorage/data-song-db/base/16384/2187 deleted file mode 100644 index b759e4fb..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2187 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2224 b/persistentStorage/data-song-db/base/16384/2224 deleted file mode 100644 index 4a49fb74..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2224 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2224_vm b/persistentStorage/data-song-db/base/16384/2224_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/2328 b/persistentStorage/data-song-db/base/16384/2328 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/2328_vm b/persistentStorage/data-song-db/base/16384/2328_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/2336 b/persistentStorage/data-song-db/base/16384/2336 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/2336_vm b/persistentStorage/data-song-db/base/16384/2336_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/2337 b/persistentStorage/data-song-db/base/16384/2337 deleted file mode 100644 index ee992828..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2337 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2579 b/persistentStorage/data-song-db/base/16384/2579 deleted file mode 100644 index 8707a480..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2579 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2600 b/persistentStorage/data-song-db/base/16384/2600 deleted file mode 100644 index ffdfb66d..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2600 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2600_fsm b/persistentStorage/data-song-db/base/16384/2600_fsm deleted file mode 100644 index e63ffab3..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2600_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2600_vm b/persistentStorage/data-song-db/base/16384/2600_vm deleted file mode 100644 index 562ae092..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2600_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2601 b/persistentStorage/data-song-db/base/16384/2601 deleted file mode 100644 index 1d44fa56..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2601 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2601_fsm b/persistentStorage/data-song-db/base/16384/2601_fsm deleted file mode 100644 index 0908076c..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2601_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2601_vm b/persistentStorage/data-song-db/base/16384/2601_vm deleted file mode 100644 index e136061c..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2601_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2602 b/persistentStorage/data-song-db/base/16384/2602 deleted file mode 100644 index bb94020c..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2602 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2602_fsm b/persistentStorage/data-song-db/base/16384/2602_fsm deleted file mode 100644 index 2f7c0547..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2602_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2602_vm b/persistentStorage/data-song-db/base/16384/2602_vm deleted file mode 100644 index 23b4a397..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2602_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2603 b/persistentStorage/data-song-db/base/16384/2603 deleted file mode 100644 index fc1644f2..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2603 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2603_fsm b/persistentStorage/data-song-db/base/16384/2603_fsm deleted file mode 100644 index 9646dc6c..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2603_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2603_vm b/persistentStorage/data-song-db/base/16384/2603_vm deleted file mode 100644 index f7296825..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2603_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2604 b/persistentStorage/data-song-db/base/16384/2604 deleted file mode 100644 index bf2f2156..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2604 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2604_vm b/persistentStorage/data-song-db/base/16384/2604_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/2605 b/persistentStorage/data-song-db/base/16384/2605 deleted file mode 100644 index 5c0c8aba..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2605 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2605_fsm b/persistentStorage/data-song-db/base/16384/2605_fsm deleted file mode 100644 index 3e435bbe..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2605_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2605_vm b/persistentStorage/data-song-db/base/16384/2605_vm deleted file mode 100644 index 67845a0b..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2605_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2606 b/persistentStorage/data-song-db/base/16384/2606 deleted file mode 100644 index add132f5..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2606 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2606_fsm b/persistentStorage/data-song-db/base/16384/2606_fsm deleted file mode 100644 index f79adf92..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2606_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2606_vm b/persistentStorage/data-song-db/base/16384/2606_vm deleted file mode 100644 index 1fefb339..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2606_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2607 b/persistentStorage/data-song-db/base/16384/2607 deleted file mode 100644 index f0bdac3d..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2607 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2607_fsm b/persistentStorage/data-song-db/base/16384/2607_fsm deleted file mode 100644 index 5b066f1a..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2607_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2607_vm b/persistentStorage/data-song-db/base/16384/2607_vm deleted file mode 100644 index 25439067..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2607_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2608 b/persistentStorage/data-song-db/base/16384/2608 deleted file mode 100644 index 537bb546..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2608 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2608_fsm b/persistentStorage/data-song-db/base/16384/2608_fsm deleted file mode 100644 index 50fd434f..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2608_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2608_vm b/persistentStorage/data-song-db/base/16384/2608_vm deleted file mode 100644 index 785744b8..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2608_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2609 b/persistentStorage/data-song-db/base/16384/2609 deleted file mode 100644 index 1e5e0dd4..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2609 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2609_fsm b/persistentStorage/data-song-db/base/16384/2609_fsm deleted file mode 100644 index a8427c61..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2609_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2609_vm b/persistentStorage/data-song-db/base/16384/2609_vm deleted file mode 100644 index 30ef1c57..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2609_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2610 b/persistentStorage/data-song-db/base/16384/2610 deleted file mode 100644 index 54168ffe..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2610 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2610_fsm b/persistentStorage/data-song-db/base/16384/2610_fsm deleted file mode 100644 index f8b644ae..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2610_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2610_vm b/persistentStorage/data-song-db/base/16384/2610_vm deleted file mode 100644 index c137743f..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2610_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2611 b/persistentStorage/data-song-db/base/16384/2611 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/2611_vm b/persistentStorage/data-song-db/base/16384/2611_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/2612 b/persistentStorage/data-song-db/base/16384/2612 deleted file mode 100644 index 0c8b5d61..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2612 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2612_fsm b/persistentStorage/data-song-db/base/16384/2612_fsm deleted file mode 100644 index 877976ac..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2612_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2612_vm b/persistentStorage/data-song-db/base/16384/2612_vm deleted file mode 100644 index 1a440474..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2612_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2613 b/persistentStorage/data-song-db/base/16384/2613 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/2613_vm b/persistentStorage/data-song-db/base/16384/2613_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/2615 b/persistentStorage/data-song-db/base/16384/2615 deleted file mode 100644 index 16bf9c18..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2615 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2615_fsm b/persistentStorage/data-song-db/base/16384/2615_fsm deleted file mode 100644 index 948882ce..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2615_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2615_vm b/persistentStorage/data-song-db/base/16384/2615_vm deleted file mode 100644 index 4536ff4a..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2615_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2616 b/persistentStorage/data-song-db/base/16384/2616 deleted file mode 100644 index 4ed2d540..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2616 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2616_fsm b/persistentStorage/data-song-db/base/16384/2616_fsm deleted file mode 100644 index 190c114a..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2616_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2616_vm b/persistentStorage/data-song-db/base/16384/2616_vm deleted file mode 100644 index b8ae452e..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2616_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2617 b/persistentStorage/data-song-db/base/16384/2617 deleted file mode 100644 index aba148f8..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2617 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2617_fsm b/persistentStorage/data-song-db/base/16384/2617_fsm deleted file mode 100644 index a90280bd..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2617_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2617_vm b/persistentStorage/data-song-db/base/16384/2617_vm deleted file mode 100644 index 9272e4f7..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2617_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2618 b/persistentStorage/data-song-db/base/16384/2618 deleted file mode 100644 index 26c840dd..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2618 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2618_fsm b/persistentStorage/data-song-db/base/16384/2618_fsm deleted file mode 100644 index 030e6ca7..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2618_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2618_vm b/persistentStorage/data-song-db/base/16384/2618_vm deleted file mode 100644 index f309f08f..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2618_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2619 b/persistentStorage/data-song-db/base/16384/2619 deleted file mode 100644 index b762b100..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2619 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2619_fsm b/persistentStorage/data-song-db/base/16384/2619_fsm deleted file mode 100644 index 68ab2a7b..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2619_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2619_vm b/persistentStorage/data-song-db/base/16384/2619_vm deleted file mode 100644 index cfc8921a..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2619_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2620 b/persistentStorage/data-song-db/base/16384/2620 deleted file mode 100644 index f5dde992..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2620 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2620_vm b/persistentStorage/data-song-db/base/16384/2620_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/2650 b/persistentStorage/data-song-db/base/16384/2650 deleted file mode 100644 index 4fe77717..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2650 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2651 b/persistentStorage/data-song-db/base/16384/2651 deleted file mode 100644 index 9fa3ede8..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2651 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2652 b/persistentStorage/data-song-db/base/16384/2652 deleted file mode 100644 index d7414a9a..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2652 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2653 b/persistentStorage/data-song-db/base/16384/2653 deleted file mode 100644 index 068979bc..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2653 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2654 b/persistentStorage/data-song-db/base/16384/2654 deleted file mode 100644 index 394e3b6f..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2654 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2655 b/persistentStorage/data-song-db/base/16384/2655 deleted file mode 100644 index 25baea2d..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2655 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2656 b/persistentStorage/data-song-db/base/16384/2656 deleted file mode 100644 index ccfb95d9..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2656 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2657 b/persistentStorage/data-song-db/base/16384/2657 deleted file mode 100644 index 1eb3d3f0..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2657 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2658 b/persistentStorage/data-song-db/base/16384/2658 deleted file mode 100644 index 7884d45c..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2658 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2659 b/persistentStorage/data-song-db/base/16384/2659 deleted file mode 100644 index b3bcdffe..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2659 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2660 b/persistentStorage/data-song-db/base/16384/2660 deleted file mode 100644 index 35c7c4fa..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2660 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2661 b/persistentStorage/data-song-db/base/16384/2661 deleted file mode 100644 index 3176dc9d..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2661 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2662 b/persistentStorage/data-song-db/base/16384/2662 deleted file mode 100644 index c740d277..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2662 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2663 b/persistentStorage/data-song-db/base/16384/2663 deleted file mode 100644 index 9c0e41bb..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2663 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2664 b/persistentStorage/data-song-db/base/16384/2664 deleted file mode 100644 index 11a82195..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2664 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2665 b/persistentStorage/data-song-db/base/16384/2665 deleted file mode 100644 index 794302b5..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2665 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2666 b/persistentStorage/data-song-db/base/16384/2666 deleted file mode 100644 index fd826764..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2666 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2667 b/persistentStorage/data-song-db/base/16384/2667 deleted file mode 100644 index 31b74f02..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2667 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2668 b/persistentStorage/data-song-db/base/16384/2668 deleted file mode 100644 index a9164882..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2668 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2669 b/persistentStorage/data-song-db/base/16384/2669 deleted file mode 100644 index b1799837..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2669 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2670 b/persistentStorage/data-song-db/base/16384/2670 deleted file mode 100644 index 557d749e..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2670 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2673 b/persistentStorage/data-song-db/base/16384/2673 deleted file mode 100644 index b2b6f116..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2673 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2674 b/persistentStorage/data-song-db/base/16384/2674 deleted file mode 100644 index 8a57715a..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2674 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2675 b/persistentStorage/data-song-db/base/16384/2675 deleted file mode 100644 index a865a6ee..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2675 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2678 b/persistentStorage/data-song-db/base/16384/2678 deleted file mode 100644 index 7f052b26..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2678 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2679 b/persistentStorage/data-song-db/base/16384/2679 deleted file mode 100644 index 2106ca5b..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2679 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2680 b/persistentStorage/data-song-db/base/16384/2680 deleted file mode 100644 index 5ccb7772..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2680 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2681 b/persistentStorage/data-song-db/base/16384/2681 deleted file mode 100644 index 2252a269..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2681 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2682 b/persistentStorage/data-song-db/base/16384/2682 deleted file mode 100644 index 4c2ac670..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2682 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2683 b/persistentStorage/data-song-db/base/16384/2683 deleted file mode 100644 index 2d90b905..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2683 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2684 b/persistentStorage/data-song-db/base/16384/2684 deleted file mode 100644 index 5672d5af..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2684 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2685 b/persistentStorage/data-song-db/base/16384/2685 deleted file mode 100644 index 64219310..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2685 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2686 b/persistentStorage/data-song-db/base/16384/2686 deleted file mode 100644 index 1cce52ef..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2686 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2687 b/persistentStorage/data-song-db/base/16384/2687 deleted file mode 100644 index f6d0b8a7..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2687 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2688 b/persistentStorage/data-song-db/base/16384/2688 deleted file mode 100644 index e0f79deb..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2688 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2689 b/persistentStorage/data-song-db/base/16384/2689 deleted file mode 100644 index 6e11243f..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2689 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2690 b/persistentStorage/data-song-db/base/16384/2690 deleted file mode 100644 index 312a2743..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2690 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2691 b/persistentStorage/data-song-db/base/16384/2691 deleted file mode 100644 index 732d710a..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2691 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2692 b/persistentStorage/data-song-db/base/16384/2692 deleted file mode 100644 index 13e4b1fc..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2692 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2693 b/persistentStorage/data-song-db/base/16384/2693 deleted file mode 100644 index 29d5c9b8..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2693 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2696 b/persistentStorage/data-song-db/base/16384/2696 deleted file mode 100644 index bb4a4516..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2696 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2699 b/persistentStorage/data-song-db/base/16384/2699 deleted file mode 100644 index 1b38c68e..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2699 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2701 b/persistentStorage/data-song-db/base/16384/2701 deleted file mode 100644 index 6f6d04d5..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2701 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2702 b/persistentStorage/data-song-db/base/16384/2702 deleted file mode 100644 index f455dde7..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2702 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2703 b/persistentStorage/data-song-db/base/16384/2703 deleted file mode 100644 index ba4b2223..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2703 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2704 b/persistentStorage/data-song-db/base/16384/2704 deleted file mode 100644 index 9721b520..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2704 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2753 b/persistentStorage/data-song-db/base/16384/2753 deleted file mode 100644 index bc0cb93f..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2753 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2753_fsm b/persistentStorage/data-song-db/base/16384/2753_fsm deleted file mode 100644 index e962a4f5..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2753_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2753_vm b/persistentStorage/data-song-db/base/16384/2753_vm deleted file mode 100644 index 65103a84..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2753_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2754 b/persistentStorage/data-song-db/base/16384/2754 deleted file mode 100644 index 36d63e7e..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2754 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2755 b/persistentStorage/data-song-db/base/16384/2755 deleted file mode 100644 index 2ff74dd5..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2755 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2756 b/persistentStorage/data-song-db/base/16384/2756 deleted file mode 100644 index 5b31770e..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2756 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2757 b/persistentStorage/data-song-db/base/16384/2757 deleted file mode 100644 index 78dbfcd7..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2757 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2830 b/persistentStorage/data-song-db/base/16384/2830 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/2830_vm b/persistentStorage/data-song-db/base/16384/2830_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/2831 b/persistentStorage/data-song-db/base/16384/2831 deleted file mode 100644 index 0149aa9a..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2831 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2832 b/persistentStorage/data-song-db/base/16384/2832 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/2832_vm b/persistentStorage/data-song-db/base/16384/2832_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/2833 b/persistentStorage/data-song-db/base/16384/2833 deleted file mode 100644 index 2afaafbb..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2833 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2834 b/persistentStorage/data-song-db/base/16384/2834 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/2834_vm b/persistentStorage/data-song-db/base/16384/2834_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/2835 b/persistentStorage/data-song-db/base/16384/2835 deleted file mode 100644 index 375600a1..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2835 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2836 b/persistentStorage/data-song-db/base/16384/2836 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/2836_vm b/persistentStorage/data-song-db/base/16384/2836_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/2837 b/persistentStorage/data-song-db/base/16384/2837 deleted file mode 100644 index 80e7375c..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2837 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2838 b/persistentStorage/data-song-db/base/16384/2838 deleted file mode 100644 index 92882c4b..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2838 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2838_fsm b/persistentStorage/data-song-db/base/16384/2838_fsm deleted file mode 100644 index 60d5036a..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2838_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2838_vm b/persistentStorage/data-song-db/base/16384/2838_vm deleted file mode 100644 index 9cb44774..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2838_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2839 b/persistentStorage/data-song-db/base/16384/2839 deleted file mode 100644 index aa4faedd..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2839 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2840 b/persistentStorage/data-song-db/base/16384/2840 deleted file mode 100644 index 43dbcfa6..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2840 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2840_fsm b/persistentStorage/data-song-db/base/16384/2840_fsm deleted file mode 100644 index 5456b2a6..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2840_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2840_vm b/persistentStorage/data-song-db/base/16384/2840_vm deleted file mode 100644 index 57adaf40..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2840_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2841 b/persistentStorage/data-song-db/base/16384/2841 deleted file mode 100644 index 74ba9907..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2841 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/2995 b/persistentStorage/data-song-db/base/16384/2995 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/2995_vm b/persistentStorage/data-song-db/base/16384/2995_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/2996 b/persistentStorage/data-song-db/base/16384/2996 deleted file mode 100644 index 3a0a8a3b..00000000 Binary files a/persistentStorage/data-song-db/base/16384/2996 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3079 b/persistentStorage/data-song-db/base/16384/3079 deleted file mode 100644 index 0a50e2cb..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3079 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3079_fsm b/persistentStorage/data-song-db/base/16384/3079_fsm deleted file mode 100644 index 7732d22b..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3079_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3079_vm b/persistentStorage/data-song-db/base/16384/3079_vm deleted file mode 100644 index ac37567f..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3079_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3080 b/persistentStorage/data-song-db/base/16384/3080 deleted file mode 100644 index 1777cead..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3080 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3081 b/persistentStorage/data-song-db/base/16384/3081 deleted file mode 100644 index ab0957b9..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3081 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3085 b/persistentStorage/data-song-db/base/16384/3085 deleted file mode 100644 index 3d091fbb..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3085 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3118 b/persistentStorage/data-song-db/base/16384/3118 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/3118_vm b/persistentStorage/data-song-db/base/16384/3118_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/3119 b/persistentStorage/data-song-db/base/16384/3119 deleted file mode 100644 index 89ce6bec..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3119 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3164 b/persistentStorage/data-song-db/base/16384/3164 deleted file mode 100644 index c5bee0eb..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3164 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3256 b/persistentStorage/data-song-db/base/16384/3256 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/3256_vm b/persistentStorage/data-song-db/base/16384/3256_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/3257 b/persistentStorage/data-song-db/base/16384/3257 deleted file mode 100644 index 1072cde4..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3257 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3258 b/persistentStorage/data-song-db/base/16384/3258 deleted file mode 100644 index b8ad6fda..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3258 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3350 b/persistentStorage/data-song-db/base/16384/3350 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/3350_vm b/persistentStorage/data-song-db/base/16384/3350_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/3351 b/persistentStorage/data-song-db/base/16384/3351 deleted file mode 100644 index 37e64629..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3351 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3379 b/persistentStorage/data-song-db/base/16384/3379 deleted file mode 100644 index a9b554c1..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3379 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3380 b/persistentStorage/data-song-db/base/16384/3380 deleted file mode 100644 index 11d9675b..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3380 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3381 b/persistentStorage/data-song-db/base/16384/3381 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/3381_vm b/persistentStorage/data-song-db/base/16384/3381_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/3394 b/persistentStorage/data-song-db/base/16384/3394 deleted file mode 100644 index 62dfdd73..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3394 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3394_fsm b/persistentStorage/data-song-db/base/16384/3394_fsm deleted file mode 100644 index e63ffab3..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3394_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3394_vm b/persistentStorage/data-song-db/base/16384/3394_vm deleted file mode 100644 index 43fe11be..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3394_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3395 b/persistentStorage/data-song-db/base/16384/3395 deleted file mode 100644 index 3d655ba2..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3395 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3439 b/persistentStorage/data-song-db/base/16384/3439 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/3439_vm b/persistentStorage/data-song-db/base/16384/3439_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/3440 b/persistentStorage/data-song-db/base/16384/3440 deleted file mode 100644 index 5a34d837..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3440 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3455 b/persistentStorage/data-song-db/base/16384/3455 deleted file mode 100644 index e8071347..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3455 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3456 b/persistentStorage/data-song-db/base/16384/3456 deleted file mode 100644 index 9a4de77e..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3456 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3456_fsm b/persistentStorage/data-song-db/base/16384/3456_fsm deleted file mode 100644 index ea43ee9d..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3456_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3456_vm b/persistentStorage/data-song-db/base/16384/3456_vm deleted file mode 100644 index 5c9dc2b3..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3456_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3466 b/persistentStorage/data-song-db/base/16384/3466 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/3466_vm b/persistentStorage/data-song-db/base/16384/3466_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/3467 b/persistentStorage/data-song-db/base/16384/3467 deleted file mode 100644 index 3b8a7cad..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3467 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3468 b/persistentStorage/data-song-db/base/16384/3468 deleted file mode 100644 index 351953a7..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3468 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3501 b/persistentStorage/data-song-db/base/16384/3501 deleted file mode 100644 index 7ff7e3a0..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3501 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3501_fsm b/persistentStorage/data-song-db/base/16384/3501_fsm deleted file mode 100644 index 0a9dda61..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3501_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3501_vm b/persistentStorage/data-song-db/base/16384/3501_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/3502 b/persistentStorage/data-song-db/base/16384/3502 deleted file mode 100644 index af086934..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3502 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3503 b/persistentStorage/data-song-db/base/16384/3503 deleted file mode 100644 index 11c8f1c8..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3503 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3534 b/persistentStorage/data-song-db/base/16384/3534 deleted file mode 100644 index 2732405d..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3534 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3541 b/persistentStorage/data-song-db/base/16384/3541 deleted file mode 100644 index ad69913a..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3541 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3541_fsm b/persistentStorage/data-song-db/base/16384/3541_fsm deleted file mode 100644 index 62f01566..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3541_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3541_vm b/persistentStorage/data-song-db/base/16384/3541_vm deleted file mode 100644 index 6f81205d..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3541_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3542 b/persistentStorage/data-song-db/base/16384/3542 deleted file mode 100644 index e4bfd841..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3542 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3574 b/persistentStorage/data-song-db/base/16384/3574 deleted file mode 100644 index 929626a5..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3574 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3575 b/persistentStorage/data-song-db/base/16384/3575 deleted file mode 100644 index bd5674c3..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3575 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3576 b/persistentStorage/data-song-db/base/16384/3576 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/3576_vm b/persistentStorage/data-song-db/base/16384/3576_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/3596 b/persistentStorage/data-song-db/base/16384/3596 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/3596_vm b/persistentStorage/data-song-db/base/16384/3596_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/3597 b/persistentStorage/data-song-db/base/16384/3597 deleted file mode 100644 index c054e788..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3597 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3598 b/persistentStorage/data-song-db/base/16384/3598 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/3598_vm b/persistentStorage/data-song-db/base/16384/3598_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/3599 b/persistentStorage/data-song-db/base/16384/3599 deleted file mode 100644 index cae63029..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3599 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3600 b/persistentStorage/data-song-db/base/16384/3600 deleted file mode 100644 index 613977cc..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3600 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3600_fsm b/persistentStorage/data-song-db/base/16384/3600_fsm deleted file mode 100644 index ffd4b159..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3600_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3600_vm b/persistentStorage/data-song-db/base/16384/3600_vm deleted file mode 100644 index 5f2324dc..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3600_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3601 b/persistentStorage/data-song-db/base/16384/3601 deleted file mode 100644 index 065e4e19..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3601 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3601_fsm b/persistentStorage/data-song-db/base/16384/3601_fsm deleted file mode 100644 index 7732d22b..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3601_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3601_vm b/persistentStorage/data-song-db/base/16384/3601_vm deleted file mode 100644 index 5d7215c1..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3601_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3602 b/persistentStorage/data-song-db/base/16384/3602 deleted file mode 100644 index cd08d614..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3602 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3602_fsm b/persistentStorage/data-song-db/base/16384/3602_fsm deleted file mode 100644 index 7cbf8340..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3602_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3602_vm b/persistentStorage/data-song-db/base/16384/3602_vm deleted file mode 100644 index 545a04e5..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3602_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3603 b/persistentStorage/data-song-db/base/16384/3603 deleted file mode 100644 index a055b23e..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3603 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3603_fsm b/persistentStorage/data-song-db/base/16384/3603_fsm deleted file mode 100644 index 6d00d685..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3603_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3603_vm b/persistentStorage/data-song-db/base/16384/3603_vm deleted file mode 100644 index c1773b04..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3603_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3604 b/persistentStorage/data-song-db/base/16384/3604 deleted file mode 100644 index 74275331..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3604 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3605 b/persistentStorage/data-song-db/base/16384/3605 deleted file mode 100644 index 2850f784..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3605 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3606 b/persistentStorage/data-song-db/base/16384/3606 deleted file mode 100644 index 7d6e7670..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3606 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3607 b/persistentStorage/data-song-db/base/16384/3607 deleted file mode 100644 index 8c5ad631..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3607 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3608 b/persistentStorage/data-song-db/base/16384/3608 deleted file mode 100644 index e50d2ba5..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3608 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3609 b/persistentStorage/data-song-db/base/16384/3609 deleted file mode 100644 index 8b2e6b4d..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3609 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3712 b/persistentStorage/data-song-db/base/16384/3712 deleted file mode 100644 index 8a67eef7..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3712 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3764 b/persistentStorage/data-song-db/base/16384/3764 deleted file mode 100644 index 971a5c60..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3764 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3764_fsm b/persistentStorage/data-song-db/base/16384/3764_fsm deleted file mode 100644 index d041693e..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3764_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3764_vm b/persistentStorage/data-song-db/base/16384/3764_vm deleted file mode 100644 index 14c5846b..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3764_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3766 b/persistentStorage/data-song-db/base/16384/3766 deleted file mode 100644 index fad3c19c..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3766 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3767 b/persistentStorage/data-song-db/base/16384/3767 deleted file mode 100644 index 63185238..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3767 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/3997 b/persistentStorage/data-song-db/base/16384/3997 deleted file mode 100644 index 4297eb48..00000000 Binary files a/persistentStorage/data-song-db/base/16384/3997 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/5002 b/persistentStorage/data-song-db/base/16384/5002 deleted file mode 100644 index a34e474e..00000000 Binary files a/persistentStorage/data-song-db/base/16384/5002 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/548 b/persistentStorage/data-song-db/base/16384/548 deleted file mode 100644 index d0f31da0..00000000 Binary files a/persistentStorage/data-song-db/base/16384/548 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/549 b/persistentStorage/data-song-db/base/16384/549 deleted file mode 100644 index 55343ef2..00000000 Binary files a/persistentStorage/data-song-db/base/16384/549 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/6102 b/persistentStorage/data-song-db/base/16384/6102 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/6102_vm b/persistentStorage/data-song-db/base/16384/6102_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/6104 b/persistentStorage/data-song-db/base/16384/6104 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/6104_vm b/persistentStorage/data-song-db/base/16384/6104_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/6106 b/persistentStorage/data-song-db/base/16384/6106 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/6106_vm b/persistentStorage/data-song-db/base/16384/6106_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/6110 b/persistentStorage/data-song-db/base/16384/6110 deleted file mode 100644 index 18a4d692..00000000 Binary files a/persistentStorage/data-song-db/base/16384/6110 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/6111 b/persistentStorage/data-song-db/base/16384/6111 deleted file mode 100644 index f0d7cbc4..00000000 Binary files a/persistentStorage/data-song-db/base/16384/6111 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/6112 b/persistentStorage/data-song-db/base/16384/6112 deleted file mode 100644 index 0518dbc0..00000000 Binary files a/persistentStorage/data-song-db/base/16384/6112 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/6113 b/persistentStorage/data-song-db/base/16384/6113 deleted file mode 100644 index 49a0523d..00000000 Binary files a/persistentStorage/data-song-db/base/16384/6113 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/6117 b/persistentStorage/data-song-db/base/16384/6117 deleted file mode 100644 index f5dd001c..00000000 Binary files a/persistentStorage/data-song-db/base/16384/6117 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/826 b/persistentStorage/data-song-db/base/16384/826 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/826_vm b/persistentStorage/data-song-db/base/16384/826_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/base/16384/827 b/persistentStorage/data-song-db/base/16384/827 deleted file mode 100644 index 136d1d28..00000000 Binary files a/persistentStorage/data-song-db/base/16384/827 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/828 b/persistentStorage/data-song-db/base/16384/828 deleted file mode 100644 index bf8caada..00000000 Binary files a/persistentStorage/data-song-db/base/16384/828 and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/PG_VERSION b/persistentStorage/data-song-db/base/16384/PG_VERSION deleted file mode 100644 index b4de3947..00000000 --- a/persistentStorage/data-song-db/base/16384/PG_VERSION +++ /dev/null @@ -1 +0,0 @@ -11 diff --git a/persistentStorage/data-song-db/base/16384/pg_filenode.map b/persistentStorage/data-song-db/base/16384/pg_filenode.map deleted file mode 100644 index 428c97e9..00000000 Binary files a/persistentStorage/data-song-db/base/16384/pg_filenode.map and /dev/null differ diff --git a/persistentStorage/data-song-db/base/16384/pg_internal.init b/persistentStorage/data-song-db/base/16384/pg_internal.init deleted file mode 100644 index 0cb9110b..00000000 Binary files a/persistentStorage/data-song-db/base/16384/pg_internal.init and /dev/null differ diff --git a/persistentStorage/data-song-db/global/1136 b/persistentStorage/data-song-db/global/1136 deleted file mode 100644 index 3d03f0bd..00000000 Binary files a/persistentStorage/data-song-db/global/1136 and /dev/null differ diff --git a/persistentStorage/data-song-db/global/1136_fsm b/persistentStorage/data-song-db/global/1136_fsm deleted file mode 100644 index 929c96e7..00000000 Binary files a/persistentStorage/data-song-db/global/1136_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/global/1136_vm b/persistentStorage/data-song-db/global/1136_vm deleted file mode 100644 index fea00c04..00000000 Binary files a/persistentStorage/data-song-db/global/1136_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/global/1137 b/persistentStorage/data-song-db/global/1137 deleted file mode 100644 index bed84713..00000000 Binary files a/persistentStorage/data-song-db/global/1137 and /dev/null differ diff --git a/persistentStorage/data-song-db/global/1213 b/persistentStorage/data-song-db/global/1213 deleted file mode 100644 index bf1087ec..00000000 Binary files a/persistentStorage/data-song-db/global/1213 and /dev/null differ diff --git a/persistentStorage/data-song-db/global/1213_fsm b/persistentStorage/data-song-db/global/1213_fsm deleted file mode 100644 index 86074bee..00000000 Binary files a/persistentStorage/data-song-db/global/1213_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/global/1213_vm b/persistentStorage/data-song-db/global/1213_vm deleted file mode 100644 index 1284a6d8..00000000 Binary files a/persistentStorage/data-song-db/global/1213_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/global/1214 b/persistentStorage/data-song-db/global/1214 deleted file mode 100644 index d0f1de0a..00000000 Binary files a/persistentStorage/data-song-db/global/1214 and /dev/null differ diff --git a/persistentStorage/data-song-db/global/1214_fsm b/persistentStorage/data-song-db/global/1214_fsm deleted file mode 100644 index f64db4df..00000000 Binary files a/persistentStorage/data-song-db/global/1214_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/global/1214_vm b/persistentStorage/data-song-db/global/1214_vm deleted file mode 100644 index 1f58e41f..00000000 Binary files a/persistentStorage/data-song-db/global/1214_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/global/1232 b/persistentStorage/data-song-db/global/1232 deleted file mode 100644 index c9569a5b..00000000 Binary files a/persistentStorage/data-song-db/global/1232 and /dev/null differ diff --git a/persistentStorage/data-song-db/global/1233 b/persistentStorage/data-song-db/global/1233 deleted file mode 100644 index 7c061a18..00000000 Binary files a/persistentStorage/data-song-db/global/1233 and /dev/null differ diff --git a/persistentStorage/data-song-db/global/1260 b/persistentStorage/data-song-db/global/1260 deleted file mode 100644 index e983e1a0..00000000 Binary files a/persistentStorage/data-song-db/global/1260 and /dev/null differ diff --git a/persistentStorage/data-song-db/global/1260_fsm b/persistentStorage/data-song-db/global/1260_fsm deleted file mode 100644 index 09d24c4a..00000000 Binary files a/persistentStorage/data-song-db/global/1260_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/global/1260_vm b/persistentStorage/data-song-db/global/1260_vm deleted file mode 100644 index 318d4bf2..00000000 Binary files a/persistentStorage/data-song-db/global/1260_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/global/1261 b/persistentStorage/data-song-db/global/1261 deleted file mode 100644 index 7bcac924..00000000 Binary files a/persistentStorage/data-song-db/global/1261 and /dev/null differ diff --git a/persistentStorage/data-song-db/global/1261_fsm b/persistentStorage/data-song-db/global/1261_fsm deleted file mode 100644 index 7732d22b..00000000 Binary files a/persistentStorage/data-song-db/global/1261_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/global/1261_vm b/persistentStorage/data-song-db/global/1261_vm deleted file mode 100644 index cfbc8517..00000000 Binary files a/persistentStorage/data-song-db/global/1261_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/global/1262 b/persistentStorage/data-song-db/global/1262 deleted file mode 100644 index bf21f7c9..00000000 Binary files a/persistentStorage/data-song-db/global/1262 and /dev/null differ diff --git a/persistentStorage/data-song-db/global/1262_fsm b/persistentStorage/data-song-db/global/1262_fsm deleted file mode 100644 index b49966ff..00000000 Binary files a/persistentStorage/data-song-db/global/1262_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/global/1262_vm b/persistentStorage/data-song-db/global/1262_vm deleted file mode 100644 index 9cbaeae2..00000000 Binary files a/persistentStorage/data-song-db/global/1262_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/global/2396 b/persistentStorage/data-song-db/global/2396 deleted file mode 100644 index 4728bf54..00000000 Binary files a/persistentStorage/data-song-db/global/2396 and /dev/null differ diff --git a/persistentStorage/data-song-db/global/2396_fsm b/persistentStorage/data-song-db/global/2396_fsm deleted file mode 100644 index 7a4f24f3..00000000 Binary files a/persistentStorage/data-song-db/global/2396_fsm and /dev/null differ diff --git a/persistentStorage/data-song-db/global/2396_vm b/persistentStorage/data-song-db/global/2396_vm deleted file mode 100644 index 5b3cef40..00000000 Binary files a/persistentStorage/data-song-db/global/2396_vm and /dev/null differ diff --git a/persistentStorage/data-song-db/global/2397 b/persistentStorage/data-song-db/global/2397 deleted file mode 100644 index 733c0949..00000000 Binary files a/persistentStorage/data-song-db/global/2397 and /dev/null differ diff --git a/persistentStorage/data-song-db/global/2671 b/persistentStorage/data-song-db/global/2671 deleted file mode 100644 index 76c71bc1..00000000 Binary files a/persistentStorage/data-song-db/global/2671 and /dev/null differ diff --git a/persistentStorage/data-song-db/global/2672 b/persistentStorage/data-song-db/global/2672 deleted file mode 100644 index d8ffa040..00000000 Binary files a/persistentStorage/data-song-db/global/2672 and /dev/null differ diff --git a/persistentStorage/data-song-db/global/2676 b/persistentStorage/data-song-db/global/2676 deleted file mode 100644 index d5b0603e..00000000 Binary files a/persistentStorage/data-song-db/global/2676 and /dev/null differ diff --git a/persistentStorage/data-song-db/global/2677 b/persistentStorage/data-song-db/global/2677 deleted file mode 100644 index 97890fa1..00000000 Binary files a/persistentStorage/data-song-db/global/2677 and /dev/null differ diff --git a/persistentStorage/data-song-db/global/2694 b/persistentStorage/data-song-db/global/2694 deleted file mode 100644 index d1b40bc1..00000000 Binary files a/persistentStorage/data-song-db/global/2694 and /dev/null differ diff --git a/persistentStorage/data-song-db/global/2695 b/persistentStorage/data-song-db/global/2695 deleted file mode 100644 index 6aba35d2..00000000 Binary files a/persistentStorage/data-song-db/global/2695 and /dev/null differ diff --git a/persistentStorage/data-song-db/global/2697 b/persistentStorage/data-song-db/global/2697 deleted file mode 100644 index 68c2cd14..00000000 Binary files a/persistentStorage/data-song-db/global/2697 and /dev/null differ diff --git a/persistentStorage/data-song-db/global/2698 b/persistentStorage/data-song-db/global/2698 deleted file mode 100644 index 1f1169c1..00000000 Binary files a/persistentStorage/data-song-db/global/2698 and /dev/null differ diff --git a/persistentStorage/data-song-db/global/2846 b/persistentStorage/data-song-db/global/2846 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/global/2846_vm b/persistentStorage/data-song-db/global/2846_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/global/2847 b/persistentStorage/data-song-db/global/2847 deleted file mode 100644 index 0ed95067..00000000 Binary files a/persistentStorage/data-song-db/global/2847 and /dev/null differ diff --git a/persistentStorage/data-song-db/global/2964 b/persistentStorage/data-song-db/global/2964 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/global/2964_vm b/persistentStorage/data-song-db/global/2964_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/global/2965 b/persistentStorage/data-song-db/global/2965 deleted file mode 100644 index 3f30d103..00000000 Binary files a/persistentStorage/data-song-db/global/2965 and /dev/null differ diff --git a/persistentStorage/data-song-db/global/2966 b/persistentStorage/data-song-db/global/2966 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/global/2966_vm b/persistentStorage/data-song-db/global/2966_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/global/2967 b/persistentStorage/data-song-db/global/2967 deleted file mode 100644 index 7eefef19..00000000 Binary files a/persistentStorage/data-song-db/global/2967 and /dev/null differ diff --git a/persistentStorage/data-song-db/global/3592 b/persistentStorage/data-song-db/global/3592 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/global/3592_vm b/persistentStorage/data-song-db/global/3592_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/global/3593 b/persistentStorage/data-song-db/global/3593 deleted file mode 100644 index ed74ac3d..00000000 Binary files a/persistentStorage/data-song-db/global/3593 and /dev/null differ diff --git a/persistentStorage/data-song-db/global/4060 b/persistentStorage/data-song-db/global/4060 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/global/4060_vm b/persistentStorage/data-song-db/global/4060_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/global/4061 b/persistentStorage/data-song-db/global/4061 deleted file mode 100644 index 88be0043..00000000 Binary files a/persistentStorage/data-song-db/global/4061 and /dev/null differ diff --git a/persistentStorage/data-song-db/global/6000 b/persistentStorage/data-song-db/global/6000 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/global/6000_vm b/persistentStorage/data-song-db/global/6000_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/global/6001 b/persistentStorage/data-song-db/global/6001 deleted file mode 100644 index c45f61f6..00000000 Binary files a/persistentStorage/data-song-db/global/6001 and /dev/null differ diff --git a/persistentStorage/data-song-db/global/6002 b/persistentStorage/data-song-db/global/6002 deleted file mode 100644 index b315aac0..00000000 Binary files a/persistentStorage/data-song-db/global/6002 and /dev/null differ diff --git a/persistentStorage/data-song-db/global/6100 b/persistentStorage/data-song-db/global/6100 deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/global/6100_vm b/persistentStorage/data-song-db/global/6100_vm deleted file mode 100644 index e69de29b..00000000 diff --git a/persistentStorage/data-song-db/global/6114 b/persistentStorage/data-song-db/global/6114 deleted file mode 100644 index 33563252..00000000 Binary files a/persistentStorage/data-song-db/global/6114 and /dev/null differ diff --git a/persistentStorage/data-song-db/global/6115 b/persistentStorage/data-song-db/global/6115 deleted file mode 100644 index cdd2ed16..00000000 Binary files a/persistentStorage/data-song-db/global/6115 and /dev/null differ diff --git a/persistentStorage/data-song-db/global/pg_control b/persistentStorage/data-song-db/global/pg_control deleted file mode 100644 index 6773462c..00000000 Binary files a/persistentStorage/data-song-db/global/pg_control and /dev/null differ diff --git a/persistentStorage/data-song-db/global/pg_filenode.map b/persistentStorage/data-song-db/global/pg_filenode.map deleted file mode 100644 index 8ee3a929..00000000 Binary files a/persistentStorage/data-song-db/global/pg_filenode.map and /dev/null differ diff --git a/persistentStorage/data-song-db/global/pg_internal.init b/persistentStorage/data-song-db/global/pg_internal.init deleted file mode 100644 index d3803ef7..00000000 Binary files a/persistentStorage/data-song-db/global/pg_internal.init and /dev/null differ diff --git a/persistentStorage/data-song-db/pg_hba.conf b/persistentStorage/data-song-db/pg_hba.conf deleted file mode 100644 index b9a7ac19..00000000 --- a/persistentStorage/data-song-db/pg_hba.conf +++ /dev/null @@ -1,95 +0,0 @@ -# PostgreSQL Client Authentication Configuration File -# =================================================== -# -# Refer to the "Client Authentication" section in the PostgreSQL -# documentation for a complete description of this file. A short -# synopsis follows. -# -# This file controls: which hosts are allowed to connect, how clients -# are authenticated, which PostgreSQL user names they can use, which -# databases they can access. Records take one of these forms: -# -# local DATABASE USER METHOD [OPTIONS] -# host DATABASE USER ADDRESS METHOD [OPTIONS] -# hostssl DATABASE USER ADDRESS METHOD [OPTIONS] -# hostnossl DATABASE USER ADDRESS METHOD [OPTIONS] -# -# (The uppercase items must be replaced by actual values.) -# -# The first field is the connection type: "local" is a Unix-domain -# socket, "host" is either a plain or SSL-encrypted TCP/IP socket, -# "hostssl" is an SSL-encrypted TCP/IP socket, and "hostnossl" is a -# plain TCP/IP socket. -# -# DATABASE can be "all", "sameuser", "samerole", "replication", a -# database name, or a comma-separated list thereof. The "all" -# keyword does not match "replication". Access to replication -# must be enabled in a separate record (see example below). -# -# USER can be "all", a user name, a group name prefixed with "+", or a -# comma-separated list thereof. In both the DATABASE and USER fields -# you can also write a file name prefixed with "@" to include names -# from a separate file. -# -# ADDRESS specifies the set of hosts the record matches. It can be a -# host name, or it is made up of an IP address and a CIDR mask that is -# an integer (between 0 and 32 (IPv4) or 128 (IPv6) inclusive) that -# specifies the number of significant bits in the mask. A host name -# that starts with a dot (.) matches a suffix of the actual host name. -# Alternatively, you can write an IP address and netmask in separate -# columns to specify the set of hosts. Instead of a CIDR-address, you -# can write "samehost" to match any of the server's own IP addresses, -# or "samenet" to match any address in any subnet that the server is -# directly connected to. -# -# METHOD can be "trust", "reject", "md5", "password", "scram-sha-256", -# "gss", "sspi", "ident", "peer", "pam", "ldap", "radius" or "cert". -# Note that "password" sends passwords in clear text; "md5" or -# "scram-sha-256" are preferred since they send encrypted passwords. -# -# OPTIONS are a set of options for the authentication in the format -# NAME=VALUE. The available options depend on the different -# authentication methods -- refer to the "Client Authentication" -# section in the documentation for a list of which options are -# available for which authentication methods. -# -# Database and user names containing spaces, commas, quotes and other -# special characters must be quoted. Quoting one of the keywords -# "all", "sameuser", "samerole" or "replication" makes the name lose -# its special character, and just match a database or username with -# that name. -# -# This file is read on server startup and when the server receives a -# SIGHUP signal. If you edit the file on a running system, you have to -# SIGHUP the server for the changes to take effect, run "pg_ctl reload", -# or execute "SELECT pg_reload_conf()". -# -# Put your actual configuration here -# ---------------------------------- -# -# If you want to allow non-local connections, you need to add more -# "host" records. In that case you will also need to make PostgreSQL -# listen on a non-local interface via the listen_addresses -# configuration parameter, or via the -i or -h command line switches. - -# CAUTION: Configuring the system for local "trust" authentication -# allows any local user to connect as any PostgreSQL user, including -# the database superuser. If you do not trust all your local users, -# use another authentication method. - - -# TYPE DATABASE USER ADDRESS METHOD - -# "local" is for Unix domain socket connections only -local all all trust -# IPv4 local connections: -host all all 127.0.0.1/32 trust -# IPv6 local connections: -host all all ::1/128 trust -# Allow replication connections from localhost, by a user with the -# replication privilege. -local replication all trust -host replication all 127.0.0.1/32 trust -host replication all ::1/128 trust - -host all all all md5 diff --git a/persistentStorage/data-song-db/pg_ident.conf b/persistentStorage/data-song-db/pg_ident.conf deleted file mode 100644 index a5870e64..00000000 --- a/persistentStorage/data-song-db/pg_ident.conf +++ /dev/null @@ -1,42 +0,0 @@ -# PostgreSQL User Name Maps -# ========================= -# -# Refer to the PostgreSQL documentation, chapter "Client -# Authentication" for a complete description. A short synopsis -# follows. -# -# This file controls PostgreSQL user name mapping. It maps external -# user names to their corresponding PostgreSQL user names. Records -# are of the form: -# -# MAPNAME SYSTEM-USERNAME PG-USERNAME -# -# (The uppercase quantities must be replaced by actual values.) -# -# MAPNAME is the (otherwise freely chosen) map name that was used in -# pg_hba.conf. SYSTEM-USERNAME is the detected user name of the -# client. PG-USERNAME is the requested PostgreSQL user name. The -# existence of a record specifies that SYSTEM-USERNAME may connect as -# PG-USERNAME. -# -# If SYSTEM-USERNAME starts with a slash (/), it will be treated as a -# regular expression. Optionally this can contain a capture (a -# parenthesized subexpression). The substring matching the capture -# will be substituted for \1 (backslash-one) if present in -# PG-USERNAME. -# -# Multiple maps may be specified in this file and used by pg_hba.conf. -# -# No map names are defined in the default configuration. If all -# system user names and PostgreSQL user names are the same, you don't -# need anything in this file. -# -# This file is read on server startup and when the postmaster receives -# a SIGHUP signal. If you edit the file on a running system, you have -# to SIGHUP the postmaster for the changes to take effect. You can -# use "pg_ctl reload" to do that. - -# Put your actual configuration here -# ---------------------------------- - -# MAPNAME SYSTEM-USERNAME PG-USERNAME diff --git a/persistentStorage/data-song-db/pg_logical/replorigin_checkpoint b/persistentStorage/data-song-db/pg_logical/replorigin_checkpoint deleted file mode 100644 index ec451b0f..00000000 Binary files a/persistentStorage/data-song-db/pg_logical/replorigin_checkpoint and /dev/null differ diff --git a/persistentStorage/data-song-db/pg_multixact/members/0000 b/persistentStorage/data-song-db/pg_multixact/members/0000 deleted file mode 100644 index 6d17cf9d..00000000 Binary files a/persistentStorage/data-song-db/pg_multixact/members/0000 and /dev/null differ diff --git a/persistentStorage/data-song-db/pg_multixact/offsets/0000 b/persistentStorage/data-song-db/pg_multixact/offsets/0000 deleted file mode 100644 index 6d17cf9d..00000000 Binary files a/persistentStorage/data-song-db/pg_multixact/offsets/0000 and /dev/null differ diff --git a/persistentStorage/data-song-db/pg_notify/0000 b/persistentStorage/data-song-db/pg_notify/0000 deleted file mode 100644 index 6d17cf9d..00000000 Binary files a/persistentStorage/data-song-db/pg_notify/0000 and /dev/null differ diff --git a/persistentStorage/data-song-db/pg_stat_tmp/db_0.stat b/persistentStorage/data-song-db/pg_stat_tmp/db_0.stat deleted file mode 100644 index 6848be44..00000000 Binary files a/persistentStorage/data-song-db/pg_stat_tmp/db_0.stat and /dev/null differ diff --git a/persistentStorage/data-song-db/pg_stat_tmp/db_16384.stat b/persistentStorage/data-song-db/pg_stat_tmp/db_16384.stat deleted file mode 100644 index 13793ff3..00000000 Binary files a/persistentStorage/data-song-db/pg_stat_tmp/db_16384.stat and /dev/null differ diff --git a/persistentStorage/data-song-db/pg_stat_tmp/global.stat b/persistentStorage/data-song-db/pg_stat_tmp/global.stat deleted file mode 100644 index f09a3bc8..00000000 Binary files a/persistentStorage/data-song-db/pg_stat_tmp/global.stat and /dev/null differ diff --git a/persistentStorage/data-song-db/pg_subtrans/0000 b/persistentStorage/data-song-db/pg_subtrans/0000 deleted file mode 100644 index 6d17cf9d..00000000 Binary files a/persistentStorage/data-song-db/pg_subtrans/0000 and /dev/null differ diff --git a/persistentStorage/data-song-db/pg_wal/000000010000000000000001 b/persistentStorage/data-song-db/pg_wal/000000010000000000000001 deleted file mode 100644 index 5e21904f..00000000 Binary files a/persistentStorage/data-song-db/pg_wal/000000010000000000000001 and /dev/null differ diff --git a/persistentStorage/data-song-db/pg_xact/0000 b/persistentStorage/data-song-db/pg_xact/0000 deleted file mode 100644 index d2d9deaa..00000000 Binary files a/persistentStorage/data-song-db/pg_xact/0000 and /dev/null differ diff --git a/persistentStorage/data-song-db/postgresql.auto.conf b/persistentStorage/data-song-db/postgresql.auto.conf deleted file mode 100644 index af7125e1..00000000 --- a/persistentStorage/data-song-db/postgresql.auto.conf +++ /dev/null @@ -1,2 +0,0 @@ -# Do not edit this file manually! -# It will be overwritten by the ALTER SYSTEM command. diff --git a/persistentStorage/data-song-db/postgresql.conf b/persistentStorage/data-song-db/postgresql.conf deleted file mode 100644 index d7b0caa0..00000000 --- a/persistentStorage/data-song-db/postgresql.conf +++ /dev/null @@ -1,688 +0,0 @@ -# ----------------------------- -# PostgreSQL configuration file -# ----------------------------- -# -# This file consists of lines of the form: -# -# name = value -# -# (The "=" is optional.) Whitespace may be used. Comments are introduced with -# "#" anywhere on a line. The complete list of parameter names and allowed -# values can be found in the PostgreSQL documentation. -# -# The commented-out settings shown in this file represent the default values. -# Re-commenting a setting is NOT sufficient to revert it to the default value; -# you need to reload the server. -# -# This file is read on server startup and when the server receives a SIGHUP -# signal. If you edit the file on a running system, you have to SIGHUP the -# server for the changes to take effect, run "pg_ctl reload", or execute -# "SELECT pg_reload_conf()". Some parameters, which are marked below, -# require a server shutdown and restart to take effect. -# -# Any parameter can also be given as a command-line option to the server, e.g., -# "postgres -c log_connections=on". Some parameters can be changed at run time -# with the "SET" SQL command. -# -# Memory units: kB = kilobytes Time units: ms = milliseconds -# MB = megabytes s = seconds -# GB = gigabytes min = minutes -# TB = terabytes h = hours -# d = days - - -#------------------------------------------------------------------------------ -# FILE LOCATIONS -#------------------------------------------------------------------------------ - -# The default values of these variables are driven from the -D command-line -# option or PGDATA environment variable, represented here as ConfigDir. - -#data_directory = 'ConfigDir' # use data in another directory - # (change requires restart) -#hba_file = 'ConfigDir/pg_hba.conf' # host-based authentication file - # (change requires restart) -#ident_file = 'ConfigDir/pg_ident.conf' # ident configuration file - # (change requires restart) - -# If external_pid_file is not explicitly set, no extra PID file is written. -#external_pid_file = '' # write an extra PID file - # (change requires restart) - - -#------------------------------------------------------------------------------ -# CONNECTIONS AND AUTHENTICATION -#------------------------------------------------------------------------------ - -# - Connection Settings - - -listen_addresses = '*' - # comma-separated list of addresses; - # defaults to 'localhost'; use '*' for all - # (change requires restart) -#port = 5432 # (change requires restart) -max_connections = 100 # (change requires restart) -#superuser_reserved_connections = 3 # (change requires restart) -#unix_socket_directories = '/var/run/postgresql' # comma-separated list of directories - # (change requires restart) -#unix_socket_group = '' # (change requires restart) -#unix_socket_permissions = 0777 # begin with 0 to use octal notation - # (change requires restart) -#bonjour = off # advertise server via Bonjour - # (change requires restart) -#bonjour_name = '' # defaults to the computer name - # (change requires restart) - -# - TCP Keepalives - -# see "man 7 tcp" for details - -#tcp_keepalives_idle = 0 # TCP_KEEPIDLE, in seconds; - # 0 selects the system default -#tcp_keepalives_interval = 0 # TCP_KEEPINTVL, in seconds; - # 0 selects the system default -#tcp_keepalives_count = 0 # TCP_KEEPCNT; - # 0 selects the system default - -# - Authentication - - -#authentication_timeout = 1min # 1s-600s -#password_encryption = md5 # md5 or scram-sha-256 -#db_user_namespace = off - -# GSSAPI using Kerberos -#krb_server_keyfile = '' -#krb_caseins_users = off - -# - SSL - - -#ssl = off -#ssl_ca_file = '' -#ssl_cert_file = 'server.crt' -#ssl_crl_file = '' -#ssl_key_file = 'server.key' -#ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL' # allowed SSL ciphers -#ssl_prefer_server_ciphers = on -#ssl_ecdh_curve = 'prime256v1' -#ssl_dh_params_file = '' -#ssl_passphrase_command = '' -#ssl_passphrase_command_supports_reload = off - - -#------------------------------------------------------------------------------ -# RESOURCE USAGE (except WAL) -#------------------------------------------------------------------------------ - -# - Memory - - -shared_buffers = 128MB # min 128kB - # (change requires restart) -#huge_pages = try # on, off, or try - # (change requires restart) -#temp_buffers = 8MB # min 800kB -#max_prepared_transactions = 0 # zero disables the feature - # (change requires restart) -# Caution: it is not advisable to set max_prepared_transactions nonzero unless -# you actively intend to use prepared transactions. -#work_mem = 4MB # min 64kB -#maintenance_work_mem = 64MB # min 1MB -#autovacuum_work_mem = -1 # min 1MB, or -1 to use maintenance_work_mem -#max_stack_depth = 2MB # min 100kB -dynamic_shared_memory_type = posix # the default is the first option - # supported by the operating system: - # posix - # sysv - # windows - # mmap - # use none to disable dynamic shared memory - # (change requires restart) - -# - Disk - - -#temp_file_limit = -1 # limits per-process temp file space - # in kB, or -1 for no limit - -# - Kernel Resources - - -#max_files_per_process = 1000 # min 25 - # (change requires restart) - -# - Cost-Based Vacuum Delay - - -#vacuum_cost_delay = 0 # 0-100 milliseconds -#vacuum_cost_page_hit = 1 # 0-10000 credits -#vacuum_cost_page_miss = 10 # 0-10000 credits -#vacuum_cost_page_dirty = 20 # 0-10000 credits -#vacuum_cost_limit = 200 # 1-10000 credits - -# - Background Writer - - -#bgwriter_delay = 200ms # 10-10000ms between rounds -#bgwriter_lru_maxpages = 100 # max buffers written/round, 0 disables -#bgwriter_lru_multiplier = 2.0 # 0-10.0 multiplier on buffers scanned/round -#bgwriter_flush_after = 512kB # measured in pages, 0 disables - -# - Asynchronous Behavior - - -#effective_io_concurrency = 1 # 1-1000; 0 disables prefetching -#max_worker_processes = 8 # (change requires restart) -#max_parallel_maintenance_workers = 2 # taken from max_parallel_workers -#max_parallel_workers_per_gather = 2 # taken from max_parallel_workers -#parallel_leader_participation = on -#max_parallel_workers = 8 # maximum number of max_worker_processes that - # can be used in parallel operations -#old_snapshot_threshold = -1 # 1min-60d; -1 disables; 0 is immediate - # (change requires restart) -#backend_flush_after = 0 # measured in pages, 0 disables - - -#------------------------------------------------------------------------------ -# WRITE-AHEAD LOG -#------------------------------------------------------------------------------ - -# - Settings - - -#wal_level = replica # minimal, replica, or logical - # (change requires restart) -#fsync = on # flush data to disk for crash safety - # (turning this off can cause - # unrecoverable data corruption) -#synchronous_commit = on # synchronization level; - # off, local, remote_write, remote_apply, or on -#wal_sync_method = fsync # the default is the first option - # supported by the operating system: - # open_datasync - # fdatasync (default on Linux) - # fsync - # fsync_writethrough - # open_sync -#full_page_writes = on # recover from partial page writes -#wal_compression = off # enable compression of full-page writes -#wal_log_hints = off # also do full page writes of non-critical updates - # (change requires restart) -#wal_buffers = -1 # min 32kB, -1 sets based on shared_buffers - # (change requires restart) -#wal_writer_delay = 200ms # 1-10000 milliseconds -#wal_writer_flush_after = 1MB # measured in pages, 0 disables - -#commit_delay = 0 # range 0-100000, in microseconds -#commit_siblings = 5 # range 1-1000 - -# - Checkpoints - - -#checkpoint_timeout = 5min # range 30s-1d -max_wal_size = 1GB -min_wal_size = 80MB -#checkpoint_completion_target = 0.5 # checkpoint target duration, 0.0 - 1.0 -#checkpoint_flush_after = 256kB # measured in pages, 0 disables -#checkpoint_warning = 30s # 0 disables - -# - Archiving - - -#archive_mode = off # enables archiving; off, on, or always - # (change requires restart) -#archive_command = '' # command to use to archive a logfile segment - # placeholders: %p = path of file to archive - # %f = file name only - # e.g. 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f' -#archive_timeout = 0 # force a logfile segment switch after this - # number of seconds; 0 disables - - -#------------------------------------------------------------------------------ -# REPLICATION -#------------------------------------------------------------------------------ - -# - Sending Servers - - -# Set these on the master and on any standby that will send replication data. - -#max_wal_senders = 10 # max number of walsender processes - # (change requires restart) -#wal_keep_segments = 0 # in logfile segments; 0 disables -#wal_sender_timeout = 60s # in milliseconds; 0 disables - -#max_replication_slots = 10 # max number of replication slots - # (change requires restart) -#track_commit_timestamp = off # collect timestamp of transaction commit - # (change requires restart) - -# - Master Server - - -# These settings are ignored on a standby server. - -#synchronous_standby_names = '' # standby servers that provide sync rep - # method to choose sync standbys, number of sync standbys, - # and comma-separated list of application_name - # from standby(s); '*' = all -#vacuum_defer_cleanup_age = 0 # number of xacts by which cleanup is delayed - -# - Standby Servers - - -# These settings are ignored on a master server. - -#hot_standby = on # "off" disallows queries during recovery - # (change requires restart) -#max_standby_archive_delay = 30s # max delay before canceling queries - # when reading WAL from archive; - # -1 allows indefinite delay -#max_standby_streaming_delay = 30s # max delay before canceling queries - # when reading streaming WAL; - # -1 allows indefinite delay -#wal_receiver_status_interval = 10s # send replies at least this often - # 0 disables -#hot_standby_feedback = off # send info from standby to prevent - # query conflicts -#wal_receiver_timeout = 60s # time that receiver waits for - # communication from master - # in milliseconds; 0 disables -#wal_retrieve_retry_interval = 5s # time to wait before retrying to - # retrieve WAL after a failed attempt - -# - Subscribers - - -# These settings are ignored on a publisher. - -#max_logical_replication_workers = 4 # taken from max_worker_processes - # (change requires restart) -#max_sync_workers_per_subscription = 2 # taken from max_logical_replication_workers - - -#------------------------------------------------------------------------------ -# QUERY TUNING -#------------------------------------------------------------------------------ - -# - Planner Method Configuration - - -#enable_bitmapscan = on -#enable_hashagg = on -#enable_hashjoin = on -#enable_indexscan = on -#enable_indexonlyscan = on -#enable_material = on -#enable_mergejoin = on -#enable_nestloop = on -#enable_parallel_append = on -#enable_seqscan = on -#enable_sort = on -#enable_tidscan = on -#enable_partitionwise_join = off -#enable_partitionwise_aggregate = off -#enable_parallel_hash = on -#enable_partition_pruning = on - -# - Planner Cost Constants - - -#seq_page_cost = 1.0 # measured on an arbitrary scale -#random_page_cost = 4.0 # same scale as above -#cpu_tuple_cost = 0.01 # same scale as above -#cpu_index_tuple_cost = 0.005 # same scale as above -#cpu_operator_cost = 0.0025 # same scale as above -#parallel_tuple_cost = 0.1 # same scale as above -#parallel_setup_cost = 1000.0 # same scale as above - -#jit_above_cost = 100000 # perform JIT compilation if available - # and query more expensive than this; - # -1 disables -#jit_inline_above_cost = 500000 # inline small functions if query is - # more expensive than this; -1 disables -#jit_optimize_above_cost = 500000 # use expensive JIT optimizations if - # query is more expensive than this; - # -1 disables - -#min_parallel_table_scan_size = 8MB -#min_parallel_index_scan_size = 512kB -#effective_cache_size = 4GB - -# - Genetic Query Optimizer - - -#geqo = on -#geqo_threshold = 12 -#geqo_effort = 5 # range 1-10 -#geqo_pool_size = 0 # selects default based on effort -#geqo_generations = 0 # selects default based on effort -#geqo_selection_bias = 2.0 # range 1.5-2.0 -#geqo_seed = 0.0 # range 0.0-1.0 - -# - Other Planner Options - - -#default_statistics_target = 100 # range 1-10000 -#constraint_exclusion = partition # on, off, or partition -#cursor_tuple_fraction = 0.1 # range 0.0-1.0 -#from_collapse_limit = 8 -#join_collapse_limit = 8 # 1 disables collapsing of explicit - # JOIN clauses -#force_parallel_mode = off -#jit = off # allow JIT compilation - - -#------------------------------------------------------------------------------ -# REPORTING AND LOGGING -#------------------------------------------------------------------------------ - -# - Where to Log - - -#log_destination = 'stderr' # Valid values are combinations of - # stderr, csvlog, syslog, and eventlog, - # depending on platform. csvlog - # requires logging_collector to be on. - -# This is used when logging to stderr: -#logging_collector = off # Enable capturing of stderr and csvlog - # into log files. Required to be on for - # csvlogs. - # (change requires restart) - -# These are only used if logging_collector is on: -#log_directory = 'log' # directory where log files are written, - # can be absolute or relative to PGDATA -#log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log' # log file name pattern, - # can include strftime() escapes -#log_file_mode = 0600 # creation mode for log files, - # begin with 0 to use octal notation -#log_truncate_on_rotation = off # If on, an existing log file with the - # same name as the new log file will be - # truncated rather than appended to. - # But such truncation only occurs on - # time-driven rotation, not on restarts - # or size-driven rotation. Default is - # off, meaning append to existing files - # in all cases. -#log_rotation_age = 1d # Automatic rotation of logfiles will - # happen after that time. 0 disables. -#log_rotation_size = 10MB # Automatic rotation of logfiles will - # happen after that much log output. - # 0 disables. - -# These are relevant when logging to syslog: -#syslog_facility = 'LOCAL0' -#syslog_ident = 'postgres' -#syslog_sequence_numbers = on -#syslog_split_messages = on - -# This is only relevant when logging to eventlog (win32): -# (change requires restart) -#event_source = 'PostgreSQL' - -# - When to Log - - -#client_min_messages = notice # values in order of decreasing detail: - # debug5 - # debug4 - # debug3 - # debug2 - # debug1 - # log - # notice - # warning - # error - -#log_min_messages = warning # values in order of decreasing detail: - # debug5 - # debug4 - # debug3 - # debug2 - # debug1 - # info - # notice - # warning - # error - # log - # fatal - # panic - -#log_min_error_statement = error # values in order of decreasing detail: - # debug5 - # debug4 - # debug3 - # debug2 - # debug1 - # info - # notice - # warning - # error - # log - # fatal - # panic (effectively off) - -#log_min_duration_statement = -1 # -1 is disabled, 0 logs all statements - # and their durations, > 0 logs only - # statements running at least this number - # of milliseconds - - -# - What to Log - - -#debug_print_parse = off -#debug_print_rewritten = off -#debug_print_plan = off -#debug_pretty_print = on -#log_checkpoints = off -#log_connections = off -#log_disconnections = off -#log_duration = off -#log_error_verbosity = default # terse, default, or verbose messages -#log_hostname = off -#log_line_prefix = '%m [%p] ' # special values: - # %a = application name - # %u = user name - # %d = database name - # %r = remote host and port - # %h = remote host - # %p = process ID - # %t = timestamp without milliseconds - # %m = timestamp with milliseconds - # %n = timestamp with milliseconds (as a Unix epoch) - # %i = command tag - # %e = SQL state - # %c = session ID - # %l = session line number - # %s = session start timestamp - # %v = virtual transaction ID - # %x = transaction ID (0 if none) - # %q = stop here in non-session - # processes - # %% = '%' - # e.g. '<%u%%%d> ' -#log_lock_waits = off # log lock waits >= deadlock_timeout -#log_statement = 'none' # none, ddl, mod, all -#log_replication_commands = off -#log_temp_files = -1 # log temporary files equal or larger - # than the specified size in kilobytes; - # -1 disables, 0 logs all temp files -log_timezone = 'UTC' - -#------------------------------------------------------------------------------ -# PROCESS TITLE -#------------------------------------------------------------------------------ - -#cluster_name = '' # added to process titles if nonempty - # (change requires restart) -#update_process_title = on - - -#------------------------------------------------------------------------------ -# STATISTICS -#------------------------------------------------------------------------------ - -# - Query and Index Statistics Collector - - -#track_activities = on -#track_counts = on -#track_io_timing = off -#track_functions = none # none, pl, all -#track_activity_query_size = 1024 # (change requires restart) -#stats_temp_directory = 'pg_stat_tmp' - - -# - Monitoring - - -#log_parser_stats = off -#log_planner_stats = off -#log_executor_stats = off -#log_statement_stats = off - - -#------------------------------------------------------------------------------ -# AUTOVACUUM -#------------------------------------------------------------------------------ - -#autovacuum = on # Enable autovacuum subprocess? 'on' - # requires track_counts to also be on. -#log_autovacuum_min_duration = -1 # -1 disables, 0 logs all actions and - # their durations, > 0 logs only - # actions running at least this number - # of milliseconds. -#autovacuum_max_workers = 3 # max number of autovacuum subprocesses - # (change requires restart) -#autovacuum_naptime = 1min # time between autovacuum runs -#autovacuum_vacuum_threshold = 50 # min number of row updates before - # vacuum -#autovacuum_analyze_threshold = 50 # min number of row updates before - # analyze -#autovacuum_vacuum_scale_factor = 0.2 # fraction of table size before vacuum -#autovacuum_analyze_scale_factor = 0.1 # fraction of table size before analyze -#autovacuum_freeze_max_age = 200000000 # maximum XID age before forced vacuum - # (change requires restart) -#autovacuum_multixact_freeze_max_age = 400000000 # maximum multixact age - # before forced vacuum - # (change requires restart) -#autovacuum_vacuum_cost_delay = 20ms # default vacuum cost delay for - # autovacuum, in milliseconds; - # -1 means use vacuum_cost_delay -#autovacuum_vacuum_cost_limit = -1 # default vacuum cost limit for - # autovacuum, -1 means use - # vacuum_cost_limit - - -#------------------------------------------------------------------------------ -# CLIENT CONNECTION DEFAULTS -#------------------------------------------------------------------------------ - -# - Statement Behavior - - -#search_path = '"$user", public' # schema names -#row_security = on -#default_tablespace = '' # a tablespace name, '' uses the default -#temp_tablespaces = '' # a list of tablespace names, '' uses - # only default tablespace -#check_function_bodies = on -#default_transaction_isolation = 'read committed' -#default_transaction_read_only = off -#default_transaction_deferrable = off -#session_replication_role = 'origin' -#statement_timeout = 0 # in milliseconds, 0 is disabled -#lock_timeout = 0 # in milliseconds, 0 is disabled -#idle_in_transaction_session_timeout = 0 # in milliseconds, 0 is disabled -#vacuum_freeze_min_age = 50000000 -#vacuum_freeze_table_age = 150000000 -#vacuum_multixact_freeze_min_age = 5000000 -#vacuum_multixact_freeze_table_age = 150000000 -#vacuum_cleanup_index_scale_factor = 0.1 # fraction of total number of tuples - # before index cleanup, 0 always performs - # index cleanup -#bytea_output = 'hex' # hex, escape -#xmlbinary = 'base64' -#xmloption = 'content' -#gin_fuzzy_search_limit = 0 -#gin_pending_list_limit = 4MB - -# - Locale and Formatting - - -datestyle = 'iso, mdy' -#intervalstyle = 'postgres' -timezone = 'UTC' -#timezone_abbreviations = 'Default' # Select the set of available time zone - # abbreviations. Currently, there are - # Default - # Australia (historical usage) - # India - # You can create your own file in - # share/timezonesets/. -#extra_float_digits = 0 # min -15, max 3 -#client_encoding = sql_ascii # actually, defaults to database - # encoding - -# These settings are initialized by initdb, but they can be changed. -lc_messages = 'en_US.utf8' # locale for system error message - # strings -lc_monetary = 'en_US.utf8' # locale for monetary formatting -lc_numeric = 'en_US.utf8' # locale for number formatting -lc_time = 'en_US.utf8' # locale for time formatting - -# default configuration for text search -default_text_search_config = 'pg_catalog.english' - -# - Shared Library Preloading - - -#shared_preload_libraries = '' # (change requires restart) -#local_preload_libraries = '' -#session_preload_libraries = '' -#jit_provider = 'llvmjit' # JIT library to use - -# - Other Defaults - - -#dynamic_library_path = '$libdir' - - -#------------------------------------------------------------------------------ -# LOCK MANAGEMENT -#------------------------------------------------------------------------------ - -#deadlock_timeout = 1s -#max_locks_per_transaction = 64 # min 10 - # (change requires restart) -#max_pred_locks_per_transaction = 64 # min 10 - # (change requires restart) -#max_pred_locks_per_relation = -2 # negative values mean - # (max_pred_locks_per_transaction - # / -max_pred_locks_per_relation) - 1 -#max_pred_locks_per_page = 2 # min 0 - - -#------------------------------------------------------------------------------ -# VERSION AND PLATFORM COMPATIBILITY -#------------------------------------------------------------------------------ - -# - Previous PostgreSQL Versions - - -#array_nulls = on -#backslash_quote = safe_encoding # on, off, or safe_encoding -#default_with_oids = off -#escape_string_warning = on -#lo_compat_privileges = off -#operator_precedence_warning = off -#quote_all_identifiers = off -#standard_conforming_strings = on -#synchronize_seqscans = on - -# - Other Platforms and Clients - - -#transform_null_equals = off - - -#------------------------------------------------------------------------------ -# ERROR HANDLING -#------------------------------------------------------------------------------ - -#exit_on_error = off # terminate session on any error? -#restart_after_crash = on # reinitialize after backend crash? - - -#------------------------------------------------------------------------------ -# CONFIG FILE INCLUDES -#------------------------------------------------------------------------------ - -# These options allow settings to be loaded from files other than the -# default postgresql.conf. - -#include_dir = 'conf.d' # include files ending in '.conf' from - # directory 'conf.d' -#include_if_exists = 'exists.conf' # include file only if it exists -#include = 'special.conf' # include file - - -#------------------------------------------------------------------------------ -# CUSTOMIZED OPTIONS -#------------------------------------------------------------------------------ - -# Add settings for extensions here diff --git a/persistentStorage/data-song-db/postmaster.opts b/persistentStorage/data-song-db/postmaster.opts deleted file mode 100644 index 6a2ab14c..00000000 --- a/persistentStorage/data-song-db/postmaster.opts +++ /dev/null @@ -1 +0,0 @@ -/usr/lib/postgresql/11/bin/postgres diff --git a/persistentStorage/data-song-db/postmaster.pid b/persistentStorage/data-song-db/postmaster.pid deleted file mode 100644 index b3b7768d..00000000 --- a/persistentStorage/data-song-db/postmaster.pid +++ /dev/null @@ -1,8 +0,0 @@ -1 -/var/lib/postgresql/data -1720109585 -5432 -/var/run/postgresql -* - 5432001 0 -ready