From 6060acdd67933c29c35cf8398c9276c47da63ed2 Mon Sep 17 00:00:00 2001 From: Suryansh5545 Date: Sat, 5 Aug 2023 14:24:36 +0530 Subject: [PATCH] added LF line ending --- .dockerignore | 7 + .flake8 | 3 + .github/workflows/django.yml | 30 + .gitignore | 233 + README.md | 70 + apps/__init__.py | 0 apps/base/__init__.py | 0 apps/base/admin.py | 3 + apps/base/apps.py | 6 + apps/base/management/commands/__init__.py | 0 apps/base/management/commands/seed.py | 22 + apps/base/migrations/__init__.py | 0 apps/base/models.py | 3 + apps/base/utils.py | 25 + apps/base/views.py | 3 + apps/event/__init__.py | 0 apps/event/admin.py | 28 + apps/event/apps.py | 6 + apps/event/migrations/0001_initial.py | 92 + apps/event/migrations/__init__.py | 0 apps/event/models.py | 85 + apps/event/serializers.py | 18 + apps/event/urls.py | 12 + apps/event/views.py | 110 + apps/ticket/__init__.py | 0 apps/ticket/admin.py | 23 + apps/ticket/apps.py | 6 + apps/ticket/migrations/0001_initial.py | 77 + apps/ticket/migrations/__init__.py | 0 apps/ticket/models.py | 80 + apps/ticket/serializers.py | 33 + apps/ticket/tests.py | 3 + apps/ticket/urls.py | 12 + apps/ticket/utils.py | 132 + apps/ticket/views.py | 177 + apps/transactions/__init__.py | 0 apps/transactions/admin.py | 10 + apps/transactions/apps.py | 6 + apps/transactions/migrations/0001_initial.py | 33 + apps/transactions/migrations/__init__.py | 0 apps/transactions/models.py | 20 + apps/transactions/serializers.py | 7 + apps/transactions/tests.py | 3 + apps/transactions/urls.py | 8 + apps/transactions/views.py | 214 + docker-compose-prod.yml | 0 docker-compose.yml | 55 + docker/dev/celery/Dockerfile | 15 + docker/dev/celery/container-start.sh | 3 + docker/dev/django/Dockerfile | 18 + docker/dev/django/container-start.sh | 6 + docker/dev/django/uwsgi.ini | 10 + docker/dev/docker.env.example | 43 + docker/dev/nodejs_v1/Dockerfile | 15 + docker/wait-for-it.sh | 161 + frontend/.editorconfig | 16 + frontend/README.md | 27 + frontend/angular.json | 144 + frontend/package.json | 48 + frontend/src/_base.scss | 3 + .../admin/dashboard/dashboard.component.html | 45 + .../admin/dashboard/dashboard.component.scss | 22 + .../dashboard/dashboard.component.spec.ts | 21 + .../admin/dashboard/dashboard.component.ts | 94 + .../ticket-dialog.component.html | 57 + .../ticket-dialog.component.scss | 73 + .../ticket-dialog.component.spec.ts | 21 + .../ticket-dialog/ticket-dialog.component.ts | 65 + .../transactions/transactions.component.html | 14 + .../transactions/transactions.component.scss | 0 .../transactions.component.spec.ts | 21 + .../transactions/transactions.component.ts | 19 + .../src/app/admin/list/list.component.html | 36 + .../src/app/admin/list/list.component.scss | 9 + .../src/app/admin/list/list.component.spec.ts | 21 + frontend/src/app/admin/list/list.component.ts | 59 + .../src/app/admin/login/login.component.html | 24 + .../src/app/admin/login/login.component.scss | 22 + .../app/admin/login/login.component.spec.ts | 21 + .../src/app/admin/login/login.component.ts | 25 + .../src/app/admin/scan/scan.component.html | 22 + .../src/app/admin/scan/scan.component.scss | 43 + .../src/app/admin/scan/scan.component.spec.ts | 21 + frontend/src/app/admin/scan/scan.component.ts | 69 + .../app/admin/tickets/tickets.component.html | 84 + .../app/admin/tickets/tickets.component.scss | 38 + .../admin/tickets/tickets.component.spec.ts | 21 + .../app/admin/tickets/tickets.component.ts | 46 + frontend/src/app/app-routing.module.ts | 10 + frontend/src/app/app.component.html | 3 + frontend/src/app/app.component.scss | 42 + frontend/src/app/app.component.spec.ts | 29 + frontend/src/app/app.component.ts | 9 + frontend/src/app/app.module.ts | 124 + .../customer/checkout/checkout.component.html | 147 + .../customer/checkout/checkout.component.scss | 53 + .../checkout/checkout.component.spec.ts | 21 + .../customer/checkout/checkout.component.ts | 168 + .../customer/delivery/delivery.component.html | 31 + .../customer/delivery/delivery.component.scss | 21 + .../delivery/delivery.component.spec.ts | 21 + .../customer/delivery/delivery.component.ts | 43 + .../loading-service.component.ts | 16 + .../maintenance/maintenance.component.html | 22 + .../maintenance/maintenance.component.scss | 13 + .../maintenance/maintenance.component.spec.ts | 21 + .../app/maintenance/maintenance.component.ts | 10 + .../api.service/api.service.component.spec.ts | 21 + .../api.service/api.service.component.ts | 38 + .../authentication/authguard.guard.spec.ts | 17 + .../authentication/authguard.guard.ts | 43 + .../event-details.service.spec.ts | 21 + .../event-details/event-details.service.ts | 244 + .../csrf-interceptor.service.spec.ts | 16 + .../interceptor/csrf-interceptor.service.ts | 31 + .../httpinterceptor.service.spec.ts | 16 + .../interceptor/httpinterceptor.service.ts | 26 + .../src/app/side-bar/side-bar.component.html | 32 + .../src/app/side-bar/side-bar.component.scss | 52 + .../app/side-bar/side-bar.component.spec.ts | 21 + .../src/app/side-bar/side-bar.component.ts | 36 + frontend/src/assets/.gitkeep | 0 frontend/src/environments/environment.prod.ts | 12 + .../src/environments/environment.staging.ts | 12 + frontend/src/environments/environment.ts | 9 + frontend/src/favicon.ico | Bin 0 -> 948 bytes frontend/src/index.html | 16 + frontend/src/main.ts | 7 + frontend/src/styles.scss | 5 + frontend/tsconfig.app.json | 14 + frontend/tsconfig.json | 34 + frontend/tsconfig.spec.json | 14 + frontend/yarn.lock | 7200 +++++++++++++++++ manage.py | 22 + pytest.ini | 3 + requirements/common.txt | 15 + requirements/dev.txt | 5 + requirements/prod.txt | 2 + scripts/__init__.py | 0 scripts/seed.py | 170 + settings/__init__.py | 0 settings/common.py | 194 + settings/dev.py | 18 + settings/prod.py | 37 + settings/test.py | 18 + static/.gitignore | 5 + templates/ticket/style.css | 184 + templates/ticket/ticket_template.html | 268 + tests/unit/__init__.py | 0 tests/unit/base/__init__.py | 0 tests/unit/base/test_utils.py | 60 + tests/unit/event/__init__.py | 0 tests/unit/event/test_views.py | 316 + tests/unit/ticket/test_utils.py | 108 + tests/unit/ticket/test_views.py | 370 + ticketify/__init__.py | 3 + ticketify/asgi.py | 16 + ticketify/celery.py | 23 + ticketify/urls.py | 36 + ticketify/wsgi.py | 16 + 160 files changed, 13807 insertions(+) create mode 100644 .dockerignore create mode 100644 .flake8 create mode 100644 .github/workflows/django.yml create mode 100644 .gitignore create mode 100644 README.md create mode 100644 apps/__init__.py create mode 100644 apps/base/__init__.py create mode 100644 apps/base/admin.py create mode 100644 apps/base/apps.py create mode 100644 apps/base/management/commands/__init__.py create mode 100644 apps/base/management/commands/seed.py create mode 100644 apps/base/migrations/__init__.py create mode 100644 apps/base/models.py create mode 100644 apps/base/utils.py create mode 100644 apps/base/views.py create mode 100644 apps/event/__init__.py create mode 100644 apps/event/admin.py create mode 100644 apps/event/apps.py create mode 100644 apps/event/migrations/0001_initial.py create mode 100644 apps/event/migrations/__init__.py create mode 100644 apps/event/models.py create mode 100644 apps/event/serializers.py create mode 100644 apps/event/urls.py create mode 100644 apps/event/views.py create mode 100644 apps/ticket/__init__.py create mode 100644 apps/ticket/admin.py create mode 100644 apps/ticket/apps.py create mode 100644 apps/ticket/migrations/0001_initial.py create mode 100644 apps/ticket/migrations/__init__.py create mode 100644 apps/ticket/models.py create mode 100644 apps/ticket/serializers.py create mode 100644 apps/ticket/tests.py create mode 100644 apps/ticket/urls.py create mode 100644 apps/ticket/utils.py create mode 100644 apps/ticket/views.py create mode 100644 apps/transactions/__init__.py create mode 100644 apps/transactions/admin.py create mode 100644 apps/transactions/apps.py create mode 100644 apps/transactions/migrations/0001_initial.py create mode 100644 apps/transactions/migrations/__init__.py create mode 100644 apps/transactions/models.py create mode 100644 apps/transactions/serializers.py create mode 100644 apps/transactions/tests.py create mode 100644 apps/transactions/urls.py create mode 100644 apps/transactions/views.py create mode 100644 docker-compose-prod.yml create mode 100644 docker-compose.yml create mode 100644 docker/dev/celery/Dockerfile create mode 100644 docker/dev/celery/container-start.sh create mode 100644 docker/dev/django/Dockerfile create mode 100644 docker/dev/django/container-start.sh create mode 100644 docker/dev/django/uwsgi.ini create mode 100644 docker/dev/docker.env.example create mode 100644 docker/dev/nodejs_v1/Dockerfile create mode 100755 docker/wait-for-it.sh create mode 100644 frontend/.editorconfig create mode 100644 frontend/README.md create mode 100644 frontend/angular.json create mode 100644 frontend/package.json create mode 100644 frontend/src/_base.scss create mode 100644 frontend/src/app/admin/dashboard/dashboard.component.html create mode 100644 frontend/src/app/admin/dashboard/dashboard.component.scss create mode 100644 frontend/src/app/admin/dashboard/dashboard.component.spec.ts create mode 100644 frontend/src/app/admin/dashboard/dashboard.component.ts create mode 100644 frontend/src/app/admin/dialog/ticket-dialog/ticket-dialog.component.html create mode 100644 frontend/src/app/admin/dialog/ticket-dialog/ticket-dialog.component.scss create mode 100644 frontend/src/app/admin/dialog/ticket-dialog/ticket-dialog.component.spec.ts create mode 100644 frontend/src/app/admin/dialog/ticket-dialog/ticket-dialog.component.ts create mode 100644 frontend/src/app/admin/dialog/transactions/transactions.component.html create mode 100644 frontend/src/app/admin/dialog/transactions/transactions.component.scss create mode 100644 frontend/src/app/admin/dialog/transactions/transactions.component.spec.ts create mode 100644 frontend/src/app/admin/dialog/transactions/transactions.component.ts create mode 100644 frontend/src/app/admin/list/list.component.html create mode 100644 frontend/src/app/admin/list/list.component.scss create mode 100644 frontend/src/app/admin/list/list.component.spec.ts create mode 100644 frontend/src/app/admin/list/list.component.ts create mode 100644 frontend/src/app/admin/login/login.component.html create mode 100644 frontend/src/app/admin/login/login.component.scss create mode 100644 frontend/src/app/admin/login/login.component.spec.ts create mode 100644 frontend/src/app/admin/login/login.component.ts create mode 100644 frontend/src/app/admin/scan/scan.component.html create mode 100644 frontend/src/app/admin/scan/scan.component.scss create mode 100644 frontend/src/app/admin/scan/scan.component.spec.ts create mode 100644 frontend/src/app/admin/scan/scan.component.ts create mode 100644 frontend/src/app/admin/tickets/tickets.component.html create mode 100644 frontend/src/app/admin/tickets/tickets.component.scss create mode 100644 frontend/src/app/admin/tickets/tickets.component.spec.ts create mode 100644 frontend/src/app/admin/tickets/tickets.component.ts create mode 100644 frontend/src/app/app-routing.module.ts create mode 100644 frontend/src/app/app.component.html create mode 100644 frontend/src/app/app.component.scss create mode 100644 frontend/src/app/app.component.spec.ts create mode 100644 frontend/src/app/app.component.ts create mode 100644 frontend/src/app/app.module.ts create mode 100644 frontend/src/app/customer/checkout/checkout.component.html create mode 100644 frontend/src/app/customer/checkout/checkout.component.scss create mode 100644 frontend/src/app/customer/checkout/checkout.component.spec.ts create mode 100644 frontend/src/app/customer/checkout/checkout.component.ts create mode 100644 frontend/src/app/customer/delivery/delivery.component.html create mode 100644 frontend/src/app/customer/delivery/delivery.component.scss create mode 100644 frontend/src/app/customer/delivery/delivery.component.spec.ts create mode 100644 frontend/src/app/customer/delivery/delivery.component.ts create mode 100644 frontend/src/app/loading-service/loading-service.component.ts create mode 100644 frontend/src/app/maintenance/maintenance.component.html create mode 100644 frontend/src/app/maintenance/maintenance.component.scss create mode 100644 frontend/src/app/maintenance/maintenance.component.spec.ts create mode 100644 frontend/src/app/maintenance/maintenance.component.ts create mode 100644 frontend/src/app/services/api.service/api.service.component.spec.ts create mode 100644 frontend/src/app/services/api.service/api.service.component.ts create mode 100644 frontend/src/app/services/authentication/authguard.guard.spec.ts create mode 100644 frontend/src/app/services/authentication/authguard.guard.ts create mode 100644 frontend/src/app/services/event-details/event-details.service.spec.ts create mode 100644 frontend/src/app/services/event-details/event-details.service.ts create mode 100644 frontend/src/app/services/interceptor/csrf-interceptor.service.spec.ts create mode 100644 frontend/src/app/services/interceptor/csrf-interceptor.service.ts create mode 100644 frontend/src/app/services/interceptor/httpinterceptor.service.spec.ts create mode 100644 frontend/src/app/services/interceptor/httpinterceptor.service.ts create mode 100644 frontend/src/app/side-bar/side-bar.component.html create mode 100644 frontend/src/app/side-bar/side-bar.component.scss create mode 100644 frontend/src/app/side-bar/side-bar.component.spec.ts create mode 100644 frontend/src/app/side-bar/side-bar.component.ts create mode 100644 frontend/src/assets/.gitkeep create mode 100644 frontend/src/environments/environment.prod.ts create mode 100644 frontend/src/environments/environment.staging.ts create mode 100644 frontend/src/environments/environment.ts create mode 100644 frontend/src/favicon.ico create mode 100644 frontend/src/index.html create mode 100644 frontend/src/main.ts create mode 100644 frontend/src/styles.scss create mode 100644 frontend/tsconfig.app.json create mode 100644 frontend/tsconfig.json create mode 100644 frontend/tsconfig.spec.json create mode 100644 frontend/yarn.lock create mode 100644 manage.py create mode 100644 pytest.ini create mode 100644 requirements/common.txt create mode 100644 requirements/dev.txt create mode 100644 requirements/prod.txt create mode 100644 scripts/__init__.py create mode 100644 scripts/seed.py create mode 100644 settings/__init__.py create mode 100644 settings/common.py create mode 100644 settings/dev.py create mode 100644 settings/prod.py create mode 100644 settings/test.py create mode 100644 static/.gitignore create mode 100644 templates/ticket/style.css create mode 100644 templates/ticket/ticket_template.html create mode 100644 tests/unit/__init__.py create mode 100644 tests/unit/base/__init__.py create mode 100644 tests/unit/base/test_utils.py create mode 100644 tests/unit/event/__init__.py create mode 100644 tests/unit/event/test_views.py create mode 100644 tests/unit/ticket/test_utils.py create mode 100644 tests/unit/ticket/test_views.py create mode 100644 ticketify/__init__.py create mode 100644 ticketify/asgi.py create mode 100644 ticketify/celery.py create mode 100644 ticketify/urls.py create mode 100644 ticketify/wsgi.py diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..12c55c2 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,7 @@ +bower_components +env +elasticmq-server-0.14.2.jar +examples +media +node_modules +static \ No newline at end of file diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000..287497a --- /dev/null +++ b/.flake8 @@ -0,0 +1,3 @@ +[flake8] +ignore = E501, W503, F403 +exclude = frontend/node_modules/ \ No newline at end of file diff --git a/.github/workflows/django.yml b/.github/workflows/django.yml new file mode 100644 index 0000000..0be44be --- /dev/null +++ b/.github/workflows/django.yml @@ -0,0 +1,30 @@ +name: Django CI + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + +jobs: + build: + + runs-on: ubuntu-latest + strategy: + max-parallel: 4 + matrix: + python-version: [3.11] + environment: dev + steps: + - uses: actions/checkout@v3 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v3 + with: + python-version: ${{ matrix.python-version }} + - name: Install Dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements/dev.txt + - name: Run Tests + run: | + pytest diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2066ccf --- /dev/null +++ b/.gitignore @@ -0,0 +1,233 @@ +# File created using '.gitignore Generator' for Visual Studio Code: https://bit.ly/vscode-gig +# Created by https://www.toptal.com/developers/gitignore/api/django,angular,yarn +# Edit at https://www.toptal.com/developers/gitignore?templates=django,angular,yarn + +### Angular ### +## Angular ## +# compiled output +dist/ +tmp/ +app/**/*.js +app/**/*.js.map + +# dependencies +node_modules/ +bower_components/ +*package-lock.json + +# IDEs and editors +.idea/ + +# misc +.sass-cache/ +connect.lock/ +coverage/ +libpeerconnection.log/ +npm-debug.log +testem.log +typings/ +.angular/ + +# e2e +e2e/*.js +e2e/*.map + +# System Files +.DS_Store/ + +### Django ### +*.log +*.pot +*.pyc +__pycache__/ +local_settings.py +db.sqlite3 +db.sqlite3-journal +media + +# If your build process includes running collectstatic, then you probably don't need or want to include staticfiles/ +# in your Git repository. Update and uncomment the following line accordingly. +# /staticfiles/ + +### Django.Python Stack ### +# Byte-compiled / optimized / DLL files +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo + +# Django stuff: + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +**.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ + +### yarn ### +# https://yarnpkg.com/getting-started/qa#which-files-should-be-gitignored + +.yarn/* +!.yarn/releases +!.yarn/patches +!.yarn/plugins +!.yarn/sdks +!.yarn/versions + +# if you are NOT using Zero-installs, then: +# comment the following lines +!.yarn/cache + +# and uncomment the following lines +# .pnp.* + +# End of https://www.toptal.com/developers/gitignore/api/django,angular,yarn + +# Custom rules (everything added below won't be overriden by 'Generate .gitignore File' if you use 'Update' option) + +# Docker Environment Files +docker/prod/docker_staging.env +docker/prod/docker_production.env + +# Visual Studio +.vscode/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..2d81980 --- /dev/null +++ b/README.md @@ -0,0 +1,70 @@ +# Ticketify + +A System Made to Sell Event Tickets + +# For whom is this system build? +This is build for the purpose of being a checkout page for events which doesn't have there own dedicated checkout page. + +# Where did the idea came from to create this? +The idea to create this came from the fact that many fest/events hosted by colleges speically uses manual methods like asking customers to fill a google form and then using excel for check in purposes. This method is very ineffective and require significant manpower. I was a part of this ineffective system last year when my college did the similar thing and put up a google form for ticket selling, with qr code of a upi account put up as a image to scan then give the transaction id. + + +# What features does this system have? +1. Ticket Generation with QR Code Support +2. QR Scanning using WebCam from Admin panel +3. Integration with Payment Gateways like Razorpay, Phonepe(Under Development) +4. Sub Events support (If a fest have its own internal event which require another fee) +5. Addon Items Support (Anything that is limited in stock and doesn't fit the category of Sub Events) +6. Admin Page with Stats for Ticket Sale, Sub Event Sale, Addon and Total Check IN. +7. Android APP for QR Scanning (A Anroid app will be far more faster and better at this then a webcam)(Under Development). +8. Celery worker support to handle heavy task of ticket image generation. +9. Webhooks to detect initation of Dispute or refund and disable the ticket or payment captured in case of late capture. This will mark the ticket paid and send a email to customer.(Razorpay Only for now) +10. Constnat Evaluation of all ticket sold for the active event to check for there payment status. Which will make sure that all scenerios are covered of transaction failure or late success. (Razorpay Only for now) + +# Is the system stable and tested for commercial use? +As of now the System is not finished for a live production usage, i will update as soon as we can declare it stable. +I am currently in process of getting a staging environment up for testing and a production environment for our upcoming Live Test run, with Sabrang 2023 at JKLU University. + +# Installation +Setting up Ticketify on your local machine is really easy. You can setup Ticketify using docker: The steps are: +1. install [docker](https://docs.docker.com/install/) on your machine. + +2. Get the source code on to your machine via git. + + ```shell + git clone https://github.com/Suryansh5545/Ticketify.git ticketify && cd ticketify + ``` + +3. Build and run the Docker containers. This might take a while. + + ``` + docker compose up --build + ``` +4. To Test Email support or Razorpay integration edit the docker.env.example file and rename the new one to docker.env +5. That's it. Open web browser and hit the URL [http://127.0.0.1:4200](http://127.0.0.1:4200). One user is created by default which are listed below - + + **SUPERUSER-** username: `admin` password: `password` + +If you are facing any issue during installation, please feel free to reach out to me by mail [suryanshpathak5545@gmail.com](mailto:suryanshpathak5545@gmail.com) + +# Planned Updates +1. Addition of more payment gateways Paytm and Phonepe(Under Development). +2. Android APP (Under Development). +3. Test Cases for most of the critical functions. +4. Addition of a organizer user to be able to add event without admin help from frontend. +5. Ability to host mutliple concurrently active events on the same site. + +# Screenshot (Early Development Phase) +![image](https://github.com/Suryansh5545/Ticketify/assets/34577232/1874be8f-f40d-4038-abc4-479b9cbd53b9) +![image](https://github.com/Suryansh5545/Ticketify/assets/34577232/62f31e56-ebfe-41b3-9cba-54f108022571) +![image](https://github.com/Suryansh5545/Ticketify/assets/34577232/631b3526-236a-4aff-bceb-0f7868f383d8) +![image](https://github.com/Suryansh5545/Ticketify/assets/34577232/9bb1fc2d-e409-401a-88c1-8f22e3e1b6be) +![image](https://github.com/Suryansh5545/Ticketify/assets/34577232/6f20f547-0a2a-4f52-a20b-af1c35f439de) + + + + + + + + diff --git a/apps/__init__.py b/apps/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/apps/base/__init__.py b/apps/base/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/apps/base/admin.py b/apps/base/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/apps/base/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/apps/base/apps.py b/apps/base/apps.py new file mode 100644 index 0000000..05011e8 --- /dev/null +++ b/apps/base/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class BaseConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'base' diff --git a/apps/base/management/commands/__init__.py b/apps/base/management/commands/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/apps/base/management/commands/seed.py b/apps/base/management/commands/seed.py new file mode 100644 index 0000000..00928a3 --- /dev/null +++ b/apps/base/management/commands/seed.py @@ -0,0 +1,22 @@ +from django.core.management import BaseCommand, call_command + + +class Command(BaseCommand): + + help = "Seeds the database with random but sensible values." + + def add_arguments(self, parser): + parser.add_argument( + "-nc", + nargs="?", + default=20, + type=int, + help="Number of challenges.", + ) + + def handle(self, *args, **options): + self.nc = options["nc"] + self.stdout.write( + self.style.SUCCESS("Starting the database seeder. Hang on...") + ) + call_command("runscript", "seed", "--script-args", self.nc) diff --git a/apps/base/migrations/__init__.py b/apps/base/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/apps/base/models.py b/apps/base/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/apps/base/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/apps/base/utils.py b/apps/base/utils.py new file mode 100644 index 0000000..953b5de --- /dev/null +++ b/apps/base/utils.py @@ -0,0 +1,25 @@ +from django.conf import settings +from django.core.mail import send_mail +import os + + +def get_url_from_hostname(hostname): + if settings.DEBUG or settings.TEST: + scheme = "http" + else: + scheme = "https" + url = "{}://{}".format(scheme, hostname) + return url + + +def EmailService(subject, message, recipient_list, from_email=None, html_message=None): + from_email = from_email or settings.DEFAULT_FROM_EMAIL + send_mail(subject, message, from_email, recipient_list, html_message=html_message) + + +def get_file_content(file_path, mode): + if os.path.isfile(file_path): + with open(file_path, mode) as file_content: + return file_content.read() + else: + raise FileNotFoundError diff --git a/apps/base/views.py b/apps/base/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/apps/base/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/apps/event/__init__.py b/apps/event/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/apps/event/admin.py b/apps/event/admin.py new file mode 100644 index 0000000..6a7bdc3 --- /dev/null +++ b/apps/event/admin.py @@ -0,0 +1,28 @@ +from django.contrib import admin +from .models import Event, SubEvent, Addon, PromoCode +from import_export.admin import ImportExportModelAdmin + +class SubEventAdmin(ImportExportModelAdmin): + list_display = ('id', 'name', 'event', 'is_active') + search_fields = ('name', ) + + +class EventAdmin(admin.ModelAdmin): + list_display = ('name', 'is_active') + search_fields = ('name', ) + + +class AddonAdmin(admin.ModelAdmin): + list_display = ('name', 'event', 'stock', 'is_active') + search_fields = ('name', ) + + +class PromoCodeAdmin(admin.ModelAdmin): + list_display = ('code', 'event', 'stock', 'is_active') + search_fields = ('code', ) + + +admin.site.register(Event, EventAdmin) +admin.site.register(SubEvent, SubEventAdmin) +admin.site.register(Addon, AddonAdmin) +admin.site.register(PromoCode, PromoCodeAdmin) diff --git a/apps/event/apps.py b/apps/event/apps.py new file mode 100644 index 0000000..49fdd6a --- /dev/null +++ b/apps/event/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class EventConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'event' diff --git a/apps/event/migrations/0001_initial.py b/apps/event/migrations/0001_initial.py new file mode 100644 index 0000000..a5c6357 --- /dev/null +++ b/apps/event/migrations/0001_initial.py @@ -0,0 +1,92 @@ +# Generated by Django 4.2.1 on 2023-08-01 15:16 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Event', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=100)), + ('description', models.TextField()), + ('start_date', models.DateField()), + ('end_date', models.DateField()), + ('image', models.ImageField(blank=True, upload_to='event')), + ('location', models.CharField(max_length=100)), + ('price', models.DecimalField(decimal_places=2, default=0.0, max_digits=10)), + ('sub_events_included_allowed', models.IntegerField(default=0)), + ('is_active', models.BooleanField(default=False)), + ('event_page', models.URLField(blank=True)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ], + options={ + 'db_table': 'event', + 'ordering': ['-created_at'], + }, + ), + migrations.CreateModel( + name='SubEvent', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=100)), + ('description', models.TextField()), + ('start_date', models.DateField()), + ('end_date', models.DateField()), + ('image', models.ImageField(blank=True, upload_to='sub_event')), + ('price', models.DecimalField(decimal_places=2, default=0.0, max_digits=10)), + ('is_active', models.BooleanField(default=True)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='event.event')), + ], + options={ + 'db_table': 'sub_event', + 'ordering': ['-created_at'], + }, + ), + migrations.CreateModel( + name='PromoCode', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('code', models.CharField(max_length=30)), + ('discount', models.DecimalField(decimal_places=2, default=0.0, max_digits=10)), + ('is_active', models.BooleanField(default=True)), + ('stock', models.IntegerField(default=0)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='event.event')), + ], + options={ + 'db_table': 'promo_code', + 'ordering': ['-created_at'], + }, + ), + migrations.CreateModel( + name='Addon', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=100)), + ('icon', models.CharField(blank=True, help_text='Font Awesome Icon Name', max_length=30)), + ('price', models.DecimalField(decimal_places=2, default=0.0, max_digits=10)), + ('is_active', models.BooleanField(default=True)), + ('stock', models.IntegerField(default=0)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='event.event')), + ], + options={ + 'db_table': 'addon', + 'ordering': ['-created_at'], + }, + ), + ] diff --git a/apps/event/migrations/__init__.py b/apps/event/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/apps/event/models.py b/apps/event/models.py new file mode 100644 index 0000000..d902858 --- /dev/null +++ b/apps/event/models.py @@ -0,0 +1,85 @@ +from django.db import models + + +class Event(models.Model): + name = models.CharField(max_length=100) + description = models.TextField() + start_date = models.DateField() + end_date = models.DateField() + image = models.ImageField(upload_to='event', blank=True) + location = models.CharField(max_length=100) + price = models.DecimalField(max_digits=10, decimal_places=2, default=0.00) + sub_events_included_allowed = models.IntegerField(default=0) + is_active = models.BooleanField(default=False) + event_page = models.URLField(max_length=200, blank=True) + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + + + def save(self, *args, **kwargs): + if self.is_active: + # If this event is set to active, deactivate all other events + Event.objects.exclude(pk=self.pk).update(is_active=False) + super().save(*args, **kwargs) + + + class Meta: + db_table = "event" + ordering = ["-created_at"] + + def __str__(self): + return self.name + + +class SubEvent(models.Model): + name = models.CharField(max_length=100) + description = models.TextField() + start_date = models.DateField() + end_date = models.DateField() + image = models.ImageField(upload_to='sub_event', blank=True) + price = models.DecimalField(max_digits=10, decimal_places=2, default=0.00) + event = models.ForeignKey('event.Event', on_delete=models.CASCADE) + is_active = models.BooleanField(default=True) + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + class Meta: + db_table = "sub_event" + ordering = ["-created_at"] + + def __str__(self): + return self.name + + +class Addon(models.Model): + name = models.CharField(max_length=100) + icon = models.CharField(max_length=30, blank=True, help_text = "Font Awesome Icon Name") + event = models.ForeignKey('event.Event', on_delete=models.CASCADE) + price = models.DecimalField(max_digits=10, decimal_places=2, default=0.00) + is_active = models.BooleanField(default=True) + stock = models.IntegerField(default=0) + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + + class Meta: + db_table = "addon" + ordering = ["-created_at"] + + def __str__(self): + return self.name + + +class PromoCode(models.Model): + code = models.CharField(max_length=30) + event = models.ForeignKey('event.Event', on_delete=models.CASCADE) + discount = models.DecimalField(max_digits=10, decimal_places=2, default=0.00) + is_active = models.BooleanField(default=True) + stock = models.IntegerField(default=0) + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + + class Meta: + db_table = "promo_code" + ordering = ["-created_at"] + + def __str__(self): + return self.code diff --git a/apps/event/serializers.py b/apps/event/serializers.py new file mode 100644 index 0000000..79f5813 --- /dev/null +++ b/apps/event/serializers.py @@ -0,0 +1,18 @@ +from .models import Event, SubEvent, Addon +from rest_framework import serializers +from django.conf import settings + +class EventSerializer(serializers.ModelSerializer): + class Meta: + model = Event + fields = ("id", "name", "description", "start_date", "end_date", "image" , "location", "event_page", "price", "sub_events_included_allowed") + +class SubEventSerializer(serializers.ModelSerializer): + class Meta: + model = SubEvent + fields = ("id", "name", "description", "start_date", "end_date", "image", "event", "price") + +class AddonSerializer(serializers.ModelSerializer): + class Meta: + model = Addon + fields = ("id", "name", "icon", "event", "price", "stock") diff --git a/apps/event/urls.py b/apps/event/urls.py new file mode 100644 index 0000000..1970112 --- /dev/null +++ b/apps/event/urls.py @@ -0,0 +1,12 @@ +from django.urls import path +from .views import GetActiveEvent, GetSubEvent, GetAddon, ProcessPromoCode, get_max_ticket_sales, get_sub_event_sales, get_addon_sales + +urlpatterns = [ + path('get_event/', GetActiveEvent.as_view(), name='get_active_event'), + path('get_sub_event//', GetSubEvent.as_view(), name='get_sub_event'), + path('get_addon//', GetAddon.as_view(), name='get_addon'), + path('process_promo_code/', ProcessPromoCode.as_view(), name='process_promo_code'), + path('get_max_ticket_sales//', get_max_ticket_sales.as_view(), name='get_max_ticket_sales'), + path('get_sub_event_sales//', get_sub_event_sales.as_view(), name='get_sub_event_sales'), + path('get_addon_sales//', get_addon_sales.as_view(), name='get_addon_sales'), +] \ No newline at end of file diff --git a/apps/event/views.py b/apps/event/views.py new file mode 100644 index 0000000..c731911 --- /dev/null +++ b/apps/event/views.py @@ -0,0 +1,110 @@ + +from rest_framework.views import APIView +from rest_framework.response import Response +from rest_framework import permissions, status, authentication +from .models import Event, PromoCode, SubEvent, Addon +from ticket.models import Ticket +from .serializers import EventSerializer, SubEventSerializer, AddonSerializer + + +from rest_framework.generics import ListAPIView +from rest_framework.response import Response +from rest_framework import status + +class GetActiveEvent(ListAPIView): + queryset = Event.objects.filter(is_active=True) + serializer_class = EventSerializer + + def list(self, request, *args, **kwargs): + if self.queryset.exists(): + return super().list(request, *args, **kwargs) + else: + return Response("No Active Event", status=status.HTTP_400_BAD_REQUEST) + + +class GetSubEvent(APIView): + def get(self, request, pk, format=None): + event = Event.objects.get(pk=pk) + sub_event = event.subevent_set.filter(is_active=True) + if sub_event: + serializer = SubEventSerializer(sub_event, context={"request": request}, many=True) + if serializer.is_valid: + return Response(serializer.data, status=status.HTTP_200_OK) + else: + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + else: + return Response("No Active Sub Event", status=status.HTTP_400_BAD_REQUEST) + +class GetAddon(APIView): + def get(self, request, pk, format=None): + event = Event.objects.get(pk=pk) + addon = event.addon_set.filter(is_active=True) + if addon: + serializer = AddonSerializer(addon, many=True) + if serializer.is_valid: + return Response(serializer.data, status=status.HTTP_200_OK) + else: + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + else: + return Response("No active Addon", status=status.HTTP_400_BAD_REQUEST) + +class ProcessPromoCode(APIView): + def post(self, request, format=None): + try: + promo_code = request.data.get("promo_code") + event_id = request.data.get("event_id") + promo_code = PromoCode.objects.get(code=promo_code,is_active=True) + if promo_code.stock == 0: + return Response({"error": "Promo code out of stock"}, status=status.HTTP_400_BAD_REQUEST) + else: + event = Event.objects.get(pk=event_id) + if promo_code.event == event: + promo_code.stock -= 1 + return Response({"discount": promo_code.discount}, status=status.HTTP_200_OK) + else: + return Response({"error": "Promo code not valid for this event"}, status=status.HTTP_400_BAD_REQUEST) + except PromoCode.DoesNotExist: + return Response({"error": "Promo code does not exist"}, status=status.HTTP_400_BAD_REQUEST) + + +class get_max_ticket_sales(APIView): + permission_classes = [permissions.IsAuthenticated] + authentication_classes = [authentication.SessionAuthentication] + def get(self, request, pk): + event = Event.objects.get(pk=pk) + tickets = Ticket.objects.filter(event=event, is_active=True) + total_amount = 0 + for ticket in tickets: + total_amount += ticket.transaction_id.payment_amount + ticket_number = tickets.count() + return Response({"total_tickets": ticket_number, "total_amount": total_amount}, status=status.HTTP_200_OK) + + +class get_sub_event_sales(APIView): + permission_classes = [permissions.IsAuthenticated] + authentication_classes = [authentication.SessionAuthentication] + def get(self, request, pk): + event = Event.objects.get(pk=pk) + sub_events = SubEvent.objects.filter(event=event) + sub_events_sales = [] + sub_events_names = [] + for sub_event in sub_events: + sub_event.ticket_count = Ticket.objects.filter(event=event, selected_sub_events=sub_event).count() + sub_events_sales.append(sub_event.ticket_count) + sub_events_names.append(sub_event.name) + return Response({"data": sub_events_sales, "label": sub_events_names}, status=status.HTTP_200_OK) + + +class get_addon_sales(APIView): + permission_classes = [permissions.IsAuthenticated] + authentication_classes = [authentication.SessionAuthentication] + def get(self, request, pk): + event = Event.objects.get(pk=pk) + addons = Addon.objects.filter(event=event) + addons_sales = [] + addons_names = [] + for addon in addons: + addon.ticket_count = Ticket.objects.filter(event=event, selected_addons=addon).count() + addons_sales.append(addon.ticket_count) + addons_names.append(addon.name) + return Response({"data": addons_sales, "label": addons_names}, status=status.HTTP_200_OK) \ No newline at end of file diff --git a/apps/ticket/__init__.py b/apps/ticket/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/apps/ticket/admin.py b/apps/ticket/admin.py new file mode 100644 index 0000000..8a706b6 --- /dev/null +++ b/apps/ticket/admin.py @@ -0,0 +1,23 @@ +from django.contrib import admin +from .models import Ticket, CheckIn, TicketEmailLog +from import_export.admin import ImportExportModelAdmin + +class TicketAdmin(ImportExportModelAdmin): + list_display = ('id', 'check_in', 'customer_name', 'customer_email', 'customer_phone','event', 'is_active', 'order_id', 'transaction_id', 'created_at', 'updated_at',) + search_fields = ('id', 'check_in', 'customer_name', 'customer_email', 'customer_phone', 'order_id') + list_filter = ('event', 'selected_sub_events' , 'selected_addons','is_active') + + def get_list_display(self, request): + # Get the default list_display for superusers + superuser_list_display = super().get_list_display(request) + + # Check if the user is a superuser + if request.user.is_superuser: + return superuser_list_display + else: + # For normal staff, remove 'check_in' from the list_display + return [field for field in superuser_list_display if field != 'check_in'] + +admin.site.register(Ticket, TicketAdmin) +admin.site.register(CheckIn) +admin.site.register(TicketEmailLog) diff --git a/apps/ticket/apps.py b/apps/ticket/apps.py new file mode 100644 index 0000000..1b423f8 --- /dev/null +++ b/apps/ticket/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class TicketConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'ticket' diff --git a/apps/ticket/migrations/0001_initial.py b/apps/ticket/migrations/0001_initial.py new file mode 100644 index 0000000..55d4713 --- /dev/null +++ b/apps/ticket/migrations/0001_initial.py @@ -0,0 +1,77 @@ +# Generated by Django 4.2.1 on 2023-08-01 15:16 + +from django.db import migrations, models +import django.db.models.deletion +import ticket.models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('event', '0001_initial'), + ('transactions', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='Ticket', + fields=[ + ('id', models.CharField(default=ticket.models.generate_id, editable=False, max_length=7, primary_key=True, serialize=False)), + ('check_in', models.CharField(editable=False, max_length=10, unique=True)), + ('customer_name', models.CharField(max_length=100)), + ('customer_email', models.EmailField(max_length=254)), + ('customer_phone', models.CharField(max_length=100)), + ('is_active', models.BooleanField(default=False)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('ticket_image_generated', models.BooleanField(default=False)), + ('ticket_image_location', models.TextField(blank=True, default='', null=True)), + ('order_id', models.CharField(default='', max_length=100, null=True, unique=True)), + ('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='event.event')), + ('selected_addons', models.ManyToManyField(blank=True, to='event.addon')), + ('selected_sub_events', models.ManyToManyField(blank=True, to='event.subevent')), + ], + options={ + 'db_table': 'ticket', + 'ordering': ['-created_at'], + }, + ), + migrations.CreateModel( + name='TicketEmailLog', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('email_sent_time', models.DateTimeField(auto_now_add=True)), + ('ticket', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='ticket_email_logs', to='ticket.ticket')), + ], + options={ + 'db_table': 'ticket_email_log', + 'ordering': ['-email_sent_time'], + }, + ), + migrations.AddField( + model_name='ticket', + name='ticket_mail_log', + field=models.ManyToManyField(blank=True, related_name='tickets', to='ticket.ticketemaillog'), + ), + migrations.AddField( + model_name='ticket', + name='transaction_id', + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='transactions.transaction'), + ), + migrations.CreateModel( + name='CheckIn', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('check_in_time', models.DateTimeField(auto_now_add=True)), + ('operator', models.CharField(blank=True, max_length=100, null=True)), + ('method', models.CharField(choices=[('QR', 'QR Code'), ('MANUAL', 'Manual')], default='QR', max_length=100)), + ('ticket', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='ticket_check_in', to='ticket.ticket')), + ], + options={ + 'db_table': 'check_in', + 'ordering': ['-check_in_time'], + }, + ), + ] diff --git a/apps/ticket/migrations/__init__.py b/apps/ticket/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/apps/ticket/models.py b/apps/ticket/models.py new file mode 100644 index 0000000..7f66b34 --- /dev/null +++ b/apps/ticket/models.py @@ -0,0 +1,80 @@ +from django.db import models +from event.models import Event, SubEvent, Addon +from transactions.models import Transaction +import random +import string + +def generate_id(): + # Generate a random 10-digit alphanumeric string + return ''.join(random.choices(string.ascii_uppercase + string.digits, k=7)) + +class Ticket(models.Model): + id = models.CharField(primary_key=True, default=generate_id, editable=False, max_length=7) + check_in = models.CharField(editable=False, max_length=10, unique=True) + customer_name = models.CharField(max_length=100) + customer_email = models.EmailField() + customer_phone = models.CharField(max_length=100) + event = models.ForeignKey(Event, on_delete=models.CASCADE) + selected_sub_events = models.ManyToManyField(SubEvent, blank=True) + selected_addons = models.ManyToManyField(Addon, blank=True) + is_active = models.BooleanField(default=False) + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + ticket_image_generated = models.BooleanField(default=False) + ticket_image_location = models.TextField(default="", null=True, blank=True) + order_id = models.CharField(max_length=100, default="", unique=True, null=True) + ticket_mail_log = models.ManyToManyField('TicketEmailLog', related_name='tickets', blank=True) + transaction_id = models.OneToOneField(Transaction, on_delete=models.CASCADE, null=True, blank=True, unique=True) + + def generate_unique_ticket_id(self): + return ''.join(random.choices(string.ascii_uppercase + string.digits, k=10)) + + def save(self, *args, **kwargs): + if self.transaction_id == None: + self.is_active = False + if not self.check_in: + # Generate a unique check_in value if it doesn't exist + self.check_in = self.generate_unique_ticket_id() + while Ticket.objects.filter(check_in=self.check_in).exists(): + # Regenerate the check_in value until it becomes unique + self.check_in = self.generate_unique_ticket_id() + super().save(*args, **kwargs) + + class Meta: + db_table = "ticket" + ordering = ["-created_at"] + + def __str__(self): + return self.customer_name + + +class CheckIn(models.Model): + + CHECK_IN_METHODS = ( + ('QR', 'QR Code'), + ('MANUAL', 'Manual'), + ) + + ticket = models.ForeignKey(Ticket, on_delete=models.CASCADE, related_name="ticket_check_in") + check_in_time = models.DateTimeField(auto_now_add=True) + operator = models.CharField(max_length=100, blank=True, null=True) + method = models.CharField(max_length=100, choices=CHECK_IN_METHODS, default='QR') + + class Meta: + db_table = "check_in" + ordering = ["-check_in_time"] + + def __str__(self): + return self.ticket, self.check_in_time + + +class TicketEmailLog(models.Model): + ticket = models.ForeignKey(Ticket, on_delete=models.CASCADE, related_name='ticket_email_logs') + email_sent_time = models.DateTimeField(auto_now_add=True) + + class Meta: + db_table = "ticket_email_log" + ordering = ["-email_sent_time"] + + def __str__(self): + return str(self.ticket) + ' ' + str(self.email_sent_time) \ No newline at end of file diff --git a/apps/ticket/serializers.py b/apps/ticket/serializers.py new file mode 100644 index 0000000..6630cf7 --- /dev/null +++ b/apps/ticket/serializers.py @@ -0,0 +1,33 @@ +from rest_framework import serializers +from event.serializers import SubEventSerializer, AddonSerializer +from transactions.serializers import TransactionSerializer + +class TicketSerializer(serializers.Serializer): + customer_name = serializers.CharField() + customer_email = serializers.EmailField() + customer_phone = serializers.CharField() + event_id = serializers.IntegerField() + selected_sub_events = serializers.ListField(child=serializers.IntegerField(), required=False) + selected_addons = serializers.ListField(child=serializers.IntegerField(), required=False) + + +class AdminTicketSerializer(serializers.Serializer): + id = serializers.CharField() + customer_name = serializers.CharField() + customer_email = serializers.EmailField() + customer_phone = serializers.CharField() + event_id = serializers.IntegerField() + selected_sub_events = SubEventSerializer(many=True, required=False) + selected_addons = AddonSerializer(many=True, required=False) + transaction_id = TransactionSerializer(required=True) + + +class CheckInSerializer(serializers.Serializer): + ticket_id = serializers.CharField() + check_in_time = serializers.DateTimeField(format="%Y-%m-%d %I:%M %p") + operator = serializers.CharField() + method = serializers.CharField() + +class TicketListSerializer(serializers.Serializer): + customer_name = serializers.CharField() + customer_phone = serializers.CharField() \ No newline at end of file diff --git a/apps/ticket/tests.py b/apps/ticket/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/apps/ticket/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/apps/ticket/urls.py b/apps/ticket/urls.py new file mode 100644 index 0000000..34ee0ce --- /dev/null +++ b/apps/ticket/urls.py @@ -0,0 +1,12 @@ +from django.urls import path +from .views import get_tickets_by_filter, handle_check_in, get_check_in_data, resend_email, get_ticket_by_subevents, get_ticket_by_addons, get_ticket_by_task + +urlpatterns = [ + path('get_tickets_by_filter/', get_tickets_by_filter.as_view(), name='get_tickets_by_filter'), + path('handle_check_in/', handle_check_in.as_view(), name='handle_check_in'), + path('get_check_in_data/', get_check_in_data.as_view(), name='get_check_in_data'), + path('resend_email/', resend_email.as_view(), name='resend_email'), + path('get_ticket_by_subevents/', get_ticket_by_subevents.as_view(), name='get_ticket_by_subevents'), + path('get_ticket_by_addons/', get_ticket_by_addons.as_view(), name='get_ticket_by_addons'), + path('get_ticket_by_task/', get_ticket_by_task.as_view(), name='get_ticket_by_task'), +] \ No newline at end of file diff --git a/apps/ticket/utils.py b/apps/ticket/utils.py new file mode 100644 index 0000000..0c7d5b8 --- /dev/null +++ b/apps/ticket/utils.py @@ -0,0 +1,132 @@ +from cryptography.fernet import Fernet +from celery import shared_task +from django.template.loader import get_template +import base64 +from django.utils import timezone +from django.core.mail import EmailMultiAlternatives +import os, qrcode, imgkit +from io import BytesIO +from .serializers import TicketSerializer +from .models import Ticket, TicketEmailLog +from event.models import Event +from django.conf import settings + + +def create_ticket(request, order_id): + if request.method == "POST": + serializer = TicketSerializer(data=request.data) + if serializer.is_valid(): + validated_data = serializer.validated_data + customer_name = validated_data['customer_name'] + customer_email = validated_data['customer_email'] + customer_phone = validated_data['customer_phone'] + event_id = validated_data['event_id'] + selected_sub_events = validated_data.get('selected_sub_events', []) + selected_addons = validated_data.get('selected_addons', []) + event = Event.objects.get(pk=event_id) + ticket = Ticket.objects.create( + customer_name=customer_name, + customer_email=customer_email, + customer_phone=customer_phone, + event=event,order_id = order_id + ) + ticket.selected_sub_events.set(selected_sub_events) + ticket.selected_addons.set(selected_addons) + ticket.save() + else: + raise Exception(serializer.errors) + + +@shared_task(name="generate_ticket_image") +def generate_ticket_image (ticket_id): + ticket = Ticket.objects.get(pk=ticket_id) + encrypted_ticket_id = encrypt_decrypt_ticket_id(ticket.id) + qr_code_image = generate_qr_code(ticket.check_in) + qr_code_image_base64 = base64.b64encode(qr_code_image).decode('utf-8') + sub_events = ticket.selected_sub_events.all().values_list('name', flat=True) + ticket_data = { + "spam": "", + "ticketNumber": ticket.id, + "artistName": ticket.customer_name, + "showName": ticket.event.name, + "location": ticket.event.location, + "day": ticket.event.start_date.strftime("%A"), + "date": ticket.event.start_date.strftime("%B %d") + " - " + ticket.event.end_date.strftime("%d"), + "year": ticket.event.start_date.strftime("%Y"), + "timeSlot": ticket.event.start_date.strftime("%I:%M %p") + " TO " + ticket.event.end_date.strftime("%I:%M %p"), + "doors": sub_events, + "barcodeImageURL": f"data:image/png;base64,{qr_code_image_base64}", + } + + template = get_template('ticket/ticket_template.html') + html_content = template.render(ticket_data) + options = { + 'width': '802', + 'height': '250', + 'quality': 100, + 'zoom': '2.0', + } + ticket_name = f"ticket_{encrypted_ticket_id}.jpg" + tickets_dir = os.path.join(settings.MEDIA_ROOT, 'tickets') + if not os.path.exists(tickets_dir): + # Create the 'tickets' directory if it doesn't exist + os.makedirs(tickets_dir) + image_path = os.path.join(settings.MEDIA_ROOT, 'tickets', ticket_name) + imgkit.from_string(html_content, image_path, options=options) + ticket.ticket_image_location = image_path + ticket.save() + send_ticket(ticket.id) + image_url = f"{settings.TICKETIFY_API_SERVER}{settings.MEDIA_URL}{'tickets/'}{ticket_name}" + return image_url + + +def generate_qr_code(ticket_id): + # Generate the QR code using the ticket ID + qr = qrcode.QRCode(version=1, error_correction=qrcode.constants.ERROR_CORRECT_H, box_size=30, border=8) + qr.add_data(ticket_id) + qr.make(fit=True) + + # Create an image from the QR code + qr_image = qr.make_image(fill_color="black", back_color="white") + + # Create a BytesIO object to store the image data + qr_image_bytes = BytesIO() + qr_image.save(qr_image_bytes, format='PNG') + qr_image_bytes.seek(0) + + return qr_image_bytes.getvalue() + +@shared_task(name="resend_email") +def send_ticket(ticket_id): + ticket = Ticket.objects.get(pk=ticket_id) + recipient_email = ticket.customer_email + event_name = ticket.event.name + image_path = ticket.ticket_image_location + # Create the email message + email = EmailMultiAlternatives(f"Your ticket for {event_name}", "Please find your ticket attached", settings.DEFAULT_FROM_EMAIL, [recipient_email]) + + # Attach the image to the email + with open(image_path, 'rb') as f: + email.attach('ticket_image.jpg', f.read(), 'image/jpeg') + + # Send the email + email.send() + ticket_send_log = TicketEmailLog.objects.create(ticket=ticket, email_sent_time=timezone.now()) + ticket.ticket_mail_log.set([ticket_send_log]) + ticket.save() + return True + + +@shared_task(name="encrypt_decrypt_ticket_id") +def encrypt_decrypt_ticket_id(ticket_id, decrypt=False): + encryption_key = os.environ.get("ENCRYPTION_KEY") + if not encryption_key: + # Generate a new encryption key + encryption_key = Fernet.generate_key() + os.environ["ENCRYPTION_KEY"] = encryption_key.decode('utf-8') + f = Fernet(encryption_key) + if decrypt: + ticket_id = f.decrypt(ticket_id.encode('utf-8')).decode('utf-8') + else: + ticket_id = f.encrypt(ticket_id.encode('utf-8')).decode('utf-8') + return ticket_id \ No newline at end of file diff --git a/apps/ticket/views.py b/apps/ticket/views.py new file mode 100644 index 0000000..889e8d0 --- /dev/null +++ b/apps/ticket/views.py @@ -0,0 +1,177 @@ +import datetime +from event.models import SubEvent, Addon +from .models import Ticket, CheckIn +from rest_framework.views import APIView, Response +from .serializers import AdminTicketSerializer, CheckInSerializer, TicketListSerializer +from django.db.models import Q +from rest_framework import permissions, status, authentication +from .utils import send_ticket +from celery.result import AsyncResult + + + +class get_tickets_by_filter(APIView): + permission_classes = (permissions.IsAuthenticated, ) + authentication_classes = [authentication.SessionAuthentication] + def post(self, request): + email = request.data.get('email') + phone = request.data.get('phone') + name = request.data.get('name') + ticket_id = request.data.get('ticket_id') + if ticket_id: + try: + ticket = Ticket.objects.get(check_in=ticket_id, is_active=True) + except Ticket.DoesNotExist: + return Response({"message": "Ticket does not exist or isn't active"}, status=status.HTTP_400_BAD_REQUEST) + serializer = AdminTicketSerializer(ticket) + return Response(serializer.data, status=status.HTTP_200_OK) + else: + if not email and not phone and not name: + return Response({"message": "At least one of email, phone or name is required"}, status=status.HTTP_400_BAD_REQUEST) + query = Q() + if email: + query &= Q(customer_email__icontains=email) + + if phone: + query &= Q(customer_phone__icontains=phone) + + if name: + query &= Q(customer_name__icontains=name) + + tickets = Ticket.objects.filter(query, is_active=True) + if not tickets.exists(): + return Response({"message": "No tickets found"}, status=status.HTTP_400_BAD_REQUEST) + serializer = AdminTicketSerializer(tickets, many=True) + return Response(serializer.data, status=status.HTTP_200_OK) + + +class handle_check_in(APIView): + permission_classes = (permissions.IsAuthenticated, ) + authentication_classes = [authentication.SessionAuthentication] + def post(self, request): + ticket_id = request.data.get('ticket_id') + if not ticket_id: + return Response({"message": "ticket_id is required"}, status=status.HTTP_400_BAD_REQUEST) + operator = request.user.id + if len(ticket_id) == 10: + method = "QR" + else: + method = "MANUAL" + time = datetime.datetime.now() + if not ticket_id or not operator or not method: + return Response({"message": "ticket_id, operator and method are required"}, status=status.HTTP_400_BAD_REQUEST) + try: + if(method == "QR"): + ticket = Ticket.objects.get(check_in=ticket_id, is_active=True) + else: + ticket = Ticket.objects.get(id=ticket_id, is_active=True) + except Ticket.DoesNotExist: + return Response({"message": "Ticket does not exist or is not active"}, status=status.HTTP_400_BAD_REQUEST) + if ticket.event.end_date < time.date(): + return Response({"message": "Event has ended"}, status=status.HTTP_400_BAD_REQUEST) + else: + if ticket.is_active: + check_in_check = CheckIn.objects.filter(ticket=ticket, check_in_time__date=time.date()) + if check_in_check.exists(): + return Response({"message": "Ticket already checked in today"}, status=status.HTTP_400_BAD_REQUEST) + + CheckIn.objects.create(ticket=ticket, operator=operator, method=method) + return Response({"message": "Ticket checked in successfully"}, status=status.HTTP_200_OK) + else: + return Response({"message": "Ticket is not active"}, status=status.HTTP_400_BAD_REQUEST) + + +class get_check_in_data(APIView): + permission_classes = (permissions.IsAuthenticated, ) + authentication_classes = [authentication.SessionAuthentication] + def post(self, request): + ticket_id = request.data.get('ticket_id') + if not ticket_id: + return Response({"message": "ticket_id is required"}, status=status.HTTP_400_BAD_REQUEST) + try: + ticket = Ticket.objects.get(id=ticket_id, is_active=True) + except Ticket.DoesNotExist: + return Response({"message": "Ticket does not exist"}, status=status.HTTP_400_BAD_REQUEST) + if ticket.is_active: + check_in = CheckIn.objects.filter(ticket=ticket) + if check_in.exists(): + serializer = CheckInSerializer(check_in, many=True) + return Response(serializer.data, status=status.HTTP_200_OK) + else: + return Response({"message": "Ticket has not been checked in"}, status=status.HTTP_400_BAD_REQUEST) + else: + return Response({"message": "Ticket is not active"}, status=status.HTTP_400_BAD_REQUEST) + + +class resend_email(APIView): + permission_classes = (permissions.IsAuthenticated, ) + authentication_classes = [authentication.SessionAuthentication] + def post(self, request): + ticket_id = request.data.get('ticket_id') + if not ticket_id: + return Response({"message": "ticket_id is required"}, status=status.HTTP_400_BAD_REQUEST) + try: + ticket = Ticket.objects.get(id=ticket_id, is_active=True) + except Ticket.DoesNotExist: + return Response({"message": "Ticket does not exist"}, status=status.HTTP_400_BAD_REQUEST) + if ticket.is_active: + send_ticket.delay(ticket.id) + return Response({"message": "Ticket email sent successfully"}, status=status.HTTP_200_OK) + else: + return Response({"message": "Ticket is not active"}, status=status.HTTP_400_BAD_REQUEST) + + +class get_ticket_by_subevents(APIView): + permission_classes = (permissions.IsAuthenticated, ) + authentication_classes = [authentication.SessionAuthentication] + def post(self, request): + list_id = request.data.get('list_id') + if not list_id: + return Response({"message": "ID is required"}, status=status.HTTP_400_BAD_REQUEST) + elif SubEvent.objects.filter(id=list_id, is_active=True).exists() == False: + return Response({"message": "Sub Event does not exist or is not active"}, status=status.HTTP_400_BAD_REQUEST) + try: + tickets = Ticket.objects.filter(selected_sub_events__in=[list_id], is_active=True) + except Ticket.DoesNotExist: + return Response({"message": "Ticket does not exist"}, status=status.HTTP_400_BAD_REQUEST) + if tickets.exists(): + serializer = TicketListSerializer(tickets, many=True) + return Response(serializer.data, status=status.HTTP_200_OK) + else: + return Response({"message": "No tickets found"}, status=status.HTTP_400_BAD_REQUEST) + + +class get_ticket_by_addons(APIView): + permission_classes = (permissions.IsAuthenticated, ) + authentication_classes = [authentication.SessionAuthentication] + def post(self, request): + list_id = request.data.get('list_id') + if not list_id: + return Response({"message": "ID is required"}, status=status.HTTP_400_BAD_REQUEST) + elif Addon.objects.filter(id=list_id, is_active=True).exists() == False: + return Response({"message": "Sub Event does not exist or is not active"}, status=status.HTTP_400_BAD_REQUEST) + try: + tickets = Ticket.objects.filter(selected_addons__in=[list_id], is_active=True) + except Ticket.DoesNotExist: + return Response({"message": "Ticket does not exist"}, status=status.HTTP_400_BAD_REQUEST) + if tickets.exists(): + serializer = TicketListSerializer(tickets, many=True) + return Response(serializer.data, status=status.HTTP_200_OK) + else: + return Response({"message": "No tickets found"}, status=status.HTTP_400_BAD_REQUEST) + + +class get_ticket_by_task(APIView): + def post(self, request): + task_id = request.data.get('task_id') + if not task_id: + return Response({"message": "task_id is required"}, status=status.HTTP_400_BAD_REQUEST) + try: + result = AsyncResult(task_id) + except: + return Response({"message": "Task does not exist"}, status=status.HTTP_400_BAD_REQUEST) + if result.status == "SUCCESS": + return Response(result.result, status=status.HTTP_200_OK) + else: + return Response({"message": "Task is not complete"}, status=status.HTTP_400_BAD_REQUEST) + diff --git a/apps/transactions/__init__.py b/apps/transactions/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/apps/transactions/admin.py b/apps/transactions/admin.py new file mode 100644 index 0000000..0732f44 --- /dev/null +++ b/apps/transactions/admin.py @@ -0,0 +1,10 @@ +from django.contrib import admin +from .models import Transaction +from import_export.admin import ImportExportModelAdmin + +class TransactionAdmin(ImportExportModelAdmin): + list_display = ('id', 'payment_status', 'order_id', 'payment_id', 'payment_amount', 'webhook_recieved','created_at', 'updated_at') + search_fields = ('id', 'payment_status', 'order_id', 'payment_id') + list_filter = ('payment_status','webhook_recieved') + +admin.site.register(Transaction, TransactionAdmin) \ No newline at end of file diff --git a/apps/transactions/apps.py b/apps/transactions/apps.py new file mode 100644 index 0000000..f806531 --- /dev/null +++ b/apps/transactions/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class TransactionsConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'transactions' diff --git a/apps/transactions/migrations/0001_initial.py b/apps/transactions/migrations/0001_initial.py new file mode 100644 index 0000000..b3981a3 --- /dev/null +++ b/apps/transactions/migrations/0001_initial.py @@ -0,0 +1,33 @@ +# Generated by Django 4.2.1 on 2023-08-01 15:16 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Transaction', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('payment_method', models.CharField(blank=True, max_length=100)), + ('payment_status', models.CharField(max_length=100)), + ('order_id', models.CharField(default='', max_length=100)), + ('payment_id', models.CharField(blank=True, max_length=100, null=True, unique=True)), + ('payment_amount', models.DecimalField(decimal_places=2, max_digits=10)), + ('payment_currency', models.CharField(max_length=100)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('webhook_recieved', models.BooleanField(default=False)), + ('updated_at', models.DateTimeField(auto_now=True)), + ], + options={ + 'db_table': 'transaction', + 'ordering': ['-id'], + }, + ), + ] diff --git a/apps/transactions/migrations/__init__.py b/apps/transactions/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/apps/transactions/models.py b/apps/transactions/models.py new file mode 100644 index 0000000..46d42c9 --- /dev/null +++ b/apps/transactions/models.py @@ -0,0 +1,20 @@ +from django.db import models + + +class Transaction(models.Model): + payment_method = models.CharField(max_length=100, blank=True) + payment_status = models.CharField(max_length=100) + order_id = models.CharField(max_length=100, default="") + payment_id = models.CharField(max_length=100, blank=True, unique=True, null=True) + payment_amount = models.DecimalField(max_digits=10, decimal_places=2) + payment_currency = models.CharField(max_length=100) + created_at = models.DateTimeField(auto_now_add=True) + webhook_recieved = models.BooleanField(default=False) + updated_at = models.DateTimeField(auto_now=True) + + class Meta: + db_table = "transaction" + ordering = ["-id"] + + def __str__(self): + return self.order_id diff --git a/apps/transactions/serializers.py b/apps/transactions/serializers.py new file mode 100644 index 0000000..802d050 --- /dev/null +++ b/apps/transactions/serializers.py @@ -0,0 +1,7 @@ +from rest_framework import serializers +from .models import Transaction + +class TransactionSerializer(serializers.ModelSerializer): + class Meta: + model = Transaction + fields = ('payment_method', 'payment_status', 'order_id', 'payment_id', 'payment_amount', 'payment_currency') \ No newline at end of file diff --git a/apps/transactions/tests.py b/apps/transactions/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/apps/transactions/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/apps/transactions/urls.py b/apps/transactions/urls.py new file mode 100644 index 0000000..20f05b8 --- /dev/null +++ b/apps/transactions/urls.py @@ -0,0 +1,8 @@ +from django.urls import path +from .views import HandlePayment, HandlePaymentSuccess, PaymentWebhook + +urlpatterns = [ + path("handle-payment/", HandlePayment.as_view(), name="handle_payment"), + path("handle-payment-success/", HandlePaymentSuccess.as_view(), name="handle_payment_success"), + path("payment-webhook/", PaymentWebhook.as_view(), name="payment_webhook"), +] \ No newline at end of file diff --git a/apps/transactions/views.py b/apps/transactions/views.py new file mode 100644 index 0000000..2c271e1 --- /dev/null +++ b/apps/transactions/views.py @@ -0,0 +1,214 @@ +from base.utils import get_url_from_hostname +from django.shortcuts import redirect, render +from rest_framework.views import APIView +from rest_framework.response import Response +from rest_framework import status +from django.conf import settings +from .models import Transaction +from ticket.utils import create_ticket, generate_ticket_image +from ticket.models import Ticket +from event.models import Event, SubEvent, Addon +from django.http import HttpResponse +import os, razorpay, json +from base.utils import EmailService + + +client = razorpay.Client(auth=(os.environ.get("RAZORPAY_KEY"), os.environ.get("RAZORPAY_SECRET"))) + +class HandlePayment(APIView): + def post(self, request): + if (os.environ.get("PAYMENT_ENV") == "development"): + transaction = Transaction.objects.create(payment_method="card", payment_status="success", payment_id="1234567890", payment_amount=1000, payment_currency="NGN") + if transaction.payment_status == "success": + ticket_status = create_ticket(request, "1234567890") + if ticket_status == True: + return Response({"message": "Payment successful"}, status=status.HTTP_200_OK) + else: + return Response({"message": "Payment failed"}, status=status.HTTP_400_BAD_REQUEST) + else: + return Response({"message": "Payment failed"}, status=status.HTTP_400_BAD_REQUEST) + else: + Total_amount = HandlePriceCalculation(request) + data = { + "amount": Total_amount * 100, + "currency": "INR", + "notes": { + "name": request.data.get('customer_name'), + "email": request.data.get('customer_email'), + "phone": request.data.get('customer_phone'), + "event_id": request.data.get('event_id'), + "selected_sub_events": json.dumps(request.data.get('selected_sub_events')), + "selected_addons": json.dumps(request.data.get('selected_addons')) + } + } + order = client.order.create(data=data) + if "error" in order: + return Response({"message": "Backend Error"}, status=status.HTTP_400_BAD_REQUEST) + else: + Transaction.objects.create(payment_status="created", + order_id=order['id'], + payment_amount=order['amount']/100, + payment_currency=order['currency']) + create_ticket(request, order['id']) + return_data = {"message": "Order Created", + "payment_id": order['id'], + "amount": order['amount'], + "currency": order['currency'], + "id": (os.environ.get("RAZORPAY_KEY")), + "Business": "JKLU", + "callback_url": get_url_from_hostname(settings.HOSTNAME) + "/api/transactions/handle-payment-success/", + "image": "https://sabrang.jklu.edu.in/wp-content/uploads/2022/10/sabrang-cover-text-e1664621537950.png"} + return Response(return_data, status=status.HTTP_200_OK) + + +def HandlePriceCalculation(request): + event_id = request.data.get('event_id') + selected_sub_events = request.data.get('selected_sub_events', []), + selected_addons = request.data.get('selected_addons', []) + total_sub_event_allowed = Event.objects.get(pk=event_id).sub_events_included_allowed + sub_event_count = 0 + sub_event_price = 0 + addon_price = 0 + for sub_event in selected_sub_events[0]: + if sub_event_count < total_sub_event_allowed: + sub_event_count += 1 + else: + sub_event_price += SubEvent.objects.get(pk=sub_event).price + for addon in selected_addons: + addon_price += Addon.objects.get(pk=addon).price + event_price = Event.objects.get(pk=event_id).price + total_price = event_price + sub_event_price + addon_price + return int(total_price) + + +class HandlePaymentSuccess(APIView): + def post(self, request): + razorpay_payment_id = request.data.get('razorpay_payment_id') + razorpay_order_id = request.data.get('razorpay_order_id') + razorpay_signature = request.data.get('razorpay_signature') + if razorpay_payment_id == None or razorpay_order_id == None or razorpay_signature == None: + error_reason = request.data.get('error[reason]') + html_response = f"

Payment Failed

Sorry, your payment has failed. Reason: {error_reason}

" + return HttpResponse(html_response, status=400) + params_dict = { + 'razorpay_payment_id': razorpay_payment_id, + 'razorpay_order_id': razorpay_order_id, + 'razorpay_signature': razorpay_signature + } + payment_complete = client.utility.verify_payment_signature(params_dict) + if payment_complete: + transaction = Transaction.objects.get(order_id=razorpay_order_id) + transaction.payment_id = razorpay_payment_id + payment_details = client.payment.fetch(transaction.payment_id) + transaction.payment_status = payment_details['status'] + transaction.payment_method = payment_details['method'] + transaction.save() + if transaction.payment_status == "captured": + ticket = Ticket.objects.get(order_id = transaction.order_id) + ticket.transaction_id = transaction + ticket.is_active = True + if ticket.ticket_image_generated == False: + ticket_url = generate_ticket_image.delay(ticket.id) + ticket.ticket_image_generated = True + else: + html_response = "

Payment Already Done

This Payment is already Handled and ticket mailed.

" + return HttpResponse(html_response, status=400) + ticket.save() + # Wait for the Celery task to complete using the get() method with a timeout + try: + task_id = ticket_url.id + # ticket_url = ticket_url.get(timeout=60) # Adjust the timeout value as needed + except TimeoutError: + html_response = "

Ticket Generation Pending

Payment Done , Your Ticket will be mailed to your email.

" + return HttpResponse(html_response, status=400) + + if task_id: + return redirect(get_url_from_hostname(settings.FRONTEND_URL) + "/delivery/" + task_id) + else: + html_response = "

Invalid Payment

This Payment ID doesn't match our database, if you believe this is a error contact us at our support mail at our homepage.

" + return HttpResponse(html_response, status=400) + else: + html_response = "

Invalid Payment

The Payment failed, if you believe this is a error contact us at our support mail at our homepage.

" + return HttpResponse(html_response, status=400) + + +class PaymentWebhook(APIView): + def post(self, request): + payload_body = json.dumps(request.data, separators=(',', ':')) + webhook_signature = request.headers.get("X-Razorpay-Signature") + webhook_secret = os.environ.get("RAZORPAY_WEBHOOK_SECRET") + webhook_valid = client.utility.verify_webhook_signature(payload_body, webhook_signature, webhook_secret) + if webhook_valid: + data = json.loads(payload_body) + if data['event'] == "order.paid": + transaction = Transaction.objects.get(order_id=data['payload']['order']['entity']['id']) + transaction.payment_status = "captured" + transaction.webhook_recieved = True + if transaction.payment_id == "": + transaction.payment_id = data['payload']['payment']['entity']['id'] + transaction.payment_method = data['payload']['payment']['entity']['method'] + transaction.save() + ticket = Ticket.objects.get(order_id = transaction.order_id) + ticket.transaction_id = transaction + ticket.is_active = True + if ticket.ticket_image_generated == False: + image = generate_ticket_image(ticket.id) + ticket.ticket_image_generated = True + else: + return Response({"message": "Webhook recieved"}, status=status.HTTP_200_OK) + ticket.save() + return Response({"message": "Order Paid Notified"}, status=status.HTTP_202_ACCEPTED) + elif data['event'] == "payment.captured": + transaction = Transaction.objects.get(order_id=data['payload']['payment']['entity']['order_id']) + if transaction.webhook_recieved == True: + return Response({"message": "Webhook Confirmation already Recieved"}, status=status.HTTP_200_OK) + transaction.payment_status = "captured" + if transaction.payment_id == "": + transaction.payment_id = data['payload']['payment']['entity']['id'] + transaction.webhook_recieved = True + transaction.payment_method = data['payload']['payment']['entity']['method'] + transaction.save() + ticket = Ticket.objects.get(order_id = transaction.order_id) + ticket.transaction_id = transaction + ticket.is_active = True + if ticket.ticket_image_generated == False: + image = generate_ticket_image(ticket.id) + ticket.ticket_image_generated = True + else: + return Response({"message": "Webhook recieved"}, status=status.HTTP_200_OK) + ticket.save() + return Response({"message": "Payment Captured Notified"}, status=status.HTTP_200_OK) + elif data['event'] == "payment.failed": + transaction = Transaction.objects.get(order_id=data['payload']['payment']['entity']['order_id']) + transaction.payment_status = "failed" + transaction.webhook_recieved = True + transaction.save() + ticket = Ticket.objects.get(order_id = transaction.order_id) + ticket.transaction_id = transaction + ticket.is_active = False + ticket.save() + return Response({"message": "Payment Captured Notified"}, status=status.HTTP_202_ACCEPTED) + elif data['event'] == "payment.dispute.created": + transaction = Transaction.objects.get(order_id=data['payload']['payment']['entity']['order_id'], payment_id=data['payload']['payment']['entity']['id']) + transaction.payment_status = "disputed" + transaction.save() + ticket = Ticket.objects.get(order_id = transaction.order_id) + ticket.is_active = False + ticket.save() + message = "Dispute Created for Order ID: " + data['payload']['payment']['entity']['order_id'] + " Payment ID: " + data['payload']['payment']['entity']['id'] + " Amount: " + data['payload']['payment']['entity']['amount'] + " Reason: " + data['payload']['dispute']['entity']['reason_code'] + EmailService.send_email("Payment Disputed", message, os.environ.get("NOTIFICATION_EMAIL")) + return Response({"message": "Payment Disputed Notified"}, status=status.HTTP_202_ACCEPTED) + elif data['event'] == "refund.created": + transaction = Transaction.objects.get(order_id=data['payload']['payment']['entity']['order_id'], payment_id=data['payload']['payment']['entity']['id']) + transaction.payment_status = "refunded" + transaction.save() + ticket = Ticket.objects.get(order_id = transaction.order_id) + ticket.is_active = False + ticket.save() + return Response({"message": "Payment Refunded Notified"}, status=status.HTTP_202_ACCEPTED) + else: + message = "Webhook recieved for " + data['event'] + "Unable to handle this event" + EmailService.send_email("Unknown Webhook Recieved", message, os.environ.get("NOTIFICATION_EMAIL")) + return Response({"message": "Webhook recieved"}, status=status.HTTP_200_OK) + else: + return Response({"message": "Invalid Webhook Signature"}, status=status.HTTP_400_BAD_REQUEST) \ No newline at end of file diff --git a/docker-compose-prod.yml b/docker-compose-prod.yml new file mode 100644 index 0000000..e69de29 diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..817d623 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,55 @@ +version: "3" +services: + db: + image: postgres:15.3 + ports: + - "5432:5432" + env_file: + - docker/dev/docker.env + + django: + hostname: django + env_file: + - docker/dev/docker.env + build: + context: ./ + dockerfile: docker/dev/django/Dockerfile + ports: + - "8000:8000" + depends_on: + - db + - redis + volumes: + - .:/code + + nodejs_v1: + hostname: nodejs_v1 + build: + context: ./ + dockerfile: docker/dev/nodejs_v1/Dockerfile + environment: + ANGULAR_ENV: development + ports: + - "49153:49153" + - "4200:4200" + volumes: + - ./frontend:/code + - /code/node_modules + + redis: + image: redis:7.2-rc3 + ports: + - "6379:6379" + + celery: + build: + context: ./ + dockerfile: docker/dev/celery/Dockerfile + env_file: + - docker/dev/docker.env + volumes: + - .:/code + depends_on: + - db + - redis + - django diff --git a/docker/dev/celery/Dockerfile b/docker/dev/celery/Dockerfile new file mode 100644 index 0000000..a624a3c --- /dev/null +++ b/docker/dev/celery/Dockerfile @@ -0,0 +1,15 @@ +FROM python:3.11 + +#System Dependencies +RUN apt-get update +RUN apt-get install -y wkhtmltopdf + +# Set work directory +RUN mkdir /code +WORKDIR /code + +# Install dependencies +ADD requirements/* /code/ +RUN pip install -r dev.txt + +CMD ["sh", "/code/docker/dev/celery/container-start.sh"] \ No newline at end of file diff --git a/docker/dev/celery/container-start.sh b/docker/dev/celery/container-start.sh new file mode 100644 index 0000000..fbae978 --- /dev/null +++ b/docker/dev/celery/container-start.sh @@ -0,0 +1,3 @@ +#!/bin/sh +cd /code && \ +celery -A ticketify worker --loglevel=INFO diff --git a/docker/dev/django/Dockerfile b/docker/dev/django/Dockerfile new file mode 100644 index 0000000..185d930 --- /dev/null +++ b/docker/dev/django/Dockerfile @@ -0,0 +1,18 @@ +FROM python:3.11 + +# Set environment variables +ENV PYTHONDONTWRITEBYTECODE 1 + +#System Dependencies +RUN apt-get update +RUN apt-get install -y wkhtmltopdf + +# Set work directory +RUN mkdir /code +WORKDIR /code + +# Install dependencies +ADD requirements/* /code/ +RUN pip install -r dev.txt + +CMD ["./docker/wait-for-it.sh", "db:5432", "--", "./docker/wait-for-it.sh", "redis:6379", "--", "sh", "/code/docker/dev/django/container-start.sh"] diff --git a/docker/dev/django/container-start.sh b/docker/dev/django/container-start.sh new file mode 100644 index 0000000..a7d61cf --- /dev/null +++ b/docker/dev/django/container-start.sh @@ -0,0 +1,6 @@ +#!/bin/sh +python manage.py makemigrations && \ +python manage.py migrate --noinput && \ +python manage.py collectstatic --noinput && \ +python manage.py seed && \ +uwsgi --ini /code/docker/dev/django/uwsgi.ini --enable-threads \ No newline at end of file diff --git a/docker/dev/django/uwsgi.ini b/docker/dev/django/uwsgi.ini new file mode 100644 index 0000000..27d5e9c --- /dev/null +++ b/docker/dev/django/uwsgi.ini @@ -0,0 +1,10 @@ +[uwsgi] +chdir = /code +module = ticketify.wsgi:application +master = true +processes = 4 +http = 0.0.0.0:8000 +vaccum = true +python-autoreload = 1 +buffer-size=32768 +chmod-socket = 777 \ No newline at end of file diff --git a/docker/dev/docker.env.example b/docker/dev/docker.env.example new file mode 100644 index 0000000..4a4c22f --- /dev/null +++ b/docker/dev/docker.env.example @@ -0,0 +1,43 @@ +POSTGRES_NAME= postgres +POSTGRES_USER= postgres +POSTGRES_PASSWORD= postgres +POSTGRES_HOST= db +POSTGRES_PORT= 5432 + +DEBUG=True +DJANGO_SETTINGS_MODULE= settings.dev +DJANGO_SERVER= django +DJANGO_SERVER_PORT= 8000 + + +ANGULAR_ENV= development + +RAZORPAY_KEY=XXXXXXXXXXXXXXXXX +RAZORPAY_SECRET=XXXXXXXXXXXXXXXXXXXXX +RAZORPAY_WEBHOOK_SECRET=XXXXXXXXXXXXXXXXXXX + +#Email +EMAIL_REQUIRED= True +EMAIL_HOST= example.com +EMAIL_PORT= 465 +EMAIL_HOST_USER=example@host.com +EMAIL_HOST_PASSWORD=example +EMAIL_USE_SSL= True + +#Notification Email +NOTIFICATION_EMAIL= example + +#Encryption Key(if not set, a random key will be generated) +ENCRYPTION_KEY= + +Ticketify_API_SERVER= http://localhost:8000 + +#Celery +CELERY_BROKER_URL= redis://redis:6379/0 +CELERY_RESULT_BACKEND= redis://redis:6379/0 + +#Redis +REDIS_HOST_URL = redis://redis:6379 + +#CORS-ORIGIN +CSRF_TRUSTED_ORIGINS= 'http://localhost:4200, https://localhost:4200' \ No newline at end of file diff --git a/docker/dev/nodejs_v1/Dockerfile b/docker/dev/nodejs_v1/Dockerfile new file mode 100644 index 0000000..5c0073f --- /dev/null +++ b/docker/dev/nodejs_v1/Dockerfile @@ -0,0 +1,15 @@ +FROM node:18.16.0 + +RUN npm install -g @angular/cli@16.0.4 +RUN mkdir /code + +# Copy codebase +COPY . /code + +WORKDIR /code + +ADD frontend/package.json frontend/yarn.lock /code/ +RUN yarn install +ENV PATH="/code/node_modules/.bin:$PATH" + +CMD ["yarn","start", "--verbose", "--host", "0.0.0.0", "--poll", "2000"] \ No newline at end of file diff --git a/docker/wait-for-it.sh b/docker/wait-for-it.sh new file mode 100755 index 0000000..a81211a --- /dev/null +++ b/docker/wait-for-it.sh @@ -0,0 +1,161 @@ +#!/usr/bin/env bash +# Use this script to test if a given TCP host/port are available + +cmdname=$(basename $0) + +echoerr() { if [[ $QUIET -ne 1 ]]; then echo "$@" 1>&2; fi } + +usage() +{ + cat << USAGE >&2 +Usage: + $cmdname host:port [-s] [-t timeout] [-- command args] + -h HOST | --host=HOST Host or IP under test + -p PORT | --port=PORT TCP port under test + Alternatively, you specify the host and port as host:port + -s | --strict Only execute subcommand if the test succeeds + -q | --quiet Don't output any status messages + -t TIMEOUT | --timeout=TIMEOUT + Timeout in seconds, zero for no timeout + -- COMMAND ARGS Execute command with args after the test finishes +USAGE + exit 1 +} + +wait_for() +{ + if [[ $TIMEOUT -gt 0 ]]; then + echoerr "$cmdname: waiting $TIMEOUT seconds for $HOST:$PORT" + else + echoerr "$cmdname: waiting for $HOST:$PORT without a timeout" + fi + start_ts=$(date +%s) + while : + do + (echo > /dev/tcp/$HOST/$PORT) >/dev/null 2>&1 + result=$? + if [[ $result -eq 0 ]]; then + end_ts=$(date +%s) + echoerr "$cmdname: $HOST:$PORT is available after $((end_ts - start_ts)) seconds" + break + fi + sleep 1 + done + return $result +} + +wait_for_wrapper() +{ + # In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692 + if [[ $QUIET -eq 1 ]]; then + timeout $TIMEOUT $0 --quiet --child --host=$HOST --port=$PORT --timeout=$TIMEOUT & + else + timeout $TIMEOUT $0 --child --host=$HOST --port=$PORT --timeout=$TIMEOUT & + fi + PID=$! + trap "kill -INT -$PID" INT + wait $PID + RESULT=$? + if [[ $RESULT -ne 0 ]]; then + echoerr "$cmdname: timeout occurred after waiting $TIMEOUT seconds for $HOST:$PORT" + fi + return $RESULT +} + +# process arguments +while [[ $# -gt 0 ]] +do + case "$1" in + *:* ) + hostport=(${1//:/ }) + HOST=${hostport[0]} + PORT=${hostport[1]} + shift 1 + ;; + --child) + CHILD=1 + shift 1 + ;; + -q | --quiet) + QUIET=1 + shift 1 + ;; + -s | --strict) + STRICT=1 + shift 1 + ;; + -h) + HOST="$2" + if [[ $HOST == "" ]]; then break; fi + shift 2 + ;; + --host=*) + HOST="${1#*=}" + shift 1 + ;; + -p) + PORT="$2" + if [[ $PORT == "" ]]; then break; fi + shift 2 + ;; + --port=*) + PORT="${1#*=}" + shift 1 + ;; + -t) + TIMEOUT="$2" + if [[ $TIMEOUT == "" ]]; then break; fi + shift 2 + ;; + --timeout=*) + TIMEOUT="${1#*=}" + shift 1 + ;; + --) + shift + CLI="$@" + break + ;; + --help) + usage + ;; + *) + echoerr "Unknown argument: $1" + usage + ;; + esac +done + +if [[ "$HOST" == "" || "$PORT" == "" ]]; then + echoerr "Error: you need to provide a host and port to test." + usage +fi + +TIMEOUT=${TIMEOUT:-45} +STRICT=${STRICT:-0} +CHILD=${CHILD:-0} +QUIET=${QUIET:-0} + +if [[ $CHILD -gt 0 ]]; then + wait_for + RESULT=$? + exit $RESULT +else + if [[ $TIMEOUT -gt 0 ]]; then + wait_for_wrapper + RESULT=$? + else + wait_for + RESULT=$? + fi +fi + +if [[ $CLI != "" ]]; then + if [[ $RESULT -ne 0 && $STRICT -eq 1 ]]; then + echoerr "$cmdname: strict mode, refusing to execute subprocess" + exit $RESULT + fi + exec $CLI +else + exit $RESULT +fi \ No newline at end of file diff --git a/frontend/.editorconfig b/frontend/.editorconfig new file mode 100644 index 0000000..59d9a3a --- /dev/null +++ b/frontend/.editorconfig @@ -0,0 +1,16 @@ +# Editor configuration, see https://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.ts] +quote_type = single + +[*.md] +max_line_length = off +trim_trailing_whitespace = false diff --git a/frontend/README.md b/frontend/README.md new file mode 100644 index 0000000..fa2f544 --- /dev/null +++ b/frontend/README.md @@ -0,0 +1,27 @@ +# Frontend + +This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 16.0.4. + +## Development server + +Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The application will automatically reload if you change any of the source files. + +## Code scaffolding + +Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. + +## Build + +Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. + +## Running unit tests + +Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). + +## Running end-to-end tests + +Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities. + +## Further help + +To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page. diff --git a/frontend/angular.json b/frontend/angular.json new file mode 100644 index 0000000..bd41dd1 --- /dev/null +++ b/frontend/angular.json @@ -0,0 +1,144 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "newProjectRoot": "projects", + "projects": { + "ticketify": { + "projectType": "application", + "schematics": { + "@schematics/angular:component": { + "style": "scss" + } + }, + "root": "", + "sourceRoot": "src", + "prefix": "app", + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:browser", + "options": { + "outputPath": "dist/ticketify", + "index": "src/index.html", + "main": "src/main.ts", + "polyfills": [ + "zone.js" + ], + "tsConfig": "tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "src/favicon.ico", + "src/assets", + { + "glob": "**/*", + "input": "node_modules/ngx-scanner-qrcode/wasm/", + "output": "./assets/wasm/" + } + ], + "styles": [ + "@angular/material/prebuilt-themes/purple-green.css", + "node_modules/bootstrap/dist/css/bootstrap.min.css", + "src/styles.scss" + ], + "scripts": [ + "node_modules/bootstrap/dist/js/bootstrap.min.js" + ] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "5mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all", + "fileReplacements": [ + { + "replace": "src/environments/environment.ts", + "with": "src/environments/environment.prod.ts" + } + ] + }, + "staging": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "5mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all", + "fileReplacements": [ + { + "replace": "src/environments/environment.ts", + "with": "src/environments/environment.prod.ts" + } + ] + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "builder": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "browserTarget": "ticketify:build:production" + }, + "development": { + "browserTarget": "ticketify:build:development" + } + }, + "defaultConfiguration": "development" + }, + "extract-i18n": { + "builder": "@angular-devkit/build-angular:extract-i18n", + "options": { + "browserTarget": "ticketify:build" + } + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "polyfills": [ + "zone.js", + "zone.js/testing" + ], + "tsConfig": "tsconfig.spec.json", + "inlineStyleLanguage": "scss", + "assets": [ + "src/favicon.ico", + "src/assets" + ], + "styles": [ + "@angular/material/prebuilt-themes/purple-green.css", + "src/styles.scss" + ], + "scripts": [] + } + } + } + } + }, + "cli": { + "analytics": "826a55a3-7fc9-4b90-bb81-41262de0e079" + } +} diff --git a/frontend/package.json b/frontend/package.json new file mode 100644 index 0000000..b579b89 --- /dev/null +++ b/frontend/package.json @@ -0,0 +1,48 @@ +{ + "name": "frontend", + "version": "0.0.0", + "scripts": { + "ng": "ng", + "start": "ng serve", + "build": "ng build", + "watch": "ng build --watch --configuration development", + "test": "ng test" + }, + "private": true, + "dependencies": { + "@angular/animations": "^16.0.0", + "@angular/cdk": "^16.1.1", + "@angular/common": "^16.0.0", + "@angular/compiler": "^16.0.0", + "@angular/core": "^16.0.0", + "@angular/forms": "^16.0.0", + "@angular/material": "^16.1.1", + "@angular/platform-browser": "^16.0.0", + "@angular/platform-browser-dynamic": "^16.0.0", + "@angular/router": "^16.0.0", + "@fortawesome/angular-fontawesome": "^0.13.0", + "@fortawesome/fontawesome-svg-core": "^6.4.0", + "@fortawesome/free-regular-svg-icons": "^6.4.0", + "@fortawesome/free-solid-svg-icons": "^6.4.0", + "bootstrap": "^5.2.3", + "chart.js": "^4.3.0", + "ngx-scanner-qrcode": "^1.5.8", + "rxjs": "~7.8.0", + "tslib": "^2.6.0", + "zone.js": "~0.13.0" + }, + "devDependencies": { + "@angular-devkit/build-angular": "^16.0.4", + "@angular/cli": "~16.0.4", + "@angular/compiler-cli": "^16.0.0", + "@types/jasmine": "~4.3.0", + "@types/node": "^20.4.5", + "jasmine-core": "~4.6.0", + "karma": "~6.4.0", + "karma-chrome-launcher": "~3.2.0", + "karma-coverage": "~2.2.0", + "karma-jasmine": "~5.1.0", + "karma-jasmine-html-reporter": "~2.0.0", + "typescript": "~5.0.2" + } +} diff --git a/frontend/src/_base.scss b/frontend/src/_base.scss new file mode 100644 index 0000000..7daaa2d --- /dev/null +++ b/frontend/src/_base.scss @@ -0,0 +1,3 @@ +@import "./node_modules/bootstrap/scss/functions"; +@import "./node_modules/bootstrap/scss/variables"; +@import "./node_modules/bootstrap/scss/variables-dark"; \ No newline at end of file diff --git a/frontend/src/app/admin/dashboard/dashboard.component.html b/frontend/src/app/admin/dashboard/dashboard.component.html new file mode 100644 index 0000000..70af523 --- /dev/null +++ b/frontend/src/app/admin/dashboard/dashboard.component.html @@ -0,0 +1,45 @@ + + + +
+
+
+
+
+

Total Tickets

+

{{SalesData.total_tickets}}

+
+
+
+
+
+
+

Total Sale

+

{{SalesData.total_amount | currency : "INR"}}

+
+
+
+
+ +
+ +
+
+
+
Events
+ +
+
+
+ + +
+
+
+
Addons
+ +
+
+
+
+
diff --git a/frontend/src/app/admin/dashboard/dashboard.component.scss b/frontend/src/app/admin/dashboard/dashboard.component.scss new file mode 100644 index 0000000..7a8bb11 --- /dev/null +++ b/frontend/src/app/admin/dashboard/dashboard.component.scss @@ -0,0 +1,22 @@ +.customer-interface-card { + background-color: #121212; + width: auto; /* Adjust the width as per your requirements */ + margin: 10px; /* Adjust the margin as per your requirements */ + border: 1px solid #ccc; /* Add a border as the bounding box */ + transition: box-shadow 0.3s ease; +} + +.graph-text { + color: #fff; + font-size: 1.5rem; + font-weight: 500; + padding: 10px 15px 10px 5px; + margin: 0; +} + +.graph-card { + background-color: #252323; + transition: box-shadow 0.3s ease; + width: 100%; + height: 300px; +} diff --git a/frontend/src/app/admin/dashboard/dashboard.component.spec.ts b/frontend/src/app/admin/dashboard/dashboard.component.spec.ts new file mode 100644 index 0000000..5e98991 --- /dev/null +++ b/frontend/src/app/admin/dashboard/dashboard.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { DashboardComponent } from './dashboard.component'; + +describe('DashboardComponent', () => { + let component: DashboardComponent; + let fixture: ComponentFixture; + + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [DashboardComponent] + }); + fixture = TestBed.createComponent(DashboardComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/frontend/src/app/admin/dashboard/dashboard.component.ts b/frontend/src/app/admin/dashboard/dashboard.component.ts new file mode 100644 index 0000000..9a0bf32 --- /dev/null +++ b/frontend/src/app/admin/dashboard/dashboard.component.ts @@ -0,0 +1,94 @@ +import { Component, OnInit } from '@angular/core'; +import { EventDetailsService } from 'src/app/services/event-details/event-details.service'; +import { Chart, registerables, Colors } from 'chart.js'; +Chart.register(...registerables); +Chart.register(Colors); + +@Component({ + selector: 'app-dashboard', + templateUrl: './dashboard.component.html', + styleUrls: ['./dashboard.component.scss'] +}) +export class DashboardComponent implements OnInit { + SalesData: any; + SubEventData: any; + AddonData: any; + +constructor(private EventDetailsService: EventDetailsService) {} + +ngOnInit(): void { + this.EventDetailsService.EventDetails().then(() => { + this.EventDetailsService.GetSalesData().then(() => { + this.SalesData = this.EventDetailsService.SalesData; + }); + this.EventDetailsService.GetSubEventsSalesData().then(() => { + this.SubEventData = this.EventDetailsService.SubEventData; + this.Createchart(document.getElementById('SubEventSaleChart'), this.SubEventData.label, this.SubEventData.data); + }); + this.EventDetailsService.GetAddonSalesData().then(() => { + this.AddonData = this.EventDetailsService.AddonData; + this.Createchart(document.getElementById('AddonSaleChart'), this.AddonData.label, this.AddonData.data); + }); + }); +} + +Createchart(ctx: any, labelData: any, salesData: any, label: any = 'Sales') { + new Chart(ctx, { + type: 'bar', + data: { + labels: labelData, + datasets: [{ + label: label, + data: salesData, + backgroundColor: [ + 'rgb(126, 191, 241)', + 'rgb(255, 159, 64)', + 'rgb(255, 255, 0)', + 'rgb(160, 160, 160)' + ], + borderColor: [ + 'rgb(126, 191, 241)', + 'rgb(255, 159, 64)', + 'rgb(255, 255, 0)', + 'rgb(160, 160, 160)' + ], + borderWidth: 1, + barThickness: 20, + }] + }, + options: { + responsive: true, + scales: { + y: { + beginAtZero: true, + ticks: { + color: "white", + font: { + size: 14, + } + } + }, + x: { + beginAtZero: true, + ticks: { + color: "white", + } + } + }, + plugins: { + legend: { + labels: { + color: "white", + font: { + size: 14, + } + } + } + }, + layout: { + padding: 20 + } + } + }); +} +} diff --git a/frontend/src/app/admin/dialog/ticket-dialog/ticket-dialog.component.html b/frontend/src/app/admin/dialog/ticket-dialog/ticket-dialog.component.html new file mode 100644 index 0000000..2b9bc92 --- /dev/null +++ b/frontend/src/app/admin/dialog/ticket-dialog/ticket-dialog.component.html @@ -0,0 +1,57 @@ + + + Ticket Details + +
+
+

Ticket ID: {{ data.ticket.id }}

+

Name: {{ data.ticket.customer_name }}

+

Customer Email: {{ data.ticket.customer_email }}

+
+
+

Phone: {{ data.ticket.customer_phone }}

+

Transaction:-

+
+ + +
+
+
+
+
+
+

Check In Log

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Email{{ checkin.ticket_id }}Phone{{ checkin.check_in_time }}Name{{ checkin.operator }}Method{{ checkin.method }}
+
+
+
+
+ + + diff --git a/frontend/src/app/admin/dialog/ticket-dialog/ticket-dialog.component.scss b/frontend/src/app/admin/dialog/ticket-dialog/ticket-dialog.component.scss new file mode 100644 index 0000000..f3d3af1 --- /dev/null +++ b/frontend/src/app/admin/dialog/ticket-dialog/ticket-dialog.component.scss @@ -0,0 +1,73 @@ +.ticket-card { + background-color: #424242; + color: #ffffff; + border-radius: 10px; + box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.5); + text-align: center; + text-align: center; +} + + + .dialog-style { + background-color: black; + color: white; + padding: 40px; + width: 100%; + display: flex; + flex-direction: column; + text-align: center; + max-height: max-content; + } + + .ticket-details { + color: white; + padding: 40px; + border-radius: 10px; + width: 100%; + box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.5); + display: flex; + flex-direction: column; + text-align: center; + } + + .ticket-details-content { + display: flex; + flex-direction: row; + justify-content: space-between; + margin: 20px; + } + + .button-container { + display: flex; + justify-content: center; + } + + .button-container button { + margin: 5px; + } + + @media (max-width: 600px) { + .ticket-card { + width: 90%; + max-width: 400px; /* Adjust the maximum width based on your design */ + margin: 0 auto; + } + + .ticket-details-content { + flex-direction: column; + margin: 10px; + } + + .ticket-details-content p { + margin: 8px 0; + } + + .button-container { + flex-direction: column; + } + + .button-container button { + margin: 5px 0; + } + } + \ No newline at end of file diff --git a/frontend/src/app/admin/dialog/ticket-dialog/ticket-dialog.component.spec.ts b/frontend/src/app/admin/dialog/ticket-dialog/ticket-dialog.component.spec.ts new file mode 100644 index 0000000..654b2f8 --- /dev/null +++ b/frontend/src/app/admin/dialog/ticket-dialog/ticket-dialog.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TicketDialogComponent } from './ticket-dialog.component'; + +describe('TicketDialogComponent', () => { + let component: TicketDialogComponent; + let fixture: ComponentFixture; + + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [TicketDialogComponent] + }); + fixture = TestBed.createComponent(TicketDialogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/frontend/src/app/admin/dialog/ticket-dialog/ticket-dialog.component.ts b/frontend/src/app/admin/dialog/ticket-dialog/ticket-dialog.component.ts new file mode 100644 index 0000000..e972282 --- /dev/null +++ b/frontend/src/app/admin/dialog/ticket-dialog/ticket-dialog.component.ts @@ -0,0 +1,65 @@ +import { Component, Inject } from '@angular/core'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { EventDetailsService } from 'src/app/services/event-details/event-details.service'; +import { MatSnackBar } from '@angular/material/snack-bar'; +import { TransactionsComponent } from '../transactions/transactions.component'; +import { MatDialog } from '@angular/material/dialog'; + + +export interface TicketDialogData { + ticket: any; +} + +@Component({ + selector: 'app-ticket-dialog', + templateUrl: './ticket-dialog.component.html', + styleUrls: ['./ticket-dialog.component.scss'] +}) +export class TicketDialogComponent { + ticket_data= {}; + CheckInData: any; + ticket_id: any; + displayedColumns: string[] = ['ticket_id', 'check_in_time', 'operator', 'method']; + constructor(@Inject(MAT_DIALOG_DATA) public data: TicketDialogData, private EventDetailsService: EventDetailsService, + private _snackBar: MatSnackBar, public dialogRef: MatDialogRef, private dialog: MatDialog) { + this.ticket_id = { + ticket_id: this.data.ticket.id + } + this.EventDetailsService.GetCheckInData(this.ticket_id).then(() => { + this.CheckInData = this.EventDetailsService.CheckInData; + + }); + } + + ResendEmail() { + this.EventDetailsService.trigger_resend_email(this.ticket_id).then(() => { + this._snackBar.open(this.EventDetailsService.ResendEmailResponse.message, 'Close'); + }); + } + + OpenTransaction() { + this.dialog.open(TransactionsComponent, { + data: { transaction: this.data.ticket.transaction_id } + }); + } + + + confirmCheckin() { + const isConfirmed = window.confirm('Are you sure you want to check in this ticket? This action cannot be undone. Please use QR Scanner if available.'); + if (isConfirmed) { + this.Checkin(); // Call your Checkin() function if the user confirmed. + } + } + + Checkin() { + this.ticket_data = { + ticket_id: this.data.ticket.id, + operator: "Admin", + } + this.EventDetailsService.SendCheckIn(this.ticket_data).then(() => { + this._snackBar.open(this.EventDetailsService.CheckInResponse.message, 'Close'); + }); + this.dialogRef.close(); + + } +} diff --git a/frontend/src/app/admin/dialog/transactions/transactions.component.html b/frontend/src/app/admin/dialog/transactions/transactions.component.html new file mode 100644 index 0000000..92174bf --- /dev/null +++ b/frontend/src/app/admin/dialog/transactions/transactions.component.html @@ -0,0 +1,14 @@ +

Ticket Details

+
+ +

Payment ID: {{ data.transaction.payment_id }}

+

Order ID: {{ data.transaction.order_id }}

+

Status: {{ data.transaction.payment_status }}

+

Amount: {{ data.transaction.payment_amount }}

+

Method: {{ data.transaction.payment_method }}

+

Method: {{ data.transaction.payment_currency }}

+ +
+
+ +
diff --git a/frontend/src/app/admin/dialog/transactions/transactions.component.scss b/frontend/src/app/admin/dialog/transactions/transactions.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/app/admin/dialog/transactions/transactions.component.spec.ts b/frontend/src/app/admin/dialog/transactions/transactions.component.spec.ts new file mode 100644 index 0000000..ce20d80 --- /dev/null +++ b/frontend/src/app/admin/dialog/transactions/transactions.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TransactionsComponent } from './transactions.component'; + +describe('TransactionsComponent', () => { + let component: TransactionsComponent; + let fixture: ComponentFixture; + + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [TransactionsComponent] + }); + fixture = TestBed.createComponent(TransactionsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/frontend/src/app/admin/dialog/transactions/transactions.component.ts b/frontend/src/app/admin/dialog/transactions/transactions.component.ts new file mode 100644 index 0000000..45e1cbd --- /dev/null +++ b/frontend/src/app/admin/dialog/transactions/transactions.component.ts @@ -0,0 +1,19 @@ +import { Component, Inject } from '@angular/core'; +import { MAT_DIALOG_DATA } from '@angular/material/dialog'; + +export interface TransactionsDialogData { + transaction: any; +} + +@Component({ + selector: 'app-transactions', + templateUrl: './transactions.component.html', + styleUrls: ['./transactions.component.scss'] +}) + +export class TransactionsComponent { + displayedColumns: string[] = ['payment_id', 'order_id', 'payment_method', 'payment_status', 'payment_amount', 'payment_currency']; + constructor(@Inject(MAT_DIALOG_DATA) public data: TransactionsDialogData) { + } + +} diff --git a/frontend/src/app/admin/list/list.component.html b/frontend/src/app/admin/list/list.component.html new file mode 100644 index 0000000..c1ce37f --- /dev/null +++ b/frontend/src/app/admin/list/list.component.html @@ -0,0 +1,36 @@ +
+
+
+
+ + Select {{ title }} + + + {{list.name}} + + + +
+
+
+
+ +
+
+ + + + + + + + + + + + + + +
Name{{ ticket.customer_name }}Phone{{ ticket.customer_phone }}
+
+
\ No newline at end of file diff --git a/frontend/src/app/admin/list/list.component.scss b/frontend/src/app/admin/list/list.component.scss new file mode 100644 index 0000000..1f45073 --- /dev/null +++ b/frontend/src/app/admin/list/list.component.scss @@ -0,0 +1,9 @@ +.row-card { + padding: 20px 120px 0px 30px; +} + +@media screen and (max-width: 1150px) { + .row-card { + padding: 20px 20px 0px 20px; + } + } \ No newline at end of file diff --git a/frontend/src/app/admin/list/list.component.spec.ts b/frontend/src/app/admin/list/list.component.spec.ts new file mode 100644 index 0000000..1b7458c --- /dev/null +++ b/frontend/src/app/admin/list/list.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ListComponent } from './list.component'; + +describe('ListComponent', () => { + let component: ListComponent; + let fixture: ComponentFixture; + + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [ListComponent] + }); + fixture = TestBed.createComponent(ListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/frontend/src/app/admin/list/list.component.ts b/frontend/src/app/admin/list/list.component.ts new file mode 100644 index 0000000..37820d0 --- /dev/null +++ b/frontend/src/app/admin/list/list.component.ts @@ -0,0 +1,59 @@ +import { Component } from '@angular/core'; +import { EventDetailsService } from '../../services/event-details/event-details.service'; +import { Router } from '@angular/router'; +import { MatSelectChange } from '@angular/material/select'; + +interface List { + name: string; + id: number; +} + +@Component({ + selector: 'app-list', + templateUrl: './list.component.html', + styleUrls: ['./list.component.scss'] +}) +export class ListComponent { + Listitems: List[] = []; + title = 'Event'; + TableData: any; + currentURL = this.router.url; + displayedColumns: string[] = ['customer_name', 'customer_phone']; + constructor(private EventDetailsService: EventDetailsService, private router: Router,) { + this.EventDetailsService.EventDetails().then(() => { + if (this.currentURL.includes('admin/events')) { + this.EventDetailsService.SubEventDetails().then(() => { + this.Listitems = this.EventDetailsService.SubEvent; + }); + } + else { + this.title = 'Addons'; + this.EventDetailsService.AddonDetails().then(() => { + this.Listitems = this.EventDetailsService.Addon; + }); + } + }); + } + + change_detection(event: MatSelectChange): void { + const newValue = event.value; + const data = { + list_id: newValue + } + if (this.currentURL.includes('admin/events')) { + this.EventDetailsService.get_ticket_by_subevent(data).then(() => { + this.TableData = this.EventDetailsService.Ticket_by_list; + }).catch((error) => { + this.TableData = []; + }); + } + else { + this.EventDetailsService.get_ticket_by_addon(data).then(() => { + this.TableData = this.EventDetailsService.Ticket_by_list; + }).catch((error) => { + this.TableData = []; + }); + } + } + +} diff --git a/frontend/src/app/admin/login/login.component.html b/frontend/src/app/admin/login/login.component.html new file mode 100644 index 0000000..95e5638 --- /dev/null +++ b/frontend/src/app/admin/login/login.component.html @@ -0,0 +1,24 @@ +
+
+
+ + + Login + + +
+ + Username + + + + Password + + + +
+
+
+
+
+
diff --git a/frontend/src/app/admin/login/login.component.scss b/frontend/src/app/admin/login/login.component.scss new file mode 100644 index 0000000..1217f5a --- /dev/null +++ b/frontend/src/app/admin/login/login.component.scss @@ -0,0 +1,22 @@ +/* login.component.css */ +.container { + background-color: #000; /* Set the background color to black */ + color: white; + max-width: 100%; + } + + .full-width { + width: 100%; + } + + .mat-card { + margin-top: 30px; + padding: 20px; + color: white; /* Set the text color to white */ + } + + + .row { + height: 100%; + } + \ No newline at end of file diff --git a/frontend/src/app/admin/login/login.component.spec.ts b/frontend/src/app/admin/login/login.component.spec.ts new file mode 100644 index 0000000..360f9f2 --- /dev/null +++ b/frontend/src/app/admin/login/login.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { LoginComponent } from './login.component'; + +describe('LoginComponent', () => { + let component: LoginComponent; + let fixture: ComponentFixture; + + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [LoginComponent] + }); + fixture = TestBed.createComponent(LoginComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/frontend/src/app/admin/login/login.component.ts b/frontend/src/app/admin/login/login.component.ts new file mode 100644 index 0000000..f0d0e8f --- /dev/null +++ b/frontend/src/app/admin/login/login.component.ts @@ -0,0 +1,25 @@ +import { Component } from '@angular/core'; +import { EventDetailsService } from '../../services/event-details/event-details.service'; +import { Router } from '@angular/router'; + +@Component({ + selector: 'app-login', + templateUrl: './login.component.html', + styleUrls: ['./login.component.scss'] +}) +export class LoginComponent { + username: string | undefined; + password: string | undefined; + + constructor(private EventDetailsService: EventDetailsService, private router: Router) { } + + login() { + const data = { + username: this.username, + password: this.password + } + this.EventDetailsService.send_login_data(data).then(() => { + this.router.navigate(['/admin/dashboard']); + }); + } +} diff --git a/frontend/src/app/admin/scan/scan.component.html b/frontend/src/app/admin/scan/scan.component.html new file mode 100644 index 0000000..a3f8cc5 --- /dev/null +++ b/frontend/src/app/admin/scan/scan.component.html @@ -0,0 +1,22 @@ +
+
+
+ +
+
+ + Select device + + + {{ c.label }} + + + + +
+
+
+
+
+
+ \ No newline at end of file diff --git a/frontend/src/app/admin/scan/scan.component.scss b/frontend/src/app/admin/scan/scan.component.scss new file mode 100644 index 0000000..b389a9d --- /dev/null +++ b/frontend/src/app/admin/scan/scan.component.scss @@ -0,0 +1,43 @@ +.search-card { + background-color: black; + color: white; + padding: 40px; + border-radius: 10px; + box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.5); + display: flex; + flex-direction: column; + text-align: center; + font-size: 20px; + font-weight: bold; + transition: 0.3s; + } + + @media screen and (max-width: 1100px) { + .search-card { + /* Customize styles for small screens */ + padding: 20px; + font-size: 16px; + } + } + +.row-card { + padding: 50px 120px 0px 120px; +} + +@media screen and (max-width: 1150px) { + .row-card { + padding: 20px 20px 0px 20px; + } + } + + .form-field { + width: 200px; /* Set the desired width */ + } + + .mat-select { + font-size: 14px; /* Set the desired font size */ + padding: 8px; /* Add some padding around the select box */ + } + + + diff --git a/frontend/src/app/admin/scan/scan.component.spec.ts b/frontend/src/app/admin/scan/scan.component.spec.ts new file mode 100644 index 0000000..aa18f32 --- /dev/null +++ b/frontend/src/app/admin/scan/scan.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ScanComponent } from './scan.component'; + +describe('ScanComponent', () => { + let component: ScanComponent; + let fixture: ComponentFixture; + + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [ScanComponent] + }); + fixture = TestBed.createComponent(ScanComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/frontend/src/app/admin/scan/scan.component.ts b/frontend/src/app/admin/scan/scan.component.ts new file mode 100644 index 0000000..3726ae3 --- /dev/null +++ b/frontend/src/app/admin/scan/scan.component.ts @@ -0,0 +1,69 @@ +import { Component, ViewChild, AfterViewInit } from '@angular/core'; +import { EventDetailsService } from 'src/app/services/event-details/event-details.service'; +import { ScannerQRCodeConfig ,NgxScannerQrcodeComponent, ScannerQRCodeResult} from 'ngx-scanner-qrcode'; +import { TicketDialogComponent, TicketDialogData } from '../dialog/ticket-dialog/ticket-dialog.component'; +import { MatDialog } from '@angular/material/dialog'; + +@Component({ + selector: 'app-scan', + templateUrl: './scan.component.html', + styleUrls: ['./scan.component.scss'] +}) +export class ScanComponent implements AfterViewInit { + constructor(private EventDetailsService: EventDetailsService, private dialog: MatDialog) {} + public config: ScannerQRCodeConfig = { + constraints: { + audio: false, + }, + }; + + @ViewChild('action') action!: NgxScannerQrcodeComponent; + + ngAfterViewInit(): void { + // Start the scanner on page load + this.startScanner(); + } + + startScanner() { + // Call the handle method with 'start' to start the scanner and 'playDeviceFacingBack' function + this.handle(this.action, 'start'); + } + + playDeviceFacingBack = (devices: any[]) => { + // front camera or back camera check here! + const device = devices.find((f) => /back|rear|environment/gi.test(f.label)); // Default Back Facing Camera + return this.action.playDevice(device ? device.deviceId : devices[0].deviceId); + }; + + handle(action: NgxScannerQrcodeComponent, fn: string) { + if (fn === 'start') { + action[fn]().subscribe( + (r: any) => console.log(fn, r), + (error: any) => console.error('Error while starting scanner:', error) + ); + } + if (fn === 'stop') { + action[fn](); + } + } + + public onEvent(e: ScannerQRCodeResult[], action?: any): void { + action.stop(); + const data = { + 'ticket_id': e[0].value, + } + this.EventDetailsService.GetTicketData(data).then(() => { + const dialogData: TicketDialogData = { + ticket: this.EventDetailsService.TicketData, + }; + let ticketdialog = this.dialog.open(TicketDialogComponent, { + data: dialogData, + }); + ticketdialog.afterClosed().subscribe(result => { + this.startScanner(); + }); + }); + + } + +} diff --git a/frontend/src/app/admin/tickets/tickets.component.html b/frontend/src/app/admin/tickets/tickets.component.html new file mode 100644 index 0000000..d4872d6 --- /dev/null +++ b/frontend/src/app/admin/tickets/tickets.component.html @@ -0,0 +1,84 @@ +
+
+ +
+
+ + + +
+
+ + + +
+
+ + + +
+
+
+
+ +
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ID{{ ticket.id }}Email{{ ticket.customer_email }}Phone{{ ticket.customer_phone }}Name{{ ticket.customer_name }}Sub Event +
    +
  • {{ subEvent.name }}
  • +
+
Addon +
    +
  • {{ addon.name }}
  • +
+
Actions
+
+
+ + \ No newline at end of file diff --git a/frontend/src/app/admin/tickets/tickets.component.scss b/frontend/src/app/admin/tickets/tickets.component.scss new file mode 100644 index 0000000..48452e6 --- /dev/null +++ b/frontend/src/app/admin/tickets/tickets.component.scss @@ -0,0 +1,38 @@ +.search-card { + background-color: black; + color: white; + padding: 40px; + border-radius: 10px; + box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.5); + display: flex; + flex-direction: column; + text-align: center; + font-size: 20px; + font-weight: bold; + transition: 0.3s; + &:hover { + background-color: #1a1a1a; + } + } + + @media screen and (max-width: 1100px) { + .search-card { + /* Customize styles for small screens */ + padding: 20px; + font-size: 16px; + } + } + +.row-card { + padding: 50px 120px 0px 120px; +} + +@media screen and (max-width: 1150px) { + .row-card { + padding: 20px 20px 0px 20px; + } + } + +.table-container { + margin-top: 20px; + } \ No newline at end of file diff --git a/frontend/src/app/admin/tickets/tickets.component.spec.ts b/frontend/src/app/admin/tickets/tickets.component.spec.ts new file mode 100644 index 0000000..51c1aee --- /dev/null +++ b/frontend/src/app/admin/tickets/tickets.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TicketsComponent } from './tickets.component'; + +describe('TicketsComponent', () => { + let component: TicketsComponent; + let fixture: ComponentFixture; + + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [TicketsComponent] + }); + fixture = TestBed.createComponent(TicketsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/frontend/src/app/admin/tickets/tickets.component.ts b/frontend/src/app/admin/tickets/tickets.component.ts new file mode 100644 index 0000000..c86eb28 --- /dev/null +++ b/frontend/src/app/admin/tickets/tickets.component.ts @@ -0,0 +1,46 @@ +import { Component } from '@angular/core'; +import { EventDetailsService } from 'src/app/services/event-details/event-details.service'; +import { TicketDialogComponent, TicketDialogData } from '../dialog/ticket-dialog/ticket-dialog.component'; +import { MatDialog } from '@angular/material/dialog'; +import { MatSnackBar } from '@angular/material/snack-bar'; + +@Component({ + selector: 'app-tickets', + templateUrl: './tickets.component.html', + styleUrls: ['./tickets.component.scss'] +}) +export class TicketsComponent { + email: any; + phone: any; + name: any; + TicketData: any; + displayedColumns: string[] = ['id', 'customer_email', 'customer_phone', 'customer_name', 'selected_sub_event', 'selected_addon', 'ticket_view']; + constructor(private EventDetailsService: EventDetailsService, private dialog: MatDialog, private _snackBar: MatSnackBar) { } + search() { + if (this.email == undefined && this.phone == undefined && this.name == undefined) { + this._snackBar.open("Please enter any one of the field", "Close") + return; + } + const data = { + 'email': this.email, + 'phone': this.phone, + 'name': this.name + } + this.EventDetailsService.GetTicketData(data).then(() => { + this.TicketData = this.EventDetailsService.TicketData; + }).catch((error) => { + this.TicketData = []; + }); + + } + + ViweTicket(ticket: any) { + const dialogData: TicketDialogData = { + ticket: ticket, + }; + this.dialog.open(TicketDialogComponent, { + data: dialogData, + }); + } + +} diff --git a/frontend/src/app/app-routing.module.ts b/frontend/src/app/app-routing.module.ts new file mode 100644 index 0000000..0297262 --- /dev/null +++ b/frontend/src/app/app-routing.module.ts @@ -0,0 +1,10 @@ +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; + +const routes: Routes = []; + +@NgModule({ + imports: [RouterModule.forRoot(routes)], + exports: [RouterModule] +}) +export class AppRoutingModule { } diff --git a/frontend/src/app/app.component.html b/frontend/src/app/app.component.html new file mode 100644 index 0000000..44695ea --- /dev/null +++ b/frontend/src/app/app.component.html @@ -0,0 +1,3 @@ +
+ +
diff --git a/frontend/src/app/app.component.scss b/frontend/src/app/app.component.scss new file mode 100644 index 0000000..03e0e7e --- /dev/null +++ b/frontend/src/app/app.component.scss @@ -0,0 +1,42 @@ +@import "../_base.scss"; + + +.custom-element { + background-color: #121212; + } + + +.customer-interface-card { + background-color: #121212; + width: auto; /* Adjust the width as per your requirements */ + margin: 10px; /* Adjust the margin as per your requirements */ + border: 1px solid #ccc; /* Add a border as the bounding box */ + transition: box-shadow 0.3s ease; +} + +.payment-interface-card { + background-color: #301E67; + width: auto; /* Adjust the width as per your requirements */ + margin: 10px; /* Adjust the margin as per your requirements */ + position: sticky; + top: 0; +} + +.customer-interface-card:hover { + box-shadow: 0 0 10px 3px rgba(0, 255, 0, 0.3); +} + +.card-image-container { + height: 200px; /* Adjust the maximum height as needed */ + overflow: hidden; +} + +.card-img { + width: auto; + max-height: 100%; +} + +.checkout { + width: 100%; + margin: 10px; +} diff --git a/frontend/src/app/app.component.spec.ts b/frontend/src/app/app.component.spec.ts new file mode 100644 index 0000000..1089c69 --- /dev/null +++ b/frontend/src/app/app.component.spec.ts @@ -0,0 +1,29 @@ +import { TestBed } from '@angular/core/testing'; +import { RouterTestingModule } from '@angular/router/testing'; +import { AppComponent } from './app.component'; + +describe('AppComponent', () => { + beforeEach(() => TestBed.configureTestingModule({ + imports: [RouterTestingModule], + declarations: [AppComponent] + })); + + it('should create the app', () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.componentInstance; + expect(app).toBeTruthy(); + }); + + it(`should have as title 'frontend'`, () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.componentInstance; + expect(app.title).toEqual('frontend'); + }); + + it('should render title', () => { + const fixture = TestBed.createComponent(AppComponent); + fixture.detectChanges(); + const compiled = fixture.nativeElement as HTMLElement; + expect(compiled.querySelector('.content span')?.textContent).toContain('frontend app is running!'); + }); +}); diff --git a/frontend/src/app/app.component.ts b/frontend/src/app/app.component.ts new file mode 100644 index 0000000..2fda2ff --- /dev/null +++ b/frontend/src/app/app.component.ts @@ -0,0 +1,9 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-root', + templateUrl: './app.component.html', + styleUrls: ['./app.component.scss'], +}) +export class AppComponent { +} diff --git a/frontend/src/app/app.module.ts b/frontend/src/app/app.module.ts new file mode 100644 index 0000000..5b328b3 --- /dev/null +++ b/frontend/src/app/app.module.ts @@ -0,0 +1,124 @@ +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'; + +import { AppRoutingModule } from './app-routing.module'; +import { AppComponent } from './app.component'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { FormsModule } from '@angular/forms'; +import { Routes , RouterModule } from '@angular/router'; +import { CheckoutComponent } from './customer/checkout/checkout.component'; +import { SideBarComponent } from './side-bar/side-bar.component'; +import { DashboardComponent } from './admin/dashboard/dashboard.component'; +import { TicketsComponent } from './admin/tickets/tickets.component'; +import { TicketDialogComponent } from './admin/dialog/ticket-dialog/ticket-dialog.component'; +import { ScanComponent } from './admin/scan/scan.component'; +import { TransactionsComponent } from './admin/dialog/transactions/transactions.component'; +import { MaintenanceComponent } from './maintenance/maintenance.component'; +import { DeliveryComponent } from './customer/delivery/delivery.component'; + +// Angular Material +import {MatButtonModule} from '@angular/material/button'; +import {MatCardModule} from '@angular/material/card'; +import {MatCheckboxModule} from '@angular/material/checkbox'; +import {MatFormFieldModule} from '@angular/material/form-field'; +import {MatListModule} from '@angular/material/list'; +import {MatIconModule} from '@angular/material/icon'; +import {MatSidenavModule} from '@angular/material/sidenav'; +import {MatToolbarModule} from '@angular/material/toolbar'; +import {MatTableModule} from '@angular/material/table'; +import { MatInputModule } from '@angular/material/input'; +import { MatDialogModule } from '@angular/material/dialog'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import {MatSnackBarModule} from '@angular/material/snack-bar'; +import {MatSlideToggleModule} from '@angular/material/slide-toggle'; +import {MatSelectModule} from '@angular/material/select'; + +// Font Awesome +import { FontAwesomeModule, FaIconLibrary } from '@fortawesome/angular-fontawesome'; +import { fas } from '@fortawesome/free-solid-svg-icons'; +import { far } from '@fortawesome/free-regular-svg-icons'; + +// NPM Module +import { NgxScannerQrcodeModule } from 'ngx-scanner-qrcode'; +import { ListComponent } from './admin/list/list.component'; +import { LoginComponent } from './admin/login/login.component'; + +// Services +import { ApiService, httpInterceptorProviders } from './services/api.service/api.service.component'; +import { EventDetailsService } from './services/event-details/event-details.service'; +import { isAtuhGuard } from './services/authentication/authguard.guard'; +import { HttpinterceptorService } from './services/interceptor/httpinterceptor.service'; + +const routes: Routes = [ + { path: 'login', component: LoginComponent}, + { path: '', redirectTo: 'checkout', pathMatch: 'full' }, + { path: 'checkout', component: CheckoutComponent }, + { + path: 'admin', + component: SideBarComponent, // AdminComponent will be displayed in the main router-outlet + canActivate: [isAtuhGuard], + children: [ + { path: '', pathMatch: 'full', redirectTo: 'dashboard' }, // Redirect to dashboard as the default child route for /admin + { path: 'dashboard', component: DashboardComponent }, // DashboardComponent will be displayed in the router-outlet of AdminComponent + { path: 'tickets', component: TicketsComponent }, + { path: 'scan', component: ScanComponent }, + { path: 'events', component: ListComponent }, + { path: 'addon', component: ListComponent }, + ], + }, + { path: 'maintenance', component: MaintenanceComponent }, + { path: 'delivery/:ticketId', component: DeliveryComponent }, +]; + + + +@NgModule({ + declarations: [ + AppComponent, + CheckoutComponent, + SideBarComponent, + DashboardComponent, + TicketsComponent, + TicketDialogComponent, + ScanComponent, + TransactionsComponent, + ListComponent, + LoginComponent, + MaintenanceComponent, + DeliveryComponent, + ], + imports: [ + BrowserModule, + AppRoutingModule, + HttpClientModule, + BrowserAnimationsModule, + MatButtonModule, + MatCardModule, + MatCheckboxModule, + MatFormFieldModule, + MatListModule, + MatIconModule, + FontAwesomeModule, + MatSidenavModule, + MatToolbarModule, + FormsModule, + MatTableModule, + MatInputModule, + MatDialogModule, + MatProgressSpinnerModule, + MatSnackBarModule, + NgxScannerQrcodeModule, + MatSlideToggleModule, + MatSelectModule, + RouterModule.forRoot(routes), + ], + providers: [ApiService, EventDetailsService, + { provide: HTTP_INTERCEPTORS, useClass: HttpinterceptorService, multi: true }, httpInterceptorProviders ], + bootstrap: [AppComponent] +}) +export class AppModule { + constructor(library: FaIconLibrary) { + library.addIconPacks(fas, far); + } + } diff --git a/frontend/src/app/customer/checkout/checkout.component.html b/frontend/src/app/customer/checkout/checkout.component.html new file mode 100644 index 0000000..071d29a --- /dev/null +++ b/frontend/src/app/customer/checkout/checkout.component.html @@ -0,0 +1,147 @@ + +
+
+
+
+
+
+ + +
+
+ + +
+
+ + +
+ + +
+
+ +
+
+ + {{ event.name }} + +
+
+ Event Image +
+
+ + Select + +
+
+ +
+

{{ event.description }}

+
+
+
+
+ + + Add On + + + + + + {{ addon.name }} - {{ addon.price | currency : "INR" }} + + + + +
+
+
+
+
+
+
+

Payment

+
+
+ + +
+
+

Event

+
+
+

{{ SubEventsSelected.length }}

+
+
+
+ +
+
+

Addons

+
+
+

{{ AddonsSelected.length }}

+
+
+
+ +
+
+

Discount

+
+
+

{{ DiscountValue | currency : "INR" }}

+
+
+
+
+ +
+
+

Total

+
+
+

{{ TotalPrice | currency : "INR" }}

+
+
+
+ +
+
+

Promo Code

+
+
+ +
+ + +
+
+
+
+
+
+ +
+
+
+
+ +
\ No newline at end of file diff --git a/frontend/src/app/customer/checkout/checkout.component.scss b/frontend/src/app/customer/checkout/checkout.component.scss new file mode 100644 index 0000000..b70b466 --- /dev/null +++ b/frontend/src/app/customer/checkout/checkout.component.scss @@ -0,0 +1,53 @@ +.loading-overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.5); /* Semi-transparent black background */ + display: flex; + justify-content: center; + align-items: center; + z-index: 9999; /* Make sure it's above other elements */ +} + + +.custom-element { + background-color: #121212; + } + + +.customer-interface-card { + background-color: #121212; + width: auto; /* Adjust the width as per your requirements */ + margin: 10px; /* Adjust the margin as per your requirements */ + border: 1px solid #ccc; /* Add a border as the bounding box */ + transition: box-shadow 0.3s ease; +} + +.payment-interface-card { + background-color: #301E67; + width: auto; /* Adjust the width as per your requirements */ + margin: 10px; /* Adjust the margin as per your requirements */ + position: sticky; + top: 0; +} + +.customer-interface-card:hover { + box-shadow: 0 0 10px 3px rgba(0, 255, 0, 0.3); +} + +.card-image-container { + height: 200px; /* Adjust the maximum height as needed */ + overflow: hidden; +} + +.card-img { + width: auto; + max-height: 100%; +} + +.checkout { + width: 100%; + margin: 10px; +} diff --git a/frontend/src/app/customer/checkout/checkout.component.spec.ts b/frontend/src/app/customer/checkout/checkout.component.spec.ts new file mode 100644 index 0000000..63d7734 --- /dev/null +++ b/frontend/src/app/customer/checkout/checkout.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CheckoutComponent } from './checkout.component'; + +describe('CheckoutComponent', () => { + let component: CheckoutComponent; + let fixture: ComponentFixture; + + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [CheckoutComponent] + }); + fixture = TestBed.createComponent(CheckoutComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/frontend/src/app/customer/checkout/checkout.component.ts b/frontend/src/app/customer/checkout/checkout.component.ts new file mode 100644 index 0000000..51d0059 --- /dev/null +++ b/frontend/src/app/customer/checkout/checkout.component.ts @@ -0,0 +1,168 @@ +import { Component } from '@angular/core'; +import { EventDetailsService } from '../../services/event-details/event-details.service'; +import { HttpClient } from '@angular/common/http'; +import { ElementRef, Renderer2 } from '@angular/core'; +import { LoadingServiceComponent } from '../../loading-service/loading-service.component'; + +@Component({ + selector: 'app-checkout', + templateUrl: './checkout.component.html', + styleUrls: ['./checkout.component.scss'] +}) +export class CheckoutComponent { + + eventdata: any; + SubEvents: any; + Addons: any; + isDiscountApplied = false; + DiscountValue: number = 0; + SubEventsSelected: any = []; + AddonsSelected: any = []; + TotalPrice: number = 0; + showCouponInput: boolean = false; + couponCode: string = ''; + + constructor( + private http: HttpClient, + private EventDetailsService: EventDetailsService, private renderer: Renderer2, private elementRef: ElementRef, public loadingService: LoadingServiceComponent) { } + + ngOnInit() { + this.EventDetailsService.EventDetails().then(() => { + this.EventDetailsService.SubEventDetails().then(() => { + this.EventDetailsService.AddonDetails().then(() => { + this.eventdata = this.EventDetailsService.event; + this.TotalPrice += parseFloat(this.eventdata[0].price); + this.SubEvents = this.EventDetailsService.SubEvent; + this.Addons = this.EventDetailsService.Addon; + }); + }); + }); + } + + toggleDescription(eventItem: any, event: Event) { + event.preventDefault(); + eventItem.showDescription = !eventItem.showDescription; + } + + toggleCouponInput() { + this.showCouponInput = !this.showCouponInput; + } + + applyCoupon(coupon: any) { + this.EventDetailsService.SendPromoCode(coupon).then(() => { + if (this.EventDetailsService.PromoData.discount) { + this.isDiscountApplied = true; + this.DiscountValue = this.EventDetailsService.PromoData.discount; + this.TotalPrice = this.TotalPrice - this.DiscountValue; + } + }); + } + + SelectSubEvent(event: any, subEvent: any) { + if (event.checked) { + this.SubEventsSelected.push(subEvent); + if (this.SubEventsSelected.length > this.EventDetailsService.event[0].sub_events_included_allowed) { + this.TotalPrice += parseFloat(subEvent.price); + } + } else { + if (this.SubEventsSelected.length > this.EventDetailsService.event[0].sub_events_included_allowed) { + this.TotalPrice -= parseFloat(subEvent.price); + } + this.SubEventsSelected.splice(this.SubEventsSelected.indexOf(subEvent), 1); + } + } + + onAddonSelectionChange(addonlist: any) { + const previouslySelectedAddons = this.AddonsSelected; + this.AddonsSelected = addonlist.selectedOptions.selected.map((option: { value: any; }) => option.value); + const deselectedAddons = previouslySelectedAddons.filter( + (addon: any) => !this.AddonsSelected.includes(addon) + ); + const newlySelectedAddons = this.AddonsSelected.filter( + (addon: any) => !previouslySelectedAddons.includes(addon) + ); + let priceDifference = 0; + deselectedAddons.forEach((addon: any) => { + priceDifference -= parseFloat(addon.price); + }); + newlySelectedAddons.forEach((addon: any) => { + priceDifference += parseFloat(addon.price); + }); + this.TotalPrice += priceDifference; + } + + Checkout() { + this.loadingService.showLoading(); + setTimeout(() => { + // Hide the loading overlay after the operation is complete + this.loadingService.hideLoading(); + }, 20000); + var nameInput = document.getElementById("name") as HTMLInputElement; + var emailInput = document.getElementById("email") as HTMLInputElement; + var phoneNumberInput = document.getElementById("phone") as HTMLInputElement; + + if(nameInput.value == '' || emailInput.value == '' || phoneNumberInput.value == '') { + alert('Please fill all the fields'); + return; + } +else { + var name = nameInput.value; + var email = emailInput.value; + var phoneNumber = phoneNumberInput.value; + } + const data = { + customer_name: name, + customer_email: email, + customer_phone: phoneNumber, + event_id: this.eventdata[0].id, + selected_sub_events: this.SubEventsSelected.map((subEvent: { id: any; }) => subEvent.id), + selected_addons: this.AddonsSelected.map((addon: { id: any; }) => addon.id), + } + this.EventDetailsService.SendCheckoutData(data).then(() => { + const checkoutData = { + "key_id": this.EventDetailsService.CheckoutData.id, + "order_id": this.EventDetailsService.CheckoutData.payment_id, + "amount": this.TotalPrice * 100, + "name": this.EventDetailsService.CheckoutData.Business, + "image": this.EventDetailsService.CheckoutData.image, + "currency": this.EventDetailsService.CheckoutData.currency, + "callback_url": this.EventDetailsService.CheckoutData.callback_url, + "prefill[name]": name, + "prefill[email]": email, + "prefill[contact]": phoneNumber, + }; + const form = this.createForm(checkoutData); + this.submitFormElement(form); + + }); + } + + private createForm(formData: { [key: string]: any }): HTMLFormElement { + const form = this.renderer.createElement('form'); + form.method = 'POST'; + form.action = 'https://api.razorpay.com/v1/checkout/embedded'; + + Object.entries(formData).forEach(([name, value]) => { + const input = this.renderer.createElement('input'); + this.renderer.setAttribute(input, 'type', 'hidden'); + this.renderer.setAttribute(input, 'name', name); + + if (typeof value === 'object') { + this.renderer.setAttribute(input, 'value', JSON.stringify(value)); + } else { + this.renderer.setAttribute(input, 'value', value.toString()); + } + + this.renderer.appendChild(form, input); + }); + + return form; + } + + + private submitFormElement(form: HTMLFormElement) { + this.renderer.appendChild(this.elementRef.nativeElement, form); + form.submit(); + } + +} diff --git a/frontend/src/app/customer/delivery/delivery.component.html b/frontend/src/app/customer/delivery/delivery.component.html new file mode 100644 index 0000000..ae9ff55 --- /dev/null +++ b/frontend/src/app/customer/delivery/delivery.component.html @@ -0,0 +1,31 @@ +
+ + + + Payment Completed + + +

+ Your Ticket is being processed. Please wait a moment. It will also be mailed to your provided email address. +

+

+ Thank you for your patience. +

+
+
+ +
+ + Ticket +
+ +
+ If your ticket isn't shown here, don't worry! It will be mailed to your provided email address. +
+ +
+
+ Loading... +
+
+
diff --git a/frontend/src/app/customer/delivery/delivery.component.scss b/frontend/src/app/customer/delivery/delivery.component.scss new file mode 100644 index 0000000..8d1c2f6 --- /dev/null +++ b/frontend/src/app/customer/delivery/delivery.component.scss @@ -0,0 +1,21 @@ +.custom-card { + background-color: #f0faff; +} + + +.custom-card-content { + color: #1a1a1a; +} + +mat-card-header { + align-self: center; + padding: 1rem; +} + +.note { + margin-top: 20px; + padding: 10px; + border-radius: 5px; + background-color: #f8f9fa; /* Light gray background */ + color: #212529; /* Dark gray text color */ + } \ No newline at end of file diff --git a/frontend/src/app/customer/delivery/delivery.component.spec.ts b/frontend/src/app/customer/delivery/delivery.component.spec.ts new file mode 100644 index 0000000..f2a9b2e --- /dev/null +++ b/frontend/src/app/customer/delivery/delivery.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { DeliveryComponent } from './delivery.component'; + +describe('DeliveryComponent', () => { + let component: DeliveryComponent; + let fixture: ComponentFixture; + + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [DeliveryComponent] + }); + fixture = TestBed.createComponent(DeliveryComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/frontend/src/app/customer/delivery/delivery.component.ts b/frontend/src/app/customer/delivery/delivery.component.ts new file mode 100644 index 0000000..88ee8c3 --- /dev/null +++ b/frontend/src/app/customer/delivery/delivery.component.ts @@ -0,0 +1,43 @@ +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute, ParamMap } from '@angular/router'; +import { EventDetailsService } from '../../services/event-details/event-details.service'; + +@Component({ + selector: 'app-delivery', + templateUrl: './delivery.component.html', + styleUrls: ['./delivery.component.scss'] +}) +export class DeliveryComponent implements OnInit { +shownnote = false; + taskId: any; + interval: any; + ticketUrl: any; + constructor(private route: ActivatedRoute, private EventDetailsService: EventDetailsService) { + setTimeout(() => { + this.shownnote = true; + } + , 20000); + } + + ngOnInit() { + this.route.paramMap.subscribe((params: ParamMap) => { + this.taskId = params.get('ticketId'); + }); + // Check the task status every 5 to 10 seconds using setInterval + this.interval = setInterval(() => { + this.checkTaskStatus(); + }, 5000); + } + + checkTaskStatus() { + const data = { + 'task_id': this.taskId + } + this.EventDetailsService.get_ticket_by_task(data).then(() => { + this.ticketUrl = this.EventDetailsService.task_result; + clearInterval(this.interval); + }); + } + + +} diff --git a/frontend/src/app/loading-service/loading-service.component.ts b/frontend/src/app/loading-service/loading-service.component.ts new file mode 100644 index 0000000..1cba538 --- /dev/null +++ b/frontend/src/app/loading-service/loading-service.component.ts @@ -0,0 +1,16 @@ +import { Injectable } from '@angular/core'; + +@Injectable({ + providedIn: 'root' +}) +export class LoadingServiceComponent { + isLoading: boolean = false; + + showLoading(): void { + this.isLoading = true; + } + + hideLoading(): void { + this.isLoading = false; + } +} diff --git a/frontend/src/app/maintenance/maintenance.component.html b/frontend/src/app/maintenance/maintenance.component.html new file mode 100644 index 0000000..c7f4f1b --- /dev/null +++ b/frontend/src/app/maintenance/maintenance.component.html @@ -0,0 +1,22 @@ +
+ + + Maintenance + + +

+ We are currently performing maintenance on our website to provide you with an even better experience. Please + check back later! +

+

+ Thank you for your patience. +

+
+
+ +
+
+ Loading... +
+
+
diff --git a/frontend/src/app/maintenance/maintenance.component.scss b/frontend/src/app/maintenance/maintenance.component.scss new file mode 100644 index 0000000..50e0e37 --- /dev/null +++ b/frontend/src/app/maintenance/maintenance.component.scss @@ -0,0 +1,13 @@ +.custom-card { + background-color: #f0faff; +} + + +.custom-card-content { + color: #1a1a1a; +} + +mat-card-header { + align-self: center; + padding: 1rem; +} \ No newline at end of file diff --git a/frontend/src/app/maintenance/maintenance.component.spec.ts b/frontend/src/app/maintenance/maintenance.component.spec.ts new file mode 100644 index 0000000..9b9bec6 --- /dev/null +++ b/frontend/src/app/maintenance/maintenance.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { MaintenanceComponent } from './maintenance.component'; + +describe('MaintenanceComponent', () => { + let component: MaintenanceComponent; + let fixture: ComponentFixture; + + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [MaintenanceComponent] + }); + fixture = TestBed.createComponent(MaintenanceComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/frontend/src/app/maintenance/maintenance.component.ts b/frontend/src/app/maintenance/maintenance.component.ts new file mode 100644 index 0000000..443fb6a --- /dev/null +++ b/frontend/src/app/maintenance/maintenance.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-maintenance', + templateUrl: './maintenance.component.html', + styleUrls: ['./maintenance.component.scss'] +}) +export class MaintenanceComponent { + +} diff --git a/frontend/src/app/services/api.service/api.service.component.spec.ts b/frontend/src/app/services/api.service/api.service.component.spec.ts new file mode 100644 index 0000000..740f15d --- /dev/null +++ b/frontend/src/app/services/api.service/api.service.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ApiServiceComponent } from './api.service.component'; + +describe('ApiServiceComponent', () => { + let component: ApiServiceComponent; + let fixture: ComponentFixture; + + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [ApiServiceComponent] + }); + fixture = TestBed.createComponent(ApiServiceComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/frontend/src/app/services/api.service/api.service.component.ts b/frontend/src/app/services/api.service/api.service.component.ts new file mode 100644 index 0000000..1cfe8ab --- /dev/null +++ b/frontend/src/app/services/api.service/api.service.component.ts @@ -0,0 +1,38 @@ +import { Injectable } from '@angular/core'; +import { environment } from 'src/environments/environment'; +import { HttpClient, HttpHeaders, HTTP_INTERCEPTORS } from '@angular/common/http'; +import { Observable } from 'rxjs'; +import { CsrfInterceptorService } from '../interceptor/csrf-interceptor.service'; + +@Injectable() +export class ApiService { + API = environment.api_endpoint; + private HEADERS = new HttpHeaders({ + 'Content-Type': 'application/json', + }); + HTTP_OPTIONS: any; + + /** + * Constructor. + * @param http Http Injection. + * @param globalService GlobalService Injection. + */ + constructor(private http: HttpClient) {} + + get(endpoint: string, withCredentials: boolean = true): Observable { + const url = `${this.API}${endpoint}`; + const options = { headers: this.HEADERS, withCredentials: withCredentials }; + return this.http.get(url, options); + } + + post(endpoint: string, data: any, withCredentials: boolean = true): Observable { + const url = `${this.API}${endpoint}`; + const options = { headers: this.HEADERS, withCredentials: withCredentials }; + return this.http.post(url, data, options); + } + +} + +export const httpInterceptorProviders = [ + { provide: HTTP_INTERCEPTORS, useClass: CsrfInterceptorService, multi: true }, +]; diff --git a/frontend/src/app/services/authentication/authguard.guard.spec.ts b/frontend/src/app/services/authentication/authguard.guard.spec.ts new file mode 100644 index 0000000..0b0a636 --- /dev/null +++ b/frontend/src/app/services/authentication/authguard.guard.spec.ts @@ -0,0 +1,17 @@ +import { TestBed } from '@angular/core/testing'; +import { CanActivateFn } from '@angular/router'; + +import { authguardGuard } from './authguard.guard'; + +describe('authguardGuard', () => { + const executeGuard: CanActivateFn = (...guardParameters) => + TestBed.runInInjectionContext(() => authguardGuard(...guardParameters)); + + beforeEach(() => { + TestBed.configureTestingModule({}); + }); + + it('should be created', () => { + expect(executeGuard).toBeTruthy(); + }); +}); diff --git a/frontend/src/app/services/authentication/authguard.guard.ts b/frontend/src/app/services/authentication/authguard.guard.ts new file mode 100644 index 0000000..664c955 --- /dev/null +++ b/frontend/src/app/services/authentication/authguard.guard.ts @@ -0,0 +1,43 @@ +import { Injectable, inject } from '@angular/core'; +import { Router, UrlTree } from '@angular/router'; +import { CanActivateFn, ActivatedRouteSnapshot, RouterStateSnapshot, UrlSegment } from '@angular/router'; +import { Observable } from 'rxjs'; + +@Injectable({ + providedIn: 'root' +}) +class AuthGuard { + + constructor(private router: Router) {} + + canActivate( + route: ActivatedRouteSnapshot, + state: RouterStateSnapshot + ): boolean | UrlTree { + const isAuth = this.checkIfAuthenticated(); + + if (isAuth) { + return true; + } else { + return this.router.parseUrl('/login'); + } + } + + private checkIfAuthenticated(): boolean { + const sessionId = this.getCookie('sessionid'); + // return !!sessionId; // Return true if session ID cookie exists, otherwise false + return true; + } + + + private getCookie(name: string): string { + const value = `; ${document.cookie}`; + const parts = value.split(`; ${name}=`); + if (parts.length === 2) return parts.pop()?.split(';').shift() || ''; + return ''; + } +} + +export const isAtuhGuard: CanActivateFn = (route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean => { + return inject(AuthGuard).canActivate(route, state) as boolean; +} diff --git a/frontend/src/app/services/event-details/event-details.service.spec.ts b/frontend/src/app/services/event-details/event-details.service.spec.ts new file mode 100644 index 0000000..ca189c4 --- /dev/null +++ b/frontend/src/app/services/event-details/event-details.service.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { EventDetailsService } from './event-details.service'; + +describe('EventDetailsComponent', () => { + let component: EventDetailsService; + let fixture: ComponentFixture; + + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [EventDetailsService] + }); + fixture = TestBed.createComponent(EventDetailsService); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/frontend/src/app/services/event-details/event-details.service.ts b/frontend/src/app/services/event-details/event-details.service.ts new file mode 100644 index 0000000..232ac4e --- /dev/null +++ b/frontend/src/app/services/event-details/event-details.service.ts @@ -0,0 +1,244 @@ +import { Injectable } from '@angular/core'; +import { ApiService } from '../api.service/api.service.component'; +import { Router } from '@angular/router'; +import { MatSnackBar } from '@angular/material/snack-bar'; +import { HttpHeaders } from '@angular/common/http'; + +@Injectable({ + providedIn: 'root' +}) +export class EventDetailsService { + event: any; + SubEvent: any; + Addon: any; + PromoData: any; + CheckoutData: any; + SalesData: any; + SubEventData: any; + AddonData: any; + TicketData: any; + CheckInResponse: any; + CheckInData: any; + ResendEmailResponse: any; + TicketID: any; + Ticket_by_list: any; + task_result: any; + + constructor(private HttpService: ApiService, private router: Router, private _snackBar: MatSnackBar) { + } + + + EventDetails(): Promise { + return new Promise((resolve, reject) => { + this.HttpService.get('event/get_event').subscribe(data => { + this.event = data; + resolve(); + }, error => { + this.router.navigate(['/maintenance']); + reject(error); + }); + }); + } + + SubEventDetails(): Promise { + return new Promise((resolve, reject) => { + if (this.event[0].id) { + this.HttpService.get('event/get_sub_event/' + this.event[0].id + '/').subscribe(data => { + this.SubEvent = data; + resolve(); + }, error => { + reject(error); + }); + } else { + reject('Event data is not available.'); // Reject the promise if event data is not available + } + }); + } + + AddonDetails(): Promise { + return new Promise((resolve, reject) => { + this.HttpService.get('event/get_addon/' + this.event[0].id + '/').subscribe(data => { + this.Addon = data; + resolve(); + }, error => { + reject(error); + }); + }); + } + + SendPromoCode(promoCode: string): Promise { + return new Promise((resolve, reject) => { + this.HttpService.post('event/process_promo_code/', { 'promo_code': promoCode, 'event_id': this.event[0].id }).subscribe(data => { + this.PromoData = data; + resolve(); + }, error => { + reject(error); + }); + }); + } + + SendCheckoutData(userData: any): Promise { + return new Promise((resolve, reject) => { + this.HttpService.post('transactions/handle-payment/', userData).subscribe(data => { + this.CheckoutData = data; + resolve(); + }, error => { + reject(error); + }); + }); + } + + GetSalesData(): Promise { + return new Promise((resolve, reject) => { + this.HttpService.get('event/get_max_ticket_sales/' + this.event[0].id + "/").subscribe(data => { + this.SalesData = data; + resolve(); + }, error => { + reject(error); + }); + }); + } + + GetSubEventsSalesData(): Promise { + return new Promise((resolve, reject) => { + this.HttpService.get('event/get_sub_event_sales/' + this.event[0].id + "/").subscribe(data => { + this.SubEventData = data; + resolve(); + }, error => { + reject(error); + }); + }); + } + + GetAddonSalesData(): Promise { + return new Promise((resolve, reject) => { + this.HttpService.get('event/get_addon_sales/' + this.event[0].id + "/").subscribe(data => { + this.AddonData = data; + resolve(); + }, error => { + reject(error); + }); + }); + } + + GetTicketData(data: any): Promise { + return new Promise((resolve, reject) => { + this.HttpService.post('ticket/get_tickets_by_filter/', data).subscribe(data => { + this.TicketData = data; + resolve(); + }, error => { + reject(error); + this._snackBar.open(error.error.message, 'Close', { + duration: 2000, + }); + }); + }); + } + + SendCheckIn(data: any): Promise { + return new Promise((resolve, reject) => { + this.HttpService.post('ticket/handle_check_in/', data).subscribe(data => { + this.CheckInResponse = data; + resolve(); + }, error => { + reject(error); + this._snackBar.open(error.error.message, 'Close', { + duration: 2000, + }); + }); + }); + } + + GetCheckInData(data: any): Promise { + return new Promise((resolve, reject) => { + this.HttpService.post('ticket/get_check_in_data/', data).subscribe(data => { + this.CheckInData = data; + resolve(); + }, error => { + reject(error); + }); + }); + } + + trigger_resend_email(data: any): Promise { + return new Promise((resolve, reject) => { + this.HttpService.post('ticket/resend_email/', data).subscribe(data => { + this.ResendEmailResponse = data; + resolve(); + }, error => { + reject(error); + }); + }); + } + + + get_ticket_by_subevent(data: any): Promise { + return new Promise((resolve, reject) => { + this.HttpService.post('ticket/get_ticket_by_subevents/', data).subscribe(data => { + this.Ticket_by_list = data; + resolve(); + }, error => { + this.Ticket_by_list = []; + reject(error); + this._snackBar.open(error.error.message, 'Close', { + duration: 2000, + }); + }); + }); + } + + get_ticket_by_addon(data: any): Promise { + return new Promise((resolve, reject) => { + this.HttpService.post('ticket/get_ticket_by_addons/', data).subscribe(data => { + this.Ticket_by_list = data; + resolve(); + }, error => { + this.Ticket_by_list = []; + reject(error); + this._snackBar.open(error.error.message, 'Close', { + duration: 2000, + }); + }); + }); + } + + send_login_data(data: any): Promise { + return new Promise((resolve, reject) => { + const headers = new HttpHeaders({ 'Content-Type': 'application/json' }); + this.HttpService.post('login/', data).subscribe(data => { + resolve(); + }, error => { + reject(error); + this._snackBar.open(error.error.message, 'Close', { + duration: 4000, + }); + }); + }); + } + + send_logout(): Promise { + return new Promise((resolve, reject) => { + this.HttpService.post('logout/', 66).subscribe(data => { + resolve(); + }, error => { + reject(error); + this._snackBar.open(error.error.message, 'Close', { + duration: 4000, + }); + }); + }); + } + + get_ticket_by_task(data: any): Promise { + return new Promise((resolve, reject) => { + this.HttpService.post('ticket/get_ticket_by_task/', data).subscribe(data => { + this.task_result = data; + resolve(); + } + , error => { + reject(error); + }); + }); + } + +} \ No newline at end of file diff --git a/frontend/src/app/services/interceptor/csrf-interceptor.service.spec.ts b/frontend/src/app/services/interceptor/csrf-interceptor.service.spec.ts new file mode 100644 index 0000000..10399ef --- /dev/null +++ b/frontend/src/app/services/interceptor/csrf-interceptor.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { CsrfInterceptorService } from './csrf-interceptor.service'; + +describe('CsrfInterceptorService', () => { + let service: CsrfInterceptorService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(CsrfInterceptorService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/frontend/src/app/services/interceptor/csrf-interceptor.service.ts b/frontend/src/app/services/interceptor/csrf-interceptor.service.ts new file mode 100644 index 0000000..af0fde4 --- /dev/null +++ b/frontend/src/app/services/interceptor/csrf-interceptor.service.ts @@ -0,0 +1,31 @@ +import { Injectable } from '@angular/core'; +import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http'; +import { Observable } from 'rxjs'; + +@Injectable() +export class CsrfInterceptorService implements HttpInterceptor { + constructor() {} + + intercept(request: HttpRequest, next: HttpHandler): Observable> { + // Get the CSRF token from the cookie + const csrftoken = this.getCookie('csrftoken'); + + // Clone the request and add the CSRF token to the headers + if (csrftoken) { + request = request.clone({ + setHeaders: { + 'X-CSRFToken': csrftoken, + }, + }); + } + + return next.handle(request); + } + + private getCookie(name: string): string { + const value = `; ${document.cookie}`; + const parts = value.split(`; ${name}=`); + if (parts.length === 2) return parts.pop()?.split(';').shift() || ''; + return ''; + } +} diff --git a/frontend/src/app/services/interceptor/httpinterceptor.service.spec.ts b/frontend/src/app/services/interceptor/httpinterceptor.service.spec.ts new file mode 100644 index 0000000..6995f72 --- /dev/null +++ b/frontend/src/app/services/interceptor/httpinterceptor.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { HttpinterceptorService } from './httpinterceptor.service'; + +describe('HttpinterceptorService', () => { + let service: HttpinterceptorService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(HttpinterceptorService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/frontend/src/app/services/interceptor/httpinterceptor.service.ts b/frontend/src/app/services/interceptor/httpinterceptor.service.ts new file mode 100644 index 0000000..375472f --- /dev/null +++ b/frontend/src/app/services/interceptor/httpinterceptor.service.ts @@ -0,0 +1,26 @@ +import { Injectable } from '@angular/core'; +import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpResponse } from '@angular/common/http'; +import { Observable, throwError } from 'rxjs'; +import { Router } from '@angular/router'; +import { catchError } from 'rxjs/operators'; + +@Injectable() +export class HttpinterceptorService implements HttpInterceptor { + constructor(private router: Router) {} + + intercept(request: HttpRequest, next: HttpHandler): Observable> { + return next.handle(request).pipe( + catchError((error) => { + if (error.status === 401) { + // Handle 401 Unauthorized: Redirect the user to the login page + this.router.navigate(['/login']); + } else if (error.status === 403) { + // Handle 403 Forbidden: Redirect the user to a different page + this.router.navigate(['/login']); + } + // Re-throw the error to continue error handling in other parts of the application + return throwError(error); + }) + ); + } +} diff --git a/frontend/src/app/side-bar/side-bar.component.html b/frontend/src/app/side-bar/side-bar.component.html new file mode 100644 index 0000000..e5b4fd5 --- /dev/null +++ b/frontend/src/app/side-bar/side-bar.component.html @@ -0,0 +1,32 @@ +
+ + +

Admin Panel

+
+ + + + + {{ link.label }} + + + + Logout + + + + + + + + +
\ No newline at end of file diff --git a/frontend/src/app/side-bar/side-bar.component.scss b/frontend/src/app/side-bar/side-bar.component.scss new file mode 100644 index 0000000..d54fd18 --- /dev/null +++ b/frontend/src/app/side-bar/side-bar.component.scss @@ -0,0 +1,52 @@ +.mat-list-item.active-link { + background-color: rgba(0, 0, 0, 0.1); /* Some background color to highlight the active link */ + font-weight: bold; /* Make the text bold for the active link */ + color: #1976d2; /* Change the text color for the active link */ + } + + .example-container { + display: flex; + flex-direction: column; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + } + + .example-is-mobile .example-toolbar { + position: fixed; + /* Make sure the toolbar will stay on top of the content as it scrolls past. */ + z-index: 2; + } + + h1.example-app-name { + margin-left: 8px; + } + + .example-sidenav-container { + /* When the sidenav is not fixed, stretch the sidenav container to fill the available space. This + causes `` to act as our scrolling element for desktop layouts. */ + flex: 1; + } + + .example-is-mobile .example-sidenav-container { + /* When the sidenav is fixed, don't constrain the height of the sidenav container. This allows the + `` to be our scrolling element for mobile layouts. */ + flex: 1 0 auto; + } + + + .active-link { + background-color: #007bff; /* Set the background color for the active link */ + color: #fff; /* Set the text color for the active link */ + font-weight: bold; /* Optionally, make the text bold for the active link */ + /* Add any other styles as needed */ + } + + /* Hover effect for the links in mat-nav-list */ + .mat-list-item:hover { + background-color: #f0f0f0; /* Set the background color on hover */ + cursor: pointer; /* Show a pointer cursor on hover */ + /* Add any other styles as needed */ + } diff --git a/frontend/src/app/side-bar/side-bar.component.spec.ts b/frontend/src/app/side-bar/side-bar.component.spec.ts new file mode 100644 index 0000000..19e0c5d --- /dev/null +++ b/frontend/src/app/side-bar/side-bar.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SideBarComponent } from './side-bar.component'; + +describe('SideBarComponent', () => { + let component: SideBarComponent; + let fixture: ComponentFixture; + + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [SideBarComponent] + }); + fixture = TestBed.createComponent(SideBarComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/frontend/src/app/side-bar/side-bar.component.ts b/frontend/src/app/side-bar/side-bar.component.ts new file mode 100644 index 0000000..c8fb2ad --- /dev/null +++ b/frontend/src/app/side-bar/side-bar.component.ts @@ -0,0 +1,36 @@ +import { Component } from '@angular/core'; +import {MediaMatcher} from '@angular/cdk/layout'; +import {ChangeDetectorRef, OnDestroy} from '@angular/core'; +import { Router } from '@angular/router'; +import { EventDetailsService } from '../services/event-details/event-details.service'; + +@Component({ + selector: 'side-bar', + templateUrl: './side-bar.component.html', + styleUrls: ['./side-bar.component.scss'] +}) +export class SideBarComponent { + mobileQuery: MediaQueryList; + links = [ + { path: '/admin/dashboard', label: 'Dashboard', icon: 'dashboard' }, + { path: '/admin/scan', label: 'Scan', icon: 'qr_code_scanner' }, + { path: '/admin/tickets', label: 'Tickets', icon: 'confirmation_number' }, + { path: '/admin/events', label: 'Events', icon: 'event' }, + { path: '/admin/addon', label: 'Addons', icon: 'add_circle' }, + ]; + private _mobileQueryListener: () => void; + constructor(changeDetectorRef: ChangeDetectorRef, media: MediaMatcher, private router: Router, private EventDetailsService: EventDetailsService) { + this.mobileQuery = media.matchMedia('(max-width: 600px)'); + this._mobileQueryListener = () => changeDetectorRef.detectChanges(); + this.mobileQuery.addListener(this._mobileQueryListener); + } + + logout() { + this.EventDetailsService.send_logout().then(() => { + localStorage.clear(); + sessionStorage.clear(); + document.cookie = 'csrftoken=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;'; + this.router.navigate(['/login']); + }); + } +} diff --git a/frontend/src/assets/.gitkeep b/frontend/src/assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/environments/environment.prod.ts b/frontend/src/environments/environment.prod.ts new file mode 100644 index 0000000..5b5cdff --- /dev/null +++ b/frontend/src/environments/environment.prod.ts @@ -0,0 +1,12 @@ +// The file contents for the current environment will overwrite these during build. +// The build system defaults to the dev environment which uses `environment.ts`, but if you do +// `ng build --env=prod` then `environment.prod.ts` will be used instead. +// The list of which env maps to which file can be found in `.angular-cli.json`. + +/** + * Environment URL for production + */ +export const environment = { + production: true, + api_endpoint: 'https://ticketify.tech/api/', + }; diff --git a/frontend/src/environments/environment.staging.ts b/frontend/src/environments/environment.staging.ts new file mode 100644 index 0000000..2e77667 --- /dev/null +++ b/frontend/src/environments/environment.staging.ts @@ -0,0 +1,12 @@ +// The file contents for the current environment will overwrite these during build. +// The build system defaults to the dev environment which uses `environment.ts`, but if you do +// `ng build --env=prod` then `environment.prod.ts` will be used instead. +// The list of which env maps to which file can be found in `.angular-cli.json`. + +/** + * Environment URL for staging + */ +export const environment = { + production: true, + api_endpoint: 'https://ticketify.tech/api/', +}; diff --git a/frontend/src/environments/environment.ts b/frontend/src/environments/environment.ts new file mode 100644 index 0000000..8993e4e --- /dev/null +++ b/frontend/src/environments/environment.ts @@ -0,0 +1,9 @@ +/** + * Environment URL for local development + */ + +export const environment = { + production: false, + api_endpoint: 'http://localhost:8000/api/', + }; + \ No newline at end of file diff --git a/frontend/src/favicon.ico b/frontend/src/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..997406ad22c29aae95893fb3d666c30258a09537 GIT binary patch literal 948 zcmV;l155mgP)CBYU7IjCFmI-B}4sMJt3^s9NVg!P0 z6hDQy(L`XWMkB@zOLgN$4KYz;j0zZxq9KKdpZE#5@k0crP^5f9KO};h)ZDQ%ybhht z%t9#h|nu0K(bJ ztIkhEr!*UyrZWQ1k2+YkGqDi8Z<|mIN&$kzpKl{cNP=OQzXHz>vn+c)F)zO|Bou>E z2|-d_=qY#Y+yOu1a}XI?cU}%04)zz%anD(XZC{#~WreV!a$7k2Ug`?&CUEc0EtrkZ zL49MB)h!_K{H(*l_93D5tO0;BUnvYlo+;yss%n^&qjt6fZOa+}+FDO(~2>G z2dx@=JZ?DHP^;b7*Y1as5^uphBsh*s*z&MBd?e@I>-9kU>63PjP&^#5YTOb&x^6Cf z?674rmSHB5Fk!{Gv7rv!?qX#ei_L(XtwVqLX3L}$MI|kJ*w(rhx~tc&L&xP#?cQow zX_|gx$wMr3pRZIIr_;;O|8fAjd;1`nOeu5K(pCu7>^3E&D2OBBq?sYa(%S?GwG&_0-s%_v$L@R!5H_fc)lOb9ZoOO#p`Nn`KU z3LTTBtjwo`7(HA6 z7gmO$yTR!5L>Bsg!X8616{JUngg_@&85%>W=mChTR;x4`P=?PJ~oPuy5 zU-L`C@_!34D21{fD~Y8NVnR3t;aqZI3fIhmgmx}$oc-dKDC6Ap$Gy>a!`A*x2L1v0 WcZ@i?LyX}70000 + + + + Frontend + + + + + + + + + + + diff --git a/frontend/src/main.ts b/frontend/src/main.ts new file mode 100644 index 0000000..c58dc05 --- /dev/null +++ b/frontend/src/main.ts @@ -0,0 +1,7 @@ +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; + + +platformBrowserDynamic().bootstrapModule(AppModule) + .catch(err => console.error(err)); diff --git a/frontend/src/styles.scss b/frontend/src/styles.scss new file mode 100644 index 0000000..6dd200c --- /dev/null +++ b/frontend/src/styles.scss @@ -0,0 +1,5 @@ +/* You can add global styles to this file, and also import other style files */ + + +html, body { height: 100%; } +body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; } \ No newline at end of file diff --git a/frontend/tsconfig.app.json b/frontend/tsconfig.app.json new file mode 100644 index 0000000..374cc9d --- /dev/null +++ b/frontend/tsconfig.app.json @@ -0,0 +1,14 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/app", + "types": [] + }, + "files": [ + "src/main.ts" + ], + "include": [ + "src/**/*.d.ts" + ] +} diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json new file mode 100644 index 0000000..191e852 --- /dev/null +++ b/frontend/tsconfig.json @@ -0,0 +1,34 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "compileOnSave": false, + "compilerOptions": { + "baseUrl": "./", + "outDir": "./dist/out-tsc", + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "sourceMap": true, + "declaration": false, + "downlevelIteration": true, + "experimentalDecorators": true, + "moduleResolution": "node", + "importHelpers": true, + "target": "ES2022", + "module": "ES2022", + "useDefineForClassFields": false, + "lib": [ + "ES2022", + "dom" + ], + "types": ["node"] + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/frontend/tsconfig.spec.json b/frontend/tsconfig.spec.json new file mode 100644 index 0000000..be7e9da --- /dev/null +++ b/frontend/tsconfig.spec.json @@ -0,0 +1,14 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/spec", + "types": [ + "jasmine" + ] + }, + "include": [ + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/frontend/yarn.lock b/frontend/yarn.lock new file mode 100644 index 0000000..50191d9 --- /dev/null +++ b/frontend/yarn.lock @@ -0,0 +1,7200 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@ampproject/remapping@^2.2.0", "@ampproject/remapping@2.2.1": + version "2.2.1" + resolved "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz" + integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@angular-devkit/architect@0.1600.5": + version "0.1600.5" + resolved "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1600.5.tgz" + integrity sha512-K2bfaBqWtwiuLEaWCbiVNO9jNUhA0cGT+XfQu01Tr5UO9XfNXg/2xBj17JGClJiLIUWZ6bWlaHyVVYTWQuzLxA== + dependencies: + "@angular-devkit/core" "16.0.5" + rxjs "7.8.1" + +"@angular-devkit/build-angular@^16.0.4": + version "16.0.5" + resolved "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-16.0.5.tgz" + integrity sha512-I4B3aYv+rtvGwpwaIE2p+Uyor52UmYo93slXprhMKCW6FfYYWUScyVkufKNfdoEGO/cLRaSTo7gYkovC7bPdaA== + dependencies: + "@ampproject/remapping" "2.2.1" + "@angular-devkit/architect" "0.1600.5" + "@angular-devkit/build-webpack" "0.1600.5" + "@angular-devkit/core" "16.0.5" + "@babel/core" "7.21.4" + "@babel/generator" "7.21.4" + "@babel/helper-annotate-as-pure" "7.18.6" + "@babel/helper-split-export-declaration" "7.18.6" + "@babel/plugin-proposal-async-generator-functions" "7.20.7" + "@babel/plugin-transform-async-to-generator" "7.20.7" + "@babel/plugin-transform-runtime" "7.21.4" + "@babel/preset-env" "7.21.4" + "@babel/runtime" "7.21.0" + "@babel/template" "7.20.7" + "@discoveryjs/json-ext" "0.5.7" + "@ngtools/webpack" "16.0.5" + "@vitejs/plugin-basic-ssl" "1.0.1" + ansi-colors "4.1.3" + autoprefixer "10.4.14" + babel-loader "9.1.2" + babel-plugin-istanbul "6.1.1" + browserslist "4.21.5" + cacache "17.0.6" + chokidar "3.5.3" + copy-webpack-plugin "11.0.0" + critters "0.0.16" + css-loader "6.7.3" + esbuild-wasm "0.17.18" + glob "8.1.0" + https-proxy-agent "5.0.1" + inquirer "8.2.4" + jsonc-parser "3.2.0" + karma-source-map-support "1.4.0" + less "4.1.3" + less-loader "11.1.0" + license-webpack-plugin "4.0.2" + loader-utils "3.2.1" + magic-string "0.30.0" + mini-css-extract-plugin "2.7.5" + mrmime "1.0.1" + open "8.4.2" + ora "5.4.1" + parse5-html-rewriting-stream "7.0.0" + picomatch "2.3.1" + piscina "3.2.0" + postcss "8.4.23" + postcss-loader "7.2.4" + resolve-url-loader "5.0.0" + rxjs "7.8.1" + sass "1.62.1" + sass-loader "13.2.2" + semver "7.4.0" + source-map-loader "4.0.1" + source-map-support "0.5.21" + terser "5.17.1" + text-table "0.2.0" + tree-kill "1.2.2" + tslib "2.5.0" + vite "4.3.9" + webpack "5.80.0" + webpack-dev-middleware "6.0.2" + webpack-dev-server "4.13.2" + webpack-merge "5.8.0" + webpack-subresource-integrity "5.1.0" + optionalDependencies: + esbuild "0.17.18" + +"@angular-devkit/build-webpack@0.1600.5": + version "0.1600.5" + resolved "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1600.5.tgz" + integrity sha512-jFFyPSafWUVdaNVlKdN00xLl2PdJyB7XeFQnL017oG38h6ov3RILKJnsl3bnuTsMvWjuWo17Xd6BrKLGi+b7dA== + dependencies: + "@angular-devkit/architect" "0.1600.5" + rxjs "7.8.1" + +"@angular-devkit/core@16.0.5": + version "16.0.5" + resolved "https://registry.npmjs.org/@angular-devkit/core/-/core-16.0.5.tgz" + integrity sha512-33dMesCj87zUux77cZ2BJ46YxPzeLCCmpI2fcR4Gvg4mVhBV8rdQgG7iwZDDZZNno3Lr60cVCUo9rqQj2ZXk6g== + dependencies: + ajv "8.12.0" + ajv-formats "2.1.1" + jsonc-parser "3.2.0" + rxjs "7.8.1" + source-map "0.7.4" + +"@angular-devkit/schematics@16.0.5": + version "16.0.5" + resolved "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-16.0.5.tgz" + integrity sha512-6Gjgd+PshVVx7iX1uhMgW6nzltaYEm4v1dwm2FTVGf2m0iIn/Ow2uUTrz/z17naOzc957IzfxxdmtcABEm/p6A== + dependencies: + "@angular-devkit/core" "16.0.5" + jsonc-parser "3.2.0" + magic-string "0.30.0" + ora "5.4.1" + rxjs "7.8.1" + +"@angular/animations@^16.0.0", "@angular/animations@^16.0.0 || ^17.0.0", "@angular/animations@16.0.5": + version "16.0.5" + resolved "https://registry.npmjs.org/@angular/animations/-/animations-16.0.5.tgz" + integrity sha512-qfIOa3Pl+3w/J196ShcHNnAtElQrTcwowoYBf73h5KX7NEsdvUcOJCK6lIdem9FKckVQpf8S+UnGXx99eJXqvg== + dependencies: + tslib "^2.3.0" + +"@angular/cdk@^16.1.1", "@angular/cdk@16.1.1": + version "16.1.1" + resolved "https://registry.npmjs.org/@angular/cdk/-/cdk-16.1.1.tgz" + integrity sha512-nVIeooGspNLT8XySfGZ4e8HYO/TsFemrjNVKb3G9+7KxY4tvE5dkGbJjx5TStEQoSzjfNbCscO89lHIaQ7+aMA== + dependencies: + tslib "^2.3.0" + optionalDependencies: + parse5 "^7.1.2" + +"@angular/cli@~16.0.4": + version "16.0.5" + resolved "https://registry.npmjs.org/@angular/cli/-/cli-16.0.5.tgz" + integrity sha512-ugo0O8Bv5A9ewylOW0h9oeyxbN9om8T+E9yY7gMphlvGFHKHqGPgpHws2Gu3tlAAkJHXpdBndhN0wfKtwHaloQ== + dependencies: + "@angular-devkit/architect" "0.1600.5" + "@angular-devkit/core" "16.0.5" + "@angular-devkit/schematics" "16.0.5" + "@schematics/angular" "16.0.5" + "@yarnpkg/lockfile" "1.1.0" + ansi-colors "4.1.3" + ini "4.0.0" + inquirer "8.2.4" + jsonc-parser "3.2.0" + npm-package-arg "10.1.0" + npm-pick-manifest "8.0.1" + open "8.4.2" + ora "5.4.1" + pacote "15.1.3" + resolve "1.22.2" + semver "7.4.0" + symbol-observable "4.0.0" + yargs "17.7.2" + +"@angular/common@^16.0.0", "@angular/common@^16.0.0 || ^17.0.0", "@angular/common@16.0.5": + version "16.0.5" + resolved "https://registry.npmjs.org/@angular/common/-/common-16.0.5.tgz" + integrity sha512-qCcfuvs6Suqv7uA3MrtIi+aY2KW6F57XnRTzWdU3PLQjv8LHN8SZQee5ce2TQ8yCgAIdiLRGDqmLz+DvmRXiIQ== + dependencies: + tslib "^2.3.0" + +"@angular/compiler-cli@^16.0.0": + version "16.0.5" + resolved "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-16.0.5.tgz" + integrity sha512-AiT7rUX2V6SB18+uCRahGfpFZlyb4dIj63YxQSZIypoA1+AiqrmLVshnaiJhb7ZggZB8PIjJI8waPBbujXBtbg== + dependencies: + "@babel/core" "7.21.8" + "@jridgewell/sourcemap-codec" "^1.4.14" + chokidar "^3.0.0" + convert-source-map "^1.5.1" + reflect-metadata "^0.1.2" + semver "^7.0.0" + tslib "^2.3.0" + yargs "^17.2.1" + +"@angular/compiler@^16.0.0", "@angular/compiler@16.0.5": + version "16.0.5" + resolved "https://registry.npmjs.org/@angular/compiler/-/compiler-16.0.5.tgz" + integrity sha512-AqUqAcK7yQHRGkJF0PD3firTak4jEXvsuDB9+h399AbVUwHcAe46jSp8Cwn6B2mg8sKPCQ65IJRze8DCYv7xOg== + dependencies: + tslib "^2.3.0" + +"@angular/core@^16.0.0", "@angular/core@^16.0.0 || ^17.0.0", "@angular/core@16.0.5": + version "16.0.5" + resolved "https://registry.npmjs.org/@angular/core/-/core-16.0.5.tgz" + integrity sha512-zZYcL10eKkwjR0zIjJzqlyKpu+a0aPQrSdVUDc/ugEEcf80sN/BBEQxC8CNqccbUDFUIk/qPi/2Q9b6U1rKJpA== + dependencies: + tslib "^2.3.0" + +"@angular/forms@^16.0.0", "@angular/forms@^16.0.0 || ^17.0.0": + version "16.0.5" + resolved "https://registry.npmjs.org/@angular/forms/-/forms-16.0.5.tgz" + integrity sha512-D5fSwa/xjrejUcC+WmirP89bKciwlCu9EDcQ83mR8tdtv27sc6Ht67RiCYVR1XSaro0bRxJZ0PeZJi7lqSZwdw== + dependencies: + tslib "^2.3.0" + +"@angular/material@^16.1.1": + version "16.1.1" + resolved "https://registry.npmjs.org/@angular/material/-/material-16.1.1.tgz" + integrity sha512-fVFsxYdCQ9PtDR2Cx6q7XqRFnMKz/OGUaC0pPa/RVuBnUbC+GaapDHd4Suy8NF/skX/xl46rZVEKrRumaWM8FA== + dependencies: + "@material/animation" "15.0.0-canary.90291f2e2.0" + "@material/auto-init" "15.0.0-canary.90291f2e2.0" + "@material/banner" "15.0.0-canary.90291f2e2.0" + "@material/base" "15.0.0-canary.90291f2e2.0" + "@material/button" "15.0.0-canary.90291f2e2.0" + "@material/card" "15.0.0-canary.90291f2e2.0" + "@material/checkbox" "15.0.0-canary.90291f2e2.0" + "@material/chips" "15.0.0-canary.90291f2e2.0" + "@material/circular-progress" "15.0.0-canary.90291f2e2.0" + "@material/data-table" "15.0.0-canary.90291f2e2.0" + "@material/density" "15.0.0-canary.90291f2e2.0" + "@material/dialog" "15.0.0-canary.90291f2e2.0" + "@material/dom" "15.0.0-canary.90291f2e2.0" + "@material/drawer" "15.0.0-canary.90291f2e2.0" + "@material/elevation" "15.0.0-canary.90291f2e2.0" + "@material/fab" "15.0.0-canary.90291f2e2.0" + "@material/feature-targeting" "15.0.0-canary.90291f2e2.0" + "@material/floating-label" "15.0.0-canary.90291f2e2.0" + "@material/form-field" "15.0.0-canary.90291f2e2.0" + "@material/icon-button" "15.0.0-canary.90291f2e2.0" + "@material/image-list" "15.0.0-canary.90291f2e2.0" + "@material/layout-grid" "15.0.0-canary.90291f2e2.0" + "@material/line-ripple" "15.0.0-canary.90291f2e2.0" + "@material/linear-progress" "15.0.0-canary.90291f2e2.0" + "@material/list" "15.0.0-canary.90291f2e2.0" + "@material/menu" "15.0.0-canary.90291f2e2.0" + "@material/menu-surface" "15.0.0-canary.90291f2e2.0" + "@material/notched-outline" "15.0.0-canary.90291f2e2.0" + "@material/radio" "15.0.0-canary.90291f2e2.0" + "@material/ripple" "15.0.0-canary.90291f2e2.0" + "@material/rtl" "15.0.0-canary.90291f2e2.0" + "@material/segmented-button" "15.0.0-canary.90291f2e2.0" + "@material/select" "15.0.0-canary.90291f2e2.0" + "@material/shape" "15.0.0-canary.90291f2e2.0" + "@material/slider" "15.0.0-canary.90291f2e2.0" + "@material/snackbar" "15.0.0-canary.90291f2e2.0" + "@material/switch" "15.0.0-canary.90291f2e2.0" + "@material/tab" "15.0.0-canary.90291f2e2.0" + "@material/tab-bar" "15.0.0-canary.90291f2e2.0" + "@material/tab-indicator" "15.0.0-canary.90291f2e2.0" + "@material/tab-scroller" "15.0.0-canary.90291f2e2.0" + "@material/textfield" "15.0.0-canary.90291f2e2.0" + "@material/theme" "15.0.0-canary.90291f2e2.0" + "@material/tooltip" "15.0.0-canary.90291f2e2.0" + "@material/top-app-bar" "15.0.0-canary.90291f2e2.0" + "@material/touch-target" "15.0.0-canary.90291f2e2.0" + "@material/typography" "15.0.0-canary.90291f2e2.0" + tslib "^2.3.0" + +"@angular/platform-browser-dynamic@^16.0.0": + version "16.0.5" + resolved "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-16.0.5.tgz" + integrity sha512-P119TZJa2JhkVeAgfDeO01pYcIzUHF/kc+JWYi8nIyWsz/ynx5kfIk1wo3GpOaqCb+iieZYLRgwIMRMpQgkxUg== + dependencies: + tslib "^2.3.0" + +"@angular/platform-browser@^16.0.0", "@angular/platform-browser@^16.0.0 || ^17.0.0", "@angular/platform-browser@16.0.5": + version "16.0.5" + resolved "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-16.0.5.tgz" + integrity sha512-2lTUsnrUMSVjkeEfEgDBbLFYYLWQMxxGWiEvXjJvAv/dg4YeRsEDk9TTYSmca4dtXcsa0v1AtvTRHa6lvupDwQ== + dependencies: + tslib "^2.3.0" + +"@angular/router@^16.0.0": + version "16.0.5" + resolved "https://registry.npmjs.org/@angular/router/-/router-16.0.5.tgz" + integrity sha512-wR65acryCchVY+cDHVVyZ/XkVd68PcB9eTKmaCGXI1vhchv75R3RtpMAfWLrnj0WywwAaG8wTJPN6C8UrmMbAQ== + dependencies: + tslib "^2.3.0" + +"@assemblyscript/loader@^0.10.1": + version "0.10.1" + resolved "https://registry.npmjs.org/@assemblyscript/loader/-/loader-0.10.1.tgz" + integrity sha512-H71nDOOL8Y7kWRLqf6Sums+01Q5msqBW2KhDUTemh1tvY04eSkSXrK0uj/4mmY0Xr16/3zyZmsrxN7CKuRbNRg== + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.18.6", "@babel/code-frame@^7.21.4", "@babel/code-frame@^7.22.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz" + integrity sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ== + dependencies: + "@babel/highlight" "^7.22.5" + +"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.20.5", "@babel/compat-data@^7.21.4", "@babel/compat-data@^7.22.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.5.tgz" + integrity sha512-4Jc/YuIaYqKnDDz892kPIledykKg12Aw1PYX5i/TY28anJtacvM1Rrr8wbieB9GfEJwlzqT0hUEao0CxEebiDA== + +"@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.12.0", "@babel/core@^7.12.3", "@babel/core@^7.13.0", "@babel/core@^7.4.0-0", "@babel/core@7.21.4": + version "7.21.4" + resolved "https://registry.npmjs.org/@babel/core/-/core-7.21.4.tgz" + integrity sha512-qt/YV149Jman/6AfmlxJ04LMIu8bMoyl3RB91yTFrxQmgbrSvQMy7cI8Q62FHx1t8wJ8B5fu0UDoLwHAhUo1QA== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.21.4" + "@babel/generator" "^7.21.4" + "@babel/helper-compilation-targets" "^7.21.4" + "@babel/helper-module-transforms" "^7.21.2" + "@babel/helpers" "^7.21.0" + "@babel/parser" "^7.21.4" + "@babel/template" "^7.20.7" + "@babel/traverse" "^7.21.4" + "@babel/types" "^7.21.4" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.2" + semver "^6.3.0" + +"@babel/core@7.21.8": + version "7.21.8" + resolved "https://registry.npmjs.org/@babel/core/-/core-7.21.8.tgz" + integrity sha512-YeM22Sondbo523Sz0+CirSPnbj9bG3P0CdHcBZdqUuaeOaYEFbOLoGU7lebvGP6P5J/WE9wOn7u7C4J9HvS1xQ== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.21.4" + "@babel/generator" "^7.21.5" + "@babel/helper-compilation-targets" "^7.21.5" + "@babel/helper-module-transforms" "^7.21.5" + "@babel/helpers" "^7.21.5" + "@babel/parser" "^7.21.8" + "@babel/template" "^7.20.7" + "@babel/traverse" "^7.21.5" + "@babel/types" "^7.21.5" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.2" + semver "^6.3.0" + +"@babel/generator@^7.21.4", "@babel/generator@7.21.4": + version "7.21.4" + resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.21.4.tgz" + integrity sha512-NieM3pVIYW2SwGzKoqfPrQsf4xGs9M9AIG3ThppsSRmO+m7eQhmI6amajKMUeIO37wFfsvnvcxQFx6x6iqxDnA== + dependencies: + "@babel/types" "^7.21.4" + "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" + jsesc "^2.5.1" + +"@babel/generator@^7.21.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.22.5.tgz" + integrity sha512-+lcUbnTRhd0jOewtFSedLyiPsD5tswKkbgcezOqqWFUVNEwoUTlpPOBmvhG7OXWLR4jMdv0czPGH5XbflnD1EA== + dependencies: + "@babel/types" "^7.22.5" + "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" + jsesc "^2.5.1" + +"@babel/generator@^7.22.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.22.5.tgz" + integrity sha512-+lcUbnTRhd0jOewtFSedLyiPsD5tswKkbgcezOqqWFUVNEwoUTlpPOBmvhG7OXWLR4jMdv0czPGH5XbflnD1EA== + dependencies: + "@babel/types" "^7.22.5" + "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" + jsesc "^2.5.1" + +"@babel/helper-annotate-as-pure@^7.18.6", "@babel/helper-annotate-as-pure@7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz" + integrity sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-annotate-as-pure@^7.22.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz" + integrity sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-builder-binary-assignment-operator-visitor@^7.22.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.5.tgz" + integrity sha512-m1EP3lVOPptR+2DwD125gziZNcmoNSHGmJROKoy87loWUQyJaVXDgpmruWqDARZSmtYQ+Dl25okU8+qhVzuykw== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.20.7", "@babel/helper-compilation-targets@^7.21.4", "@babel/helper-compilation-targets@^7.21.5", "@babel/helper-compilation-targets@^7.22.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.5.tgz" + integrity sha512-Ji+ywpHeuqxB8WDxraCiqR0xfhYjiDE/e6k7FuIaANnoOFxAHskHChz4vA1mJC9Lbm01s1PVAGhQY4FUKSkGZw== + dependencies: + "@babel/compat-data" "^7.22.5" + "@babel/helper-validator-option" "^7.22.5" + browserslist "^4.21.3" + lru-cache "^5.1.1" + semver "^6.3.0" + +"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.21.0": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.5.tgz" + integrity sha512-xkb58MyOYIslxu3gKmVXmjTtUPvBU4odYzbiIQbWwLKIHCsx6UGZGX6F1IznMFVnDdirseUZopzN+ZRt8Xb33Q== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-member-expression-to-functions" "^7.22.5" + "@babel/helper-optimise-call-expression" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.5" + semver "^6.3.0" + +"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.22.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.5.tgz" + integrity sha512-1VpEFOIbMRaXyDeUwUfmTIxExLwQ+zkW+Bh5zXpApA3oQedBx9v/updixWxnx/bZpKw7u8VxWjb/qWpIcmPq8A== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + regexpu-core "^5.3.1" + semver "^6.3.0" + +"@babel/helper-define-polyfill-provider@^0.3.3": + version "0.3.3" + resolved "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz" + integrity sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww== + dependencies: + "@babel/helper-compilation-targets" "^7.17.7" + "@babel/helper-plugin-utils" "^7.16.7" + debug "^4.1.1" + lodash.debounce "^4.0.8" + resolve "^1.14.2" + semver "^6.1.2" + +"@babel/helper-environment-visitor@^7.18.9", "@babel/helper-environment-visitor@^7.22.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz" + integrity sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q== + +"@babel/helper-function-name@^7.22.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz" + integrity sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ== + dependencies: + "@babel/template" "^7.22.5" + "@babel/types" "^7.22.5" + +"@babel/helper-hoist-variables@^7.22.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz" + integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-member-expression-to-functions@^7.22.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.22.5.tgz" + integrity sha512-aBiH1NKMG0H2cGZqspNvsaBe6wNGjbJjuLy29aU+eDZjSbbN53BaxlpB02xm9v34pLTZ1nIQPFYn2qMZoa5BQQ== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-module-imports@^7.18.6", "@babel/helper-module-imports@^7.21.4", "@babel/helper-module-imports@^7.22.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz" + integrity sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-module-transforms@^7.21.2", "@babel/helper-module-transforms@^7.21.5", "@babel/helper-module-transforms@^7.22.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.5.tgz" + integrity sha512-+hGKDt/Ze8GFExiVHno/2dvG5IdstpzCq0y4Qc9OJ25D4q3pKfiIP/4Vp3/JvhDkLKsDK2api3q3fpIgiIF5bw== + dependencies: + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-module-imports" "^7.22.5" + "@babel/helper-simple-access" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.5" + "@babel/template" "^7.22.5" + "@babel/traverse" "^7.22.5" + "@babel/types" "^7.22.5" + +"@babel/helper-optimise-call-expression@^7.22.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz" + integrity sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.18.9", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz" + integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== + +"@babel/helper-remap-async-to-generator@^7.18.9": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.5.tgz" + integrity sha512-cU0Sq1Rf4Z55fgz7haOakIyM7+x/uCFwXpLPaeRzfoUtAEAuUZjZvFPjL/rk5rW693dIgn2hng1W7xbT7lWT4g== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-wrap-function" "^7.22.5" + "@babel/types" "^7.22.5" + +"@babel/helper-replace-supers@^7.22.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.5.tgz" + integrity sha512-aLdNM5I3kdI/V9xGNyKSF3X/gTyMUBohTZ+/3QdQKAA9vxIiy12E+8E2HoOP1/DjeqU+g6as35QHJNMDDYpuCg== + dependencies: + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-member-expression-to-functions" "^7.22.5" + "@babel/helper-optimise-call-expression" "^7.22.5" + "@babel/template" "^7.22.5" + "@babel/traverse" "^7.22.5" + "@babel/types" "^7.22.5" + +"@babel/helper-simple-access@^7.22.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz" + integrity sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-skip-transparent-expression-wrappers@^7.20.0", "@babel/helper-skip-transparent-expression-wrappers@^7.22.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz" + integrity sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-split-export-declaration@^7.22.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.5.tgz" + integrity sha512-thqK5QFghPKWLhAV321lxF95yCg2K3Ob5yw+M3VHWfdia0IkPXUtoLH8x/6Fh486QUvzhb8YOWHChTVen2/PoQ== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-split-export-declaration@7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz" + integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-string-parser@^7.22.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz" + integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw== + +"@babel/helper-validator-identifier@^7.22.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz" + integrity sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ== + +"@babel/helper-validator-option@^7.21.0", "@babel/helper-validator-option@^7.22.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz" + integrity sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw== + +"@babel/helper-wrap-function@^7.22.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.5.tgz" + integrity sha512-bYqLIBSEshYcYQyfks8ewYA8S30yaGSeRslcvKMvoUk6HHPySbxHq9YRi6ghhzEU+yhQv9bP/jXnygkStOcqZw== + dependencies: + "@babel/helper-function-name" "^7.22.5" + "@babel/template" "^7.22.5" + "@babel/traverse" "^7.22.5" + "@babel/types" "^7.22.5" + +"@babel/helpers@^7.21.0", "@babel/helpers@^7.21.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.5.tgz" + integrity sha512-pSXRmfE1vzcUIDFQcSGA5Mr+GxBV9oiRKDuDxXvWQQBCh8HoIjs/2DlDB7H8smac1IVrB9/xdXj2N3Wol9Cr+Q== + dependencies: + "@babel/template" "^7.22.5" + "@babel/traverse" "^7.22.5" + "@babel/types" "^7.22.5" + +"@babel/highlight@^7.22.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz" + integrity sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw== + dependencies: + "@babel/helper-validator-identifier" "^7.22.5" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.21.4", "@babel/parser@^7.21.8", "@babel/parser@^7.22.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.22.5.tgz" + integrity sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q== + +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.5.tgz" + integrity sha512-NP1M5Rf+u2Gw9qfSO4ihjcTGW5zXTi36ITLd4/EoAcEhIZ0yjMqmftDNl3QC19CX7olhrjpyU454g/2W7X0jvQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.20.7": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.22.5.tgz" + integrity sha512-31Bb65aZaUwqCbWMnZPduIZxCBngHFlzyN6Dq6KAJjtx+lx6ohKHubc61OomYi7XwVD4Ol0XCVz4h+pYFR048g== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/plugin-transform-optional-chaining" "^7.22.5" + +"@babel/plugin-proposal-async-generator-functions@^7.20.7", "@babel/plugin-proposal-async-generator-functions@7.20.7": + version "7.20.7" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.7.tgz" + integrity sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA== + dependencies: + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-remap-async-to-generator" "^7.18.9" + "@babel/plugin-syntax-async-generators" "^7.8.4" + +"@babel/plugin-proposal-class-properties@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz" + integrity sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-proposal-class-static-block@^7.21.0": + version "7.21.0" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.21.0.tgz" + integrity sha512-XP5G9MWNUskFuP30IfFSEFB0Z6HzLIUcjYM4bYOPHXl7eiJ9HFv8tWj6TXTN5QODiEhDZAeI4hLok2iHFFV4hw== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.21.0" + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + +"@babel/plugin-proposal-dynamic-import@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz" + integrity sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + +"@babel/plugin-proposal-export-namespace-from@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz" + integrity sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + +"@babel/plugin-proposal-json-strings@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz" + integrity sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-json-strings" "^7.8.3" + +"@babel/plugin-proposal-logical-assignment-operators@^7.20.7": + version "7.20.7" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.20.7.tgz" + integrity sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug== + dependencies: + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + +"@babel/plugin-proposal-nullish-coalescing-operator@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz" + integrity sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + +"@babel/plugin-proposal-numeric-separator@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz" + integrity sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + +"@babel/plugin-proposal-object-rest-spread@^7.20.7": + version "7.20.7" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz" + integrity sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg== + dependencies: + "@babel/compat-data" "^7.20.5" + "@babel/helper-compilation-targets" "^7.20.7" + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.20.7" + +"@babel/plugin-proposal-optional-catch-binding@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz" + integrity sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + +"@babel/plugin-proposal-optional-chaining@^7.21.0": + version "7.21.0" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz" + integrity sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA== + dependencies: + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + +"@babel/plugin-proposal-private-methods@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz" + integrity sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-proposal-private-property-in-object@^7.21.0": + version "7.21.11" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.11.tgz" + integrity sha512-0QZ8qP/3RLDVBwBFoWAwCtgcDZJVwA5LUJRZU8x2YFfKNuFq161wK3cuGrALu5yiPu+vzwTAg/sMWVNeWeNyaw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-create-class-features-plugin" "^7.21.0" + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + +"@babel/plugin-proposal-unicode-property-regex@^7.18.6", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz" + integrity sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-syntax-async-generators@^7.8.4": + 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== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-class-properties@^7.12.13": + 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== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-syntax-class-static-block@^7.14.5": + 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== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-dynamic-import@^7.8.3": + version "7.8.3" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz" + integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-export-namespace-from@^7.8.3": + version "7.8.3" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz" + integrity sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-syntax-import-assertions@^7.20.0": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.22.5.tgz" + integrity sha512-rdV97N7KqsRzeNGoWUOK6yUsWarLjE5Su/Snk9IYPU9CwkWHs4t+rTGOvffTR8XGkJMTAdLfO0xVnXm8wugIJg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-syntax-json-strings@^7.8.3": + 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== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-logical-assignment-operators@^7.10.4": + 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== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": + 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== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-numeric-separator@^7.10.4": + 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== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-object-rest-spread@^7.8.3": + 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== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.8.3": + 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== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-chaining@^7.8.3": + 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== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-private-property-in-object@^7.14.5": + 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== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-top-level-await@^7.14.5": + 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== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-arrow-functions@^7.20.7": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.22.5.tgz" + integrity sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-async-to-generator@^7.20.7", "@babel/plugin-transform-async-to-generator@7.20.7": + version "7.20.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.20.7.tgz" + integrity sha512-Uo5gwHPT9vgnSXQxqGtpdufUiWp96gk7yiP4Mp5bm1QMkEmLXBO7PAGYbKoJ6DhAwiNkcHFBol/x5zZZkL/t0Q== + dependencies: + "@babel/helper-module-imports" "^7.18.6" + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-remap-async-to-generator" "^7.18.9" + +"@babel/plugin-transform-block-scoped-functions@^7.18.6": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.22.5.tgz" + integrity sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-block-scoping@^7.21.0": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.22.5.tgz" + integrity sha512-EcACl1i5fSQ6bt+YGuU/XGCeZKStLmyVGytWkpyhCLeQVA0eu6Wtiw92V+I1T/hnezUv7j74dA/Ro69gWcU+hg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-classes@^7.21.0": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.22.5.tgz" + integrity sha512-2edQhLfibpWpsVBx2n/GKOz6JdGQvLruZQfGr9l1qes2KQaWswjBzhQF7UDUZMNaMMQeYnQzxwOMPsbYF7wqPQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-compilation-targets" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-optimise-call-expression" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.5" + globals "^11.1.0" + +"@babel/plugin-transform-computed-properties@^7.20.7": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.22.5.tgz" + integrity sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/template" "^7.22.5" + +"@babel/plugin-transform-destructuring@^7.21.3": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.22.5.tgz" + integrity sha512-GfqcFuGW8vnEqTUBM7UtPd5A4q797LTvvwKxXTgRsFjoqaJiEg9deBG6kWeQYkVEL569NpnmpC0Pkr/8BLKGnQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-dotall-regex@^7.18.6", "@babel/plugin-transform-dotall-regex@^7.4.4": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.22.5.tgz" + integrity sha512-5/Yk9QxCQCl+sOIB1WelKnVRxTJDSAIxtJLL2/pqL14ZVlbH0fUQUZa/T5/UnQtBNgghR7mfB8ERBKyKPCi7Vw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-duplicate-keys@^7.18.9": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.22.5.tgz" + integrity sha512-dEnYD+9BBgld5VBXHnF/DbYGp3fqGMsyxKbtD1mDyIA7AkTSpKXFhCVuj/oQVOoALfBs77DudA0BE4d5mcpmqw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-exponentiation-operator@^7.18.6": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.22.5.tgz" + integrity sha512-vIpJFNM/FjZ4rh1myqIya9jXwrwwgFRHPjT3DkUA9ZLHuzox8jiXkOLvwm1H+PQIP3CqfC++WPKeuDi0Sjdj1g== + dependencies: + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-for-of@^7.21.0": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.22.5.tgz" + integrity sha512-3kxQjX1dU9uudwSshyLeEipvrLjBCVthCgeTp6CzE/9JYrlAIaeekVxRpCWsDDfYTfRZRoCeZatCQvwo+wvK8A== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-function-name@^7.18.9": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.22.5.tgz" + integrity sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg== + dependencies: + "@babel/helper-compilation-targets" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-literals@^7.18.9": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.22.5.tgz" + integrity sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-member-expression-literals@^7.18.6": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.22.5.tgz" + integrity sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-modules-amd@^7.20.11": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.22.5.tgz" + integrity sha512-R+PTfLTcYEmb1+kK7FNkhQ1gP4KgjpSO6HfH9+f8/yfp2Nt3ggBjiVpRwmwTlfqZLafYKJACy36yDXlEmI9HjQ== + dependencies: + "@babel/helper-module-transforms" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-modules-commonjs@^7.21.2": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.5.tgz" + integrity sha512-B4pzOXj+ONRmuaQTg05b3y/4DuFz3WcCNAXPLb2Q0GT0TrGKGxNKV4jwsXts+StaM0LQczZbOpj8o1DLPDJIiA== + dependencies: + "@babel/helper-module-transforms" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-simple-access" "^7.22.5" + +"@babel/plugin-transform-modules-systemjs@^7.20.11": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.22.5.tgz" + integrity sha512-emtEpoaTMsOs6Tzz+nbmcePl6AKVtS1yC4YNAeMun9U8YCsgadPNxnOPQ8GhHFB2qdx+LZu9LgoC0Lthuu05DQ== + dependencies: + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-module-transforms" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.5" + +"@babel/plugin-transform-modules-umd@^7.18.6": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.22.5.tgz" + integrity sha512-+S6kzefN/E1vkSsKx8kmQuqeQsvCKCd1fraCM7zXm4SFoggI099Tr4G8U81+5gtMdUeMQ4ipdQffbKLX0/7dBQ== + dependencies: + "@babel/helper-module-transforms" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-named-capturing-groups-regex@^7.20.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz" + integrity sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-new-target@^7.18.6": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.22.5.tgz" + integrity sha512-AsF7K0Fx/cNKVyk3a+DW0JLo+Ua598/NxMRvxDnkpCIGFh43+h/v2xyhRUYf6oD8gE4QtL83C7zZVghMjHd+iw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-object-super@^7.18.6": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.22.5.tgz" + integrity sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.5" + +"@babel/plugin-transform-optional-chaining@^7.22.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.22.5.tgz" + integrity sha512-AconbMKOMkyG+xCng2JogMCDcqW8wedQAqpVIL4cOSescZ7+iW8utC6YDZLMCSUIReEA733gzRSaOSXMAt/4WQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + +"@babel/plugin-transform-parameters@^7.20.7", "@babel/plugin-transform-parameters@^7.21.3": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.22.5.tgz" + integrity sha512-AVkFUBurORBREOmHRKo06FjHYgjrabpdqRSwq6+C7R5iTCZOsM4QbcB27St0a4U6fffyAOqh3s/qEfybAhfivg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-property-literals@^7.18.6": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.22.5.tgz" + integrity sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-regenerator@^7.20.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.22.5.tgz" + integrity sha512-rR7KePOE7gfEtNTh9Qw+iO3Q/e4DEsoQ+hdvM6QUDH7JRJ5qxq5AA52ZzBWbI5i9lfNuvySgOGP8ZN7LAmaiPw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + regenerator-transform "^0.15.1" + +"@babel/plugin-transform-reserved-words@^7.18.6": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.22.5.tgz" + integrity sha512-DTtGKFRQUDm8svigJzZHzb/2xatPc6TzNvAIJ5GqOKDsGFYgAskjRulbR/vGsPKq3OPqtexnz327qYpP57RFyA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-runtime@7.21.4": + version "7.21.4" + resolved "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.21.4.tgz" + integrity sha512-1J4dhrw1h1PqnNNpzwxQ2UBymJUF8KuPjAAnlLwZcGhHAIqUigFW7cdK6GHoB64ubY4qXQNYknoUeks4Wz7CUA== + dependencies: + "@babel/helper-module-imports" "^7.21.4" + "@babel/helper-plugin-utils" "^7.20.2" + babel-plugin-polyfill-corejs2 "^0.3.3" + babel-plugin-polyfill-corejs3 "^0.6.0" + babel-plugin-polyfill-regenerator "^0.4.1" + semver "^6.3.0" + +"@babel/plugin-transform-shorthand-properties@^7.18.6": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.22.5.tgz" + integrity sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-spread@^7.20.7": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.22.5.tgz" + integrity sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + +"@babel/plugin-transform-sticky-regex@^7.18.6": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.22.5.tgz" + integrity sha512-zf7LuNpHG0iEeiyCNwX4j3gDg1jgt1k3ZdXBKbZSoA3BbGQGvMiSvfbZRR3Dr3aeJe3ooWFZxOOG3IRStYp2Bw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-template-literals@^7.18.9": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.22.5.tgz" + integrity sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-typeof-symbol@^7.18.9": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.22.5.tgz" + integrity sha512-bYkI5lMzL4kPii4HHEEChkD0rkc+nvnlR6+o/qdqR6zrm0Sv/nodmyLhlq2DO0YKLUNd2VePmPRjJXSBh9OIdA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-unicode-escapes@^7.18.10": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.22.5.tgz" + integrity sha512-biEmVg1IYB/raUO5wT1tgfacCef15Fbzhkx493D3urBI++6hpJ+RFG4SrWMn0NEZLfvilqKf3QDrRVZHo08FYg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-unicode-regex@^7.18.6": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.22.5.tgz" + integrity sha512-028laaOKptN5vHJf9/Arr/HiJekMd41hOEZYvNsrsXqJ7YPYuX2bQxh31fkZzGmq3YqHRJzYFFAVYvKfMPKqyg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/preset-env@7.21.4": + version "7.21.4" + resolved "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.21.4.tgz" + integrity sha512-2W57zHs2yDLm6GD5ZpvNn71lZ0B/iypSdIeq25OurDKji6AdzV07qp4s3n1/x5BqtiGaTrPN3nerlSCaC5qNTw== + dependencies: + "@babel/compat-data" "^7.21.4" + "@babel/helper-compilation-targets" "^7.21.4" + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-validator-option" "^7.21.0" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.18.6" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.20.7" + "@babel/plugin-proposal-async-generator-functions" "^7.20.7" + "@babel/plugin-proposal-class-properties" "^7.18.6" + "@babel/plugin-proposal-class-static-block" "^7.21.0" + "@babel/plugin-proposal-dynamic-import" "^7.18.6" + "@babel/plugin-proposal-export-namespace-from" "^7.18.9" + "@babel/plugin-proposal-json-strings" "^7.18.6" + "@babel/plugin-proposal-logical-assignment-operators" "^7.20.7" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.18.6" + "@babel/plugin-proposal-numeric-separator" "^7.18.6" + "@babel/plugin-proposal-object-rest-spread" "^7.20.7" + "@babel/plugin-proposal-optional-catch-binding" "^7.18.6" + "@babel/plugin-proposal-optional-chaining" "^7.21.0" + "@babel/plugin-proposal-private-methods" "^7.18.6" + "@babel/plugin-proposal-private-property-in-object" "^7.21.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.18.6" + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-class-properties" "^7.12.13" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + "@babel/plugin-syntax-import-assertions" "^7.20.0" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + "@babel/plugin-syntax-top-level-await" "^7.14.5" + "@babel/plugin-transform-arrow-functions" "^7.20.7" + "@babel/plugin-transform-async-to-generator" "^7.20.7" + "@babel/plugin-transform-block-scoped-functions" "^7.18.6" + "@babel/plugin-transform-block-scoping" "^7.21.0" + "@babel/plugin-transform-classes" "^7.21.0" + "@babel/plugin-transform-computed-properties" "^7.20.7" + "@babel/plugin-transform-destructuring" "^7.21.3" + "@babel/plugin-transform-dotall-regex" "^7.18.6" + "@babel/plugin-transform-duplicate-keys" "^7.18.9" + "@babel/plugin-transform-exponentiation-operator" "^7.18.6" + "@babel/plugin-transform-for-of" "^7.21.0" + "@babel/plugin-transform-function-name" "^7.18.9" + "@babel/plugin-transform-literals" "^7.18.9" + "@babel/plugin-transform-member-expression-literals" "^7.18.6" + "@babel/plugin-transform-modules-amd" "^7.20.11" + "@babel/plugin-transform-modules-commonjs" "^7.21.2" + "@babel/plugin-transform-modules-systemjs" "^7.20.11" + "@babel/plugin-transform-modules-umd" "^7.18.6" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.20.5" + "@babel/plugin-transform-new-target" "^7.18.6" + "@babel/plugin-transform-object-super" "^7.18.6" + "@babel/plugin-transform-parameters" "^7.21.3" + "@babel/plugin-transform-property-literals" "^7.18.6" + "@babel/plugin-transform-regenerator" "^7.20.5" + "@babel/plugin-transform-reserved-words" "^7.18.6" + "@babel/plugin-transform-shorthand-properties" "^7.18.6" + "@babel/plugin-transform-spread" "^7.20.7" + "@babel/plugin-transform-sticky-regex" "^7.18.6" + "@babel/plugin-transform-template-literals" "^7.18.9" + "@babel/plugin-transform-typeof-symbol" "^7.18.9" + "@babel/plugin-transform-unicode-escapes" "^7.18.10" + "@babel/plugin-transform-unicode-regex" "^7.18.6" + "@babel/preset-modules" "^0.1.5" + "@babel/types" "^7.21.4" + babel-plugin-polyfill-corejs2 "^0.3.3" + babel-plugin-polyfill-corejs3 "^0.6.0" + babel-plugin-polyfill-regenerator "^0.4.1" + core-js-compat "^3.25.1" + semver "^6.3.0" + +"@babel/preset-modules@^0.1.5": + version "0.1.5" + resolved "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz" + integrity sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" + "@babel/plugin-transform-dotall-regex" "^7.4.4" + "@babel/types" "^7.4.4" + esutils "^2.0.2" + +"@babel/regjsgen@^0.8.0": + version "0.8.0" + resolved "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz" + integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== + +"@babel/runtime@^7.8.4", "@babel/runtime@7.21.0": + version "7.21.0" + resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.0.tgz" + integrity sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw== + dependencies: + regenerator-runtime "^0.13.11" + +"@babel/template@^7.20.7", "@babel/template@7.20.7": + version "7.20.7" + resolved "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz" + integrity sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/parser" "^7.20.7" + "@babel/types" "^7.20.7" + +"@babel/template@^7.22.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz" + integrity sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw== + dependencies: + "@babel/code-frame" "^7.22.5" + "@babel/parser" "^7.22.5" + "@babel/types" "^7.22.5" + +"@babel/traverse@^7.21.4", "@babel/traverse@^7.21.5", "@babel/traverse@^7.22.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.5.tgz" + integrity sha512-7DuIjPgERaNo6r+PZwItpjCZEa5vyw4eJGufeLxrPdBXBoLcCJCIasvK6pK/9DVNrLZTLFhUGqaC6X/PA007TQ== + dependencies: + "@babel/code-frame" "^7.22.5" + "@babel/generator" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.5" + "@babel/parser" "^7.22.5" + "@babel/types" "^7.22.5" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/types@^7.18.6", "@babel/types@^7.20.7", "@babel/types@^7.21.4", "@babel/types@^7.21.5", "@babel/types@^7.22.5", "@babel/types@^7.4.4": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/types/-/types-7.22.5.tgz" + integrity sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA== + dependencies: + "@babel/helper-string-parser" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.5" + to-fast-properties "^2.0.0" + +"@colors/colors@1.5.0": + version "1.5.0" + resolved "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz" + integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== + +"@cspotcode/source-map-support@^0.8.0": + 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== + dependencies: + "@jridgewell/trace-mapping" "0.3.9" + +"@discoveryjs/json-ext@0.5.7": + version "0.5.7" + resolved "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz" + integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== + +"@esbuild/win32-x64@0.17.18": + version "0.17.18" + resolved "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.18.tgz" + integrity sha512-qU25Ma1I3NqTSHJUOKi9sAH1/Mzuvlke0ioMJRthLXKm7JiSKVwFghlGbDLOO2sARECGhja4xYfRAZNPAkooYg== + +"@fortawesome/angular-fontawesome@^0.13.0": + version "0.13.0" + resolved "https://registry.npmjs.org/@fortawesome/angular-fontawesome/-/angular-fontawesome-0.13.0.tgz" + integrity sha512-gzSPRdveOXNO7NIiMgTyB46aiHG0i98KinnAEqHXi8qzraM/kCcHn/0y3f4MhemX6kftwsFli0IU8RyHmtXlSQ== + dependencies: + tslib "^2.4.1" + +"@fortawesome/fontawesome-common-types@6.4.0": + version "6.4.0" + resolved "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.4.0.tgz" + integrity sha512-HNii132xfomg5QVZw0HwXXpN22s7VBHQBv9CeOu9tfJnhsWQNd2lmTNi8CSrnw5B+5YOmzu1UoPAyxaXsJ6RgQ== + +"@fortawesome/fontawesome-svg-core@^6.4.0", "@fortawesome/fontawesome-svg-core@~1.2.27 || ~1.3.0-beta2 || ^6.1.0": + version "6.4.0" + resolved "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.4.0.tgz" + integrity sha512-Bertv8xOiVELz5raB2FlXDPKt+m94MQ3JgDfsVbrqNpLU9+UE2E18GKjLKw+d3XbeYPqg1pzyQKGsrzbw+pPaw== + dependencies: + "@fortawesome/fontawesome-common-types" "6.4.0" + +"@fortawesome/free-regular-svg-icons@^6.4.0": + version "6.4.0" + resolved "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.4.0.tgz" + integrity sha512-ZfycI7D0KWPZtf7wtMFnQxs8qjBXArRzczABuMQqecA/nXohquJ5J/RCR77PmY5qGWkxAZDxpnUFVXKwtY/jPw== + dependencies: + "@fortawesome/fontawesome-common-types" "6.4.0" + +"@fortawesome/free-solid-svg-icons@^6.4.0": + version "6.4.0" + resolved "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.4.0.tgz" + integrity sha512-kutPeRGWm8V5dltFP1zGjQOEAzaLZj4StdQhWVZnfGFCvAPVvHh8qk5bRrU4KXnRRRNni5tKQI9PBAdI6MP8nQ== + dependencies: + "@fortawesome/fontawesome-common-types" "6.4.0" + +"@gar/promisify@^1.1.3": + version "1.1.3" + resolved "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz" + integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw== + +"@isaacs/cliui@^8.0.2": + version "8.0.2" + resolved "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz" + integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== + dependencies: + string-width "^5.1.2" + string-width-cjs "npm:string-width@^4.2.0" + strip-ansi "^7.0.1" + strip-ansi-cjs "npm:strip-ansi@^6.0.1" + wrap-ansi "^8.1.0" + wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" + +"@istanbuljs/load-nyc-config@^1.0.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz" + integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== + 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" + +"@istanbuljs/schema@^0.1.2": + version "0.1.3" + resolved "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz" + integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== + +"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": + version "0.3.3" + resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz" + integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/resolve-uri@^3.0.3", "@jridgewell/resolve-uri@3.1.0": + version "3.1.0" + resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz" + integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== + +"@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + +"@jridgewell/source-map@^0.3.2": + version "0.3.3" + resolved "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.3.tgz" + integrity sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.13", "@jridgewell/sourcemap-codec@^1.4.14": + version "1.4.15" + resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== + +"@jridgewell/sourcemap-codec@1.4.14": + version "1.4.14" + resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz" + integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== + +"@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.18" + resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz" + integrity sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA== + dependencies: + "@jridgewell/resolve-uri" "3.1.0" + "@jridgewell/sourcemap-codec" "1.4.14" + +"@jridgewell/trace-mapping@0.3.9": + version "0.3.9" + resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz" + integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + +"@kurkle/color@^0.3.0": + version "0.3.2" + resolved "https://registry.npmjs.org/@kurkle/color/-/color-0.3.2.tgz" + integrity sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw== + +"@leichtgewicht/ip-codec@^2.0.1": + version "2.0.4" + resolved "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz" + integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== + +"@material/animation@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/animation/-/animation-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-tr1y4KYZ2Ml9lFU9b91r5jivDCbh0N3Zv6VFe0frphztlZO5Lqx7MCxsliQ7NwQjqpXg3MkD6ZusVNvnMyo+LA== + dependencies: + tslib "^2.1.0" + +"@material/auto-init@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/auto-init/-/auto-init-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-ZslBlje2LajaL5d7JCxUoWCKOBOsZYT33CamqPoDeY0Cjl77t3O+8B9YPHF8libytI8j9lrrDrTItQr53PHeHw== + dependencies: + "@material/base" "15.0.0-canary.90291f2e2.0" + tslib "^2.1.0" + +"@material/banner@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/banner/-/banner-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-mVtGop9rBXRD6UYkMD7y+OJwd3MA73w7BJ/oJIKFij2q2fn/5hZba6vQ6d6YGUGv+iJPP/S/HaiMQuRE5yyoqA== + dependencies: + "@material/base" "15.0.0-canary.90291f2e2.0" + "@material/button" "15.0.0-canary.90291f2e2.0" + "@material/dom" "15.0.0-canary.90291f2e2.0" + "@material/elevation" "15.0.0-canary.90291f2e2.0" + "@material/feature-targeting" "15.0.0-canary.90291f2e2.0" + "@material/ripple" "15.0.0-canary.90291f2e2.0" + "@material/rtl" "15.0.0-canary.90291f2e2.0" + "@material/shape" "15.0.0-canary.90291f2e2.0" + "@material/theme" "15.0.0-canary.90291f2e2.0" + "@material/tokens" "15.0.0-canary.90291f2e2.0" + "@material/typography" "15.0.0-canary.90291f2e2.0" + tslib "^2.1.0" + +"@material/base@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/base/-/base-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-DNelmohDScmGvWWS/J05dkIJb/dKOVkA6s0URgPrnTFKXNSavPsmwj7hWzYB5kusz3ZrXJBYBJsE6VqkRRXl0w== + dependencies: + tslib "^2.1.0" + +"@material/button@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/button/-/button-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-m3YqCh33kcPGYehCKviDy7RxQIEM2m8Exo6AswPPsxd95jSN3rAeF+pXopoXW5QTOqyKHqHymTKTRYYvwvZHYg== + dependencies: + "@material/density" "15.0.0-canary.90291f2e2.0" + "@material/dom" "15.0.0-canary.90291f2e2.0" + "@material/elevation" "15.0.0-canary.90291f2e2.0" + "@material/feature-targeting" "15.0.0-canary.90291f2e2.0" + "@material/focus-ring" "15.0.0-canary.90291f2e2.0" + "@material/ripple" "15.0.0-canary.90291f2e2.0" + "@material/rtl" "15.0.0-canary.90291f2e2.0" + "@material/shape" "15.0.0-canary.90291f2e2.0" + "@material/theme" "15.0.0-canary.90291f2e2.0" + "@material/tokens" "15.0.0-canary.90291f2e2.0" + "@material/touch-target" "15.0.0-canary.90291f2e2.0" + "@material/typography" "15.0.0-canary.90291f2e2.0" + tslib "^2.1.0" + +"@material/card@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/card/-/card-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-8Z8KQDmEIwt5IK0n+9C9Be9p4mWLKBXILbH+c6XcMCTemmUxH6cTTax1MwuAmqBGuIq3WE3g7qDpdzjFLTC2kw== + dependencies: + "@material/dom" "15.0.0-canary.90291f2e2.0" + "@material/elevation" "15.0.0-canary.90291f2e2.0" + "@material/feature-targeting" "15.0.0-canary.90291f2e2.0" + "@material/ripple" "15.0.0-canary.90291f2e2.0" + "@material/rtl" "15.0.0-canary.90291f2e2.0" + "@material/shape" "15.0.0-canary.90291f2e2.0" + "@material/theme" "15.0.0-canary.90291f2e2.0" + "@material/tokens" "15.0.0-canary.90291f2e2.0" + tslib "^2.1.0" + +"@material/checkbox@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/checkbox/-/checkbox-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-hCilHX0vLedMgeRSOskf+JjdfLIUvEg597LEkTJHnTtJkhwypvol8OwP3eqz3TyJ3qGimIi/sFPKdMBn1Uk4AQ== + dependencies: + "@material/animation" "15.0.0-canary.90291f2e2.0" + "@material/base" "15.0.0-canary.90291f2e2.0" + "@material/density" "15.0.0-canary.90291f2e2.0" + "@material/dom" "15.0.0-canary.90291f2e2.0" + "@material/feature-targeting" "15.0.0-canary.90291f2e2.0" + "@material/focus-ring" "15.0.0-canary.90291f2e2.0" + "@material/ripple" "15.0.0-canary.90291f2e2.0" + "@material/rtl" "15.0.0-canary.90291f2e2.0" + "@material/theme" "15.0.0-canary.90291f2e2.0" + "@material/touch-target" "15.0.0-canary.90291f2e2.0" + tslib "^2.1.0" + +"@material/chips@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/chips/-/chips-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-TMtlzuadWP/YMRYg8mpqmaD9M9GzRL5ulHHgYO5F4kaZmI3L+3zvaPvUme/x5qwPkIJUO9S21NxxGAsp9X+ZJQ== + dependencies: + "@material/animation" "15.0.0-canary.90291f2e2.0" + "@material/base" "15.0.0-canary.90291f2e2.0" + "@material/checkbox" "15.0.0-canary.90291f2e2.0" + "@material/density" "15.0.0-canary.90291f2e2.0" + "@material/dom" "15.0.0-canary.90291f2e2.0" + "@material/elevation" "15.0.0-canary.90291f2e2.0" + "@material/feature-targeting" "15.0.0-canary.90291f2e2.0" + "@material/focus-ring" "15.0.0-canary.90291f2e2.0" + "@material/ripple" "15.0.0-canary.90291f2e2.0" + "@material/rtl" "15.0.0-canary.90291f2e2.0" + "@material/shape" "15.0.0-canary.90291f2e2.0" + "@material/theme" "15.0.0-canary.90291f2e2.0" + "@material/tokens" "15.0.0-canary.90291f2e2.0" + "@material/touch-target" "15.0.0-canary.90291f2e2.0" + "@material/typography" "15.0.0-canary.90291f2e2.0" + safevalues "^0.3.4" + tslib "^2.1.0" + +"@material/circular-progress@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/circular-progress/-/circular-progress-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-znCz3cXC8rmC+1k1ZEeZNOhngm7O7kVG2PoANaE79NN9taDtCTyBGGeocJ4Kza3tb01vxJ2/tuQXC39GNFkHFg== + dependencies: + "@material/animation" "15.0.0-canary.90291f2e2.0" + "@material/base" "15.0.0-canary.90291f2e2.0" + "@material/dom" "15.0.0-canary.90291f2e2.0" + "@material/feature-targeting" "15.0.0-canary.90291f2e2.0" + "@material/progress-indicator" "15.0.0-canary.90291f2e2.0" + "@material/rtl" "15.0.0-canary.90291f2e2.0" + "@material/theme" "15.0.0-canary.90291f2e2.0" + tslib "^2.1.0" + +"@material/data-table@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/data-table/-/data-table-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-9YU6KkOeKs2ARPXZdg7Cv6nPwLkEyBIN331ZB92apcbQpTMJMhR3uuW8SSw4p7aXCE6CJjREsCc0KuYAnFSa2A== + dependencies: + "@material/animation" "15.0.0-canary.90291f2e2.0" + "@material/base" "15.0.0-canary.90291f2e2.0" + "@material/checkbox" "15.0.0-canary.90291f2e2.0" + "@material/density" "15.0.0-canary.90291f2e2.0" + "@material/dom" "15.0.0-canary.90291f2e2.0" + "@material/elevation" "15.0.0-canary.90291f2e2.0" + "@material/feature-targeting" "15.0.0-canary.90291f2e2.0" + "@material/icon-button" "15.0.0-canary.90291f2e2.0" + "@material/linear-progress" "15.0.0-canary.90291f2e2.0" + "@material/list" "15.0.0-canary.90291f2e2.0" + "@material/menu" "15.0.0-canary.90291f2e2.0" + "@material/rtl" "15.0.0-canary.90291f2e2.0" + "@material/select" "15.0.0-canary.90291f2e2.0" + "@material/shape" "15.0.0-canary.90291f2e2.0" + "@material/theme" "15.0.0-canary.90291f2e2.0" + "@material/tokens" "15.0.0-canary.90291f2e2.0" + "@material/touch-target" "15.0.0-canary.90291f2e2.0" + "@material/typography" "15.0.0-canary.90291f2e2.0" + tslib "^2.1.0" + +"@material/density@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/density/-/density-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-z2L49vc5tbIGe7tUHwbmzoPvOugsTNVP24WWwBwtg9PRuK4Td5HIsMGYqSzSuwFJvDWQK9Ugvl37jGZSv4vxog== + dependencies: + tslib "^2.1.0" + +"@material/dialog@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/dialog/-/dialog-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-n0o4MELpVqJHbJDPBYeXf3xeL9a8hbzHmfXYLDI1MUhDIr4xgSkckKdCRc2IFda/g7kxjAgcUTga9EFWqns2qA== + dependencies: + "@material/animation" "15.0.0-canary.90291f2e2.0" + "@material/base" "15.0.0-canary.90291f2e2.0" + "@material/button" "15.0.0-canary.90291f2e2.0" + "@material/dom" "15.0.0-canary.90291f2e2.0" + "@material/elevation" "15.0.0-canary.90291f2e2.0" + "@material/feature-targeting" "15.0.0-canary.90291f2e2.0" + "@material/icon-button" "15.0.0-canary.90291f2e2.0" + "@material/ripple" "15.0.0-canary.90291f2e2.0" + "@material/rtl" "15.0.0-canary.90291f2e2.0" + "@material/shape" "15.0.0-canary.90291f2e2.0" + "@material/theme" "15.0.0-canary.90291f2e2.0" + "@material/tokens" "15.0.0-canary.90291f2e2.0" + "@material/touch-target" "15.0.0-canary.90291f2e2.0" + "@material/typography" "15.0.0-canary.90291f2e2.0" + tslib "^2.1.0" + +"@material/dom@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/dom/-/dom-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-90JKk/Ncnqn2dKopNxs1uruiiQZzgLTZQF3a8jxa/w3RQd3Ac9ET1KqmaJSfzXaxgebm+1RZfL9lL+ANEfLWwQ== + dependencies: + "@material/feature-targeting" "15.0.0-canary.90291f2e2.0" + "@material/rtl" "15.0.0-canary.90291f2e2.0" + tslib "^2.1.0" + +"@material/drawer@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/drawer/-/drawer-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-7MJbjUxqpQG9J52xWGVKRhSI/0/7Uhf7l2P9VI2WFb5Fz0IeUupXlw2k1Ktb97nxSjMe9OazjtVUgzBNwOad/Q== + dependencies: + "@material/animation" "15.0.0-canary.90291f2e2.0" + "@material/base" "15.0.0-canary.90291f2e2.0" + "@material/dom" "15.0.0-canary.90291f2e2.0" + "@material/elevation" "15.0.0-canary.90291f2e2.0" + "@material/feature-targeting" "15.0.0-canary.90291f2e2.0" + "@material/list" "15.0.0-canary.90291f2e2.0" + "@material/ripple" "15.0.0-canary.90291f2e2.0" + "@material/rtl" "15.0.0-canary.90291f2e2.0" + "@material/shape" "15.0.0-canary.90291f2e2.0" + "@material/theme" "15.0.0-canary.90291f2e2.0" + "@material/typography" "15.0.0-canary.90291f2e2.0" + tslib "^2.1.0" + +"@material/elevation@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/elevation/-/elevation-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-4eYbCDc6IfgfguNmRc5GT4QMCfOEwj+K3BAraABcbpuCzEQ5nCClsVrPbRLfPnhWbQrFc2/eBglB8wsrNTjVBw== + dependencies: + "@material/animation" "15.0.0-canary.90291f2e2.0" + "@material/base" "15.0.0-canary.90291f2e2.0" + "@material/feature-targeting" "15.0.0-canary.90291f2e2.0" + "@material/rtl" "15.0.0-canary.90291f2e2.0" + "@material/theme" "15.0.0-canary.90291f2e2.0" + tslib "^2.1.0" + +"@material/fab@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/fab/-/fab-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-YJuJRdqe57DnJ4qyc04flknuGeN+7Nc9ciFZE6snPn84wD6J1khscb21yRARbALDki18kbfnJNrNbzHkYaEMZg== + dependencies: + "@material/animation" "15.0.0-canary.90291f2e2.0" + "@material/dom" "15.0.0-canary.90291f2e2.0" + "@material/elevation" "15.0.0-canary.90291f2e2.0" + "@material/feature-targeting" "15.0.0-canary.90291f2e2.0" + "@material/focus-ring" "15.0.0-canary.90291f2e2.0" + "@material/ripple" "15.0.0-canary.90291f2e2.0" + "@material/rtl" "15.0.0-canary.90291f2e2.0" + "@material/shape" "15.0.0-canary.90291f2e2.0" + "@material/theme" "15.0.0-canary.90291f2e2.0" + "@material/tokens" "15.0.0-canary.90291f2e2.0" + "@material/touch-target" "15.0.0-canary.90291f2e2.0" + "@material/typography" "15.0.0-canary.90291f2e2.0" + tslib "^2.1.0" + +"@material/feature-targeting@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/feature-targeting/-/feature-targeting-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-mjUemPnMLXPooDcPHxxc2uhVUzm7X3NDsE0x0QJnsHDwuejakaRLghVcRDX3x1VmL/p52Eu5HrgW2FryFEiVhQ== + dependencies: + tslib "^2.1.0" + +"@material/floating-label@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/floating-label/-/floating-label-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-dYtgNlXkO0H9Vn76oESZZg1KOa2XIOLhVxhV/qPYrhntET534i7TyajmVk54ncuSSoLPZrbrwrhhR2fUJWxZIg== + dependencies: + "@material/animation" "15.0.0-canary.90291f2e2.0" + "@material/base" "15.0.0-canary.90291f2e2.0" + "@material/dom" "15.0.0-canary.90291f2e2.0" + "@material/feature-targeting" "15.0.0-canary.90291f2e2.0" + "@material/rtl" "15.0.0-canary.90291f2e2.0" + "@material/theme" "15.0.0-canary.90291f2e2.0" + "@material/typography" "15.0.0-canary.90291f2e2.0" + tslib "^2.1.0" + +"@material/focus-ring@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/focus-ring/-/focus-ring-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-U7ERDgHi33ZRmqsiO6syFaWsCUGneltX2sYVtLpQnxME7pKFzi22GdUUIslhgHOFjSMBFF9av2Y79VFbyj9BaQ== + dependencies: + "@material/dom" "15.0.0-canary.90291f2e2.0" + "@material/feature-targeting" "15.0.0-canary.90291f2e2.0" + "@material/rtl" "15.0.0-canary.90291f2e2.0" + +"@material/form-field@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/form-field/-/form-field-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-KTj+EOobLcPUYy4nR+t0c2Cjvs7jCI4F1w8XuV0bbmSa6Sxh02tMKY2Xa7Lx55A/uUrsUfViMdP60OLzi7HgjQ== + dependencies: + "@material/base" "15.0.0-canary.90291f2e2.0" + "@material/feature-targeting" "15.0.0-canary.90291f2e2.0" + "@material/ripple" "15.0.0-canary.90291f2e2.0" + "@material/rtl" "15.0.0-canary.90291f2e2.0" + "@material/theme" "15.0.0-canary.90291f2e2.0" + "@material/typography" "15.0.0-canary.90291f2e2.0" + tslib "^2.1.0" + +"@material/icon-button@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/icon-button/-/icon-button-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-bpqiVPkf/LJEP7iIV5VL9Th0chCIQKTeOuw0mK8HmYucuvqq+k76oPsUcE7mvxRvuKyVh6KJ9fTHAkjse0y7cg== + dependencies: + "@material/base" "15.0.0-canary.90291f2e2.0" + "@material/density" "15.0.0-canary.90291f2e2.0" + "@material/dom" "15.0.0-canary.90291f2e2.0" + "@material/elevation" "15.0.0-canary.90291f2e2.0" + "@material/feature-targeting" "15.0.0-canary.90291f2e2.0" + "@material/focus-ring" "15.0.0-canary.90291f2e2.0" + "@material/ripple" "15.0.0-canary.90291f2e2.0" + "@material/rtl" "15.0.0-canary.90291f2e2.0" + "@material/theme" "15.0.0-canary.90291f2e2.0" + "@material/touch-target" "15.0.0-canary.90291f2e2.0" + tslib "^2.1.0" + +"@material/image-list@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/image-list/-/image-list-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-JobM4lWsf9grgbqrLuUtJ5fr8BkG02r9c2oFMl5++dtjtLdXWnUIWbiofna8CeqDFQCKXsCk4Jw8ydSKZvj/3A== + dependencies: + "@material/feature-targeting" "15.0.0-canary.90291f2e2.0" + "@material/shape" "15.0.0-canary.90291f2e2.0" + "@material/theme" "15.0.0-canary.90291f2e2.0" + "@material/typography" "15.0.0-canary.90291f2e2.0" + tslib "^2.1.0" + +"@material/layout-grid@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/layout-grid/-/layout-grid-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-f5DSHGf1ka6vHu+8VoTvcU9NkR8fdN2wHmPnITZHQXPVvR6SKoyDzdAf2gacmiTYy69ZFmmJeMcdfNnbcPPUJw== + dependencies: + tslib "^2.1.0" + +"@material/line-ripple@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/line-ripple/-/line-ripple-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-cWpS7l/pFg6cUzL7Lx3ywF6RYF6ESYPkiGlDo9kFERv8lVA2/3m4NF4d9b4kC9h9OWx1b1CaUFRFGD07okgI+g== + dependencies: + "@material/animation" "15.0.0-canary.90291f2e2.0" + "@material/base" "15.0.0-canary.90291f2e2.0" + "@material/feature-targeting" "15.0.0-canary.90291f2e2.0" + "@material/theme" "15.0.0-canary.90291f2e2.0" + tslib "^2.1.0" + +"@material/linear-progress@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/linear-progress/-/linear-progress-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-nK5RYn8NFZi/+fznLYoEdY6tSzXiJqOU0tX5by7hStURhP2g/RM5SQaJwyjEmHdorfCUIStgmKsN4rB5aMnxdw== + dependencies: + "@material/animation" "15.0.0-canary.90291f2e2.0" + "@material/base" "15.0.0-canary.90291f2e2.0" + "@material/dom" "15.0.0-canary.90291f2e2.0" + "@material/feature-targeting" "15.0.0-canary.90291f2e2.0" + "@material/progress-indicator" "15.0.0-canary.90291f2e2.0" + "@material/rtl" "15.0.0-canary.90291f2e2.0" + "@material/theme" "15.0.0-canary.90291f2e2.0" + tslib "^2.1.0" + +"@material/list@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/list/-/list-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-h2c6G5aPH1bhgl2yBYAW4y86pl+yVl3YdqU0ixemQ5/2uB/t92imUbI+gKH5LzlbuJKenk3rZJ5eaV+t5zTS1A== + dependencies: + "@material/base" "15.0.0-canary.90291f2e2.0" + "@material/density" "15.0.0-canary.90291f2e2.0" + "@material/dom" "15.0.0-canary.90291f2e2.0" + "@material/feature-targeting" "15.0.0-canary.90291f2e2.0" + "@material/ripple" "15.0.0-canary.90291f2e2.0" + "@material/rtl" "15.0.0-canary.90291f2e2.0" + "@material/shape" "15.0.0-canary.90291f2e2.0" + "@material/theme" "15.0.0-canary.90291f2e2.0" + "@material/tokens" "15.0.0-canary.90291f2e2.0" + "@material/typography" "15.0.0-canary.90291f2e2.0" + tslib "^2.1.0" + +"@material/menu-surface@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/menu-surface/-/menu-surface-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-AkRpOjFOJi2ROZPvFo1z8ik61eEyJEew8NuvlzCE4S3BX/RNFrYVh4W5ylo030S01ALCS5zhVOeekxa/4eokZA== + dependencies: + "@material/animation" "15.0.0-canary.90291f2e2.0" + "@material/base" "15.0.0-canary.90291f2e2.0" + "@material/elevation" "15.0.0-canary.90291f2e2.0" + "@material/feature-targeting" "15.0.0-canary.90291f2e2.0" + "@material/rtl" "15.0.0-canary.90291f2e2.0" + "@material/shape" "15.0.0-canary.90291f2e2.0" + "@material/theme" "15.0.0-canary.90291f2e2.0" + tslib "^2.1.0" + +"@material/menu@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/menu/-/menu-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-yfpBN4Hg59pHMNplh2LIe8t+/qsfyP0iRAtJoCK90SBwX43kv65u22+3vEJmYzm3Ey/m3S3YRFXTFQRQnn9cmA== + dependencies: + "@material/base" "15.0.0-canary.90291f2e2.0" + "@material/dom" "15.0.0-canary.90291f2e2.0" + "@material/elevation" "15.0.0-canary.90291f2e2.0" + "@material/feature-targeting" "15.0.0-canary.90291f2e2.0" + "@material/list" "15.0.0-canary.90291f2e2.0" + "@material/menu-surface" "15.0.0-canary.90291f2e2.0" + "@material/ripple" "15.0.0-canary.90291f2e2.0" + "@material/rtl" "15.0.0-canary.90291f2e2.0" + "@material/shape" "15.0.0-canary.90291f2e2.0" + "@material/theme" "15.0.0-canary.90291f2e2.0" + "@material/tokens" "15.0.0-canary.90291f2e2.0" + tslib "^2.1.0" + +"@material/notched-outline@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/notched-outline/-/notched-outline-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-4lpoIoFJ8cb++M1iQpZ+8iypUuTruzyBAkOvoaNjk7EftEV+aS3K6XntGNtlUZoB/fFho3mAUVjT19IHFWD03A== + dependencies: + "@material/base" "15.0.0-canary.90291f2e2.0" + "@material/feature-targeting" "15.0.0-canary.90291f2e2.0" + "@material/floating-label" "15.0.0-canary.90291f2e2.0" + "@material/rtl" "15.0.0-canary.90291f2e2.0" + "@material/shape" "15.0.0-canary.90291f2e2.0" + "@material/theme" "15.0.0-canary.90291f2e2.0" + tslib "^2.1.0" + +"@material/progress-indicator@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/progress-indicator/-/progress-indicator-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-trQLSstZIA0C64adW/HycycD+PtMfg6iZCIVuTNlZr7PR2Yc1EjuGyA7ts+iXBHZ0TxVshRbDYMwcDogP0rc1w== + dependencies: + tslib "^2.1.0" + +"@material/radio@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/radio/-/radio-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-Ypl4BZ9w1NdbiiEUV3Xw2pb97prMPGEE+5Lm719sVsaFmI4yCKgtsWNEbCbKixborh2ZDZWGCzgMyUQHf3a8xA== + dependencies: + "@material/animation" "15.0.0-canary.90291f2e2.0" + "@material/base" "15.0.0-canary.90291f2e2.0" + "@material/density" "15.0.0-canary.90291f2e2.0" + "@material/dom" "15.0.0-canary.90291f2e2.0" + "@material/feature-targeting" "15.0.0-canary.90291f2e2.0" + "@material/focus-ring" "15.0.0-canary.90291f2e2.0" + "@material/ripple" "15.0.0-canary.90291f2e2.0" + "@material/theme" "15.0.0-canary.90291f2e2.0" + "@material/touch-target" "15.0.0-canary.90291f2e2.0" + tslib "^2.1.0" + +"@material/ripple@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/ripple/-/ripple-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-8yCR/V+7SJ9om0cvAOULF/i5+gPQeT+cuPoCZJQRWq9IndfCmQPY3Zmy26reIT/zEyCebAvMG4/WtU4rc+jxyw== + dependencies: + "@material/animation" "15.0.0-canary.90291f2e2.0" + "@material/base" "15.0.0-canary.90291f2e2.0" + "@material/dom" "15.0.0-canary.90291f2e2.0" + "@material/feature-targeting" "15.0.0-canary.90291f2e2.0" + "@material/rtl" "15.0.0-canary.90291f2e2.0" + "@material/theme" "15.0.0-canary.90291f2e2.0" + tslib "^2.1.0" + +"@material/rtl@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/rtl/-/rtl-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-HkUhD8K03BxWVw21WDViWo01Chi22cZ1rmlsdCtggkxdVjtDhTbYm/3XvRnxt4RVpr6KaYQgRXI/52T5RtBUnw== + dependencies: + "@material/theme" "15.0.0-canary.90291f2e2.0" + tslib "^2.1.0" + +"@material/segmented-button@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/segmented-button/-/segmented-button-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-u1DF+jbysX6wCqt7dDnHgEo2XhNrwkqHq6YsMOFVCoo54PHt3gpwhD89DONqQJKspkdvZuxYHzpqRtV0GIzYDQ== + dependencies: + "@material/base" "15.0.0-canary.90291f2e2.0" + "@material/elevation" "15.0.0-canary.90291f2e2.0" + "@material/feature-targeting" "15.0.0-canary.90291f2e2.0" + "@material/ripple" "15.0.0-canary.90291f2e2.0" + "@material/theme" "15.0.0-canary.90291f2e2.0" + "@material/touch-target" "15.0.0-canary.90291f2e2.0" + "@material/typography" "15.0.0-canary.90291f2e2.0" + tslib "^2.1.0" + +"@material/select@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/select/-/select-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-CCaftyi3eIJl2XqBfHbzj8W2jgTMBzSM2+q4WthA+7z0fYQI4JIHQVHO5YKQG5J9MR1VjYQ0Gy0GNotZLAcoOQ== + dependencies: + "@material/animation" "15.0.0-canary.90291f2e2.0" + "@material/base" "15.0.0-canary.90291f2e2.0" + "@material/density" "15.0.0-canary.90291f2e2.0" + "@material/dom" "15.0.0-canary.90291f2e2.0" + "@material/elevation" "15.0.0-canary.90291f2e2.0" + "@material/feature-targeting" "15.0.0-canary.90291f2e2.0" + "@material/floating-label" "15.0.0-canary.90291f2e2.0" + "@material/line-ripple" "15.0.0-canary.90291f2e2.0" + "@material/list" "15.0.0-canary.90291f2e2.0" + "@material/menu" "15.0.0-canary.90291f2e2.0" + "@material/menu-surface" "15.0.0-canary.90291f2e2.0" + "@material/notched-outline" "15.0.0-canary.90291f2e2.0" + "@material/ripple" "15.0.0-canary.90291f2e2.0" + "@material/rtl" "15.0.0-canary.90291f2e2.0" + "@material/shape" "15.0.0-canary.90291f2e2.0" + "@material/theme" "15.0.0-canary.90291f2e2.0" + "@material/tokens" "15.0.0-canary.90291f2e2.0" + "@material/typography" "15.0.0-canary.90291f2e2.0" + tslib "^2.1.0" + +"@material/shape@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/shape/-/shape-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-UEB168x8ovLvH4eoBtRnoCT9QvnxB/ZMpOKW1+C+xWisis6Wy9AX0wKT5T6wIpffYYCaBJuhI+ExX2134rAxJw== + dependencies: + "@material/feature-targeting" "15.0.0-canary.90291f2e2.0" + "@material/rtl" "15.0.0-canary.90291f2e2.0" + "@material/theme" "15.0.0-canary.90291f2e2.0" + tslib "^2.1.0" + +"@material/slider@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/slider/-/slider-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-krbdGHcROlvnZ0X7HT0d+PvJummczeShQeWeV/ZezXnQM7bQoy86qfwtX4ai1dIXYkF9qKTFlta2zZezTJyf5g== + dependencies: + "@material/animation" "15.0.0-canary.90291f2e2.0" + "@material/base" "15.0.0-canary.90291f2e2.0" + "@material/dom" "15.0.0-canary.90291f2e2.0" + "@material/elevation" "15.0.0-canary.90291f2e2.0" + "@material/feature-targeting" "15.0.0-canary.90291f2e2.0" + "@material/ripple" "15.0.0-canary.90291f2e2.0" + "@material/rtl" "15.0.0-canary.90291f2e2.0" + "@material/theme" "15.0.0-canary.90291f2e2.0" + "@material/tokens" "15.0.0-canary.90291f2e2.0" + "@material/typography" "15.0.0-canary.90291f2e2.0" + tslib "^2.1.0" + +"@material/snackbar@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/snackbar/-/snackbar-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-f1+HaSaAkALtQqEr6WMUqfwOsJr5nOUjP15GA+sTs9SD7yzwqMeWsVriBdWXVRe0zNgew6sfBM+cLjg2w4VAOQ== + dependencies: + "@material/animation" "15.0.0-canary.90291f2e2.0" + "@material/base" "15.0.0-canary.90291f2e2.0" + "@material/button" "15.0.0-canary.90291f2e2.0" + "@material/dom" "15.0.0-canary.90291f2e2.0" + "@material/elevation" "15.0.0-canary.90291f2e2.0" + "@material/feature-targeting" "15.0.0-canary.90291f2e2.0" + "@material/icon-button" "15.0.0-canary.90291f2e2.0" + "@material/ripple" "15.0.0-canary.90291f2e2.0" + "@material/rtl" "15.0.0-canary.90291f2e2.0" + "@material/shape" "15.0.0-canary.90291f2e2.0" + "@material/theme" "15.0.0-canary.90291f2e2.0" + "@material/tokens" "15.0.0-canary.90291f2e2.0" + "@material/typography" "15.0.0-canary.90291f2e2.0" + tslib "^2.1.0" + +"@material/switch@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/switch/-/switch-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-94/+Zp2VjlLVJXY7u8VHPcJMHPRVNAwHydiGrKvnJ+6LfbLxAcILNBP9RVKqqqOWQeDxB4ApUl+0TV2Lj6mOzA== + dependencies: + "@material/animation" "15.0.0-canary.90291f2e2.0" + "@material/base" "15.0.0-canary.90291f2e2.0" + "@material/density" "15.0.0-canary.90291f2e2.0" + "@material/dom" "15.0.0-canary.90291f2e2.0" + "@material/elevation" "15.0.0-canary.90291f2e2.0" + "@material/feature-targeting" "15.0.0-canary.90291f2e2.0" + "@material/focus-ring" "15.0.0-canary.90291f2e2.0" + "@material/ripple" "15.0.0-canary.90291f2e2.0" + "@material/rtl" "15.0.0-canary.90291f2e2.0" + "@material/shape" "15.0.0-canary.90291f2e2.0" + "@material/theme" "15.0.0-canary.90291f2e2.0" + "@material/tokens" "15.0.0-canary.90291f2e2.0" + safevalues "^0.3.4" + tslib "^2.1.0" + +"@material/tab-bar@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/tab-bar/-/tab-bar-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-dTC7oGZg6KuDK2OXO7luJWqshtNY2YgImwZbQ9a1vZZrIGMRHdu+ZtP6RVH2srFVlNIWjzcxfLgNrG+U027RdA== + dependencies: + "@material/animation" "15.0.0-canary.90291f2e2.0" + "@material/base" "15.0.0-canary.90291f2e2.0" + "@material/density" "15.0.0-canary.90291f2e2.0" + "@material/elevation" "15.0.0-canary.90291f2e2.0" + "@material/feature-targeting" "15.0.0-canary.90291f2e2.0" + "@material/tab" "15.0.0-canary.90291f2e2.0" + "@material/tab-indicator" "15.0.0-canary.90291f2e2.0" + "@material/tab-scroller" "15.0.0-canary.90291f2e2.0" + "@material/theme" "15.0.0-canary.90291f2e2.0" + "@material/tokens" "15.0.0-canary.90291f2e2.0" + "@material/typography" "15.0.0-canary.90291f2e2.0" + tslib "^2.1.0" + +"@material/tab-indicator@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/tab-indicator/-/tab-indicator-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-GXdFO6rO1crXcj+todijzZQVACW4EC72XwLAl6z69TKBgZrhwCoZ6RgzX6vIXSs+KoZ0eIyQLr+yQQx1JjDd4w== + dependencies: + "@material/animation" "15.0.0-canary.90291f2e2.0" + "@material/base" "15.0.0-canary.90291f2e2.0" + "@material/feature-targeting" "15.0.0-canary.90291f2e2.0" + "@material/theme" "15.0.0-canary.90291f2e2.0" + tslib "^2.1.0" + +"@material/tab-scroller@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/tab-scroller/-/tab-scroller-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-R6trOZpkfk54VV0w0NjMMDcZPQgbnARxCoHLrWeSzv5KOMoiDyWji7FFpLc4fynX/F2lNg8xHpEolpugNRW/1g== + dependencies: + "@material/animation" "15.0.0-canary.90291f2e2.0" + "@material/base" "15.0.0-canary.90291f2e2.0" + "@material/dom" "15.0.0-canary.90291f2e2.0" + "@material/feature-targeting" "15.0.0-canary.90291f2e2.0" + "@material/tab" "15.0.0-canary.90291f2e2.0" + tslib "^2.1.0" + +"@material/tab@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/tab/-/tab-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-zju6UP038Ddi3XAfliYy58A3OvkQ+zSlOdNOd5l82oMArLYEFi3t51QTjKVjV1wokr6ZQ3Chs4kcrgwVTElYtg== + dependencies: + "@material/base" "15.0.0-canary.90291f2e2.0" + "@material/elevation" "15.0.0-canary.90291f2e2.0" + "@material/feature-targeting" "15.0.0-canary.90291f2e2.0" + "@material/focus-ring" "15.0.0-canary.90291f2e2.0" + "@material/ripple" "15.0.0-canary.90291f2e2.0" + "@material/rtl" "15.0.0-canary.90291f2e2.0" + "@material/tab-indicator" "15.0.0-canary.90291f2e2.0" + "@material/theme" "15.0.0-canary.90291f2e2.0" + "@material/tokens" "15.0.0-canary.90291f2e2.0" + "@material/typography" "15.0.0-canary.90291f2e2.0" + tslib "^2.1.0" + +"@material/textfield@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/textfield/-/textfield-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-ipxPH8DRh9+cn4MOtAYvGsRLP5RJH/gB/BWh/BiJwjI38Djt4FK4LDHbx7fFo/C8hoj7UNs/BWaSLllyxuWKcg== + dependencies: + "@material/animation" "15.0.0-canary.90291f2e2.0" + "@material/base" "15.0.0-canary.90291f2e2.0" + "@material/density" "15.0.0-canary.90291f2e2.0" + "@material/dom" "15.0.0-canary.90291f2e2.0" + "@material/feature-targeting" "15.0.0-canary.90291f2e2.0" + "@material/floating-label" "15.0.0-canary.90291f2e2.0" + "@material/line-ripple" "15.0.0-canary.90291f2e2.0" + "@material/notched-outline" "15.0.0-canary.90291f2e2.0" + "@material/ripple" "15.0.0-canary.90291f2e2.0" + "@material/rtl" "15.0.0-canary.90291f2e2.0" + "@material/shape" "15.0.0-canary.90291f2e2.0" + "@material/theme" "15.0.0-canary.90291f2e2.0" + "@material/tokens" "15.0.0-canary.90291f2e2.0" + "@material/typography" "15.0.0-canary.90291f2e2.0" + tslib "^2.1.0" + +"@material/theme@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/theme/-/theme-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-rDSZ0bPoJothI8nRPQWB4Cyu7DTmc8qIuvFm3OOD4uI/2n+yIFqktS6X+6YF82LeKt4uMTZE+Ce/l51bb8UJGA== + dependencies: + "@material/feature-targeting" "15.0.0-canary.90291f2e2.0" + tslib "^2.1.0" + +"@material/tokens@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/tokens/-/tokens-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-ZTis8UeSRrm/4iQ6BujtcTf1J2bs2H+SAEnugtZSQiX8pyf90gQvylEoTuMPdUs1+YJ273cn04ipHdkq3OHaew== + dependencies: + "@material/elevation" "15.0.0-canary.90291f2e2.0" + +"@material/tooltip@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/tooltip/-/tooltip-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-H3XsrctgRriNwt++NN+Zy6/JhyRznWo2pXiTFnOlaYwHOiGIFCNZR0A/0vf/3Kpf0GYhTfkJEFJMosUSZidSDg== + dependencies: + "@material/animation" "15.0.0-canary.90291f2e2.0" + "@material/base" "15.0.0-canary.90291f2e2.0" + "@material/button" "15.0.0-canary.90291f2e2.0" + "@material/dom" "15.0.0-canary.90291f2e2.0" + "@material/elevation" "15.0.0-canary.90291f2e2.0" + "@material/feature-targeting" "15.0.0-canary.90291f2e2.0" + "@material/rtl" "15.0.0-canary.90291f2e2.0" + "@material/shape" "15.0.0-canary.90291f2e2.0" + "@material/theme" "15.0.0-canary.90291f2e2.0" + "@material/tokens" "15.0.0-canary.90291f2e2.0" + "@material/typography" "15.0.0-canary.90291f2e2.0" + safevalues "^0.3.4" + tslib "^2.1.0" + +"@material/top-app-bar@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/top-app-bar/-/top-app-bar-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-ZiJjK4WpIsE0MZTWokP9r4C9/oDqzUhKRn3ef2WCeJEIU3Vjg4t0xBTnST2vIrcBGw1s7WP1gfaxb3DSXSxzpw== + dependencies: + "@material/animation" "15.0.0-canary.90291f2e2.0" + "@material/base" "15.0.0-canary.90291f2e2.0" + "@material/elevation" "15.0.0-canary.90291f2e2.0" + "@material/ripple" "15.0.0-canary.90291f2e2.0" + "@material/rtl" "15.0.0-canary.90291f2e2.0" + "@material/shape" "15.0.0-canary.90291f2e2.0" + "@material/theme" "15.0.0-canary.90291f2e2.0" + "@material/typography" "15.0.0-canary.90291f2e2.0" + tslib "^2.1.0" + +"@material/touch-target@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/touch-target/-/touch-target-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-IpRFf4umZ4ZNxrP+qJkRY9syh7TFZmU4c7EbAlANAJ0/8rlkEo7WJiqa9P1p4nFaT4eMo4n5g+qRI0Dkb9zW5g== + dependencies: + "@material/base" "15.0.0-canary.90291f2e2.0" + "@material/feature-targeting" "15.0.0-canary.90291f2e2.0" + "@material/rtl" "15.0.0-canary.90291f2e2.0" + "@material/theme" "15.0.0-canary.90291f2e2.0" + tslib "^2.1.0" + +"@material/typography@15.0.0-canary.90291f2e2.0": + version "15.0.0-canary.90291f2e2.0" + resolved "https://registry.npmjs.org/@material/typography/-/typography-15.0.0-canary.90291f2e2.0.tgz" + integrity sha512-tv1HWkJYi5T0470k8vbBb+nefdPgsaIO04ocWMf7luvmfE+MZIaR13RxdupLJ4k5otrdydL3/wEaCNhQ+Ipnvw== + dependencies: + "@material/feature-targeting" "15.0.0-canary.90291f2e2.0" + "@material/theme" "15.0.0-canary.90291f2e2.0" + tslib "^2.1.0" + +"@ngtools/webpack@16.0.5": + version "16.0.5" + resolved "https://registry.npmjs.org/@ngtools/webpack/-/webpack-16.0.5.tgz" + integrity sha512-qKQmPKxfcI9pumaKqM4EodcjauLA2JCGdAhBu+xafdmqV52K7goZKCqqzjYpraqeS+UOphi08XetX4mBPu9KMg== + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": + version "2.0.5" + resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.8" + resolved "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@npmcli/fs@^2.1.0": + version "2.1.2" + resolved "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.2.tgz" + integrity sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ== + dependencies: + "@gar/promisify" "^1.1.3" + semver "^7.3.5" + +"@npmcli/fs@^3.1.0": + version "3.1.0" + resolved "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.0.tgz" + integrity sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w== + dependencies: + semver "^7.3.5" + +"@npmcli/git@^4.0.0": + version "4.1.0" + resolved "https://registry.npmjs.org/@npmcli/git/-/git-4.1.0.tgz" + integrity sha512-9hwoB3gStVfa0N31ymBmrX+GuDGdVA/QWShZVqE0HK2Af+7QGGrCTbZia/SW0ImUTjTne7SP91qxDmtXvDHRPQ== + dependencies: + "@npmcli/promise-spawn" "^6.0.0" + lru-cache "^7.4.4" + npm-pick-manifest "^8.0.0" + proc-log "^3.0.0" + promise-inflight "^1.0.1" + promise-retry "^2.0.1" + semver "^7.3.5" + which "^3.0.0" + +"@npmcli/installed-package-contents@^2.0.1": + version "2.0.2" + resolved "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-2.0.2.tgz" + integrity sha512-xACzLPhnfD51GKvTOOuNX2/V4G4mz9/1I2MfDoye9kBM3RYe5g2YbscsaGoTlaWqkxeiapBWyseULVKpSVHtKQ== + dependencies: + npm-bundled "^3.0.0" + npm-normalize-package-bin "^3.0.0" + +"@npmcli/move-file@^2.0.0": + version "2.0.1" + resolved "https://registry.npmjs.org/@npmcli/move-file/-/move-file-2.0.1.tgz" + integrity sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ== + dependencies: + mkdirp "^1.0.4" + rimraf "^3.0.2" + +"@npmcli/node-gyp@^3.0.0": + version "3.0.0" + resolved "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-3.0.0.tgz" + integrity sha512-gp8pRXC2oOxu0DUE1/M3bYtb1b3/DbJ5aM113+XJBgfXdussRAsX0YOrOhdd8WvnAR6auDBvJomGAkLKA5ydxA== + +"@npmcli/promise-spawn@^6.0.0", "@npmcli/promise-spawn@^6.0.1": + version "6.0.2" + resolved "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-6.0.2.tgz" + integrity sha512-gGq0NJkIGSwdbUt4yhdF8ZrmkGKVz9vAdVzpOfnom+V8PLSmSOVhZwbNvZZS1EYcJN5hzzKBxmmVVAInM6HQLg== + dependencies: + which "^3.0.0" + +"@npmcli/run-script@^6.0.0": + version "6.0.2" + resolved "https://registry.npmjs.org/@npmcli/run-script/-/run-script-6.0.2.tgz" + integrity sha512-NCcr1uQo1k5U+SYlnIrbAh3cxy+OQT1VtqiAbxdymSlptbzBb62AjH2xXgjNCoP073hoa1CfCAcwoZ8k96C4nA== + dependencies: + "@npmcli/node-gyp" "^3.0.0" + "@npmcli/promise-spawn" "^6.0.0" + node-gyp "^9.0.0" + read-package-json-fast "^3.0.0" + which "^3.0.0" + +"@pkgjs/parseargs@^0.11.0": + version "0.11.0" + resolved "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz" + integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== + +"@popperjs/core@^2.11.7": + version "2.11.8" + resolved "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz" + integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A== + +"@schematics/angular@16.0.5": + version "16.0.5" + resolved "https://registry.npmjs.org/@schematics/angular/-/angular-16.0.5.tgz" + integrity sha512-AddtFA95H7IkaY+H9u0Hdci3Ywwe6oNopL9kvm5hj8bFY6pukDWclRWOf2H2KqZu0qeAxMhETBpmoVYUuDbYmw== + dependencies: + "@angular-devkit/core" "16.0.5" + "@angular-devkit/schematics" "16.0.5" + jsonc-parser "3.2.0" + +"@sigstore/protobuf-specs@^0.1.0": + version "0.1.0" + resolved "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.1.0.tgz" + integrity sha512-a31EnjuIDSX8IXBUib3cYLDRlPMU36AWX4xS8ysLaNu4ZzUesDiPt83pgrW2X1YLMe5L2HbDyaKK5BrL4cNKaQ== + +"@sigstore/tuf@^1.0.0": + version "1.0.0" + resolved "https://registry.npmjs.org/@sigstore/tuf/-/tuf-1.0.0.tgz" + integrity sha512-bLzi9GeZgMCvjJeLUIfs8LJYCxrPRA8IXQkzUtaFKKVPTz0mucRyqFcV2U20yg9K+kYAD0YSitzGfRZCFLjdHQ== + dependencies: + "@sigstore/protobuf-specs" "^0.1.0" + make-fetch-happen "^11.0.1" + tuf-js "^1.1.3" + +"@socket.io/component-emitter@~3.1.0": + version "3.1.0" + resolved "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz" + integrity sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg== + +"@tootallnate/once@2": + version "2.0.0" + resolved "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz" + integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== + +"@tsconfig/node10@^1.0.7": + version "1.0.9" + resolved "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz" + integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== + +"@tsconfig/node12@^1.0.7": + version "1.0.11" + resolved "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz" + integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== + +"@tsconfig/node14@^1.0.0": + version "1.0.3" + resolved "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz" + integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== + +"@tsconfig/node16@^1.0.2": + version "1.0.4" + resolved "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz" + integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== + +"@tufjs/canonical-json@1.0.0": + version "1.0.0" + resolved "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-1.0.0.tgz" + integrity sha512-QTnf++uxunWvG2z3UFNzAoQPHxnSXOwtaI3iJ+AohhV+5vONuArPjJE7aPXPVXfXJsqrVbZBu9b81AJoSd09IQ== + +"@tufjs/models@1.0.4": + version "1.0.4" + resolved "https://registry.npmjs.org/@tufjs/models/-/models-1.0.4.tgz" + integrity sha512-qaGV9ltJP0EO25YfFUPhxRVK0evXFIAGicsVXuRim4Ed9cjPxYhNnNJ49SFmbeLgtxpslIkX317IgpfcHPVj/A== + dependencies: + "@tufjs/canonical-json" "1.0.0" + minimatch "^9.0.0" + +"@types/body-parser@*": + version "1.19.2" + resolved "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz" + integrity sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/bonjour@^3.5.9": + version "3.5.10" + resolved "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.10.tgz" + integrity sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw== + dependencies: + "@types/node" "*" + +"@types/connect-history-api-fallback@^1.3.5": + version "1.5.0" + resolved "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz" + integrity sha512-4x5FkPpLipqwthjPsF7ZRbOv3uoLUFkTA9G9v583qi4pACvq0uTELrB8OLUzPWUI4IJIyvM85vzkV1nyiI2Lig== + dependencies: + "@types/express-serve-static-core" "*" + "@types/node" "*" + +"@types/connect@*": + version "3.4.35" + resolved "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz" + integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== + dependencies: + "@types/node" "*" + +"@types/cookie@^0.4.1": + version "0.4.1" + resolved "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz" + integrity sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q== + +"@types/cors@^2.8.12": + version "2.8.13" + resolved "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz" + integrity sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA== + dependencies: + "@types/node" "*" + +"@types/eslint-scope@^3.7.3": + version "3.7.4" + resolved "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz" + integrity sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA== + dependencies: + "@types/eslint" "*" + "@types/estree" "*" + +"@types/eslint@*": + version "8.40.1" + resolved "https://registry.npmjs.org/@types/eslint/-/eslint-8.40.1.tgz" + integrity sha512-vRb792M4mF1FBT+eoLecmkpLXwxsBHvWWRGJjzbYANBM6DtiJc6yETyv4rqDA6QNjF1pkj1U7LMA6dGb3VYlHw== + dependencies: + "@types/estree" "*" + "@types/json-schema" "*" + +"@types/estree@*", "@types/estree@^1.0.0": + version "1.0.1" + resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz" + integrity sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA== + +"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.33": + version "4.17.35" + resolved "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.35.tgz" + integrity sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + "@types/send" "*" + +"@types/express@*", "@types/express@^4.17.13": + version "4.17.17" + resolved "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz" + integrity sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.33" + "@types/qs" "*" + "@types/serve-static" "*" + +"@types/http-proxy@^1.17.8": + version "1.17.11" + resolved "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.11.tgz" + integrity sha512-HC8G7c1WmaF2ekqpnFq626xd3Zz0uvaqFmBJNRZCGEZCXkvSdJoNFn/8Ygbd9fKNQj8UzLdCETaI0UWPAjK7IA== + dependencies: + "@types/node" "*" + +"@types/jasmine@~4.3.0": + version "4.3.2" + resolved "https://registry.npmjs.org/@types/jasmine/-/jasmine-4.3.2.tgz" + integrity sha512-lKkWBcbxEZX/7nxPqEtv/OjPLaBa2j0o+hmv5Yn83b/+11C1kfBAkgvmrb13WDkmizUJ3B+jYrWh4M0YRtrzEQ== + +"@types/json-schema@*", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": + version "7.0.12" + resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz" + integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA== + +"@types/mime@*", "@types/mime@^1": + version "1.3.2" + resolved "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz" + integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw== + +"@types/node@*", "@types/node@^20.4.5", "@types/node@>= 14", "@types/node@>=10.0.0": + version "20.4.5" + resolved "https://registry.npmjs.org/@types/node/-/node-20.4.5.tgz" + integrity sha512-rt40Nk13II9JwQBdeYqmbn2Q6IVTA5uPhvSO+JVqdXw/6/4glI6oR9ezty/A9Hg5u7JH4OmYmuQ+XvjKm0Datg== + +"@types/qs@*": + version "6.9.7" + resolved "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz" + integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== + +"@types/range-parser@*": + version "1.2.4" + resolved "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz" + integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== + +"@types/retry@0.12.0": + version "0.12.0" + resolved "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz" + integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== + +"@types/send@*": + version "0.17.1" + resolved "https://registry.npmjs.org/@types/send/-/send-0.17.1.tgz" + integrity sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q== + dependencies: + "@types/mime" "^1" + "@types/node" "*" + +"@types/serve-index@^1.9.1": + version "1.9.1" + resolved "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz" + integrity sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg== + dependencies: + "@types/express" "*" + +"@types/serve-static@*", "@types/serve-static@^1.13.10": + version "1.15.1" + resolved "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.1.tgz" + integrity sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ== + dependencies: + "@types/mime" "*" + "@types/node" "*" + +"@types/sockjs@^0.3.33": + version "0.3.33" + resolved "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.33.tgz" + integrity sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw== + dependencies: + "@types/node" "*" + +"@types/ws@^8.5.1": + version "8.5.5" + resolved "https://registry.npmjs.org/@types/ws/-/ws-8.5.5.tgz" + integrity sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg== + dependencies: + "@types/node" "*" + +"@vitejs/plugin-basic-ssl@1.0.1": + version "1.0.1" + resolved "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-1.0.1.tgz" + integrity sha512-pcub+YbFtFhaGRTo1832FQHQSHvMrlb43974e2eS8EKleR3p1cDdkJFPci1UhwkEf1J9Bz+wKBSzqpKp7nNj2A== + +"@webassemblyjs/ast@^1.11.5", "@webassemblyjs/ast@1.11.6": + version "1.11.6" + resolved "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz" + integrity sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q== + dependencies: + "@webassemblyjs/helper-numbers" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + +"@webassemblyjs/floating-point-hex-parser@1.11.6": + version "1.11.6" + resolved "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz" + integrity sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw== + +"@webassemblyjs/helper-api-error@1.11.6": + version "1.11.6" + resolved "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz" + integrity sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q== + +"@webassemblyjs/helper-buffer@1.11.6": + version "1.11.6" + resolved "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz" + integrity sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA== + +"@webassemblyjs/helper-numbers@1.11.6": + version "1.11.6" + resolved "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz" + integrity sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g== + dependencies: + "@webassemblyjs/floating-point-hex-parser" "1.11.6" + "@webassemblyjs/helper-api-error" "1.11.6" + "@xtuc/long" "4.2.2" + +"@webassemblyjs/helper-wasm-bytecode@1.11.6": + version "1.11.6" + resolved "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz" + integrity sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA== + +"@webassemblyjs/helper-wasm-section@1.11.6": + version "1.11.6" + resolved "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz" + integrity sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-buffer" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/wasm-gen" "1.11.6" + +"@webassemblyjs/ieee754@1.11.6": + version "1.11.6" + resolved "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz" + integrity sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.11.6": + version "1.11.6" + resolved "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz" + integrity sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ== + dependencies: + "@xtuc/long" "4.2.2" + +"@webassemblyjs/utf8@1.11.6": + version "1.11.6" + resolved "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz" + integrity sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA== + +"@webassemblyjs/wasm-edit@^1.11.5": + version "1.11.6" + resolved "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz" + integrity sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-buffer" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/helper-wasm-section" "1.11.6" + "@webassemblyjs/wasm-gen" "1.11.6" + "@webassemblyjs/wasm-opt" "1.11.6" + "@webassemblyjs/wasm-parser" "1.11.6" + "@webassemblyjs/wast-printer" "1.11.6" + +"@webassemblyjs/wasm-gen@1.11.6": + version "1.11.6" + resolved "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz" + integrity sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/ieee754" "1.11.6" + "@webassemblyjs/leb128" "1.11.6" + "@webassemblyjs/utf8" "1.11.6" + +"@webassemblyjs/wasm-opt@1.11.6": + version "1.11.6" + resolved "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz" + integrity sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-buffer" "1.11.6" + "@webassemblyjs/wasm-gen" "1.11.6" + "@webassemblyjs/wasm-parser" "1.11.6" + +"@webassemblyjs/wasm-parser@^1.11.5", "@webassemblyjs/wasm-parser@1.11.6": + version "1.11.6" + resolved "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz" + integrity sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-api-error" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/ieee754" "1.11.6" + "@webassemblyjs/leb128" "1.11.6" + "@webassemblyjs/utf8" "1.11.6" + +"@webassemblyjs/wast-printer@1.11.6": + version "1.11.6" + resolved "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz" + integrity sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@xtuc/long" "4.2.2" + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== + +"@yarnpkg/lockfile@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz" + integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ== + +abab@^2.0.6: + version "2.0.6" + resolved "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz" + integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== + +abbrev@^1.0.0: + version "1.1.1" + resolved "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + +accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: + version "1.3.8" + resolved "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + +acorn-import-assertions@^1.7.6: + version "1.9.0" + resolved "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz" + integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== + +acorn-walk@^8.1.1: + version "8.2.0" + resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz" + integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== + +acorn@^8, acorn@^8.4.1, acorn@^8.5.0, acorn@^8.7.1: + version "8.8.2" + resolved "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz" + integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== + +adjust-sourcemap-loader@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz" + integrity sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A== + dependencies: + loader-utils "^2.0.0" + regex-parser "^2.2.11" + +agent-base@^6.0.2, agent-base@6: + version "6.0.2" + resolved "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + +agentkeepalive@^4.2.1: + version "4.3.0" + resolved "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.3.0.tgz" + integrity sha512-7Epl1Blf4Sy37j4v9f9FjICCh4+KAQOyXgHEwlyBiAQLbhKdq/i2QQU3amQalS/wPhdPzDXPL5DMR5bkn+YeWg== + dependencies: + debug "^4.1.0" + depd "^2.0.0" + humanize-ms "^1.2.1" + +aggregate-error@^3.0.0: + version "3.1.0" + resolved "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz" + integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== + dependencies: + clean-stack "^2.0.0" + indent-string "^4.0.0" + +ajv-formats@^2.1.1, ajv-formats@2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz" + integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== + dependencies: + ajv "^8.0.0" + +ajv-keywords@^3.5.2: + version "3.5.2" + resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== + +ajv-keywords@^5.1.0: + version "5.1.0" + resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz" + integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== + dependencies: + fast-deep-equal "^3.1.3" + +ajv@^6.12.5, ajv@^6.9.1: + version "6.12.6" + resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + 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" + +ajv@^8.0.0, ajv@^8.8.2, ajv@^8.9.0, ajv@8.12.0: + version "8.12.0" + resolved "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz" + integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + +ansi-colors@4.1.3: + version "4.1.3" + resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz" + integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== + +ansi-escapes@^4.2.1: + version "4.3.2" + resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== + dependencies: + type-fest "^0.21.3" + +ansi-html-community@^0.0.8: + version "0.0.8" + resolved "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz" + integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw== + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-regex@^6.0.1: + version "6.0.1" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz" + integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0: + version "4.3.0" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +ansi-styles@^6.1.0: + version "6.2.1" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz" + integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== + +anymatch@~3.1.2: + version "3.1.3" + resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +"aproba@^1.0.3 || ^2.0.0": + version "2.0.0" + resolved "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz" + integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== + +are-we-there-yet@^3.0.0: + version "3.0.1" + resolved "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz" + integrity sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg== + dependencies: + delegates "^1.0.0" + readable-stream "^3.6.0" + +arg@^4.1.0: + version "4.1.3" + resolved "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz" + integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +array-flatten@^2.1.2: + version "2.1.2" + resolved "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz" + integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz" + integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== + +autoprefixer@10.4.14: + version "10.4.14" + resolved "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.14.tgz" + integrity sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ== + dependencies: + browserslist "^4.21.5" + caniuse-lite "^1.0.30001464" + fraction.js "^4.2.0" + normalize-range "^0.1.2" + picocolors "^1.0.0" + postcss-value-parser "^4.2.0" + +babel-loader@9.1.2: + version "9.1.2" + resolved "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.2.tgz" + integrity sha512-mN14niXW43tddohGl8HPu5yfQq70iUThvFL/4QzESA7GcZoC0eVOhvWdQ8+3UlSjaDE9MVtsW9mxDY07W7VpVA== + dependencies: + find-cache-dir "^3.3.2" + schema-utils "^4.0.0" + +babel-plugin-istanbul@6.1.1: + 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== + 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" + +babel-plugin-polyfill-corejs2@^0.3.3: + version "0.3.3" + resolved "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz" + integrity sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q== + dependencies: + "@babel/compat-data" "^7.17.7" + "@babel/helper-define-polyfill-provider" "^0.3.3" + semver "^6.1.1" + +babel-plugin-polyfill-corejs3@^0.6.0: + version "0.6.0" + resolved "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz" + integrity sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.3.3" + core-js-compat "^3.25.1" + +babel-plugin-polyfill-regenerator@^0.4.1: + version "0.4.1" + resolved "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz" + integrity sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.3.3" + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +base64-js@^1.2.0, base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + +base64id@~2.0.0, base64id@2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz" + integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog== + +batch@0.6.1: + version "0.6.1" + resolved "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz" + integrity sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw== + +big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz" + integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +bl@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz" + integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== + dependencies: + buffer "^5.5.0" + inherits "^2.0.4" + readable-stream "^3.4.0" + +body-parser@^1.19.0: + version "1.20.2" + resolved "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz" + integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA== + dependencies: + bytes "3.1.2" + content-type "~1.0.5" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.11.0" + raw-body "2.5.2" + type-is "~1.6.18" + unpipe "1.0.0" + +body-parser@1.20.1: + version "1.20.1" + resolved "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz" + integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw== + dependencies: + bytes "3.1.2" + content-type "~1.0.4" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.11.0" + raw-body "2.5.1" + type-is "~1.6.18" + unpipe "1.0.0" + +bonjour-service@^1.0.11: + version "1.1.1" + resolved "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.1.1.tgz" + integrity sha512-Z/5lQRMOG9k7W+FkeGTNjh7htqn/2LMnfOvBZ8pynNZCM9MwkQkI3zeI4oz09uWdcgmgHugVvBqxGg4VQJ5PCg== + dependencies: + array-flatten "^2.1.2" + dns-equal "^1.0.0" + fast-deep-equal "^3.1.3" + multicast-dns "^7.2.5" + +boolbase@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz" + integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== + +bootstrap@^5.2.3: + version "5.3.0" + resolved "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.0.tgz" + integrity sha512-UnBV3E3v4STVNQdms6jSGO2CvOkjUMdDAVR2V5N4uCMdaIkaQjbcEAMqRimDHIs4uqBYzDAKCQwCB+97tJgHQw== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + +braces@^3.0.2, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +browserslist@^4.14.5, browserslist@^4.21.3, browserslist@^4.21.5, "browserslist@>= 4.21.0", browserslist@4.21.5: + version "4.21.5" + resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz" + integrity sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w== + dependencies: + caniuse-lite "^1.0.30001449" + electron-to-chromium "^1.4.284" + node-releases "^2.0.8" + update-browserslist-db "^1.0.10" + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +buffer@^5.5.0: + version "5.7.1" + resolved "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + +builtins@^5.0.0: + version "5.0.1" + resolved "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz" + integrity sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ== + dependencies: + semver "^7.0.0" + +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz" + integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw== + +bytes@3.1.2: + version "3.1.2" + resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + +cacache@^16.1.0: + version "16.1.3" + resolved "https://registry.npmjs.org/cacache/-/cacache-16.1.3.tgz" + integrity sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ== + dependencies: + "@npmcli/fs" "^2.1.0" + "@npmcli/move-file" "^2.0.0" + chownr "^2.0.0" + fs-minipass "^2.1.0" + glob "^8.0.1" + infer-owner "^1.0.4" + lru-cache "^7.7.1" + minipass "^3.1.6" + minipass-collect "^1.0.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + mkdirp "^1.0.4" + p-map "^4.0.0" + promise-inflight "^1.0.1" + rimraf "^3.0.2" + ssri "^9.0.0" + tar "^6.1.11" + unique-filename "^2.0.0" + +cacache@^17.0.0, cacache@17.0.6: + version "17.0.6" + resolved "https://registry.npmjs.org/cacache/-/cacache-17.0.6.tgz" + integrity sha512-ixcYmEBExFa/+ajIPjcwypxL97CjJyOsH9A/W+4qgEPIpJvKlC+HmVY8nkIck6n3PwUTdgq9c489niJGwl+5Cw== + dependencies: + "@npmcli/fs" "^3.1.0" + fs-minipass "^3.0.0" + glob "^10.2.2" + lru-cache "^7.7.1" + minipass "^5.0.0" + minipass-collect "^1.0.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + p-map "^4.0.0" + promise-inflight "^1.0.1" + ssri "^10.0.0" + tar "^6.1.11" + unique-filename "^3.0.0" + +call-bind@^1.0.0: + version "1.0.2" + resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camelcase@^5.3.1: + version "5.3.1" + resolved "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +caniuse-lite@^1.0.30001449, caniuse-lite@^1.0.30001464: + version "1.0.30001497" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001497.tgz" + integrity sha512-I4/duVK4wL6rAK/aKZl3HXB4g+lIZvaT4VLAn2rCgJ38jVLb0lv2Xug6QuqmxXFVRJMF74SPPWPJ/1Sdm3vCzw== + +chalk@^2.0.0: + version "2.4.2" + resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^4.1.0: + version "4.1.2" + resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chalk@^4.1.1: + version "4.1.2" + resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chardet@^0.7.0: + version "0.7.0" + resolved "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz" + integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== + +chart.js@^4.3.0: + version "4.3.2" + resolved "https://registry.npmjs.org/chart.js/-/chart.js-4.3.2.tgz" + integrity sha512-pvQNyFOY1QmbmIr8oDORL16/FFivfxj8V26VFpFilMo4cNvkV5WXLJetDio365pd9gKUHGdirUTbqJfw8tr+Dg== + dependencies: + "@kurkle/color" "^0.3.0" + +chokidar@^3.0.0, chokidar@^3.5.1, chokidar@^3.5.2, chokidar@^3.5.3, "chokidar@>=3.0.0 <4.0.0", chokidar@3.5.3: + version "3.5.3" + resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + 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" + optionalDependencies: + fsevents "~2.3.2" + +chownr@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz" + integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== + +chrome-trace-event@^1.0.2: + version "1.0.3" + resolved "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz" + integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== + +clean-stack@^2.0.0: + version "2.2.0" + resolved "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz" + integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== + +cli-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz" + integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== + dependencies: + restore-cursor "^3.1.0" + +cli-spinners@^2.5.0: + version "2.9.0" + resolved "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.0.tgz" + integrity sha512-4/aL9X3Wh0yiMQlE+eeRhWP6vclO3QRtw1JHKIT0FFUs5FjpFmESqtMvYZ0+lbzBw900b95mS0hohy+qn2VK/g== + +cli-width@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz" + integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== + +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + +cliui@^8.0.1: + version "8.0.1" + resolved "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz" + integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.1" + wrap-ansi "^7.0.0" + +clone-deep@^4.0.1: + version "4.0.1" + resolved "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz" + integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== + dependencies: + is-plain-object "^2.0.4" + kind-of "^6.0.2" + shallow-clone "^3.0.0" + +clone@^1.0.2: + version "1.0.4" + resolved "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz" + integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg== + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + +color-support@^1.1.3: + version "1.1.3" + resolved "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz" + integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== + +colorette@^2.0.10: + version "2.0.20" + resolved "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz" + integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== + +commander@^2.20.0: + 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== + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz" + integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== + +compressible@~2.0.16: + version "2.0.18" + resolved "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz" + integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== + dependencies: + mime-db ">= 1.43.0 < 2" + +compression@^1.7.4: + version "1.7.4" + resolved "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz" + integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== + dependencies: + accepts "~1.3.5" + bytes "3.0.0" + compressible "~2.0.16" + debug "2.6.9" + on-headers "~1.0.2" + safe-buffer "5.1.2" + vary "~1.1.2" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +connect-history-api-fallback@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz" + integrity sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA== + +connect@^3.7.0: + version "3.7.0" + resolved "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz" + integrity sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ== + dependencies: + debug "2.6.9" + finalhandler "1.1.2" + parseurl "~1.3.3" + utils-merge "1.0.1" + +console-control-strings@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz" + integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== + +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +content-type@~1.0.4, content-type@~1.0.5: + version "1.0.5" + resolved "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz" + integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== + +convert-source-map@^1.5.1, convert-source-map@^1.7.0: + 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== + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz" + integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== + +cookie@~0.4.1: + version "0.4.2" + resolved "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz" + integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== + +cookie@0.5.0: + version "0.5.0" + resolved "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz" + integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== + +copy-anything@^2.0.1: + version "2.0.6" + resolved "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz" + integrity sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw== + dependencies: + is-what "^3.14.1" + +copy-webpack-plugin@11.0.0: + version "11.0.0" + resolved "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz" + integrity sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ== + dependencies: + fast-glob "^3.2.11" + glob-parent "^6.0.1" + globby "^13.1.1" + normalize-path "^3.0.0" + schema-utils "^4.0.0" + serialize-javascript "^6.0.0" + +core-js-compat@^3.25.1: + version "3.30.2" + resolved "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.30.2.tgz" + integrity sha512-nriW1nuJjUgvkEjIot1Spwakz52V9YkYHZAQG6A1eCgC8AA1p0zngrQEP9R0+V6hji5XilWKG1Bd0YRppmGimA== + dependencies: + browserslist "^4.21.5" + +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + +cors@~2.8.5: + version "2.8.5" + resolved "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz" + integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== + dependencies: + object-assign "^4" + vary "^1" + +cosmiconfig-typescript-loader@^4.3.0: + version "4.3.0" + resolved "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-4.3.0.tgz" + integrity sha512-NTxV1MFfZDLPiBMjxbHRwSh5LaLcPMwNdCutmnHJCKoVnlvldPWlllonKwrsRJ5pYZBIBGRWWU2tfvzxgeSW5Q== + +cosmiconfig@^8.1.3, cosmiconfig@>=7: + version "8.2.0" + resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.2.0.tgz" + integrity sha512-3rTMnFJA1tCOPwRxtgF4wd7Ab2qvDbL8jX+3smjIbS4HlZBagTlpERbdN7iAbWlrfxE3M8c27kTwTawQ7st+OQ== + dependencies: + import-fresh "^3.2.1" + js-yaml "^4.1.0" + parse-json "^5.0.0" + path-type "^4.0.0" + +create-require@^1.1.0: + version "1.1.1" + resolved "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz" + integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== + +critters@0.0.16: + version "0.0.16" + resolved "https://registry.npmjs.org/critters/-/critters-0.0.16.tgz" + integrity sha512-JwjgmO6i3y6RWtLYmXwO5jMd+maZt8Tnfu7VVISmEWyQqfLpB8soBswf8/2bu6SBXxtKA68Al3c+qIG1ApT68A== + dependencies: + chalk "^4.1.0" + css-select "^4.2.0" + parse5 "^6.0.1" + parse5-htmlparser2-tree-adapter "^6.0.1" + postcss "^8.3.7" + pretty-bytes "^5.3.0" + +cross-spawn@^7.0.0, cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +css-loader@6.7.3: + version "6.7.3" + resolved "https://registry.npmjs.org/css-loader/-/css-loader-6.7.3.tgz" + integrity sha512-qhOH1KlBMnZP8FzRO6YCH9UHXQhVMcEGLyNdb7Hv2cpcmJbW0YrddO+tG1ab5nT41KpHIYGsbeHqxB9xPu1pKQ== + dependencies: + icss-utils "^5.1.0" + postcss "^8.4.19" + postcss-modules-extract-imports "^3.0.0" + postcss-modules-local-by-default "^4.0.0" + postcss-modules-scope "^3.0.0" + postcss-modules-values "^4.0.0" + postcss-value-parser "^4.2.0" + semver "^7.3.8" + +css-select@^4.2.0: + version "4.3.0" + resolved "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz" + integrity sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ== + dependencies: + boolbase "^1.0.0" + css-what "^6.0.1" + domhandler "^4.3.1" + domutils "^2.8.0" + nth-check "^2.0.1" + +css-what@^6.0.1: + version "6.1.0" + resolved "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz" + integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== + +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + +custom-event@~1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz" + integrity sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg== + +date-format@^4.0.14: + version "4.0.14" + resolved "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz" + integrity sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg== + +debug@^3.2.6: + version "3.2.7" + resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + +debug@^4.1.0, debug@^4.1.1, debug@^4.3.3, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2, debug@4: + version "4.3.4" + resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +debug@2.6.9: + version "2.6.9" + resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +default-gateway@^6.0.3: + version "6.0.3" + resolved "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz" + integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg== + dependencies: + execa "^5.0.0" + +defaults@^1.0.3: + version "1.0.4" + resolved "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz" + integrity sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A== + dependencies: + clone "^1.0.2" + +define-lazy-prop@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz" + integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz" + integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== + +depd@^2.0.0, depd@2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz" + integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== + +destroy@1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== + +detect-node@^2.0.4: + version "2.1.0" + resolved "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz" + integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== + +di@^0.0.1: + version "0.0.1" + resolved "https://registry.npmjs.org/di/-/di-0.0.1.tgz" + integrity sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA== + +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +dns-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz" + integrity sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg== + +dns-packet@^5.2.2: + version "5.6.0" + resolved "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.0.tgz" + integrity sha512-rza3UH1LwdHh9qyPXp8lkwpjSNk/AMD3dPytUoRoqnypDUhY0xvbdmVhWOfxO68frEfV9BU8V12Ez7ZsHGZpCQ== + dependencies: + "@leichtgewicht/ip-codec" "^2.0.1" + +dom-serialize@^2.2.1: + version "2.2.1" + resolved "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz" + integrity sha512-Yra4DbvoW7/Z6LBN560ZwXMjoNOSAN2wRsKFGc4iBeso+mpIA6qj1vfdf9HpMaKAqG6wXTy+1SYEzmNpKXOSsQ== + dependencies: + custom-event "~1.0.0" + ent "~2.2.0" + extend "^3.0.0" + void-elements "^2.0.0" + +dom-serializer@^1.0.1: + version "1.4.1" + resolved "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz" + integrity sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.2.0" + entities "^2.0.0" + +domelementtype@^2.0.1, domelementtype@^2.2.0: + version "2.3.0" + resolved "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz" + integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== + +domhandler@^4.2.0, domhandler@^4.3.1: + version "4.3.1" + resolved "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz" + integrity sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ== + dependencies: + domelementtype "^2.2.0" + +domutils@^2.8.0: + version "2.8.0" + resolved "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz" + integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A== + dependencies: + dom-serializer "^1.0.1" + domelementtype "^2.2.0" + domhandler "^4.2.0" + +eastasianwidth@^0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz" + integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz" + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== + +electron-to-chromium@^1.4.284: + version "1.4.427" + resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.427.tgz" + integrity sha512-HK3r9l+Jm8dYAm1ctXEWIC+hV60zfcjS9UA5BDlYvnI5S7PU/yytjpvSrTNrSSRRkuu3tDyZhdkwIczh+0DWaw== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + +emojis-list@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz" + integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz" + integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== + +encoding@^0.1.13: + version "0.1.13" + resolved "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz" + integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== + dependencies: + iconv-lite "^0.6.2" + +engine.io-parser@~5.0.3: + version "5.0.7" + resolved "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.7.tgz" + integrity sha512-P+jDFbvK6lE3n1OL+q9KuzdOFWkkZ/cMV9gol/SbVfpyqfvrfrFTOFJ6fQm2VC3PZHlU3QPhVwmbsCnauHF2MQ== + +engine.io@~6.4.2: + version "6.4.2" + resolved "https://registry.npmjs.org/engine.io/-/engine.io-6.4.2.tgz" + integrity sha512-FKn/3oMiJjrOEOeUub2WCox6JhxBXq/Zn3fZOMCBxKnNYtsdKjxhl7yR3fZhM9PV+rdE75SU5SYMc+2PGzo+Tg== + dependencies: + "@types/cookie" "^0.4.1" + "@types/cors" "^2.8.12" + "@types/node" ">=10.0.0" + accepts "~1.3.4" + base64id "2.0.0" + cookie "~0.4.1" + cors "~2.8.5" + debug "~4.3.1" + engine.io-parser "~5.0.3" + ws "~8.11.0" + +enhanced-resolve@^5.13.0: + version "5.14.1" + resolved "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.14.1.tgz" + integrity sha512-Vklwq2vDKtl0y/vtwjSesgJ5MYS7Etuk5txS8VdKL4AOS1aUlD96zqIfsOSLQsdv3xgMRbtkWM8eG9XDfKUPow== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + +ent@~2.2.0: + version "2.2.0" + resolved "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz" + integrity sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA== + +entities@^2.0.0: + version "2.2.0" + resolved "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz" + integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== + +entities@^4.3.0, entities@^4.4.0: + version "4.5.0" + resolved "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz" + integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== + +env-paths@^2.2.0: + version "2.2.1" + resolved "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz" + integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== + +err-code@^2.0.2: + version "2.0.3" + resolved "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz" + integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA== + +errno@^0.1.1: + version "0.1.8" + resolved "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz" + integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== + dependencies: + prr "~1.0.1" + +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +es-module-lexer@^1.2.1: + version "1.2.1" + resolved "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.2.1.tgz" + integrity sha512-9978wrXM50Y4rTMmW5kXIC09ZdXQZqkE4mxhwkd8VbzsGkXGPgV4zWuqQJgCEzYngdo2dYDa0l8xhX4fkSwJSg== + +esbuild-wasm@0.17.18: + version "0.17.18" + resolved "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.17.18.tgz" + integrity sha512-h4m5zVa+KaDuRFIbH9dokMwovvkIjTQJS7/Ry+0Z1paVuS9aIkso2vdA2GmwH9GSvGX6w71WveJ3PfkoLuWaRw== + +esbuild@^0.17.5, esbuild@0.17.18: + version "0.17.18" + resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.17.18.tgz" + integrity sha512-z1lix43jBs6UKjcZVKOw2xx69ffE2aG0PygLL5qJ9OS/gy0Ewd1gW/PUQIOIQGXBHWNywSc0floSKoMFF8aK2w== + optionalDependencies: + "@esbuild/android-arm" "0.17.18" + "@esbuild/android-arm64" "0.17.18" + "@esbuild/android-x64" "0.17.18" + "@esbuild/darwin-arm64" "0.17.18" + "@esbuild/darwin-x64" "0.17.18" + "@esbuild/freebsd-arm64" "0.17.18" + "@esbuild/freebsd-x64" "0.17.18" + "@esbuild/linux-arm" "0.17.18" + "@esbuild/linux-arm64" "0.17.18" + "@esbuild/linux-ia32" "0.17.18" + "@esbuild/linux-loong64" "0.17.18" + "@esbuild/linux-mips64el" "0.17.18" + "@esbuild/linux-ppc64" "0.17.18" + "@esbuild/linux-riscv64" "0.17.18" + "@esbuild/linux-s390x" "0.17.18" + "@esbuild/linux-x64" "0.17.18" + "@esbuild/netbsd-x64" "0.17.18" + "@esbuild/openbsd-x64" "0.17.18" + "@esbuild/sunos-x64" "0.17.18" + "@esbuild/win32-arm64" "0.17.18" + "@esbuild/win32-ia32" "0.17.18" + "@esbuild/win32-x64" "0.17.18" + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz" + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== + +eslint-scope@5.1.1: + version "5.1.1" + resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz" + integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== + +eventemitter-asyncresource@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/eventemitter-asyncresource/-/eventemitter-asyncresource-1.0.0.tgz" + integrity sha512-39F7TBIV0G7gTelxwbEqnwhp90eqCPON1k0NwNfwhgKn4Co4ybUbj2pECcXT0B3ztRKZ7Pw1JujUUgmQJHcVAQ== + +eventemitter3@^4.0.0: + version "4.0.7" + resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== + +events@^3.2.0: + version "3.3.0" + resolved "https://registry.npmjs.org/events/-/events-3.3.0.tgz" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + 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" + +express@^4.17.3: + version "4.18.2" + resolved "https://registry.npmjs.org/express/-/express-4.18.2.tgz" + integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== + dependencies: + accepts "~1.3.8" + array-flatten "1.1.1" + body-parser "1.20.1" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.5.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "2.0.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.2.0" + fresh "0.5.2" + http-errors "2.0.0" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "2.4.1" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.11.0" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.18.0" + serve-static "1.15.0" + setprototypeof "1.2.0" + statuses "2.0.1" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +extend@^3.0.0: + version "3.0.2" + resolved "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +external-editor@^3.0.3: + version "3.1.0" + resolved "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz" + integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== + dependencies: + chardet "^0.7.0" + iconv-lite "^0.4.24" + tmp "^0.0.33" + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + 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== + +fast-glob@^3.2.11: + version "3.2.12" + resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz" + integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fast-json-stable-stringify@^2.0.0: + 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== + +fastq@^1.6.0: + version "1.15.0" + resolved "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz" + integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== + dependencies: + reusify "^1.0.4" + +faye-websocket@^0.11.3: + version "0.11.4" + resolved "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz" + integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== + dependencies: + websocket-driver ">=0.5.1" + +figures@^3.0.0: + version "3.2.0" + resolved "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz" + integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== + dependencies: + escape-string-regexp "^1.0.5" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +finalhandler@1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz" + integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.3" + statuses "~1.5.0" + unpipe "~1.0.0" + +finalhandler@1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz" + integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "2.4.1" + parseurl "~1.3.3" + statuses "2.0.1" + unpipe "~1.0.0" + +find-cache-dir@^3.3.2: + version "3.3.2" + resolved "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz" + integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig== + dependencies: + commondir "^1.0.1" + make-dir "^3.0.2" + pkg-dir "^4.1.0" + +find-up@^4.0.0, find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +flatted@^3.2.7: + version "3.2.7" + resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz" + integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== + +follow-redirects@^1.0.0: + version "1.15.2" + resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz" + integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== + +foreground-child@^3.1.0: + version "3.1.1" + resolved "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz" + integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg== + dependencies: + cross-spawn "^7.0.0" + signal-exit "^4.0.1" + +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + +fraction.js@^4.2.0: + version "4.2.0" + resolved "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz" + integrity sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA== + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz" + integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== + +fs-extra@^8.1.0: + version "8.1.0" + resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz" + integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-minipass@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz" + integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== + dependencies: + minipass "^3.0.0" + +fs-minipass@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz" + integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== + dependencies: + minipass "^3.0.0" + +fs-minipass@^3.0.0: + version "3.0.2" + resolved "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.2.tgz" + integrity sha512-2GAfyfoaCDRrM6jaOS3UsBts8yJ55VioXdWcOL7dK9zdAuKT71+WBA4ifnNYqVjYv+4SsPxjK0JT4yIIn4cA/g== + dependencies: + minipass "^5.0.0" + +fs-monkey@^1.0.4: + version "1.0.4" + resolved "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.4.tgz" + integrity sha512-INM/fWAxMICjttnD0DX1rBvinKskj5G1w+oy/pnm9u/tSlnBrzFonJMcalKJ30P8RRsPzKcCG7Q8l0jx5Fh9YQ== + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +gauge@^4.0.3: + version "4.0.4" + resolved "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz" + integrity sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg== + dependencies: + aproba "^1.0.3 || ^2.0.0" + color-support "^1.1.3" + console-control-strings "^1.1.0" + has-unicode "^2.0.1" + signal-exit "^3.0.7" + string-width "^4.2.3" + strip-ansi "^6.0.1" + wide-align "^1.1.5" + +gensync@^1.0.0-beta.2: + 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== + +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-intrinsic@^1.0.2: + version "1.2.1" + resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz" + integrity sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-proto "^1.0.1" + has-symbols "^1.0.3" + +get-package-type@^0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz" + integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== + +get-stream@^6.0.0: + version "6.0.1" + resolved "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +glob-parent@^5.1.2, glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-parent@^6.0.1: + version "6.0.2" + resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + +glob-to-regexp@^0.4.1: + 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== + +glob@^10.2.2: + version "10.2.7" + resolved "https://registry.npmjs.org/glob/-/glob-10.2.7.tgz" + integrity sha512-jTKehsravOJo8IJxUGfZILnkvVJM/MOfHRs8QcXolVef2zNI9Tqyy5+SeuOAZd3upViEZQLyFpQhYiHLrMUNmA== + dependencies: + foreground-child "^3.1.0" + jackspeak "^2.0.3" + minimatch "^9.0.1" + minipass "^5.0.0 || ^6.0.2" + path-scurry "^1.7.0" + +glob@^7.1.3: + version "7.2.3" + resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + 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" + +glob@^7.1.4: + version "7.2.3" + resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + 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" + +glob@^7.1.7: + version "7.2.3" + resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + 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" + +glob@^8.0.1, glob@8.1.0: + version "8.1.0" + resolved "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz" + integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^5.0.1" + once "^1.3.0" + +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +globby@^13.1.1: + version "13.1.4" + resolved "https://registry.npmjs.org/globby/-/globby-13.1.4.tgz" + integrity sha512-iui/IiiW+QrJ1X1hKH5qwlMQyv34wJAYwH1vrf8b9kBA4sNiif3gKsMHa+BrdnOpEudWjpotfa7LrTzB1ERS/g== + dependencies: + dir-glob "^3.0.1" + fast-glob "^3.2.11" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^4.0.0" + +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: + 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== + +handle-thing@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz" + integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz" + integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== + +has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +has-unicode@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz" + integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +hdr-histogram-js@^2.0.1: + version "2.0.3" + resolved "https://registry.npmjs.org/hdr-histogram-js/-/hdr-histogram-js-2.0.3.tgz" + integrity sha512-Hkn78wwzWHNCp2uarhzQ2SGFLU3JY8SBDDd3TAABK4fc30wm+MuPOrg5QVFVfkKOQd6Bfz3ukJEI+q9sXEkK1g== + dependencies: + "@assemblyscript/loader" "^0.10.1" + base64-js "^1.2.0" + pako "^1.0.3" + +hdr-histogram-percentiles-obj@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/hdr-histogram-percentiles-obj/-/hdr-histogram-percentiles-obj-3.0.0.tgz" + integrity sha512-7kIufnBqdsBGcSZLPJwqHT3yhk1QTsSlFsVD3kx5ixH/AlgBs9yM1q6DPhXZ8f8gtdqgh7N7/5btRLpQsS2gHw== + +hosted-git-info@^6.0.0: + version "6.1.1" + resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.1.tgz" + integrity sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w== + dependencies: + lru-cache "^7.5.1" + +hpack.js@^2.1.6: + version "2.1.6" + resolved "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz" + integrity sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ== + dependencies: + inherits "^2.0.1" + obuf "^1.0.0" + readable-stream "^2.0.1" + wbuf "^1.1.0" + +html-entities@^2.3.2: + version "2.3.5" + resolved "https://registry.npmjs.org/html-entities/-/html-entities-2.3.5.tgz" + integrity sha512-72TJlcMkYsEJASa/3HnX7VT59htM7iSHbH59NSZbtc+22Ap0Txnlx91sfeB+/A7wNZg7UxtZdhAW4y+/jimrdg== + +html-escaper@^2.0.0: + version "2.0.2" + resolved "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz" + integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== + +http-cache-semantics@^4.1.0, http-cache-semantics@^4.1.1: + version "4.1.1" + resolved "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz" + integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== + +http-deceiver@^1.2.7: + version "1.2.7" + resolved "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz" + integrity sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw== + +http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz" + integrity sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A== + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== + dependencies: + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" + +http-parser-js@>=0.5.1: + version "0.5.8" + resolved "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz" + integrity sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q== + +http-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz" + integrity sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w== + dependencies: + "@tootallnate/once" "2" + agent-base "6" + debug "4" + +http-proxy-middleware@^2.0.3: + version "2.0.6" + resolved "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz" + integrity sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw== + dependencies: + "@types/http-proxy" "^1.17.8" + http-proxy "^1.18.1" + is-glob "^4.0.1" + is-plain-obj "^3.0.0" + micromatch "^4.0.2" + +http-proxy@^1.18.1: + version "1.18.1" + resolved "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz" + integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== + dependencies: + eventemitter3 "^4.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + +https-proxy-agent@^5.0.0, https-proxy-agent@5.0.1: + 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== + dependencies: + agent-base "6" + debug "4" + +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + +humanize-ms@^1.2.1: + version "1.2.1" + resolved "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz" + integrity sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ== + dependencies: + ms "^2.0.0" + +iconv-lite@^0.4.24, iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +iconv-lite@^0.6.2: + version "0.6.3" + resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + +iconv-lite@^0.6.3: + version "0.6.3" + resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + +icss-utils@^5.0.0, icss-utils@^5.1.0: + version "5.1.0" + resolved "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz" + integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== + +ieee754@^1.1.13: + version "1.2.1" + resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + +ignore-walk@^6.0.0: + version "6.0.3" + resolved "https://registry.npmjs.org/ignore-walk/-/ignore-walk-6.0.3.tgz" + integrity sha512-C7FfFoTA+bI10qfeydT8aZbvr91vAEU+2W5BZUlzPec47oNb07SsOfwYrtxuvOYdUApPP/Qlh4DtAO51Ekk2QA== + dependencies: + minimatch "^9.0.0" + +ignore@^5.2.0: + version "5.2.4" + resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz" + integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== + +image-size@~0.5.0: + version "0.5.5" + resolved "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz" + integrity sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ== + +immutable@^4.0.0: + version "4.3.0" + resolved "https://registry.npmjs.org/immutable/-/immutable-4.3.0.tgz" + integrity sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg== + +import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + +infer-owner@^1.0.4: + version "1.0.4" + resolved "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz" + integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3, inherits@2, inherits@2.0.4: + version "2.0.4" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" + integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== + +ini@4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/ini/-/ini-4.0.0.tgz" + integrity sha512-t0ikzf5qkSFqRl1e6ejKBe+Tk2bsQd8ivEkcisyGXsku2t8NvXZ1Y3RRz5vxrDgOrTBOi13CvGsVoI5wVpd7xg== + +inquirer@8.2.4: + version "8.2.4" + resolved "https://registry.npmjs.org/inquirer/-/inquirer-8.2.4.tgz" + integrity sha512-nn4F01dxU8VeKfq192IjLsxu0/OmMZ4Lg3xKAns148rCaXP6ntAoEkVYZThWjwON8AlzdZZi6oqnhNbxUG9hVg== + dependencies: + ansi-escapes "^4.2.1" + chalk "^4.1.1" + cli-cursor "^3.1.0" + cli-width "^3.0.0" + external-editor "^3.0.3" + figures "^3.0.0" + lodash "^4.17.21" + mute-stream "0.0.8" + ora "^5.4.1" + run-async "^2.4.0" + rxjs "^7.5.5" + string-width "^4.1.0" + strip-ansi "^6.0.0" + through "^2.3.6" + wrap-ansi "^7.0.0" + +ip@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz" + integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ== + +ipaddr.js@^2.0.1: + version "2.1.0" + resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz" + integrity sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ== + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz" + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-core-module@^2.11.0, is-core-module@^2.8.1: + version "2.12.1" + resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz" + integrity sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg== + dependencies: + has "^1.0.3" + +is-docker@^2.0.0, is-docker@^2.1.1: + version "2.2.1" + resolved "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-fullwidth-code-point@^3.0.0: + 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== + +is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-interactive@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz" + integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== + +is-lambda@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz" + integrity sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ== + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-plain-obj@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz" + integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA== + +is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +is-unicode-supported@^0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz" + integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== + +is-what@^3.14.1: + version "3.14.1" + resolved "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz" + integrity sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA== + +is-wsl@^2.2.0: + version "2.2.0" + resolved "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + +isbinaryfile@^4.0.8: + version "4.0.10" + resolved "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz" + integrity sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz" + integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== + +istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: + version "3.2.0" + resolved "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz" + integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== + +istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: + version "5.2.1" + resolved "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz" + integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg== + 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" + +istanbul-lib-report@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz" + integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw== + dependencies: + istanbul-lib-coverage "^3.0.0" + make-dir "^3.0.0" + supports-color "^7.1.0" + +istanbul-lib-source-maps@^4.0.1: + 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== + dependencies: + debug "^4.1.1" + istanbul-lib-coverage "^3.0.0" + source-map "^0.6.1" + +istanbul-reports@^3.0.5: + version "3.1.5" + resolved "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz" + integrity sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w== + dependencies: + html-escaper "^2.0.0" + istanbul-lib-report "^3.0.0" + +jackspeak@^2.0.3: + version "2.2.1" + resolved "https://registry.npmjs.org/jackspeak/-/jackspeak-2.2.1.tgz" + integrity sha512-MXbxovZ/Pm42f6cDIDkl3xpwv1AGwObKwfmjs2nQePiy85tP3fatofl3FC1aBsOtP/6fq5SbtgHwWcMsLP+bDw== + dependencies: + "@isaacs/cliui" "^8.0.2" + optionalDependencies: + "@pkgjs/parseargs" "^0.11.0" + +jasmine-core@^4.0.0, jasmine-core@^4.1.0, jasmine-core@~4.6.0: + version "4.6.0" + resolved "https://registry.npmjs.org/jasmine-core/-/jasmine-core-4.6.0.tgz" + integrity sha512-O236+gd0ZXS8YAjFx8xKaJ94/erqUliEkJTDedyE7iHvv4ZVqi+q+8acJxu05/WJDKm512EUNn809In37nWlAQ== + +jest-worker@^27.4.5: + version "27.5.1" + resolved "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz" + integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.13.1: + version "3.14.1" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz" + integrity sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA== + +json-parse-even-better-errors@^2.3.0, json-parse-even-better-errors@^2.3.1: + 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== + +json-parse-even-better-errors@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.0.tgz" + integrity sha512-iZbGHafX/59r39gPwVPRBGw0QQKnA7tte5pSMrhWOW7swGsVvVTjmfyAV9pNqk8YGT7tRCdxRu8uzcgZwoDooA== + +json-schema-traverse@^0.4.1: + 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== + +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + +json5@^2.1.2, json5@^2.2.2: + version "2.2.3" + resolved "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== + +jsonc-parser@3.2.0: + version "3.2.0" + resolved "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz" + integrity sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w== + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz" + integrity sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg== + optionalDependencies: + graceful-fs "^4.1.6" + +jsonparse@^1.3.1: + version "1.3.1" + resolved "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz" + integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg== + +karma-chrome-launcher@~3.2.0: + version "3.2.0" + resolved "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.2.0.tgz" + integrity sha512-rE9RkUPI7I9mAxByQWkGJFXfFD6lE4gC5nPuZdobf/QdTEJI6EU4yIay/cfU/xV4ZxlM5JiTv7zWYgA64NpS5Q== + dependencies: + which "^1.2.1" + +karma-coverage@~2.2.0: + version "2.2.0" + resolved "https://registry.npmjs.org/karma-coverage/-/karma-coverage-2.2.0.tgz" + integrity sha512-gPVdoZBNDZ08UCzdMHHhEImKrw1+PAOQOIiffv1YsvxFhBjqvo/SVXNk4tqn1SYqX0BJZT6S/59zgxiBe+9OuA== + dependencies: + istanbul-lib-coverage "^3.2.0" + istanbul-lib-instrument "^5.1.0" + istanbul-lib-report "^3.0.0" + istanbul-lib-source-maps "^4.0.1" + istanbul-reports "^3.0.5" + minimatch "^3.0.4" + +karma-jasmine-html-reporter@~2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-2.0.0.tgz" + integrity sha512-SB8HNNiazAHXM1vGEzf8/tSyEhkfxuDdhYdPBX2Mwgzt0OuF2gicApQ+uvXLID/gXyJQgvrM9+1/2SxZFUUDIA== + +karma-jasmine@^5.0.0, karma-jasmine@~5.1.0: + version "5.1.0" + resolved "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-5.1.0.tgz" + integrity sha512-i/zQLFrfEpRyQoJF9fsCdTMOF5c2dK7C7OmsuKg2D0YSsuZSfQDiLuaiktbuio6F2wiCsZSnSnieIQ0ant/uzQ== + dependencies: + jasmine-core "^4.1.0" + +karma-source-map-support@1.4.0: + version "1.4.0" + resolved "https://registry.npmjs.org/karma-source-map-support/-/karma-source-map-support-1.4.0.tgz" + integrity sha512-RsBECncGO17KAoJCYXjv+ckIz+Ii9NCi+9enk+rq6XC81ezYkb4/RHE6CTXdA7IOJqoF3wcaLfVG0CPmE5ca6A== + dependencies: + source-map-support "^0.5.5" + +karma@^6.0.0, karma@^6.3.0, karma@~6.4.0: + version "6.4.2" + resolved "https://registry.npmjs.org/karma/-/karma-6.4.2.tgz" + integrity sha512-C6SU/53LB31BEgRg+omznBEMY4SjHU3ricV6zBcAe1EeILKkeScr+fZXtaI5WyDbkVowJxxAI6h73NcFPmXolQ== + dependencies: + "@colors/colors" "1.5.0" + body-parser "^1.19.0" + braces "^3.0.2" + chokidar "^3.5.1" + connect "^3.7.0" + di "^0.0.1" + dom-serialize "^2.2.1" + glob "^7.1.7" + graceful-fs "^4.2.6" + http-proxy "^1.18.1" + isbinaryfile "^4.0.8" + lodash "^4.17.21" + log4js "^6.4.1" + mime "^2.5.2" + minimatch "^3.0.4" + mkdirp "^0.5.5" + qjobs "^1.2.0" + range-parser "^1.2.1" + rimraf "^3.0.2" + socket.io "^4.4.1" + source-map "^0.6.1" + tmp "^0.2.1" + ua-parser-js "^0.7.30" + yargs "^16.1.1" + +kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +klona@^2.0.4, klona@^2.0.6: + version "2.0.6" + resolved "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz" + integrity sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA== + +launch-editor@^2.6.0: + version "2.6.0" + resolved "https://registry.npmjs.org/launch-editor/-/launch-editor-2.6.0.tgz" + integrity sha512-JpDCcQnyAAzZZaZ7vEiSqL690w7dAEyLao+KC96zBplnYbJS7TYNjvM3M7y3dGz+v7aIsJk3hllWuc0kWAjyRQ== + dependencies: + picocolors "^1.0.0" + shell-quote "^1.7.3" + +less-loader@11.1.0: + version "11.1.0" + resolved "https://registry.npmjs.org/less-loader/-/less-loader-11.1.0.tgz" + integrity sha512-C+uDBV7kS7W5fJlUjq5mPBeBVhYpTIm5gB09APT9o3n/ILeaXVsiSFTbZpTJCJwQ/Crczfn3DmfQFwxYusWFug== + dependencies: + klona "^2.0.4" + +less@*, "less@^3.5.0 || ^4.0.0", less@4.1.3: + version "4.1.3" + resolved "https://registry.npmjs.org/less/-/less-4.1.3.tgz" + integrity sha512-w16Xk/Ta9Hhyei0Gpz9m7VS8F28nieJaL/VyShID7cYvP6IL5oHeL6p4TXSDJqZE/lNv0oJ2pGVjJsRkfwm5FA== + dependencies: + copy-anything "^2.0.1" + parse-node-version "^1.0.1" + tslib "^2.3.0" + optionalDependencies: + errno "^0.1.1" + graceful-fs "^4.1.2" + image-size "~0.5.0" + make-dir "^2.1.0" + mime "^1.4.1" + needle "^3.1.0" + source-map "~0.6.0" + +license-webpack-plugin@4.0.2: + version "4.0.2" + resolved "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-4.0.2.tgz" + integrity sha512-771TFWFD70G1wLTC4oU2Cw4qvtmNrIw+wRvBtn+okgHl7slJVi7zfNcdmqDL72BojM30VNJ2UHylr1o77U37Jw== + dependencies: + webpack-sources "^3.0.0" + +lines-and-columns@^1.1.6: + version "1.2.4" + resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== + +loader-runner@^4.2.0: + version "4.3.0" + resolved "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz" + integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== + +loader-utils@^2.0.0: + version "2.0.4" + resolved "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz" + integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^2.1.2" + +loader-utils@3.2.1: + version "3.2.1" + resolved "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz" + integrity sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw== + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz" + integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== + +lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +log-symbols@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz" + integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== + dependencies: + chalk "^4.1.0" + is-unicode-supported "^0.1.0" + +log4js@^6.4.1: + version "6.9.1" + resolved "https://registry.npmjs.org/log4js/-/log4js-6.9.1.tgz" + integrity sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g== + dependencies: + date-format "^4.0.14" + debug "^4.3.4" + flatted "^3.2.7" + rfdc "^1.3.0" + streamroller "^3.1.5" + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +lru-cache@^7.4.4: + version "7.18.3" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz" + integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA== + +lru-cache@^7.5.1: + version "7.18.3" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz" + integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA== + +lru-cache@^7.7.1: + version "7.18.3" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz" + integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA== + +lru-cache@^9.1.1: + version "9.1.2" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-9.1.2.tgz" + integrity sha512-ERJq3FOzJTxBbFjZ7iDs+NiK4VI9Wz+RdrrAB8dio1oV+YvdPzUEE4QNiT2VD51DkIbCYRUUzCRkssXCHqSnKQ== + +magic-string@0.30.0: + version "0.30.0" + resolved "https://registry.npmjs.org/magic-string/-/magic-string-0.30.0.tgz" + integrity sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ== + dependencies: + "@jridgewell/sourcemap-codec" "^1.4.13" + +make-dir@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz" + integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== + dependencies: + pify "^4.0.1" + semver "^5.6.0" + +make-dir@^3.0.0, make-dir@^3.0.2: + version "3.1.0" + resolved "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== + dependencies: + semver "^6.0.0" + +make-error@^1.1.1: + version "1.3.6" + resolved "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + +make-fetch-happen@^10.0.3: + version "10.2.1" + resolved "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz" + integrity sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w== + dependencies: + agentkeepalive "^4.2.1" + cacache "^16.1.0" + http-cache-semantics "^4.1.0" + http-proxy-agent "^5.0.0" + https-proxy-agent "^5.0.0" + is-lambda "^1.0.1" + lru-cache "^7.7.1" + minipass "^3.1.6" + minipass-collect "^1.0.2" + minipass-fetch "^2.0.3" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + negotiator "^0.6.3" + promise-retry "^2.0.1" + socks-proxy-agent "^7.0.0" + ssri "^9.0.0" + +make-fetch-happen@^11.0.0: + version "11.1.1" + resolved "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz" + integrity sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w== + dependencies: + agentkeepalive "^4.2.1" + cacache "^17.0.0" + http-cache-semantics "^4.1.1" + http-proxy-agent "^5.0.0" + https-proxy-agent "^5.0.0" + is-lambda "^1.0.1" + lru-cache "^7.7.1" + minipass "^5.0.0" + minipass-fetch "^3.0.0" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + negotiator "^0.6.3" + promise-retry "^2.0.1" + socks-proxy-agent "^7.0.0" + ssri "^10.0.0" + +make-fetch-happen@^11.0.1: + version "11.1.1" + resolved "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz" + integrity sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w== + dependencies: + agentkeepalive "^4.2.1" + cacache "^17.0.0" + http-cache-semantics "^4.1.1" + http-proxy-agent "^5.0.0" + https-proxy-agent "^5.0.0" + is-lambda "^1.0.1" + lru-cache "^7.7.1" + minipass "^5.0.0" + minipass-fetch "^3.0.0" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + negotiator "^0.6.3" + promise-retry "^2.0.1" + socks-proxy-agent "^7.0.0" + ssri "^10.0.0" + +make-fetch-happen@^11.1.0: + version "11.1.1" + resolved "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz" + integrity sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w== + dependencies: + agentkeepalive "^4.2.1" + cacache "^17.0.0" + http-cache-semantics "^4.1.1" + http-proxy-agent "^5.0.0" + https-proxy-agent "^5.0.0" + is-lambda "^1.0.1" + lru-cache "^7.7.1" + minipass "^5.0.0" + minipass-fetch "^3.0.0" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + negotiator "^0.6.3" + promise-retry "^2.0.1" + socks-proxy-agent "^7.0.0" + ssri "^10.0.0" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz" + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== + +memfs@^3.4.12, memfs@^3.4.3: + version "3.5.3" + resolved "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz" + integrity sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw== + dependencies: + fs-monkey "^1.0.4" + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz" + integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +merge2@^1.3.0, merge2@^1.4.1: + version "1.4.1" + resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz" + integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== + +micromatch@^4.0.2, micromatch@^4.0.4: + version "4.0.5" + resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + +"mime-db@>= 1.43.0 < 2", mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mime@^1.4.1: + version "1.6.0" + resolved "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mime@^2.5.2: + version "2.6.0" + resolved "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz" + integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +mini-css-extract-plugin@2.7.5: + version "2.7.5" + resolved "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.5.tgz" + integrity sha512-9HaR++0mlgom81s95vvNjxkg52n2b5s//3ZTI1EtzFb98awsLSivs2LMsVqnQ3ay0PVhqWcGNyDaTE961FOcjQ== + dependencies: + schema-utils "^4.0.0" + +minimalistic-assert@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimatch@^3.0.4, minimatch@^3.1.1: + version "3.1.2" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimatch@^5.0.1: + version "5.1.6" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz" + integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== + dependencies: + brace-expansion "^2.0.1" + +minimatch@^9.0.0: + version "9.0.1" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz" + integrity sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w== + dependencies: + brace-expansion "^2.0.1" + +minimatch@^9.0.1: + version "9.0.1" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz" + integrity sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w== + dependencies: + brace-expansion "^2.0.1" + +minimist@^1.2.6: + version "1.2.8" + resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + +minipass-collect@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz" + integrity sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA== + dependencies: + minipass "^3.0.0" + +minipass-fetch@^2.0.3: + version "2.1.2" + resolved "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.2.tgz" + integrity sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA== + dependencies: + minipass "^3.1.6" + minipass-sized "^1.0.3" + minizlib "^2.1.2" + optionalDependencies: + encoding "^0.1.13" + +minipass-fetch@^3.0.0: + version "3.0.3" + resolved "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.3.tgz" + integrity sha512-n5ITsTkDqYkYJZjcRWzZt9qnZKCT7nKCosJhHoj7S7zD+BP4jVbWs+odsniw5TA3E0sLomhTKOKjF86wf11PuQ== + dependencies: + minipass "^5.0.0" + minipass-sized "^1.0.3" + minizlib "^2.1.2" + optionalDependencies: + encoding "^0.1.13" + +minipass-flush@^1.0.5: + version "1.0.5" + resolved "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz" + integrity sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw== + dependencies: + minipass "^3.0.0" + +minipass-json-stream@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/minipass-json-stream/-/minipass-json-stream-1.0.1.tgz" + integrity sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg== + dependencies: + jsonparse "^1.3.1" + minipass "^3.0.0" + +minipass-pipeline@^1.2.4: + version "1.2.4" + resolved "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz" + integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A== + dependencies: + minipass "^3.0.0" + +minipass-sized@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz" + integrity sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g== + dependencies: + minipass "^3.0.0" + +minipass@^3.0.0, minipass@^3.1.1, minipass@^3.1.6: + version "3.3.6" + resolved "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz" + integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== + dependencies: + yallist "^4.0.0" + +minipass@^5.0.0, "minipass@^5.0.0 || ^6.0.2": + version "5.0.0" + resolved "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz" + integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== + +minizlib@^2.1.1, minizlib@^2.1.2: + version "2.1.2" + resolved "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz" + integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== + dependencies: + minipass "^3.0.0" + yallist "^4.0.0" + +mkdirp@^0.5.5: + version "0.5.6" + resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz" + integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== + dependencies: + minimist "^1.2.6" + +mkdirp@^1.0.3: + version "1.0.4" + resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + +mkdirp@^1.0.4: + version "1.0.4" + resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + +mrmime@1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/mrmime/-/mrmime-1.0.1.tgz" + integrity sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw== + +ms@^2.0.0, ms@^2.1.1, ms@2.1.2: + version "2.1.2" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + +ms@2.1.3: + version "2.1.3" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +multicast-dns@^7.2.5: + version "7.2.5" + resolved "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz" + integrity sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg== + dependencies: + dns-packet "^5.2.2" + thunky "^1.0.2" + +mute-stream@0.0.8: + version "0.0.8" + resolved "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz" + integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== + +nanoid@^3.3.6: + version "3.3.6" + resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz" + integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA== + +needle@^3.1.0: + version "3.2.0" + resolved "https://registry.npmjs.org/needle/-/needle-3.2.0.tgz" + integrity sha512-oUvzXnyLiVyVGoianLijF9O/RecZUf7TkBfimjGrLM4eQhXyeJwM6GeAWccwfQ9aa4gMCZKqhAOuLaMIcQxajQ== + dependencies: + debug "^3.2.6" + iconv-lite "^0.6.3" + sax "^1.2.4" + +negotiator@^0.6.3, negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + +neo-async@^2.6.2: + version "2.6.2" + resolved "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + +ngx-scanner-qrcode@^1.5.8: + version "1.5.8" + resolved "https://registry.npmjs.org/ngx-scanner-qrcode/-/ngx-scanner-qrcode-1.5.8.tgz" + integrity sha512-jLfSgxzQidLuYIsIACfTvi9zEh8aT5Jg7JynewuXWZYZpXHRlaJntkfheMGGQBeY/l9RBrTW4NEXY2XI4T+F2Q== + dependencies: + tslib "^2.3.0" + +node-forge@^1: + version "1.3.1" + resolved "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz" + integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== + +node-gyp@^9.0.0: + version "9.3.1" + resolved "https://registry.npmjs.org/node-gyp/-/node-gyp-9.3.1.tgz" + integrity sha512-4Q16ZCqq3g8awk6UplT7AuxQ35XN4R/yf/+wSAwcBUAjg7l58RTactWaP8fIDTi0FzI7YcVLujwExakZlfWkXg== + dependencies: + env-paths "^2.2.0" + glob "^7.1.4" + graceful-fs "^4.2.6" + make-fetch-happen "^10.0.3" + nopt "^6.0.0" + npmlog "^6.0.0" + rimraf "^3.0.2" + semver "^7.3.5" + tar "^6.1.2" + which "^2.0.2" + +node-releases@^2.0.8: + version "2.0.12" + resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.12.tgz" + integrity sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ== + +nopt@^6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz" + integrity sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g== + dependencies: + abbrev "^1.0.0" + +normalize-package-data@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-5.0.0.tgz" + integrity sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q== + dependencies: + hosted-git-info "^6.0.0" + is-core-module "^2.8.1" + semver "^7.3.5" + validate-npm-package-license "^3.0.4" + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +normalize-range@^0.1.2: + version "0.1.2" + resolved "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz" + integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== + +npm-bundled@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/npm-bundled/-/npm-bundled-3.0.0.tgz" + integrity sha512-Vq0eyEQy+elFpzsKjMss9kxqb9tG3YHg4dsyWuUENuzvSUWe1TCnW/vV9FkhvBk/brEDoDiVd+M1Btosa6ImdQ== + dependencies: + npm-normalize-package-bin "^3.0.0" + +npm-install-checks@^6.0.0: + version "6.1.1" + resolved "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-6.1.1.tgz" + integrity sha512-dH3GmQL4vsPtld59cOn8uY0iOqRmqKvV+DLGwNXV/Q7MDgD2QfOADWd/mFXcIE5LVhYYGjA3baz6W9JneqnuCw== + dependencies: + semver "^7.1.1" + +npm-normalize-package-bin@^3.0.0: + version "3.0.1" + resolved "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz" + integrity sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ== + +npm-package-arg@^10.0.0, npm-package-arg@10.1.0: + version "10.1.0" + resolved "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-10.1.0.tgz" + integrity sha512-uFyyCEmgBfZTtrKk/5xDfHp6+MdrqGotX/VoOyEEl3mBwiEE5FlBaePanazJSVMPT7vKepcjYBY2ztg9A3yPIA== + dependencies: + hosted-git-info "^6.0.0" + proc-log "^3.0.0" + semver "^7.3.5" + validate-npm-package-name "^5.0.0" + +npm-packlist@^7.0.0: + version "7.0.4" + resolved "https://registry.npmjs.org/npm-packlist/-/npm-packlist-7.0.4.tgz" + integrity sha512-d6RGEuRrNS5/N84iglPivjaJPxhDbZmlbTwTDX2IbcRHG5bZCdtysYMhwiPvcF4GisXHGn7xsxv+GQ7T/02M5Q== + dependencies: + ignore-walk "^6.0.0" + +npm-pick-manifest@^8.0.0, npm-pick-manifest@8.0.1: + version "8.0.1" + resolved "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-8.0.1.tgz" + integrity sha512-mRtvlBjTsJvfCCdmPtiu2bdlx8d/KXtF7yNXNWe7G0Z36qWA9Ny5zXsI2PfBZEv7SXgoxTmNaTzGSbbzDZChoA== + dependencies: + npm-install-checks "^6.0.0" + npm-normalize-package-bin "^3.0.0" + npm-package-arg "^10.0.0" + semver "^7.3.5" + +npm-registry-fetch@^14.0.0: + version "14.0.5" + resolved "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-14.0.5.tgz" + integrity sha512-kIDMIo4aBm6xg7jOttupWZamsZRkAqMqwqqbVXnUqstY5+tapvv6bkH/qMR76jdgV+YljEUCyWx3hRYMrJiAgA== + dependencies: + make-fetch-happen "^11.0.0" + minipass "^5.0.0" + minipass-fetch "^3.0.0" + minipass-json-stream "^1.0.1" + minizlib "^2.1.2" + npm-package-arg "^10.0.0" + proc-log "^3.0.0" + +npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +npmlog@^6.0.0: + version "6.0.2" + resolved "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz" + integrity sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg== + dependencies: + are-we-there-yet "^3.0.0" + console-control-strings "^1.1.0" + gauge "^4.0.3" + set-blocking "^2.0.0" + +nth-check@^2.0.1: + version "2.1.1" + resolved "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz" + integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== + dependencies: + boolbase "^1.0.0" + +object-assign@^4: + version "4.1.1" + resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== + +object-inspect@^1.9.0: + version "1.12.3" + resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz" + integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== + +obuf@^1.0.0, obuf@^1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz" + integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz" + integrity sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww== + dependencies: + ee-first "1.1.1" + +on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + +on-headers@~1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz" + integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +onetime@^5.1.0, onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +open@^8.0.9, open@8.4.2: + version "8.4.2" + resolved "https://registry.npmjs.org/open/-/open-8.4.2.tgz" + integrity sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ== + dependencies: + define-lazy-prop "^2.0.0" + is-docker "^2.1.1" + is-wsl "^2.2.0" + +ora@^5.4.1, ora@5.4.1: + version "5.4.1" + resolved "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz" + integrity sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ== + dependencies: + bl "^4.1.0" + chalk "^4.1.0" + cli-cursor "^3.1.0" + cli-spinners "^2.5.0" + is-interactive "^1.0.0" + is-unicode-supported "^0.1.0" + log-symbols "^4.1.0" + strip-ansi "^6.0.0" + wcwidth "^1.0.1" + +os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz" + integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== + +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-map@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz" + integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== + dependencies: + aggregate-error "^3.0.0" + +p-retry@^4.5.0: + version "4.6.2" + resolved "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz" + integrity sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ== + dependencies: + "@types/retry" "0.12.0" + retry "^0.13.1" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +pacote@15.1.3: + version "15.1.3" + resolved "https://registry.npmjs.org/pacote/-/pacote-15.1.3.tgz" + integrity sha512-aRts8cZqxiJVDitmAh+3z+FxuO3tLNWEmwDRPEpDDiZJaRz06clP4XX112ynMT5uF0QNoMPajBBHnaStUEPJXA== + dependencies: + "@npmcli/git" "^4.0.0" + "@npmcli/installed-package-contents" "^2.0.1" + "@npmcli/promise-spawn" "^6.0.1" + "@npmcli/run-script" "^6.0.0" + cacache "^17.0.0" + fs-minipass "^3.0.0" + minipass "^5.0.0" + npm-package-arg "^10.0.0" + npm-packlist "^7.0.0" + npm-pick-manifest "^8.0.0" + npm-registry-fetch "^14.0.0" + proc-log "^3.0.0" + promise-retry "^2.0.1" + read-package-json "^6.0.0" + read-package-json-fast "^3.0.0" + sigstore "^1.3.0" + ssri "^10.0.0" + tar "^6.1.11" + +pako@^1.0.3: + version "1.0.11" + resolved "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz" + integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +parse-json@^5.0.0: + version "5.2.0" + resolved "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + +parse-node-version@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz" + integrity sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA== + +parse5-html-rewriting-stream@7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/parse5-html-rewriting-stream/-/parse5-html-rewriting-stream-7.0.0.tgz" + integrity sha512-mazCyGWkmCRWDI15Zp+UiCqMp/0dgEmkZRvhlsqqKYr4SsVm/TvnSpD9fCvqCA2zoWJcfRym846ejWBBHRiYEg== + dependencies: + entities "^4.3.0" + parse5 "^7.0.0" + parse5-sax-parser "^7.0.0" + +parse5-htmlparser2-tree-adapter@^6.0.1: + version "6.0.1" + resolved "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz" + integrity sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA== + dependencies: + parse5 "^6.0.1" + +parse5-sax-parser@^7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/parse5-sax-parser/-/parse5-sax-parser-7.0.0.tgz" + integrity sha512-5A+v2SNsq8T6/mG3ahcz8ZtQ0OUFTatxPbeidoMB7tkJSGDY3tdfl4MHovtLQHkEn5CGxijNWRQHhRQ6IRpXKg== + dependencies: + parse5 "^7.0.0" + +parse5@^6.0.1: + version "6.0.1" + resolved "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz" + integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== + +parse5@^7.0.0: + version "7.1.2" + resolved "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz" + integrity sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw== + dependencies: + entities "^4.4.0" + +parse5@^7.1.2: + version "7.1.2" + resolved "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz" + integrity sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw== + dependencies: + entities "^4.4.0" + +parseurl@~1.3.2, parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-scurry@^1.7.0: + version "1.9.2" + resolved "https://registry.npmjs.org/path-scurry/-/path-scurry-1.9.2.tgz" + integrity sha512-qSDLy2aGFPm8i4rsbHd4MNyTcrzHFsLQykrtbuGRknZZCBBVXSv2tSCDN2Cg6Rt/GFRw8GoW9y9Ecw5rIPG1sg== + dependencies: + lru-cache "^9.1.1" + minipass "^5.0.0 || ^6.0.2" + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz" + integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1, picomatch@2.3.1: + version "2.3.1" + resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pify@^4.0.1: + version "4.0.1" + resolved "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz" + integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== + +piscina@3.2.0: + version "3.2.0" + resolved "https://registry.npmjs.org/piscina/-/piscina-3.2.0.tgz" + integrity sha512-yn/jMdHRw+q2ZJhFhyqsmANcbF6V2QwmD84c6xRau+QpQOmtrBCoRGdvTfeuFDYXB5W2m6MfLkjkvQa9lUSmIA== + dependencies: + eventemitter-asyncresource "^1.0.0" + hdr-histogram-js "^2.0.1" + hdr-histogram-percentiles-obj "^3.0.0" + optionalDependencies: + nice-napi "^1.0.2" + +pkg-dir@^4.1.0: + 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== + dependencies: + find-up "^4.0.0" + +postcss-loader@7.2.4: + version "7.2.4" + resolved "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.2.4.tgz" + integrity sha512-F88rpxxNspo5hatIc+orYwZDtHFaVFOSIVAx+fBfJC1GmhWbVmPWtmg2gXKE1OxJbneOSGn8PWdIwsZFcruS+w== + dependencies: + cosmiconfig "^8.1.3" + cosmiconfig-typescript-loader "^4.3.0" + klona "^2.0.6" + semver "^7.3.8" + +postcss-modules-extract-imports@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz" + integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== + +postcss-modules-local-by-default@^4.0.0: + version "4.0.3" + resolved "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.3.tgz" + integrity sha512-2/u2zraspoACtrbFRnTijMiQtb4GW4BvatjaG/bCjYQo8kLTdevCUlwuBHx2sCnSyrI3x3qj4ZK1j5LQBgzmwA== + dependencies: + icss-utils "^5.0.0" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.1.0" + +postcss-modules-scope@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz" + integrity sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg== + dependencies: + postcss-selector-parser "^6.0.4" + +postcss-modules-values@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz" + integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ== + dependencies: + icss-utils "^5.0.0" + +postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: + version "6.0.13" + resolved "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz" + integrity sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ== + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + +postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: + version "4.2.0" + resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz" + integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== + +"postcss@^7.0.0 || ^8.0.1", postcss@^8.1.0, postcss@^8.2.14, postcss@^8.3.7, postcss@^8.4.19, postcss@^8.4.23, postcss@8.4.23: + version "8.4.23" + resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.23.tgz" + integrity sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA== + dependencies: + nanoid "^3.3.6" + picocolors "^1.0.0" + source-map-js "^1.0.2" + +pretty-bytes@^5.3.0: + version "5.6.0" + resolved "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz" + integrity sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg== + +proc-log@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/proc-log/-/proc-log-3.0.0.tgz" + integrity sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A== + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz" + integrity sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g== + +promise-retry@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz" + integrity sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g== + dependencies: + err-code "^2.0.2" + retry "^0.12.0" + +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz" + integrity sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw== + +punycode@^2.1.0: + version "2.3.0" + resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz" + integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== + +qjobs@^1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz" + integrity sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg== + +qs@6.11.0: + version "6.11.0" + resolved "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz" + integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== + dependencies: + side-channel "^1.0.4" + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +range-parser@^1.2.1, range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.5.1: + version "2.5.1" + resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz" + integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + +raw-body@2.5.2: + version "2.5.2" + resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz" + integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + +read-package-json-fast@^3.0.0: + version "3.0.2" + resolved "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-3.0.2.tgz" + integrity sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw== + dependencies: + json-parse-even-better-errors "^3.0.0" + npm-normalize-package-bin "^3.0.0" + +read-package-json@^6.0.0: + version "6.0.4" + resolved "https://registry.npmjs.org/read-package-json/-/read-package-json-6.0.4.tgz" + integrity sha512-AEtWXYfopBj2z5N5PbkAOeNHRPUg5q+Nen7QLxV8M2zJq1ym6/lCz3fYNTCXe19puu2d06jfHhrP7v/S2PtMMw== + dependencies: + glob "^10.2.2" + json-parse-even-better-errors "^3.0.0" + normalize-package-data "^5.0.0" + npm-normalize-package-bin "^3.0.0" + +readable-stream@^2.0.1: + version "2.3.8" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz" + integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.0.6, readable-stream@^3.4.0, readable-stream@^3.6.0: + version "3.6.2" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +reflect-metadata@^0.1.2: + version "0.1.13" + resolved "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz" + integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg== + +regenerate-unicode-properties@^10.1.0: + version "10.1.0" + resolved "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz" + integrity sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ== + dependencies: + regenerate "^1.4.2" + +regenerate@^1.4.2: + version "1.4.2" + resolved "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz" + integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== + +regenerator-runtime@^0.13.11: + version "0.13.11" + resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz" + integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== + +regenerator-transform@^0.15.1: + version "0.15.1" + resolved "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz" + integrity sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg== + dependencies: + "@babel/runtime" "^7.8.4" + +regex-parser@^2.2.11: + version "2.2.11" + resolved "https://registry.npmjs.org/regex-parser/-/regex-parser-2.2.11.tgz" + integrity sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q== + +regexpu-core@^5.3.1: + version "5.3.2" + resolved "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz" + integrity sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ== + dependencies: + "@babel/regjsgen" "^0.8.0" + regenerate "^1.4.2" + regenerate-unicode-properties "^10.1.0" + regjsparser "^0.9.1" + unicode-match-property-ecmascript "^2.0.0" + unicode-match-property-value-ecmascript "^2.1.0" + +regjsparser@^0.9.1: + version "0.9.1" + resolved "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz" + integrity sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ== + dependencies: + jsesc "~0.5.0" + +require-directory@^2.1.1: + 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== + +require-from-string@^2.0.2: + 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== + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz" + integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve-url-loader@5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-5.0.0.tgz" + integrity sha512-uZtduh8/8srhBoMx//5bwqjQ+rfYOUq8zC9NrMUGtjBiGTtFJM42s58/36+hTqeqINcnYe08Nj3LkK9lW4N8Xg== + dependencies: + adjust-sourcemap-loader "^4.0.0" + convert-source-map "^1.7.0" + loader-utils "^2.0.0" + postcss "^8.2.14" + source-map "0.6.1" + +resolve@^1.14.2, resolve@1.22.2: + version "1.22.2" + resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz" + integrity sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g== + dependencies: + is-core-module "^2.11.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +restore-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz" + integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" + +retry@^0.12.0: + version "0.12.0" + resolved "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz" + integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== + +retry@^0.13.1: + version "0.13.1" + resolved "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz" + integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rfdc@^1.3.0: + version "1.3.0" + resolved "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz" + integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== + +rimraf@^3.0.0, rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +rollup@^3.21.0: + version "3.24.1" + resolved "https://registry.npmjs.org/rollup/-/rollup-3.24.1.tgz" + integrity sha512-REHe5dx30ERBRFS0iENPHy+t6wtSEYkjrhwNsLyh3qpRaZ1+aylvMUdMBUHWUD/RjjLmLzEvY8Z9XRlpcdIkHA== + optionalDependencies: + fsevents "~2.3.2" + +run-async@^2.4.0: + version "2.4.1" + resolved "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz" + integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +"rxjs@^6.5.3 || ^7.4.0", rxjs@^7.5.5, rxjs@~7.8.0, rxjs@7.8.1: + version "7.8.1" + resolved "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz" + integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== + dependencies: + tslib "^2.1.0" + +safe-buffer@^5.1.0, safe-buffer@>=5.1.0, safe-buffer@~5.2.0, safe-buffer@5.2.1: + version "5.2.1" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-buffer@5.1.2: + version "5.1.2" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": + version "2.1.2" + resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +safevalues@^0.3.4: + version "0.3.4" + resolved "https://registry.npmjs.org/safevalues/-/safevalues-0.3.4.tgz" + integrity sha512-LRneZZRXNgjzwG4bDQdOTSbze3fHm1EAKN/8bePxnlEZiBmkYEDggaHbuvHI9/hoqHbGfsEA7tWS9GhYHZBBsw== + +sass-loader@13.2.2: + version "13.2.2" + resolved "https://registry.npmjs.org/sass-loader/-/sass-loader-13.2.2.tgz" + integrity sha512-nrIdVAAte3B9icfBiGWvmMhT/D+eCDwnk+yA7VE/76dp/WkHX+i44Q/pfo71NYbwj0Ap+PGsn0ekOuU1WFJ2AA== + dependencies: + klona "^2.0.6" + neo-async "^2.6.2" + +sass@*, sass@^1.3.0, sass@1.62.1: + version "1.62.1" + resolved "https://registry.npmjs.org/sass/-/sass-1.62.1.tgz" + integrity sha512-NHpxIzN29MXvWiuswfc1W3I0N8SXBd8UR26WntmDlRYf0bSADnwnOjsyMZ3lMezSlArD33Vs3YFhp7dWvL770A== + dependencies: + chokidar ">=3.0.0 <4.0.0" + immutable "^4.0.0" + source-map-js ">=0.6.2 <2.0.0" + +sax@^1.2.4: + version "1.2.4" + resolved "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + +schema-utils@^3.1.1: + version "3.2.0" + resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-3.2.0.tgz" + integrity sha512-0zTyLGyDJYd/MBxG1AhJkKa6fpEBds4OQO2ut0w7OYG+ZGhGea09lijvzsqegYSik88zc7cUtIlnnO+/BvD6gQ== + dependencies: + "@types/json-schema" "^7.0.8" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + +schema-utils@^3.1.2: + version "3.2.0" + resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-3.2.0.tgz" + integrity sha512-0zTyLGyDJYd/MBxG1AhJkKa6fpEBds4OQO2ut0w7OYG+ZGhGea09lijvzsqegYSik88zc7cUtIlnnO+/BvD6gQ== + dependencies: + "@types/json-schema" "^7.0.8" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + +schema-utils@^4.0.0: + version "4.1.0" + resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-4.1.0.tgz" + integrity sha512-Jw+GZVbP5IggB2WAn6UHI02LBwGmsIeYN/lNbSMZyDziQ7jmtAUrqKqDja+W89YHVs+KL/3IkIMltAklqB1vAw== + dependencies: + "@types/json-schema" "^7.0.9" + ajv "^8.9.0" + ajv-formats "^2.1.1" + ajv-keywords "^5.1.0" + +select-hose@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz" + integrity sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg== + +selfsigned@^2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/selfsigned/-/selfsigned-2.1.1.tgz" + integrity sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ== + dependencies: + node-forge "^1" + +semver@^5.6.0: + version "5.7.1" + resolved "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@^6.0.0: + version "6.3.0" + resolved "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +semver@^6.1.1: + version "6.3.0" + resolved "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +semver@^6.1.2: + version "6.3.0" + resolved "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +semver@^6.3.0: + version "6.3.0" + resolved "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +semver@^7.0.0, semver@^7.1.1, semver@^7.3.5, semver@^7.3.8, semver@7.4.0: + version "7.4.0" + resolved "https://registry.npmjs.org/semver/-/semver-7.4.0.tgz" + integrity sha512-RgOxM8Mw+7Zus0+zcLEUn8+JfoLpj/huFTItQy2hsM4khuC1HYRDp0cU482Ewn/Fcy6bCjufD8vAj7voC66KQw== + dependencies: + lru-cache "^6.0.0" + +send@0.18.0: + version "0.18.0" + resolved "https://registry.npmjs.org/send/-/send-0.18.0.tgz" + integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== + dependencies: + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "2.0.0" + mime "1.6.0" + ms "2.1.3" + on-finished "2.4.1" + range-parser "~1.2.1" + statuses "2.0.1" + +serialize-javascript@^6.0.0, serialize-javascript@^6.0.1: + version "6.0.1" + resolved "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz" + integrity sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w== + dependencies: + randombytes "^2.1.0" + +serve-index@^1.9.1: + version "1.9.1" + resolved "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz" + integrity sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw== + dependencies: + accepts "~1.3.4" + batch "0.6.1" + debug "2.6.9" + escape-html "~1.0.3" + http-errors "~1.6.2" + mime-types "~2.1.17" + parseurl "~1.3.2" + +serve-static@1.15.0: + version "1.15.0" + resolved "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz" + integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.18.0" + +set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz" + integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +shallow-clone@^3.0.0: + version "3.0.1" + resolved "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz" + integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== + dependencies: + kind-of "^6.0.2" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +shell-quote@^1.7.3: + version "1.8.1" + resolved "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz" + integrity sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA== + +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + +signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: + version "3.0.7" + resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +signal-exit@^4.0.1: + version "4.0.2" + resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz" + integrity sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q== + +sigstore@^1.3.0: + version "1.6.0" + resolved "https://registry.npmjs.org/sigstore/-/sigstore-1.6.0.tgz" + integrity sha512-QODKff/qW/TXOZI6V/Clqu74xnInAS6it05mufj4/fSewexLtfEntgLZZcBtUK44CDQyUE5TUXYy1ARYzlfG9g== + dependencies: + "@sigstore/protobuf-specs" "^0.1.0" + "@sigstore/tuf" "^1.0.0" + make-fetch-happen "^11.0.1" + tuf-js "^1.1.3" + +slash@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz" + integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew== + +smart-buffer@^4.2.0: + version "4.2.0" + resolved "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz" + integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== + +socket.io-adapter@~2.5.2: + version "2.5.2" + resolved "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.2.tgz" + integrity sha512-87C3LO/NOMc+eMcpcxUBebGjkpMDkNBS9tf7KJqcDsmL936EChtVva71Dw2q4tQcuVC+hAUy4an2NO/sYXmwRA== + dependencies: + ws "~8.11.0" + +socket.io-parser@~4.2.4: + version "4.2.4" + resolved "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz" + integrity sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew== + dependencies: + "@socket.io/component-emitter" "~3.1.0" + debug "~4.3.1" + +socket.io@^4.4.1: + version "4.6.2" + resolved "https://registry.npmjs.org/socket.io/-/socket.io-4.6.2.tgz" + integrity sha512-Vp+lSks5k0dewYTfwgPT9UeGGd+ht7sCpB7p0e83VgO4X/AHYWhXITMrNk/pg8syY2bpx23ptClCQuHhqi2BgQ== + dependencies: + accepts "~1.3.4" + base64id "~2.0.0" + debug "~4.3.2" + engine.io "~6.4.2" + socket.io-adapter "~2.5.2" + socket.io-parser "~4.2.4" + +sockjs@^0.3.24: + version "0.3.24" + resolved "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz" + integrity sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ== + dependencies: + faye-websocket "^0.11.3" + uuid "^8.3.2" + websocket-driver "^0.7.4" + +socks-proxy-agent@^7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz" + integrity sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww== + dependencies: + agent-base "^6.0.2" + debug "^4.3.3" + socks "^2.6.2" + +socks@^2.6.2: + version "2.7.1" + resolved "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz" + integrity sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ== + dependencies: + ip "^2.0.0" + smart-buffer "^4.2.0" + +source-map-js@^1.0.2, "source-map-js@>=0.6.2 <2.0.0": + version "1.0.2" + resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz" + integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== + +source-map-loader@4.0.1: + version "4.0.1" + resolved "https://registry.npmjs.org/source-map-loader/-/source-map-loader-4.0.1.tgz" + integrity sha512-oqXpzDIByKONVY8g1NUPOTQhe0UTU5bWUl32GSkqK2LjJj0HmwTMVKxcUip0RgAYhY1mqgOxjbQM48a0mmeNfA== + dependencies: + abab "^2.0.6" + iconv-lite "^0.6.3" + source-map-js "^1.0.2" + +source-map-support@^0.5.5, source-map-support@~0.5.20, source-map-support@0.5.21: + 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== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0: + version "0.6.1" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@^0.6.1: + version "0.6.1" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@~0.6.0: + version "0.6.1" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@0.6.1: + version "0.6.1" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@0.7.4: + version "0.7.4" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz" + integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== + +spdx-correct@^3.0.0: + version "3.2.0" + resolved "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz" + integrity sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.3.0" + resolved "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz" + integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== + +spdx-expression-parse@^3.0.0: + version "3.0.1" + resolved "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz" + integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.13" + resolved "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz" + integrity sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w== + +spdy-transport@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz" + integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== + dependencies: + debug "^4.1.0" + detect-node "^2.0.4" + hpack.js "^2.1.6" + obuf "^1.1.2" + readable-stream "^3.0.6" + wbuf "^1.7.3" + +spdy@^4.0.2: + version "4.0.2" + resolved "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz" + integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA== + dependencies: + debug "^4.1.0" + handle-thing "^2.0.0" + http-deceiver "^1.2.7" + select-hose "^2.0.0" + spdy-transport "^3.0.0" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" + integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== + +ssri@^10.0.0: + version "10.0.4" + resolved "https://registry.npmjs.org/ssri/-/ssri-10.0.4.tgz" + integrity sha512-12+IR2CB2C28MMAw0Ncqwj5QbTcs0nGIhgJzYWzDkb21vWmfNI83KS4f3Ci6GI98WreIfG7o9UXp3C0qbpA8nQ== + dependencies: + minipass "^5.0.0" + +ssri@^9.0.0: + version "9.0.1" + resolved "https://registry.npmjs.org/ssri/-/ssri-9.0.1.tgz" + integrity sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q== + dependencies: + minipass "^3.1.1" + +"statuses@>= 1.4.0 < 2", statuses@~1.5.0: + version "1.5.0" + resolved "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz" + integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== + +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + +streamroller@^3.1.5: + version "3.1.5" + resolved "https://registry.npmjs.org/streamroller/-/streamroller-3.1.5.tgz" + integrity sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw== + dependencies: + date-format "^4.0.14" + debug "^4.3.4" + fs-extra "^8.1.0" + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^5.0.1, string-width@^5.1.2: + version "5.1.2" + resolved "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz" + integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== + dependencies: + eastasianwidth "^0.2.0" + emoji-regex "^9.2.2" + strip-ansi "^7.0.1" + +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": + version "6.0.1" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^7.0.1: + version "7.1.0" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz" + integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== + dependencies: + ansi-regex "^6.0.1" + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-color@^8.0.0: + version "8.1.1" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + 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== + +symbol-observable@4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz" + integrity sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ== + +tapable@^2.1.1, tapable@^2.2.0: + version "2.2.1" + resolved "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz" + integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== + +tar@^6.1.11, tar@^6.1.2: + version "6.1.15" + resolved "https://registry.npmjs.org/tar/-/tar-6.1.15.tgz" + integrity sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A== + dependencies: + chownr "^2.0.0" + fs-minipass "^2.0.0" + minipass "^5.0.0" + minizlib "^2.1.1" + mkdirp "^1.0.3" + yallist "^4.0.0" + +terser-webpack-plugin@^5.3.7: + version "5.3.9" + resolved "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz" + integrity sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA== + dependencies: + "@jridgewell/trace-mapping" "^0.3.17" + jest-worker "^27.4.5" + schema-utils "^3.1.1" + serialize-javascript "^6.0.1" + terser "^5.16.8" + +terser@^5.16.8, terser@^5.4.0, terser@5.17.1: + version "5.17.1" + resolved "https://registry.npmjs.org/terser/-/terser-5.17.1.tgz" + integrity sha512-hVl35zClmpisy6oaoKALOpS0rDYLxRFLHhRuDlEGTKey9qHjS1w9GMORjuwIMt70Wan4lwsLYyWDVnWgF+KUEw== + dependencies: + "@jridgewell/source-map" "^0.3.2" + acorn "^8.5.0" + commander "^2.20.0" + source-map-support "~0.5.20" + +test-exclude@^6.0.0: + 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== + dependencies: + "@istanbuljs/schema" "^0.1.2" + glob "^7.1.4" + minimatch "^3.0.4" + +text-table@0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" + integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== + +through@^2.3.6: + version "2.3.8" + resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz" + integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== + +thunky@^1.0.2: + version "1.1.0" + resolved "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz" + integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== + +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== + dependencies: + os-tmpdir "~1.0.2" + +tmp@^0.2.1: + version "0.2.1" + resolved "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz" + integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== + dependencies: + rimraf "^3.0.0" + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz" + integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== + +to-regex-range@^5.0.1: + 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== + dependencies: + is-number "^7.0.0" + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +tree-kill@1.2.2: + version "1.2.2" + resolved "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz" + integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== + +ts-node@>=10: + version "10.9.1" + resolved "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz" + integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== + 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" + +tslib@^2.1.0, tslib@^2.3.0, tslib@^2.4.1, tslib@^2.6.0: + version "2.6.0" + resolved "https://registry.npmjs.org/tslib/-/tslib-2.6.0.tgz" + integrity sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA== + +tslib@2.5.0: + version "2.5.0" + resolved "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz" + integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== + +tuf-js@^1.1.3: + version "1.1.6" + resolved "https://registry.npmjs.org/tuf-js/-/tuf-js-1.1.6.tgz" + integrity sha512-CXwFVIsXGbVY4vFiWF7TJKWmlKJAT8TWkH4RmiohJRcDJInix++F0dznDmoVbtJNzZ8yLprKUG4YrDIhv3nBMg== + dependencies: + "@tufjs/models" "1.0.4" + debug "^4.3.4" + make-fetch-happen "^11.1.0" + +type-fest@^0.21.3: + 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== + +type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +typed-assert@^1.0.8: + version "1.0.9" + resolved "https://registry.npmjs.org/typed-assert/-/typed-assert-1.0.9.tgz" + integrity sha512-KNNZtayBCtmnNmbo5mG47p1XsCyrx6iVqomjcZnec/1Y5GGARaxPs6r49RnSPeUP3YjNYiU9sQHAtY4BBvnZwg== + +typescript@>=2.7, typescript@>=3, typescript@>=4, "typescript@>=4.9.3 <5.1", typescript@~5.0.2: + version "5.0.4" + resolved "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz" + integrity sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw== + +ua-parser-js@^0.7.30: + version "0.7.35" + resolved "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.35.tgz" + integrity sha512-veRf7dawaj9xaWEu9HoTVn5Pggtc/qj+kqTOFvNiN1l0YdxwC1kvel57UCjThjGa3BHBihE8/UJAHI+uQHmd/g== + +unicode-canonical-property-names-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz" + integrity sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ== + +unicode-match-property-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz" + integrity sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q== + dependencies: + unicode-canonical-property-names-ecmascript "^2.0.0" + unicode-property-aliases-ecmascript "^2.0.0" + +unicode-match-property-value-ecmascript@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz" + integrity sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA== + +unicode-property-aliases-ecmascript@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz" + integrity sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w== + +unique-filename@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/unique-filename/-/unique-filename-2.0.1.tgz" + integrity sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A== + dependencies: + unique-slug "^3.0.0" + +unique-filename@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz" + integrity sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g== + dependencies: + unique-slug "^4.0.0" + +unique-slug@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/unique-slug/-/unique-slug-3.0.0.tgz" + integrity sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w== + dependencies: + imurmurhash "^0.1.4" + +unique-slug@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz" + integrity sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ== + dependencies: + imurmurhash "^0.1.4" + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +unpipe@~1.0.0, unpipe@1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" + integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== + +update-browserslist-db@^1.0.10: + version "1.0.11" + resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz" + integrity sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz" + integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== + +uuid@^8.3.2: + version "8.3.2" + resolved "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + +v8-compile-cache-lib@^3.0.1: + 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== + +validate-npm-package-license@^3.0.4: + version "3.0.4" + resolved "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +validate-npm-package-name@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.0.tgz" + integrity sha512-YuKoXDAhBYxY7SfOKxHBDoSyENFeW5VvIIQp2TGQuit8gpK6MnWaQelBKxso72DoxTZfZdcP3W90LqpSkgPzLQ== + dependencies: + builtins "^5.0.0" + +vary@^1, vary@~1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz" + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== + +"vite@^3.0.0 || ^4.0.0", vite@4.3.9: + version "4.3.9" + resolved "https://registry.npmjs.org/vite/-/vite-4.3.9.tgz" + integrity sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg== + dependencies: + esbuild "^0.17.5" + postcss "^8.4.23" + rollup "^3.21.0" + optionalDependencies: + fsevents "~2.3.2" + +void-elements@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz" + integrity sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung== + +watchpack@^2.4.0: + version "2.4.0" + resolved "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz" + integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg== + dependencies: + glob-to-regexp "^0.4.1" + graceful-fs "^4.1.2" + +wbuf@^1.1.0, wbuf@^1.7.3: + version "1.7.3" + resolved "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz" + integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== + dependencies: + minimalistic-assert "^1.0.0" + +wcwidth@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz" + integrity sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg== + dependencies: + defaults "^1.0.3" + +webpack-dev-middleware@^5.3.1: + version "5.3.3" + resolved "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz" + integrity sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA== + dependencies: + colorette "^2.0.10" + memfs "^3.4.3" + mime-types "^2.1.31" + range-parser "^1.2.1" + schema-utils "^4.0.0" + +webpack-dev-middleware@6.0.2: + version "6.0.2" + resolved "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-6.0.2.tgz" + integrity sha512-iOddiJzPcQC6lwOIu60vscbGWth8PCRcWRCwoQcTQf9RMoOWBHg5EyzpGdtSmGMrSPd5vHEfFXmVErQEmkRngQ== + dependencies: + colorette "^2.0.10" + memfs "^3.4.12" + mime-types "^2.1.31" + range-parser "^1.2.1" + schema-utils "^4.0.0" + +webpack-dev-server@^4.0.0, webpack-dev-server@4.13.2: + version "4.13.2" + resolved "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.13.2.tgz" + integrity sha512-5i6TrGBRxG4vnfDpB6qSQGfnB6skGBXNL5/542w2uRGLimX6qeE5BQMLrzIC3JYV/xlGOv+s+hTleI9AZKUQNw== + dependencies: + "@types/bonjour" "^3.5.9" + "@types/connect-history-api-fallback" "^1.3.5" + "@types/express" "^4.17.13" + "@types/serve-index" "^1.9.1" + "@types/serve-static" "^1.13.10" + "@types/sockjs" "^0.3.33" + "@types/ws" "^8.5.1" + ansi-html-community "^0.0.8" + bonjour-service "^1.0.11" + chokidar "^3.5.3" + colorette "^2.0.10" + compression "^1.7.4" + connect-history-api-fallback "^2.0.0" + default-gateway "^6.0.3" + express "^4.17.3" + graceful-fs "^4.2.6" + html-entities "^2.3.2" + http-proxy-middleware "^2.0.3" + ipaddr.js "^2.0.1" + launch-editor "^2.6.0" + open "^8.0.9" + p-retry "^4.5.0" + rimraf "^3.0.2" + schema-utils "^4.0.0" + selfsigned "^2.1.1" + serve-index "^1.9.1" + sockjs "^0.3.24" + spdy "^4.0.2" + webpack-dev-middleware "^5.3.1" + ws "^8.13.0" + +webpack-merge@5.8.0: + version "5.8.0" + resolved "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz" + integrity sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q== + dependencies: + clone-deep "^4.0.1" + wildcard "^2.0.0" + +webpack-sources@^3.0.0, webpack-sources@^3.2.3: + 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== + +webpack-subresource-integrity@5.1.0: + version "5.1.0" + resolved "https://registry.npmjs.org/webpack-subresource-integrity/-/webpack-subresource-integrity-5.1.0.tgz" + integrity sha512-sacXoX+xd8r4WKsy9MvH/q/vBtEHr86cpImXwyg74pFIpERKt6FmB8cXpeuh0ZLgclOlHI4Wcll7+R5L02xk9Q== + dependencies: + typed-assert "^1.0.8" + +"webpack@^4.0.0 || ^5.0.0", "webpack@^4.37.0 || ^5.0.0", webpack@^5.0.0, webpack@^5.1.0, webpack@^5.12.0, webpack@^5.30.0, webpack@^5.54.0, webpack@^5.72.1, webpack@>=5, webpack@5.80.0: + version "5.80.0" + resolved "https://registry.npmjs.org/webpack/-/webpack-5.80.0.tgz" + integrity sha512-OIMiq37XK1rWO8mH9ssfFKZsXg4n6klTEDL7S8/HqbAOBBaiy8ABvXvz0dDCXeEF9gqwxSvVk611zFPjS8hJxA== + dependencies: + "@types/eslint-scope" "^3.7.3" + "@types/estree" "^1.0.0" + "@webassemblyjs/ast" "^1.11.5" + "@webassemblyjs/wasm-edit" "^1.11.5" + "@webassemblyjs/wasm-parser" "^1.11.5" + acorn "^8.7.1" + acorn-import-assertions "^1.7.6" + browserslist "^4.14.5" + chrome-trace-event "^1.0.2" + enhanced-resolve "^5.13.0" + es-module-lexer "^1.2.1" + eslint-scope "5.1.1" + events "^3.2.0" + glob-to-regexp "^0.4.1" + graceful-fs "^4.2.9" + json-parse-even-better-errors "^2.3.1" + loader-runner "^4.2.0" + mime-types "^2.1.27" + neo-async "^2.6.2" + schema-utils "^3.1.2" + tapable "^2.1.1" + terser-webpack-plugin "^5.3.7" + watchpack "^2.4.0" + webpack-sources "^3.2.3" + +websocket-driver@^0.7.4, websocket-driver@>=0.5.1: + version "0.7.4" + resolved "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz" + integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== + dependencies: + http-parser-js ">=0.5.1" + safe-buffer ">=5.1.0" + websocket-extensions ">=0.1.1" + +websocket-extensions@>=0.1.1: + version "0.1.4" + resolved "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz" + integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== + +which@^1.2.1: + version "1.3.1" + resolved "https://registry.npmjs.org/which/-/which-1.3.1.tgz" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +which@^2.0.2: + version "2.0.2" + resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +which@^3.0.0: + version "3.0.1" + resolved "https://registry.npmjs.org/which/-/which-3.0.1.tgz" + integrity sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg== + dependencies: + isexe "^2.0.0" + +wide-align@^1.1.5: + version "1.1.5" + resolved "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz" + integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== + dependencies: + string-width "^1.0.2 || 2 || 3 || 4" + +wildcard@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz" + integrity sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ== + +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": + version "7.0.0" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrap-ansi@^8.1.0: + version "8.1.0" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz" + integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== + dependencies: + ansi-styles "^6.1.0" + string-width "^5.0.1" + strip-ansi "^7.0.1" + +wrappy@1: + version "1.0.2" + resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +ws@^8.13.0: + version "8.13.0" + resolved "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz" + integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA== + +ws@~8.11.0: + version "8.11.0" + resolved "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz" + integrity sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg== + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yargs-parser@^20.2.2: + version "20.2.9" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + +yargs-parser@^21.1.1: + version "21.1.1" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz" + integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== + +yargs@^16.1.1: + version "16.2.0" + resolved "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + 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" + +yargs@^17.2.1, yargs@17.7.2: + version "17.7.2" + resolved "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz" + integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== + dependencies: + cliui "^8.0.1" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.1.1" + +yn@3.1.1: + version "3.1.1" + resolved "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz" + integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== + +zone.js@~0.13.0: + version "0.13.0" + resolved "https://registry.npmjs.org/zone.js/-/zone.js-0.13.0.tgz" + integrity sha512-7m3hNNyswsdoDobCkYNAy5WiUulkMd3+fWaGT9ij6iq3Zr/IwJo4RMCYPSDjT+r7tnPErmY9sZpKhWQ8S5k6XQ== + dependencies: + tslib "^2.3.0" diff --git a/manage.py b/manage.py new file mode 100644 index 0000000..1b243ab --- /dev/null +++ b/manage.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python +"""Django's command-line utility for administrative tasks.""" +import os +import sys + + +def main(): + """Run administrative tasks.""" + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'settings') + try: + from django.core.management import execute_from_command_line + except ImportError as exc: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) from exc + execute_from_command_line(sys.argv) + + +if __name__ == '__main__': + main() diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 0000000..7574714 --- /dev/null +++ b/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +python_files=test*.py +DJANGO_SETTINGS_MODULE = settings.test \ No newline at end of file diff --git a/requirements/common.txt b/requirements/common.txt new file mode 100644 index 0000000..bf10fca --- /dev/null +++ b/requirements/common.txt @@ -0,0 +1,15 @@ +Django==4.2.3 +djangorestframework==3.14.0 +Pillow==9.5.0 +django-cors-headers==4.0.0 +paytm-pg==1.1.1 +razorpay==1.3.0 +qrcode==7.4.2 +imgkit==1.2.3 +django-import-export==3.2.0 +cryptography==41.0.2 +celery==5.3.1 +redis==4.6.0 +hiredis==2.2.3 +dj-rest-auth==4.0.1 +djangorestframework-simplejwt==5.2.2 \ No newline at end of file diff --git a/requirements/dev.txt b/requirements/dev.txt new file mode 100644 index 0000000..6d2496b --- /dev/null +++ b/requirements/dev.txt @@ -0,0 +1,5 @@ +-r common.txt +uWSGI==2.0.21 +psycopg==3.1.9 +django-extensions==3.2.1 +pytest-django==4.5.2 diff --git a/requirements/prod.txt b/requirements/prod.txt new file mode 100644 index 0000000..81ac746 --- /dev/null +++ b/requirements/prod.txt @@ -0,0 +1,2 @@ +-r common.txt +sentry-sdk==1.28.1 \ No newline at end of file diff --git a/scripts/__init__.py b/scripts/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/scripts/seed.py b/scripts/seed.py new file mode 100644 index 0000000..d45cc29 --- /dev/null +++ b/scripts/seed.py @@ -0,0 +1,170 @@ +# Command to run : python manage.py shell < scripts/seed.py +from django.conf import settings +from django.contrib.auth.models import User +from event.models import Event, SubEvent, Addon +from base.utils import get_file_content +from django.core.files.base import ContentFile + +def check_database(): + if len(User.objects.all()) > 0: + print( + "Are you sure you want to wipe the existing development database and reseed it? (Y/N)" + ) + if settings.TEST or input().lower() == "y": + destroy_database() + return True + else: + return False + else: + return True + + +def destroy_database(): + print("Destroying existing database...") + print("Destroying User objects...") + User.objects.all().delete() + return True + + +def create_user(is_admin, username=""): + """ + Creates superuser, participant user, host user and returns it. + """ + if is_admin: + username = "admin" + email = "admin@example.com" + else: + email = "%s@example.com" % (username) + user = User.objects.create_user( + email=email, + username=username, + password="password", + is_staff=is_admin, + is_superuser=is_admin, + ) + print( + "{} was created with username: {} password: password".format( + "Super user" if is_admin else "User", username + ) + ) + return user + +def create_event(): + event = Event.objects.create( + name="Sabrang", + description="Sabrang is the flagship annual festival of J K Lakshmipat University, Jaipur (JKLU). Since 2011, Sabrang has been celebrated annually, with the objective to provide students from different colleges and universities an opportunity to display their talents.", + start_date="2023-09-26", + end_date="2023-09-29", + image= ContentFile(get_file_content("example/logo/sabrang-cover-text-e1664621537950.png", "rb"), "logo.png"), + location="JKLU, Jaipur", + price=300.00, + sub_events_included_allowed=3, + is_active=True, + event_page="", + ) + print("Sabrang was created") + return event + +def create_sub_event(event): + sub_event = SubEvent.objects.create( + name="Panache", + description="This is a sub event of Sabrang", + start_date="2023-09-26", + end_date="2020-09-29", + image= ContentFile(get_file_content("example/logo/3-725x1024.png", "rb"), "logo.png"), + price=100.00, + event=event, + is_active=True, + ) + sub_event2 = SubEvent.objects.create( + name="Step Up", + description="This is a sub event of Sabrang", + start_date="2023-09-26", + end_date="2020-09-29", + image= ContentFile(get_file_content("example/logo/4-725x1024.png", "rb"), "logo.png"), + price=100.00, + event=event, + is_active=True, + ) + sub_event3 = SubEvent.objects.create( + name="Band Jam", + description="This is a sub event of Sabrang", + start_date="2023-09-26", + end_date="2020-09-29", + image= ContentFile(get_file_content("example/logo/1-725x1024.png", "rb"), "logo.png"), + price=100.00, + event=event, + is_active=True, + ) + sub_event4 = SubEvent.objects.create( + name="Court Room", + description="This is a sub event of Sabrang", + start_date="2023-09-26", + end_date="2020-09-29", + image= ContentFile(get_file_content("example/logo/6-725x1024.png", "rb"), "logo.png"), + price=100.00, + event=event, + is_active=True, + ) + sub_event5 = SubEvent.objects.create( + name="Bland Coding", + description="This is a sub event of Sabrang", + start_date="2023-09-26", + end_date="2020-09-29", + image= ContentFile(get_file_content("example/logo/5-725x1024.png", "rb"), "logo.png"), + price=100.00, + event=event, + is_active=True, + ) + sub_event6 = SubEvent.objects.create( + name="Bidding", + description="This is a sub event of Sabrang", + start_date="2023-09-26", + end_date="2020-09-29", + image= ContentFile(get_file_content("example/logo/2-725x1024.png", "rb"), "logo.png"), + price=100.00, + event=event, + is_active=True, + ) + sub_event7 = SubEvent.objects.create( + name="Marketing Mystros", + description="This is a sub event of Sabrang", + start_date="2023-09-26", + end_date="2020-09-29", + image= ContentFile(get_file_content("example/logo/7-768x1085.png", "rb"), "logo.png"), + price=100.00, + event=event, + is_active=True, + ) + print("Sub Events was created") + return sub_event, sub_event2, sub_event3, sub_event4, sub_event5, sub_event6, sub_event7 + +def create_addon(event): + addon = Addon.objects.create( + name="Hostel", + icon="hotel", + price=300.00, + event=event, + stock=10, + is_active=True, + ) + print("Addon 1 was created") + return addon + + +def run(*args): + try: + NUMBER_OF_CHALLENGES = int(args[0]) + status = check_database() + if status is False: + print("Seeding aborted.") + return 0 + print("Seeding...") + # Create superuser + create_user(is_admin=True) + event = create_event() + create_sub_event(event) + create_addon(event) + print("Database successfully seeded.") + except Exception as e: + print(e) \ No newline at end of file diff --git a/settings/__init__.py b/settings/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/settings/common.py b/settings/common.py new file mode 100644 index 0000000..c728527 --- /dev/null +++ b/settings/common.py @@ -0,0 +1,194 @@ +""" +Django settings for ticketify project. + +Generated by 'django-admin startproject' using Django 4.2.1. + +For more information on this file, see +https://docs.djangoproject.com/en/4.2/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/4.2/ref/settings/ +""" +import os +from os import getenv +import sys +from pathlib import Path + +# Build paths inside the project like this: BASE_DIR / 'subdir'. +BASE_DIR = Path(__file__).resolve().parent.parent +APPS_DIR = os.path.join(BASE_DIR, "apps") + +sys.path.append(APPS_DIR) + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = os.environ.get("SECRET_KEY", "random_secret_key") + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +TEST = False + +ALLOWED_HOSTS = [] + + +# Application definition + + +DEFAULT_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', +] + +OUR_APPS = [ + 'base', + 'event', + 'ticket', + 'transactions', +] + +THIRD_PARTY_APPS = [ + 'django_extensions', + 'rest_framework', + 'rest_framework.authtoken', + 'corsheaders', + 'import_export', + 'dj_rest_auth' +] + +INSTALLED_APPS = DEFAULT_APPS + OUR_APPS + THIRD_PARTY_APPS + +MIDDLEWARE = [ + 'corsheaders.middleware.CorsMiddleware', + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +ROOT_URLCONF = 'ticketify.urls' +TEMPLATE_DIR = os.path.join(BASE_DIR, "templates") + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [TEMPLATE_DIR], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + + +REST_FRAMEWORK = { + 'DEFAULT_PERMISSION_CLASSES': [ + 'rest_framework.permissions.AllowAny', + ], + 'DEFAULT_AUTHENTICATION_CLASSES': [ + 'rest_framework.authentication.SessionAuthentication', + ] +} + +WSGI_APPLICATION = 'ticketify.wsgi.application' + + +# Password validation +# https://docs.djangoproject.com/en/4.2/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/4.2/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'UTC' + +USE_I18N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/4.2/howto/static-files/ + +STATIC_URL = '/static/' +STATIC_ROOT = os.path.join(BASE_DIR, 'static') + +MEDIA_ROOT = os.path.join(BASE_DIR, "media") +MEDIA_URL = "/media/" + +TICKETIFY_API_SERVER = os.environ.get( + "TICKETIFY_API_SERVER", "http://localhost:8000" +) + +# Default primary key field type +# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field + +DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' + +# Celery settings +CELERY_BROKER_URL = os.environ.get("CELERY_BROKER_URL" , "redis://redis:6379/0") +CELERY_RESULT_BACKEND = os.environ.get("CELERY_RESULT_BACKEND" , "redis://redis:6379/0") +CELERY_ACCEPT_CONTENT = ["application/json"] +CELERY_TASK_SERIALIZER = "json" +CELERY_RESULT_SERIALIZER = "json" +CELERY_TIMEZONE = os.environ.get("TIME_ZONE", "Asia/Kolkata") + +CACHES = { + "default": { + "BACKEND": "django.core.cache.backends.redis.RedisCache", + "LOCATION": os.environ.get("REDIS_HOST_URL", "redis://localhost:6379"), + 'OPTIONS': { + "db": "10", + } + } +} + +# CORS settings +CORS_ALLOW_CREDENTIALS = True + +CORS_ALLOWED_ORIGINS = [ + "http://localhost:4200", +] + +CSRF_COOKIE_SECURE = True +CSRF_COOKIE_SAMESITE = 'None' + +if getenv("CSRF_TRUSTED_ORIGINS"): + CSRF_TRUSTED_ORIGINS = getenv("CSRF_TRUSTED_ORIGINS").split(",") +else: + CSRF_TRUSTED_ORIGINS = [] + +HOSTNAME = os.environ.get("HOSTNAME", "localhost:8000") + +FRONTEND_URL = os.environ.get("FRONTEND_URL", "localhost:4200") \ No newline at end of file diff --git a/settings/dev.py b/settings/dev.py new file mode 100644 index 0000000..aec3ff1 --- /dev/null +++ b/settings/dev.py @@ -0,0 +1,18 @@ +from .common import * + +ALLOWED_HOSTS = ["*"] + +# Database +# https://docs.djangoproject.com/en/4.2/ref/settings/#databases +DATABASES = { + "default": { + "ENGINE": "django.db.backends.postgresql", + "NAME": os.environ.get("POSTGRES_NAME", "ticketify"), + "USER": os.environ.get("POSTGRES_USER", "postgres"), + "PASSWORD": os.environ.get("POSTGRES_PASSWORD", "postgres"), + "HOST": os.environ.get("POSTGRES_HOST", "localhost"), + "PORT": os.environ.get("POSTGRES_PORT", 5432), + } +} + +EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend" diff --git a/settings/prod.py b/settings/prod.py new file mode 100644 index 0000000..b8ceaea --- /dev/null +++ b/settings/prod.py @@ -0,0 +1,37 @@ +from .common import * +import sentry_sdk +from sentry_sdk.integrations.django import DjangoIntegration + + +# Email settings if EMAIL_REQUIRED is set to True +if os.environ.get("EMAIL_REQUIRED") == "True": + EMAIL_HOST = os.environ.get("EMAIL_HOST", "email_host") + EMAIL_PORT = os.environ.get("EMAIL_PORT", "email_port") + EMAIL_HOST_USER = os.environ.get("EMAIL_HOST_USER", "email_host_user") + EMAIL_HOST_PASSWORD = os.environ.get("EMAIL_HOST_PASSWORD", "email_host_password") + EMAIL_USE_SSL = os.environ.get("EMAIL_USE_SSL", "email_use_ssl") + EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' + DEFAULT_FROM_EMAIL = EMAIL_HOST_USER + +# Database +DATABASES = { + "default": { + "ENGINE": "django.db.backends.postgresql", + "NAME": os.environ.get("POSTGRES_NAME", "ticketify"), + "USER": os.environ.get("POSTGRES_USER", "postgres"), + "PASSWORD": os.environ.get("POSTGRES_PASSWORD", "postgres"), + "HOST": os.environ.get("POSTGRES_HOST", "localhost"), + "PORT": os.environ.get("POSTGRES_PORT", 5432), + } +} + + +# Rest Framework +REST_FRAMEWORK = { + 'DEFAULT_RENDERER_CLASSES': ( + 'rest_framework.renderers.JSONRenderer', + ) +} + +if os.environ.get("SENTRY_ENABLED") == "True": + sentry_sdk.init(dsn=os.environ.get("SENTRY_DSN") ,integrations=[DjangoIntegration()] ,traces_sample_rate=1.0 ,send_default_pii=True) \ No newline at end of file diff --git a/settings/test.py b/settings/test.py new file mode 100644 index 0000000..fa64508 --- /dev/null +++ b/settings/test.py @@ -0,0 +1,18 @@ +from .common import * + +DEBUG = False + +# E-Mail Settings +EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend" + +# Database +DATABASES = { + "default": { + "ENGINE": "django.db.backends.sqlite3", + "NAME": "mydatabase", + } +} + +CELERY_TASK_ALWAYS_EAGER = True + +TEST = True \ No newline at end of file diff --git a/static/.gitignore b/static/.gitignore new file mode 100644 index 0000000..71059e1 --- /dev/null +++ b/static/.gitignore @@ -0,0 +1,5 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore +!.htaccess \ No newline at end of file diff --git a/templates/ticket/style.css b/templates/ticket/style.css new file mode 100644 index 0000000..9dbc3d8 --- /dev/null +++ b/templates/ticket/style.css @@ -0,0 +1,184 @@ +@import url("https://fonts.googleapis.com/css2?family=Staatliches&display=swap"); +@import url("https://fonts.googleapis.com/css2?family=Nanum+Pen+Script&display=swap"); + +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body, +html { + height: 100vh; + display: grid; + font-family: "Staatliches", cursive; + color: black; + font-size: 14px; + letter-spacing: 0.1em; +} + +.ticket { + margin: auto; + display: flex; + background: white; + box-shadow: rgba(0, 0, 0, 0.3) 0px 19px 38px, rgba(0, 0, 0, 0.22) 0px 15px 12px; +} + +.left { + display: flex; +} + +.image { + height: 250px; + width: 250px; + background-image: url("https://media.pitchfork.com/photos/60db53e71dfc7ddc9f5086f9/1:1/w_1656,h_1656,c_limit/Olivia-Rodrigo-Sour-Prom.jpg"); + background-size: contain; + opacity: 0.85; +} + +.admit-one { + position: absolute; + color: darkgray; + height: 250px; + padding: 0 10px; + letter-spacing: 0.15em; + display: flex; + text-align: center; + justify-content: space-around; + writing-mode: vertical-rl; + transform: rotate(-180deg); +} + +.admit-one span:nth-child(2) { + color: white; + font-weight: 700; +} + +.left .ticket-number { + height: 250px; + width: 250px; + display: flex; + justify-content: flex-end; + align-items: flex-end; + padding: 5px; +} + +.ticket-info { + padding: 10px 30px; + display: flex; + flex-direction: column; + text-align: center; + justify-content: space-between; + align-items: center; +} + +.date { + border-top: 1px solid gray; + border-bottom: 1px solid gray; + padding: 5px 0; + font-weight: 700; + display: flex; + align-items: center; + justify-content: space-around; +} + +.date span { + width: 100px; +} + +.date span:first-child { + text-align: left; +} + +.date span:last-child { + text-align: right; +} + +.date .june-29 { + color: #d83565; + font-size: 20px; +} + +.show-name { + font-size: 32px; + font-family: "Nanum Pen Script", cursive; + color: #d83565; +} + +.show-name h1 { + font-size: 48px; + font-weight: 700; + letter-spacing: 0.1em; + color: #4a437e; +} + +.time { + padding: 10px 0; + color: #4a437e; + text-align: center; + display: flex; + flex-direction: column; + gap: 10px; + font-weight: 700; +} + +.time span { + font-weight: 400; + color: gray; +} + +.left .time { + font-size: 16px; +} + + +.location { + display: flex; + justify-content: space-around; + align-items: center; + width: 100%; + padding-top: 8px; + border-top: 1px solid gray; +} + +.location .separator { + font-size: 20px; +} + +.right { + width: 180px; + border-left: 1px dashed #404040; +} + +.right .admit-one { + color: darkgray; +} + +.right .admit-one span:nth-child(2) { + color: gray; +} + +.right .right-info-container { + height: 250px; + padding: 10px 10px 10px 35px; + display: flex; + flex-direction: column; + justify-content: space-around; + align-items: center; +} + +.right .show-name h1 { + font-size: 18px; +} + +.barcode { + height: 100px; +} + +.barcode img { + height: 100%; +} + +.right .ticket-number { + color: gray; +} diff --git a/templates/ticket/ticket_template.html b/templates/ticket/ticket_template.html new file mode 100644 index 0000000..ae21153 --- /dev/null +++ b/templates/ticket/ticket_template.html @@ -0,0 +1,268 @@ + + + + QR Code Ticket + + + + +
+
+
+

+ {{spam}} + {{spam}} + {{spam}} +

+
+

{{ticketNumber}}

+
+
+
+

+ {{day}} + {{date}} + {{year}} +

+
+

+

{{artistName}}

+
+
+

{{timeSlot}}

+

+ {% for sub_event in doors %} + {{ sub_event }}{% if not forloop.last %}, {% endif %} + {% if forloop.counter|divisibleby:4 %}
{% endif %} + {% endfor %} +

+ +
+

+ {{location}} +

+
+
+
+

+ {{spam}} + {{spam}} + {{spam}} +

+
+
+

{{showName}}

+
+
+

{{timeSlot}}

+

+ {% for sub_event in doors %} + {{ sub_event }}{% if not forloop.last %}, {% endif %} + {% if forloop.counter|divisibleby:4 %}
{% endif %} + {% endfor %} +

+
+
+ QR code +
+

{{ticketNumber}}

+
+
+
+ + diff --git a/tests/unit/__init__.py b/tests/unit/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/unit/base/__init__.py b/tests/unit/base/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/unit/base/test_utils.py b/tests/unit/base/test_utils.py new file mode 100644 index 0000000..0029b4b --- /dev/null +++ b/tests/unit/base/test_utils.py @@ -0,0 +1,60 @@ +import os +from django.core import mail +from django.test import TestCase +from base.utils import get_url_from_hostname, EmailService, get_file_content +from django.conf import settings + + +class TestGetUrl(TestCase): + def test_get_url_from_hostname(self): + settings.DEBUG = True + url = get_url_from_hostname("localhost:8000") + self.assertEqual(url, "http://localhost:8000") + + def test_get_url_from_hostname_with_https(self): + settings.DEBUG = False + settings.TEST = False + url = get_url_from_hostname("localhost:8000") + self.assertEqual(url, "https://localhost:8000") + +class TestEmailService(TestCase): + def test_email_service(self): + subject = "Test Email" + message = "This is a test email." + recipient_list = ["test@example.com"] + from_email = "noreply@example.com" + html_message = "

This is a test email.

" + + EmailService(subject, message, recipient_list, from_email, html_message) + + # Check that the email was sent successfully + self.assertEqual(len(mail.outbox), 1) + self.assertEqual(mail.outbox[0].subject, subject) + self.assertEqual(mail.outbox[0].body, message) + self.assertEqual(mail.outbox[0].from_email, from_email) + self.assertEqual(mail.outbox[0].to, recipient_list) + self.assertEqual(mail.outbox[0].alternatives[0][0], html_message) + + +class TestGetFileContent(TestCase): + def setUp(self): + # Create a temporary file with sample content for testing + self.file_path = "test_file.txt" + with open(self.file_path, "w") as f: + f.write("This is a test file.\nLine 2.\nLine 3.") + + def tearDown(self): + # Remove the temporary file after the test is done + os.remove(self.file_path) + + def test_get_file_content_existing_file(self): + # Test when providing an existing file path + expected_content = "This is a test file.\nLine 2.\nLine 3." + actual_content = get_file_content(self.file_path, "r") + self.assertEqual(actual_content, expected_content) + + def test_get_file_content_nonexistent_file(self): + # Test when providing a non-existent file path + nonexistent_file = "nonexistent.txt" + with self.assertRaises(FileNotFoundError): + get_file_content(nonexistent_file, "r") diff --git a/tests/unit/event/__init__.py b/tests/unit/event/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/unit/event/test_views.py b/tests/unit/event/test_views.py new file mode 100644 index 0000000..94f64e4 --- /dev/null +++ b/tests/unit/event/test_views.py @@ -0,0 +1,316 @@ +from decimal import Decimal +from django.test import TestCase +from django.urls import reverse +from event.models import Event, SubEvent, Addon, PromoCode +from ticket.models import Ticket +from transactions.models import Transaction +from django.contrib.auth.models import User + + +class TestEvent(TestCase): + def setUp(self): + self.event = Event.objects.create( + name="Event", + description="Test Event", + start_date="2023-09-26", + end_date="2023-09-29", + location="Test", + price=300.00, + sub_events_included_allowed=3, + is_active=True, + event_page="", + ) + def test_get_event_when_active(self): + expected = [ + { + "id": self.event.id, + "name": self.event.name, + "description": self.event.description, + "start_date": self.event.start_date, + "end_date": self.event.end_date, + "image": None, + "location": self.event.location, + "event_page": self.event.event_page, + "price": format(self.event.price, ".2f"), + "sub_events_included_allowed": self.event.sub_events_included_allowed, + } + ] + response = self.client.get(reverse('get_active_event')) + self.assertEqual(response.data, expected) + self.assertEqual(response.status_code, 200) + + def test_get_event_when_inactive(self): + self.event.is_active = False + self.event.save() + response = self.client.get(reverse('get_active_event')) + self.assertEqual(response.status_code, 400) + + +class TestSubEvent(TestCase): + def setUp(self): + self.event = Event.objects.create( + name="Event", + description="Test Event", + start_date="2023-09-26", + end_date="2023-09-29", + location="Test", + price=300.00, + sub_events_included_allowed=3, + is_active=True, + event_page="", + ) + + self.sub_event = SubEvent.objects.create( + name="SubEvent", + description="This is a sub event of Event", + start_date="2023-09-26", + end_date="2020-09-29", + price=100.00, + event=self.event, + is_active=True, + ) + + def test_get_subevent_when_active(self): + expected = [ + { + "id": self.sub_event.id, + "name": self.sub_event.name, + "description": self.sub_event.description, + "start_date": self.sub_event.start_date, + "end_date": self.sub_event.end_date, + "image": None, + "event": self.sub_event.event.id, + "price": format(self.sub_event.price, ".2f"), + } + ] + + response = self.client.get(reverse('get_sub_event', kwargs={'pk': self.event.id})) + self.assertEqual(response.data, expected) + self.assertEqual(response.status_code, 200) + + def test_get_subevent_when_inactive(self): + self.sub_event.is_active = False + self.sub_event.save() + response = self.client.get(reverse('get_sub_event', kwargs={'pk': self.event.id})) + self.assertEqual(response.status_code, 400) + + +class TestAddon(TestCase): + def setUp(self): + self.event = Event.objects.create( + name="Event", + description="Test Event", + start_date="2023-09-26", + end_date="2023-09-29", + location="Test", + price=300.00, + sub_events_included_allowed=3, + is_active=True, + event_page="", + ) + + self.addon= Addon.objects.create( + name="Hostel", + icon="hotel", + price=300.00, + event=self.event, + stock=10, + is_active=True, + ) + + def test_get_addon_when_active(self): + expected = [ + { + "id": self.addon.id, + "name": self.addon.name, + "icon": self.addon.icon, + "event": self.addon.event.id, + "price": format(self.addon.price, ".2f"), + "stock": self.addon.stock, + } + ] + + response = self.client.get(reverse('get_addon', kwargs={'pk': self.event.id})) + self.assertEqual(response.data, expected) + self.assertEqual(response.status_code, 200) + + def test_get_addon_when_inactive(self): + self.addon.is_active = False + self.addon.save() + response = self.client.get(reverse('get_addon', kwargs={'pk': self.event.id})) + self.assertEqual(response.status_code, 400) + + +class TestPromoCode(TestCase): + def setUp(self): + self.event = Event.objects.create( + name="Event", + description="Test Event", + start_date="2023-09-26", + end_date="2023-09-29", + location="Test", + price=300.00, + sub_events_included_allowed=3, + is_active=True, + event_page="", + ) + + self.promo_code = PromoCode.objects.create( + code="TEST", + discount=10, + event=self.event, + stock=10, + ) + + def test_get_promo_code_when_active(self): + expected = { + "discount": self.promo_code.discount, + } + + response = self.client.post(reverse('process_promo_code'), data={"promo_code": self.promo_code.code, "event_id": self.event.id}) + self.assertEqual(response.data, expected) + self.assertEqual(response.status_code, 200) + + def test_get_promo_code_when_inactive(self): + self.promo_code.is_active = False + self.promo_code.save() + response = self.client.post(reverse('process_promo_code'), data={"promo_code": self.promo_code.code, "event_id": self.event.id}) + self.assertEqual(response.status_code, 400) + + def test_get_promo_when_stock_zero(self): + self.promo_code.stock = 0 + self.promo_code.save() + response = self.client.post(reverse('process_promo_code'), data={"promo_code": self.promo_code.code, "event_id": self.event.id}) + self.assertEqual(response.status_code, 400) + + def test_get_promo_code_when_invalid(self): + response = self.client.post(reverse('process_promo_code'), data={"promo_code": "INVALID", "event_id": self.event.id}) + self.assertEqual(response.status_code, 400) + + +class TestStats(TestCase): + def setUp(self): + + self.user = User.objects.create_user( + username="testuser", + email="example@example.com", + password="testpassword", + ) + + self.event = Event.objects.create( + name="Event", + description="Test Event", + start_date="2023-09-26", + end_date="2023-09-29", + location="Test", + price=300.00, + sub_events_included_allowed=3, + is_active=True, + event_page="", + ) + + self.sub_event = SubEvent.objects.create( + name="SubEvent", + description="This is a sub event of Event", + start_date="2023-09-26", + end_date="2020-09-29", + price=100.00, + event=self.event, + is_active=True, + ) + + self.addon = Addon.objects.create( + name="Hostel", + icon="hotel", + price=300.00, + event=self.event, + stock=10, + is_active=True, + ) + + self.transaction = Transaction.objects.create( + payment_method="upi", + payment_status="captured", + order_id="1234567890", + payment_id="1234567890", + payment_amount=self.event.price + self.sub_event.price + self.addon.price, + payment_currency="INR", + ) + + self.ticket = Ticket.objects.create( + customer_name="Test User", + customer_email="example@example.com", + customer_phone="1234567890", + event=self.event, + is_active=True, + transaction_id=self.transaction, + ) + + self.ticket.selected_sub_events.set([self.sub_event]) + self.ticket.selected_addons.set([self.addon]) + + self.client.force_login(self.user) + + def test_get_max_ticket_sales(self): + expected = { + "total_tickets": 1, + "total_amount": Decimal(format(self.event.price + self.sub_event.price + self.addon.price , ".2f")), + } + + response = self.client.get(reverse('get_max_ticket_sales', kwargs={'pk': self.event.id})) + self.assertEqual(response.data, expected) + self.assertEqual(response.status_code, 200) + + def test_get_sub_event_sales(self): + expected = { + "data": [1], + "label": ["SubEvent"], + } + + response = self.client.get(reverse('get_sub_event_sales', kwargs={'pk': self.event.id})) + self.assertEqual(response.data, expected) + self.assertEqual(response.status_code, 200) + + def test_get_addon_sales(self): + expected = { + "data": [1], + "label": ["Hostel"], + } + + response = self.client.get(reverse('get_addon_sales', kwargs={'pk': self.event.id})) + self.assertEqual(response.data, expected) + self.assertEqual(response.status_code, 200) + + def test_get_max_ticket_sales_when_no_tickets(self): + self.ticket.delete() + expected = { + "total_tickets": 0, + "total_amount": 0.00, + } + + response = self.client.get(reverse('get_max_ticket_sales', kwargs={'pk': self.event.id})) + self.assertEqual(response.data, expected) + self.assertEqual(response.status_code, 200) + + def test_get_sub_event_sales_when_no_tickets(self): + self.ticket.delete() + expected = { + "data": [0], + "label": ["SubEvent"], + } + + response = self.client.get(reverse('get_sub_event_sales', kwargs={'pk': self.event.id})) + self.assertEqual(response.data, expected) + self.assertEqual(response.status_code, 200) + + def test_get_addon_sales_when_no_tickets(self): + self.ticket.delete() + expected = { + "data": [0], + "label": ["Hostel"], + } + + response = self.client.get(reverse('get_addon_sales', kwargs={'pk': self.event.id})) + self.assertEqual(response.data, expected) + self.assertEqual(response.status_code, 200) + diff --git a/tests/unit/ticket/test_utils.py b/tests/unit/ticket/test_utils.py new file mode 100644 index 0000000..1feb54a --- /dev/null +++ b/tests/unit/ticket/test_utils.py @@ -0,0 +1,108 @@ +from ticket.utils import generate_ticket_image, create_ticket, generate_qr_code, encrypt_decrypt_ticket_id +from django.test import TestCase +from rest_framework.test import APIRequestFactory +from ticket.models import Ticket +from unittest.mock import patch +from event.models import Event, SubEvent, Addon + + +class TestCreateTicket(TestCase): + def setUp(self): + self.event = Event.objects.create( + name="Event", + description="Test Event", + start_date="2023-09-26", + end_date="2023-09-29", + location="Test", + price=300.00, + sub_events_included_allowed=3, + is_active=True, + event_page="", + ) + self.sub_event = SubEvent.objects.create( + name="SubEvent", + description="This is a sub event of Event", + start_date="2023-09-26", + end_date="2020-09-29", + price=100.00, + event=self.event, + is_active=True, + ) + + self.addon = Addon.objects.create( + name="Hostel", + icon="hotel", + price=300.00, + event=self.event, + stock=10, + is_active=True, + ) + + def test_create_ticket(self): + order_id = 1 + request_data = { + "customer_name": "Test User", + "customer_email": "example@example.com", + "customer_phone": "1234567890", + "event_id": self.event.id, + "selected_sub_events": [self.sub_event.id], + "selected_addons": [self.addon.id], + } + factory = APIRequestFactory() + request = factory.post('/create_ticket/') + request.data = request_data + create_ticket(request, order_id) + + # Check that the ticket was created successfully + self.assertEqual(Ticket.objects.count(), 1) + ticket = Ticket.objects.first() + self.assertEqual(ticket.customer_name, request_data["customer_name"]) + self.assertEqual(ticket.customer_email, request_data["customer_email"]) + self.assertEqual(ticket.customer_phone, request_data["customer_phone"]) + self.assertEqual(ticket.event_id, request_data["event_id"]) + self.assertEqual(ticket.selected_sub_events.count(), 1) + self.assertEqual(ticket.selected_addons.count(), 1) + self.assertEqual(int(ticket.order_id), order_id) + + +class TestGenerateTicketImage(TestCase): + @patch("ticket.utils.imgkit") + @patch("ticket.utils.send_ticket") + def test_generate_ticket_image(self, mock_imgkit, mock_send_ticket): + self.event = Event.objects.create( + name="Event", + description="Test Event", + start_date="2023-09-26", + end_date="2023-09-29", + location="Test", + price=300.00, + sub_events_included_allowed=3, + is_active=True, + event_page="", + ) + self.ticket = Ticket.objects.create( + customer_name="Test User", + customer_email="example@email.com", + customer_phone="1234567890", + event_id=1, + ) + mock_imgkit.from_string.return_value = None + mock_send_ticket.return_value = None + generate_ticket_image(self.ticket.id) + self.assertNotEqual(self.ticket.ticket_image_location, None) + + +class TestGenerateQRCode(TestCase): + def test_generate_qr_code(self): + ticket_id = 14323 + qr_code_image = generate_qr_code(ticket_id) + self.assertNotEqual(qr_code_image, None) + + +class TestEncryptDecryptTicketId(TestCase): + def test_encrypt_decrypt_ticket_id(self): + ticket_id = 'DFGN45' + encrypted_ticket_id = encrypt_decrypt_ticket_id(ticket_id) + self.assertNotEqual(encrypted_ticket_id, None) + decrypted_ticket_id = encrypt_decrypt_ticket_id(encrypted_ticket_id, True) + self.assertEqual(decrypted_ticket_id, ticket_id) \ No newline at end of file diff --git a/tests/unit/ticket/test_views.py b/tests/unit/ticket/test_views.py new file mode 100644 index 0000000..d2132d9 --- /dev/null +++ b/tests/unit/ticket/test_views.py @@ -0,0 +1,370 @@ +import datetime +from unittest.mock import patch +from django.test import TestCase +from event.models import Event, SubEvent, Addon +from ticket.models import Ticket, CheckIn +from transactions.models import Transaction +from django.contrib.auth.models import User +from django.utils.timezone import make_aware + + +class TestTicket(TestCase): + def setUp(self): + self.user = User.objects.create_user( + username="testuser", password="testpassword" + ) + self.event = Event.objects.create( + name="Event", + description="Test Event", + start_date="2023-09-26", + end_date="2023-09-29", + location="Test", + price=300.00, + sub_events_included_allowed=3, + is_active=True, + event_page="", + ) + self.sub_event = SubEvent.objects.create( + name="SubEvent", + description="This is a sub event of Event", + start_date="2023-09-26", + end_date="2020-09-29", + price=100.00, + event=self.event, + is_active=True, + ) + self.addon = Addon.objects.create( + name="Hostel", + icon="hotel", + price=300.00, + event=self.event, + stock=10, + is_active=True, + ) + self.transaction = Transaction.objects.create( + payment_method="upi", + payment_status="captured", + order_id="1234567890", + payment_id="1234567890", + payment_amount=self.event.price + self.sub_event.price + self.addon.price, + payment_currency="INR", + ) + self.ticket = Ticket.objects.create( + customer_name="Test User", + customer_email="example@email.com", + customer_phone="1234567890", + event_id=1, + is_active=True, + check_in="1234567890", + transaction_id=self.transaction, + ) + self.ticket.selected_sub_events.add(self.sub_event) + self.ticket.selected_addons.add(self.addon) + + def test_get_tickets_by_filter_without_ticket_id(self): + self.client.force_login(self.user) + + request = self.client.post( + "/api/ticket/get_tickets_by_filter/", + { + "email": self.ticket.customer_email, + "phone": self.ticket.customer_phone, + "name": self.ticket.customer_name, + }, + ) + self.assertEqual(request.status_code, 200) + + def test_get_tickets_by_filter_with_ticket_id(self): + self.client.force_login(self.user) + + request = self.client.post( + "/api/ticket/get_tickets_by_filter/", + { + "ticket_id": self.ticket.check_in, + }, + ) + self.assertEqual(request.status_code, 200) + + def test_get_tickets_by_filter_with_in_active_ticket(self): + self.client.force_login(self.user) + self.ticket.is_active = False + self.ticket.save() + request = self.client.post( + "/api/ticket/get_tickets_by_filter/", + { + "email": self.ticket.customer_email, + "phone": self.ticket.customer_phone, + "name": self.ticket.customer_name, + }, + ) + self.assertEqual(request.status_code, 400) + + self.ticket.is_active = True + self.ticket.save() + + def test_handle_check_in_with_qr(self): + self.client.force_login(self.user) + request = self.client.post( + "/api/ticket/handle_check_in/", + { + "ticket_id": self.ticket.check_in, + "operator": self.user.id, + }, + ) + self.assertEqual(request.status_code, 200) + + def test_handle_check_in_with_manual(self): + self.client.force_login(self.user) + request = self.client.post( + "/api/ticket/handle_check_in/", + { + "ticket_id": self.ticket.id, + }, + ) + self.assertEqual(request.status_code, 200) + + def test_handle_check_in_with_invalid_ticket_id(self): + self.client.force_login(self.user) + request = self.client.post( + "/api/ticket/handle_check_in/", + { + "ticket_id": "123456789s0", + }, + ) + self.assertEqual(request.status_code, 400) + + def test_handle_check_in_with_inactive_ticket(self): + self.client.force_login(self.user) + self.ticket.is_active = False + self.ticket.save() + request = self.client.post( + "/api/ticket/handle_check_in/", + { + "ticket_id": self.ticket.id, + }, + ) + self.assertEqual(request.status_code, 400) + + self.ticket.is_active = True + self.ticket.save() + + def test_handle_check_in_with_event_ended(self): + self.client.force_login(self.user) + self.event.end_date = "2020-09-29" + self.event.save() + request = self.client.post( + "/api/ticket/handle_check_in/", + { + "ticket_id": self.ticket.id, + }, + ) + self.assertEqual(request.status_code, 400) + + self.event.end_date = "2023-09-29" + self.event.save() + + def test_handle_check_in_already_check_in_for_the_day(self): + self.client.force_login(self.user) + CheckIn.objects.create( + ticket=self.ticket, + operator=self.user.id, + method="QR", + check_in_time=datetime.datetime.now(), + ) + request = self.client.post( + "/api/ticket/handle_check_in/", + { + "ticket_id": self.ticket.id, + }, + ) + self.assertEqual(request.status_code, 400) + + def test_handle_check_in_other_day_check_in(self): + self.client.force_login(self.user) + past_date = datetime.datetime.now() - datetime.timedelta(days=1) + past_date_aware = make_aware(past_date) + with patch('django.utils.timezone.now', return_value=past_date_aware): + CheckIn.objects.create( + ticket=self.ticket, + operator=self.user.id, + method="QR", + ) + request = self.client.post( + "/api/ticket/handle_check_in/", + { + "ticket_id": self.ticket.id, + }, + ) + self.assertEqual(request.status_code, 200) + + def test_handle_check_in_with_no_ticket_id(self): + self.client.force_login(self.user) + request = self.client.post( + "/api/ticket/handle_check_in/", + ) + self.assertEqual(request.status_code, 400) + + def test_get_check_in_data(self): + self.client.force_login(self.user) + CheckIn.objects.create( + ticket=self.ticket, + operator=self.user.id, + method="QR", + ) + request = self.client.post( + "/api/ticket/get_check_in_data/", + { + "ticket_id": self.ticket.id, + }, + ) + self.assertEqual(request.status_code, 200) + + def test_get_check_in_data_with_no_ticket_id(self): + self.client.force_login(self.user) + request = self.client.post( + "/api/ticket/get_check_in_data/", + ) + self.assertEqual(request.status_code, 400) + + def test_get_check_in_data_with_invalid_ticket_id(self): + self.client.force_login(self.user) + request = self.client.post( + "/api/ticket/get_check_in_data/", + { + "ticket_id": "1234567890", + }, + ) + self.assertEqual(request.status_code, 400) + + def test_get_check_in_data_with_no_check_in(self): + self.client.force_login(self.user) + request = self.client.post( + "/api/ticket/get_check_in_data/", + { + "ticket_id": self.ticket.id, + }, + ) + self.assertEqual(request.status_code, 400) + + def test_get_check_in_data_with_inactive_ticket(self): + self.client.force_login(self.user) + self.ticket.is_active = False + self.ticket.save() + request = self.client.post( + "/api/ticket/get_check_in_data/", + { + "ticket_id": self.ticket.id, + }, + ) + self.assertEqual(request.status_code, 400) + + self.ticket.is_active = True + self.ticket.save() + + def test_resend_ticket_email(self): + self.client.force_login(self.user) + request = self.client.post( + "/api/ticket/resend_email/", + { + "ticket_id": self.ticket.id, + }, + ) + self.assertEqual(request.status_code, 200) + + def test_resend_ticket_email_with_invalid_ticket_id(self): + self.client.force_login(self.user) + request = self.client.post( + "/api/ticket/resend_email/", + { + "ticket_id": "1234567890", + }, + ) + self.assertEqual(request.status_code, 400) + + def test_resend_ticket_email_with_inactive_ticket(self): + self.client.force_login(self.user) + self.ticket.is_active = False + self.ticket.save() + request = self.client.post( + "/api/ticket/resend_email/", + { + "ticket_id": self.ticket.id, + }, + ) + self.assertEqual(request.status_code, 400) + + self.ticket.is_active = True + self.ticket.save() + + def test_get_ticket_by_subevents(self): + self.client.force_login(self.user) + request = self.client.post( + "/api/ticket/get_ticket_by_subevents/", + { + "list_id": self.sub_event.id, + }, + ) + self.assertEqual(request.status_code, 200) + + def test_get_ticket_by_subevents_with_invalid_subevent_id(self): + self.client.force_login(self.user) + request = self.client.post( + "/api/ticket/get_ticket_by_subevents/", + { + "list_id": "1234567890", + }, + ) + self.assertEqual(request.status_code, 400) + + def test_get_ticket_by_subevents_with_inactive_subevent(self): + self.client.force_login(self.user) + self.sub_event.is_active = False + self.sub_event.save() + request = self.client.post( + "/api/ticket/get_ticket_by_subevents/", + { + "list_id": self.sub_event.id, + }, + ) + self.assertEqual(request.status_code, 400) + + self.sub_event.is_active = True + self.sub_event.save() + + def test_get_ticket_by_addons(self): + self.client.force_login(self.user) + request = self.client.post( + "/api/ticket/get_ticket_by_addons/", + { + "list_id": self.addon.id, + }, + ) + self.assertEqual(request.status_code, 200) + + def test_get_ticket_by_addons_with_invalid_addon_id(self): + self.client.force_login(self.user) + request = self.client.post( + "/api/ticket/get_ticket_by_addons/", + { + "list_id": "1234567890", + }, + ) + self.assertEqual(request.status_code, 400) + + def test_get_ticket_by_addons_with_inactive_addon(self): + self.client.force_login(self.user) + self.addon.is_active = False + self.addon.save() + request = self.client.post( + "/api/ticket/get_ticket_by_addons/", + { + "list_id": self.addon.id, + }, + ) + self.assertEqual(request.status_code, 400) + + self.addon.is_active = True + self.addon.save() + + + \ No newline at end of file diff --git a/ticketify/__init__.py b/ticketify/__init__.py new file mode 100644 index 0000000..9e0d95f --- /dev/null +++ b/ticketify/__init__.py @@ -0,0 +1,3 @@ +from .celery import app as celery_app + +__all__ = ('celery_app',) \ No newline at end of file diff --git a/ticketify/asgi.py b/ticketify/asgi.py new file mode 100644 index 0000000..0140782 --- /dev/null +++ b/ticketify/asgi.py @@ -0,0 +1,16 @@ +""" +ASGI config for ticketify project. + +It exposes the ASGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/4.2/howto/deployment/asgi/ +""" + +import os + +from django.core.asgi import get_asgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'ticketify.settings') + +application = get_asgi_application() diff --git a/ticketify/celery.py b/ticketify/celery.py new file mode 100644 index 0000000..5cccf84 --- /dev/null +++ b/ticketify/celery.py @@ -0,0 +1,23 @@ +import os + +from celery import Celery +from django.conf import settings + +# Set the default Django settings module for the 'celery' program. +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings") + +app = Celery(broker=settings.CELERY_BROKER_URL) +app.conf.enable_utc = False +# Using a string here means the worker doesn't have to serialize +# the configuration object to child processes. +# - namespace='CELERY' means all celery-related configuration keys +# should have a `CELERY_` prefix. +app.config_from_object("django.conf:settings", namespace='CELERY') + +# Load task modules from all registered Django apps. +app.autodiscover_tasks() + + +@app.task(bind=True, ignore_result=True) +def debug_task(self): + print(f'Request: {self.request!r}') \ No newline at end of file diff --git a/ticketify/urls.py b/ticketify/urls.py new file mode 100644 index 0000000..9d87b00 --- /dev/null +++ b/ticketify/urls.py @@ -0,0 +1,36 @@ +""" +URL configuration for ticketify project. + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/4.2/topics/http/urls/ +Examples: +Function views + 1. Add an import: from my_app import views + 2. Add a URL to urlpatterns: path('', views.home, name='home') +Class-based views + 1. Add an import: from other_app.views import Home + 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') +Including another URLconf + 1. Import the include() function: from django.urls import include, path + 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) +""" +from django.contrib import admin +from django.urls import path, include +from django.conf import settings +from django.conf.urls.static import static + +urlpatterns = [ + path('api/admin/', admin.site.urls), + path('api/event/', include('event.urls')), + path('api/transactions/', include('transactions.urls')), + path('api/ticket/', include('ticket.urls')), + path('api/', include('dj_rest_auth.urls')), +] + +if settings.DEBUG: + urlpatterns += ( + [ + ] + + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) + + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) + ) diff --git a/ticketify/wsgi.py b/ticketify/wsgi.py new file mode 100644 index 0000000..c613849 --- /dev/null +++ b/ticketify/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for ticketify project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/4.2/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'ticketify.settings') + +application = get_wsgi_application()